diff --git a/DEPS b/DEPS index 3f5f3f8..48f4de84 100644 --- a/DEPS +++ b/DEPS
@@ -42,12 +42,12 @@ 'boringssl_git': 'https://boringssl.googlesource.com', 'libvpx_revision': '5cdd30205301c293be6160f778bce981300b5a28', 'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac', - 'skia_revision': 'fef4c32bdf02f1bf3cde722cd48c4ac4cd137ab6', + 'skia_revision': 'f16201250315bd807e06547f1c412fcdc5c8805a', # 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': 'c9709b92ec2a695cf85a688f63eff3ef97939a78', + 'v8_revision': 'e8694f69297c3bee240490aecd29fab6c40ec3f0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling WebRTC # and V8 without interference from each other. @@ -58,7 +58,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'bc393df9cd8ae893da686533644da29a8c4911ae', + 'angle_revision': '592ab9dd91e653f5c2d4f7395267046d229e20c1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -66,7 +66,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'b3a788e5e37955620b26be5b6e3048d37b605e00', + 'pdfium_revision': '615082de70c7fc18d46d0d1a03b62d0d76b1daa9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -74,7 +74,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': 'be629e0e920ae32cca691f5e45410ff00db1a849', + 'boringssl_revision': '8f5e2ebcee628ef02add9b21955402b0c6256624', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nss # and whatever else without interference from each other. @@ -94,7 +94,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': '7c13b1d2cb6133e2edcf21df769e708c350b5fb0', + 'nacl_revision': 'e8fbd4b6737a83a082f3de3b713a6f48cadd3e37', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -441,7 +441,7 @@ Var('chromium_git') + '/external/android_protobuf.git' + '@' + '94f522f907e3f34f70d9e7816b947e62fddbb267', 'src/third_party/android_tools': - Var('chromium_git') + '/android_tools.git' + '@' + 'aaeda3d69df4b4352e3cac7c16bea7f16bd1ec12', + Var('chromium_git') + '/android_tools.git' + '@' + 'f6e2370dff438125897bb3b3800de1ad7aa62c27', 'src/third_party/apache-mime4j': Var('chromium_git') + '/chromium/deps/apache-mime4j.git' + '@' + '28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 3326d8c..8e4880b2 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -359,6 +359,69 @@ '\n'.join(problems))] +def _FindHistogramNameInLine(histogram_name, line): + """Tries to find a histogram name or prefix in a line.""" + if not "affected-histogram" in line: + return histogram_name in line + # A histogram_suffixes tag type has an affected-histogram name as a prefix of + # the histogram_name. + if not '"' in line: + return False + histogram_prefix = line.split('\"')[1] + return histogram_prefix in histogram_name + + +def _CheckUmaHistogramChanges(input_api, output_api): + """Check that UMA histogram names in touched lines can still be found in other + lines of the patch or in histograms.xml. Note that this check would not catch + the reverse: changes in histograms.xml not matched in the code itself.""" + touched_histograms = [] + histograms_xml_modifications = [] + pattern = input_api.re.compile('UMA_HISTOGRAM.*\("(.*)"') + for f in input_api.AffectedFiles(): + # If histograms.xml itself is modified, keep the modified lines for later. + if f.LocalPath().endswith(('histograms.xml')): + histograms_xml_modifications = f.ChangedContents() + continue + if not f.LocalPath().endswith(('cc', 'mm', 'cpp')): + continue + for line_num, line in f.ChangedContents(): + found = pattern.search(line) + if found: + touched_histograms.append([found.group(1), f, line_num]) + + # Search for the touched histogram names in the local modifications to + # histograms.xml, and, if not found, on the base histograms.xml file. + unmatched_histograms = [] + for histogram_info in touched_histograms: + histogram_name_found = False + for line_num, line in histograms_xml_modifications: + histogram_name_found = _FindHistogramNameInLine(histogram_info[0], line) + if histogram_name_found: + break + if not histogram_name_found: + unmatched_histograms.append(histogram_info) + + problems = [] + if unmatched_histograms: + with open('tools/metrics/histograms/histograms.xml') as histograms_xml: + for histogram_name, f, line_num in unmatched_histograms: + histogram_name_found = False + for line in histograms_xml: + histogram_name_found = _FindHistogramNameInLine(histogram_name, line) + if histogram_name_found: + break + if not histogram_name_found: + problems.append(' [%s:%d] %s' % + (f.LocalPath(), line_num, histogram_name)) + + if not problems: + return [] + return [output_api.PresubmitPromptWarning('Some UMA_HISTOGRAM lines have ' + 'been modified and the associated histogram name has no match in either ' + 'metrics/histograms.xml or the modifications of it:', problems)] + + def _CheckNoNewWStrings(input_api, output_api): """Checks to make sure we don't introduce use of wstrings.""" problems = [] @@ -1585,6 +1648,7 @@ results.extend(_CheckJavaStyle(input_api, output_api)) results.extend( input_api.canned_checks.CheckGNFormatted(input_api, output_api)) + results.extend(_CheckUmaHistogramChanges(input_api, output_api)) return results
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 58ca402..00997b43 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -270,6 +270,73 @@ self.assertTrue('3' in errors[1]) self.assertTrue('5' in errors[2]) +class UmaHistogramChangeMatchedOrNotTest(unittest.TestCase): + def testTypicalCorrectlyMatchedChange(self): + diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)'] + diff_xml = ['<histogram name="Bla.Foo.Dummy"> </histogram>'] + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('some/path/foo.cc', diff_cc), + MockFile('tools/metrics/histograms/histograms.xml', diff_xml), + ] + warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, + MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testTypicalNotMatchedChange(self): + diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)'] + mock_input_api = MockInputApi() + mock_input_api.files = [MockFile('some/path/foo.cc', diff_cc)] + warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual('warning', warnings[0].type) + + def testTypicalNotMatchedChangeViaSuffixes(self): + diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)'] + diff_xml = ['<histogram_suffixes name="SuperHistogram">', + ' <suffix name="Dummy"/>', + ' <affected-histogram name="Snafu.Dummy"/>', + '</histogram>'] + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('some/path/foo.cc', diff_cc), + MockFile('tools/metrics/histograms/histograms.xml', diff_xml), + ] + warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, + MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertEqual('warning', warnings[0].type) + + def testTypicalCorrectlyMatchedChangeViaSuffixes(self): + diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)'] + diff_xml = ['<histogram_suffixes name="SuperHistogram">', + ' <suffix name="Dummy"/>', + ' <affected-histogram name="Bla.Foo"/>', + '</histogram>'] + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('some/path/foo.cc', diff_cc), + MockFile('tools/metrics/histograms/histograms.xml', diff_xml), + ] + warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, + MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testTypicalCorrectlyMatchedChangeViaSuffixesWithSeparator(self): + diff_cc = ['UMA_HISTOGRAM_BOOL("Snafu_Dummy", true)'] + diff_xml = ['<histogram_suffixes name="SuperHistogram" separator="_">', + ' <suffix name="Dummy"/>', + ' <affected-histogram name="Snafu"/>', + '</histogram>'] + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockFile('some/path/foo.cc', diff_cc), + MockFile('tools/metrics/histograms/histograms.xml', diff_xml), + ] + warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api, + MockOutputApi()) + self.assertEqual(0, len(warnings)) class BadExtensionsTest(unittest.TestCase): def testBadRejFile(self):
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h index b9e1d66a..755a838 100644 --- a/android_webview/browser/aw_browser_context.h +++ b/android_webview/browser/aw_browser_context.h
@@ -56,7 +56,7 @@ AwBrowserContext(const base::FilePath path, JniDependencyFactory* native_factory); - virtual ~AwBrowserContext(); + ~AwBrowserContext() override; // Currently only one instance per process is supported. static AwBrowserContext* GetDefault(); @@ -106,28 +106,26 @@ // content::BrowserContext implementation. scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate( const base::FilePath& partition_path) override; - virtual base::FilePath GetPath() const override; - virtual bool IsOffTheRecord() const override; - virtual net::URLRequestContextGetter* GetRequestContext() override; - virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess( + base::FilePath GetPath() const override; + bool IsOffTheRecord() const override; + net::URLRequestContextGetter* GetRequestContext() override; + net::URLRequestContextGetter* GetRequestContextForRenderProcess( int renderer_child_id) override; - virtual net::URLRequestContextGetter* GetMediaRequestContext() override; - virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess( + net::URLRequestContextGetter* GetMediaRequestContext() override; + net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess( int renderer_child_id) override; - virtual net::URLRequestContextGetter* - GetMediaRequestContextForStoragePartition( - const base::FilePath& partition_path, bool in_memory) override; - virtual content::ResourceContext* GetResourceContext() override; - virtual content::DownloadManagerDelegate* - GetDownloadManagerDelegate() override; - virtual content::BrowserPluginGuestManager* GetGuestManager() override; - virtual storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; - virtual content::PushMessagingService* GetPushMessagingService() override; - virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; + net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) override; + content::ResourceContext* GetResourceContext() override; + content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; + content::BrowserPluginGuestManager* GetGuestManager() override; + storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; + content::PushMessagingService* GetPushMessagingService() override; + content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; // visitedlink::VisitedLinkDelegate implementation. - virtual void RebuildTable( - const scoped_refptr<URLEnumerator>& enumerator) override; + void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override; private: void CreateDataReductionProxyStatisticsIfNecessary();
diff --git a/android_webview/browser/aw_browser_main_parts.h b/android_webview/browser/aw_browser_main_parts.h index 62a3505..2f417c0 100644 --- a/android_webview/browser/aw_browser_main_parts.h +++ b/android_webview/browser/aw_browser_main_parts.h
@@ -20,13 +20,13 @@ class AwBrowserMainParts : public content::BrowserMainParts { public: explicit AwBrowserMainParts(AwBrowserContext* browser_context); - virtual ~AwBrowserMainParts(); + ~AwBrowserMainParts() override; // Overriding methods from content::BrowserMainParts. - virtual void PreEarlyInitialization() override; - virtual int PreCreateThreads() override; - virtual void PreMainMessageLoopRun() override; - virtual bool MainMessageLoopRun(int* result_code) override; + void PreEarlyInitialization() override; + int PreCreateThreads() override; + void PreMainMessageLoopRun() override; + bool MainMessageLoopRun(int* result_code) override; private: // Android specific UI MessageLoop.
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index c38ce6a..f56dc6c 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -54,11 +54,9 @@ explicit AwContentsMessageFilter(int process_id); // BrowserMessageFilter methods. - virtual void OverrideThreadForMessage( - const IPC::Message& message, - BrowserThread::ID* thread) override; - virtual bool OnMessageReceived( - const IPC::Message& message) override; + void OverrideThreadForMessage(const IPC::Message& message, + BrowserThread::ID* thread) override; + bool OnMessageReceived(const IPC::Message& message) override; void OnShouldOverrideUrlLoading(int routing_id, const base::string16& url, @@ -66,7 +64,7 @@ void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id); private: - virtual ~AwContentsMessageFilter(); + ~AwContentsMessageFilter() override; int process_id_; @@ -126,18 +124,17 @@ AwAccessTokenStore() { } // content::AccessTokenStore implementation - virtual void LoadAccessTokens( - const LoadAccessTokensCallbackType& request) override { + void LoadAccessTokens(const LoadAccessTokensCallbackType& request) override { AccessTokenStore::AccessTokenSet access_token_set; // AccessTokenSet and net::URLRequestContextGetter not used on Android, // but Run needs to be called to finish the geolocation setup. request.Run(access_token_set, NULL); } - virtual void SaveAccessToken(const GURL& server_url, - const base::string16& access_token) override { } + void SaveAccessToken(const GURL& server_url, + const base::string16& access_token) override {} private: - virtual ~AwAccessTokenStore() { } + ~AwAccessTokenStore() override {} DISALLOW_COPY_AND_ASSIGN(AwAccessTokenStore); };
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index f9507a67..93080a9 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -25,73 +25,71 @@ static AwBrowserContext* GetAwBrowserContext(); AwContentBrowserClient(JniDependencyFactory* native_factory); - virtual ~AwContentBrowserClient(); + ~AwContentBrowserClient() override; // Overriden methods from ContentBrowserClient. - virtual void AddCertificate(net::CertificateMimeType cert_type, - const void* cert_data, - size_t cert_size, - int render_process_id, - int render_frame_id) override; - virtual content::BrowserMainParts* CreateBrowserMainParts( + void AddCertificate(net::CertificateMimeType cert_type, + const void* cert_data, + size_t cert_size, + int render_process_id, + int render_frame_id) override; + content::BrowserMainParts* CreateBrowserMainParts( const content::MainFunctionParams& parameters) override; - virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate( + content::WebContentsViewDelegate* GetWebContentsViewDelegate( content::WebContents* web_contents) override; - virtual void RenderProcessWillLaunch( - content::RenderProcessHost* host) override; - virtual net::URLRequestContextGetter* CreateRequestContext( + void RenderProcessWillLaunch(content::RenderProcessHost* host) override; + net::URLRequestContextGetter* CreateRequestContext( content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; - virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition( + net::URLRequestContextGetter* CreateRequestContextForStoragePartition( content::BrowserContext* browser_context, const base::FilePath& partition_path, bool in_memory, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) override; - virtual std::string GetCanonicalEncodingNameByAliasName( + std::string GetCanonicalEncodingNameByAliasName( const std::string& alias_name) override; - virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line, - int child_process_id) override; - virtual std::string GetApplicationLocale() override; - virtual std::string GetAcceptLangs(content::BrowserContext* context) override; - virtual const gfx::ImageSkia* GetDefaultFavicon() override; - virtual bool AllowAppCache(const GURL& manifest_url, - const GURL& first_party, - content::ResourceContext* context) override; - virtual bool AllowGetCookie(const GURL& url, - const GURL& first_party, - const net::CookieList& cookie_list, - content::ResourceContext* context, - int render_process_id, - int render_frame_id) override; - virtual bool AllowSetCookie(const GURL& url, - const GURL& first_party, - const std::string& cookie_line, - content::ResourceContext* context, - int render_process_id, - int render_frame_id, - net::CookieOptions* options) override; - virtual bool AllowWorkerDatabase( + void AppendExtraCommandLineSwitches(base::CommandLine* command_line, + int child_process_id) override; + std::string GetApplicationLocale() override; + std::string GetAcceptLangs(content::BrowserContext* context) override; + const gfx::ImageSkia* GetDefaultFavicon() override; + bool AllowAppCache(const GURL& manifest_url, + const GURL& first_party, + content::ResourceContext* context) override; + bool AllowGetCookie(const GURL& url, + const GURL& first_party, + const net::CookieList& cookie_list, + content::ResourceContext* context, + int render_process_id, + int render_frame_id) override; + bool AllowSetCookie(const GURL& url, + const GURL& first_party, + const std::string& cookie_line, + content::ResourceContext* context, + int render_process_id, + int render_frame_id, + net::CookieOptions* options) override; + bool AllowWorkerDatabase( const GURL& url, const base::string16& name, const base::string16& display_name, unsigned long estimated_size, content::ResourceContext* context, - const std::vector<std::pair<int, int> >& render_frames) override; - virtual void AllowWorkerFileSystem( + const std::vector<std::pair<int, int>>& render_frames) override; + void AllowWorkerFileSystem( const GURL& url, content::ResourceContext* context, - const std::vector<std::pair<int, int> >& render_frames, + const std::vector<std::pair<int, int>>& render_frames, base::Callback<void(bool)> callback) override; - virtual bool AllowWorkerIndexedDB( + bool AllowWorkerIndexedDB( const GURL& url, const base::string16& name, content::ResourceContext* context, - const std::vector<std::pair<int, int> >& render_frames) override; - virtual content::QuotaPermissionContext* - CreateQuotaPermissionContext() override; - virtual void AllowCertificateError( + const std::vector<std::pair<int, int>>& render_frames) override; + content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + void AllowCertificateError( int render_process_id, int render_frame_id, int cert_error, @@ -103,61 +101,59 @@ bool expired_previous_decision, const base::Callback<void(bool)>& callback, content::CertificateRequestResultType* result) override; - virtual void SelectClientCertificate( + void SelectClientCertificate( int render_process_id, int render_frame_id, net::SSLCertRequestInfo* cert_request_info, const base::Callback<void(net::X509Certificate*)>& callback) override; - virtual void RequestPermission( + void RequestPermission( content::PermissionType permission, content::WebContents* web_contents, int bridge_id, const GURL& requesting_frame, bool user_gesture, const base::Callback<void(bool)>& result_callback) override; - virtual void CancelPermissionRequest(content::PermissionType permission, - content::WebContents* web_contents, - int bridge_id, - const GURL& origin) override; - virtual bool CanCreateWindow(const GURL& opener_url, - const GURL& opener_top_level_frame_url, - const GURL& source_origin, - WindowContainerType container_type, - const GURL& target_url, - const content::Referrer& referrer, - WindowOpenDisposition disposition, - const blink::WebWindowFeatures& features, - bool user_gesture, - bool opener_suppressed, - content::ResourceContext* context, - int render_process_id, - int opener_id, - bool* no_javascript_access) override; - virtual void ResourceDispatcherHostCreated() override; - virtual net::NetLog* GetNetLog() override; - virtual content::AccessTokenStore* CreateAccessTokenStore() override; - virtual bool IsFastShutdownPossible() override; - virtual void ClearCache(content::RenderViewHost* rvh) override; - virtual void ClearCookies(content::RenderViewHost* rvh) override; - virtual base::FilePath GetDefaultDownloadDirectory() override; - virtual std::string GetDefaultDownloadName() override; - virtual void DidCreatePpapiPlugin( - content::BrowserPpapiHost* browser_host) override; - virtual bool AllowPepperSocketAPI( + void CancelPermissionRequest(content::PermissionType permission, + content::WebContents* web_contents, + int bridge_id, + const GURL& origin) override; + bool CanCreateWindow(const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + const blink::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + content::ResourceContext* context, + int render_process_id, + int opener_id, + bool* no_javascript_access) override; + void ResourceDispatcherHostCreated() override; + net::NetLog* GetNetLog() override; + content::AccessTokenStore* CreateAccessTokenStore() override; + bool IsFastShutdownPossible() override; + void ClearCache(content::RenderViewHost* rvh) override; + void ClearCookies(content::RenderViewHost* rvh) override; + base::FilePath GetDefaultDownloadDirectory() override; + std::string GetDefaultDownloadName() override; + void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; + bool AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, bool private_api, const content::SocketPermissionRequest* params) override; - virtual void OverrideWebkitPrefs(content::RenderViewHost* rvh, - const GURL& url, - content::WebPreferences* web_prefs) override; + void OverrideWebkitPrefs(content::RenderViewHost* rvh, + const GURL& url, + content::WebPreferences* web_prefs) override; #if defined(VIDEO_HOLE) - virtual content::ExternalVideoSurfaceContainer* - OverrideCreateExternalVideoSurfaceContainer( - content::WebContents* web_contents) override; + content::ExternalVideoSurfaceContainer* + OverrideCreateExternalVideoSurfaceContainer( + content::WebContents* web_contents) override; #endif - virtual content::DevToolsManagerDelegate* - GetDevToolsManagerDelegate() override; + content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; private: // Android WebView currently has a single global (non-off-the-record) browser
diff --git a/android_webview/browser/aw_dev_tools_manager_delegate.cc b/android_webview/browser/aw_dev_tools_manager_delegate.cc index 8cc3ce8..c1f2e3f 100644 --- a/android_webview/browser/aw_dev_tools_manager_delegate.cc +++ b/android_webview/browser/aw_dev_tools_manager_delegate.cc
@@ -30,9 +30,9 @@ public: explicit Target(scoped_refptr<DevToolsAgentHost> agent_host); - virtual std::string GetId() const override { return agent_host_->GetId(); } - virtual std::string GetParentId() const override { return std::string(); } - virtual std::string GetType() const override { + std::string GetId() const override { return agent_host_->GetId(); } + std::string GetParentId() const override { return std::string(); } + std::string GetType() const override { switch (agent_host_->GetType()) { case DevToolsAgentHost::TYPE_WEB_CONTENTS: return kTargetTypePage; @@ -43,23 +43,19 @@ } return kTargetTypeOther; } - virtual std::string GetTitle() const override { - return agent_host_->GetTitle(); - } - virtual std::string GetDescription() const override { return description_; } - virtual GURL GetURL() const override { return agent_host_->GetURL(); } - virtual GURL GetFaviconURL() const override { return GURL(); } - virtual base::TimeTicks GetLastActivityTime() const override { + std::string GetTitle() const override { return agent_host_->GetTitle(); } + std::string GetDescription() const override { return description_; } + GURL GetURL() const override { return agent_host_->GetURL(); } + GURL GetFaviconURL() const override { return GURL(); } + base::TimeTicks GetLastActivityTime() const override { return last_activity_time_; } - virtual bool IsAttached() const override { - return agent_host_->IsAttached(); - } - virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { + bool IsAttached() const override { return agent_host_->IsAttached(); } + scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { return agent_host_; } - virtual bool Activate() const override { return agent_host_->Activate(); } - virtual bool Close() const override { return agent_host_->Close(); } + bool Activate() const override { return agent_host_->Activate(); } + bool Close() const override { return agent_host_->Close(); } private: scoped_refptr<DevToolsAgentHost> agent_host_;
diff --git a/android_webview/browser/aw_dev_tools_manager_delegate.h b/android_webview/browser/aw_dev_tools_manager_delegate.h index ea72c6f..68f22851 100644 --- a/android_webview/browser/aw_dev_tools_manager_delegate.h +++ b/android_webview/browser/aw_dev_tools_manager_delegate.h
@@ -13,22 +13,19 @@ class AwDevToolsManagerDelegate : public content::DevToolsManagerDelegate { public: AwDevToolsManagerDelegate(); - virtual ~AwDevToolsManagerDelegate(); + ~AwDevToolsManagerDelegate() override; // content::DevToolsManagerDelegate implementation. - virtual void Inspect( - content::BrowserContext* browser_context, - content::DevToolsAgentHost* agent_host) override {} - virtual void DevToolsAgentStateChanged( - content::DevToolsAgentHost* agent_host, - bool attached) override {} - virtual base::DictionaryValue* HandleCommand( + void Inspect(content::BrowserContext* browser_context, + content::DevToolsAgentHost* agent_host) override {} + void DevToolsAgentStateChanged(content::DevToolsAgentHost* agent_host, + bool attached) override {} + base::DictionaryValue* HandleCommand( content::DevToolsAgentHost* agent_host, base::DictionaryValue* command_dict) override; - virtual scoped_ptr<content::DevToolsTarget> CreateNewTarget( - const GURL& url) override; - virtual void EnumerateTargets(TargetCallback callback) override; - virtual std::string GetPageThumbnailData(const GURL& url) override; + scoped_ptr<content::DevToolsTarget> CreateNewTarget(const GURL& url) override; + void EnumerateTargets(TargetCallback callback) override; + std::string GetPageThumbnailData(const GURL& url) override; private: DISALLOW_COPY_AND_ASSIGN(AwDevToolsManagerDelegate);
diff --git a/android_webview/browser/aw_download_manager_delegate.h b/android_webview/browser/aw_download_manager_delegate.h index 6aed565..36b3d6b 100644 --- a/android_webview/browser/aw_download_manager_delegate.h +++ b/android_webview/browser/aw_download_manager_delegate.h
@@ -13,19 +13,18 @@ // unconditionally cancel the download. class AwDownloadManagerDelegate : public content::DownloadManagerDelegate { public: - virtual ~AwDownloadManagerDelegate(); + ~AwDownloadManagerDelegate() override; // content::DownloadManagerDelegate implementation. - virtual bool DetermineDownloadTarget( + bool DetermineDownloadTarget( content::DownloadItem* item, const content::DownloadTargetCallback& callback) override; - virtual bool ShouldCompleteDownload( - content::DownloadItem* item, - const base::Closure& complete_callback) override; - virtual bool ShouldOpenDownload( + bool ShouldCompleteDownload(content::DownloadItem* item, + const base::Closure& complete_callback) override; + bool ShouldOpenDownload( content::DownloadItem* item, const content::DownloadOpenDelayedCallback& callback) override; - virtual void GetNextId(const content::DownloadIdCallback& callback) override; + void GetNextId(const content::DownloadIdCallback& callback) override; }; } // namespace android_webview
diff --git a/android_webview/browser/aw_form_database_service.h b/android_webview/browser/aw_form_database_service.h index 5a58953..857b23a 100644 --- a/android_webview/browser/aw_form_database_service.h +++ b/android_webview/browser/aw_form_database_service.h
@@ -25,7 +25,7 @@ public: AwFormDatabaseService(const base::FilePath path); - virtual ~AwFormDatabaseService(); + ~AwFormDatabaseService() override; void Shutdown(); @@ -40,9 +40,8 @@ get_autofill_webdata_service(); // WebDataServiceConsumer implementation. - virtual void OnWebDataServiceRequestDone( - WebDataServiceBase::Handle h, - const WDTypedResult* result) override; + void OnWebDataServiceRequestDone(WebDataServiceBase::Handle h, + const WDTypedResult* result) override; private: struct PendingQuery {
diff --git a/android_webview/browser/aw_form_database_service_unittest.cc b/android_webview/browser/aw_form_database_service_unittest.cc index 9750fc8..34f4449 100644 --- a/android_webview/browser/aw_form_database_service_unittest.cc +++ b/android_webview/browser/aw_form_database_service_unittest.cc
@@ -33,7 +33,7 @@ } protected: - virtual void SetUp() { + void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); env_ = AttachCurrentThread(); ASSERT_TRUE(env_ != NULL); @@ -42,9 +42,7 @@ service_.reset(new AwFormDatabaseService(temp_dir_.path())); } - virtual void TearDown() { - service_->Shutdown(); - } + void TearDown() override { service_->Shutdown(); } // The path to the temporary directory used for the test operations. base::ScopedTempDir temp_dir_;
diff --git a/android_webview/browser/aw_gl_surface.h b/android_webview/browser/aw_gl_surface.h index 9e48133c..128b5515 100644 --- a/android_webview/browser/aw_gl_surface.h +++ b/android_webview/browser/aw_gl_surface.h
@@ -17,19 +17,19 @@ AwGLSurface(); // Implement GLSurface. - virtual void Destroy() override; - virtual bool IsOffscreen() override; - virtual unsigned int GetBackingFrameBufferObject() override; - virtual bool SwapBuffers() override; - virtual gfx::Size GetSize() override; - virtual void* GetHandle() override; - virtual void* GetDisplay() override; + void Destroy() override; + bool IsOffscreen() override; + unsigned int GetBackingFrameBufferObject() override; + bool SwapBuffers() override; + gfx::Size GetSize() override; + void* GetHandle() override; + void* GetDisplay() override; void SetBackingFrameBufferObject(unsigned int fbo); void ResetBackingFrameBufferObject(); protected: - virtual ~AwGLSurface(); + ~AwGLSurface() override; private: unsigned int fbo_;
diff --git a/android_webview/browser/aw_javascript_dialog_manager.h b/android_webview/browser/aw_javascript_dialog_manager.h index edd6d38..8713e3d 100644 --- a/android_webview/browser/aw_javascript_dialog_manager.h +++ b/android_webview/browser/aw_javascript_dialog_manager.h
@@ -12,27 +12,24 @@ class AwJavaScriptDialogManager : public content::JavaScriptDialogManager { public: explicit AwJavaScriptDialogManager(); - virtual ~AwJavaScriptDialogManager(); + ~AwJavaScriptDialogManager() override; // Overridden from content::JavaScriptDialogManager: - virtual void RunJavaScriptDialog( - content::WebContents* web_contents, - const GURL& origin_url, - const std::string& accept_lang, - content::JavaScriptMessageType message_type, - const base::string16& message_text, - const base::string16& default_prompt_text, - const DialogClosedCallback& callback, - bool* did_suppress_message) override; - virtual void RunBeforeUnloadDialog( - content::WebContents* web_contents, - const base::string16& message_text, - bool is_reload, - const DialogClosedCallback& callback) override; - virtual void CancelActiveAndPendingDialogs( + void RunJavaScriptDialog(content::WebContents* web_contents, + const GURL& origin_url, + const std::string& accept_lang, + content::JavaScriptMessageType message_type, + const base::string16& message_text, + const base::string16& default_prompt_text, + const DialogClosedCallback& callback, + bool* did_suppress_message) override; + void RunBeforeUnloadDialog(content::WebContents* web_contents, + const base::string16& message_text, + bool is_reload, + const DialogClosedCallback& callback) override; + void CancelActiveAndPendingDialogs( content::WebContents* web_contents) override; - virtual void WebContentsDestroyed( - content::WebContents* web_contents) override; + void WebContentsDestroyed(content::WebContents* web_contents) override; private: DISALLOW_COPY_AND_ASSIGN(AwJavaScriptDialogManager);
diff --git a/android_webview/browser/aw_login_delegate.h b/android_webview/browser/aw_login_delegate.h index bb0fe44..0331c6b5 100644 --- a/android_webview/browser/aw_login_delegate.h +++ b/android_webview/browser/aw_login_delegate.h
@@ -29,10 +29,10 @@ virtual void Cancel(); // from ResourceDispatcherHostLoginDelegate - virtual void OnRequestCancelled() override; + void OnRequestCancelled() override; private: - virtual ~AwLoginDelegate(); + ~AwLoginDelegate() override; void HandleHttpAuthRequestOnUIThread(bool first_auth_attempt); void CancelOnIOThread(); void ProceedOnIOThread(const base::string16& user,
diff --git a/android_webview/browser/aw_pref_store.h b/android_webview/browser/aw_pref_store.h index dec25b57..6935c719 100644 --- a/android_webview/browser/aw_pref_store.h +++ b/android_webview/browser/aw_pref_store.h
@@ -22,29 +22,27 @@ AwPrefStore(); // Overriden from PrefStore. - virtual bool GetValue(const std::string& key, - const base::Value** result) const override; - virtual void AddObserver(PrefStore::Observer* observer) override; - virtual void RemoveObserver(PrefStore::Observer* observer) override; - virtual bool HasObservers() const override; - virtual bool IsInitializationComplete() const override; + bool GetValue(const std::string& key, + const base::Value** result) const override; + void AddObserver(PrefStore::Observer* observer) override; + void RemoveObserver(PrefStore::Observer* observer) override; + bool HasObservers() const override; + bool IsInitializationComplete() const override; // PersistentPrefStore overrides: - virtual bool GetMutableValue(const std::string& key, - base::Value** result) override; - virtual void ReportValueChanged(const std::string& key) override; - virtual void SetValue(const std::string& key, base::Value* value) override; - virtual void SetValueSilently(const std::string& key, - base::Value* value) override; - virtual void RemoveValue(const std::string& key) override; - virtual bool ReadOnly() const override; - virtual PrefReadError GetReadError() const override; - virtual PersistentPrefStore::PrefReadError ReadPrefs() override; - virtual void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override; - virtual void CommitPendingWrite() override {} + bool GetMutableValue(const std::string& key, base::Value** result) override; + void ReportValueChanged(const std::string& key) override; + void SetValue(const std::string& key, base::Value* value) override; + void SetValueSilently(const std::string& key, base::Value* value) override; + void RemoveValue(const std::string& key) override; + bool ReadOnly() const override; + PrefReadError GetReadError() const override; + PersistentPrefStore::PrefReadError ReadPrefs() override; + void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override; + void CommitPendingWrite() override {} protected: - virtual ~AwPrefStore(); + ~AwPrefStore() override; private: // Stores the preference values.
diff --git a/android_webview/browser/aw_quota_permission_context.h b/android_webview/browser/aw_quota_permission_context.h index a42f00b..035557e 100644 --- a/android_webview/browser/aw_quota_permission_context.h +++ b/android_webview/browser/aw_quota_permission_context.h
@@ -14,13 +14,12 @@ public: AwQuotaPermissionContext(); - virtual void RequestQuotaPermission( - const content::StorageQuotaParams& params, - int render_process_id, - const PermissionCallback& callback) override; + void RequestQuotaPermission(const content::StorageQuotaParams& params, + int render_process_id, + const PermissionCallback& callback) override; private: - virtual ~AwQuotaPermissionContext(); + ~AwQuotaPermissionContext() override; DISALLOW_COPY_AND_ASSIGN(AwQuotaPermissionContext); };
diff --git a/android_webview/browser/aw_request_interceptor.h b/android_webview/browser/aw_request_interceptor.h index d66f1b6c..adbb18b 100644 --- a/android_webview/browser/aw_request_interceptor.h +++ b/android_webview/browser/aw_request_interceptor.h
@@ -27,10 +27,10 @@ class AwRequestInterceptor : public net::URLRequestInterceptor { public: AwRequestInterceptor(); - virtual ~AwRequestInterceptor(); + ~AwRequestInterceptor() override; // net::URLRequestInterceptor override -------------------------------------- - virtual net::URLRequestJob* MaybeInterceptRequest( + net::URLRequestJob* MaybeInterceptRequest( net::URLRequest* request, net::NetworkDelegate* network_delegate) const override;
diff --git a/android_webview/browser/aw_resource_context.h b/android_webview/browser/aw_resource_context.h index 87396df..49922ca 100644 --- a/android_webview/browser/aw_resource_context.h +++ b/android_webview/browser/aw_resource_context.h
@@ -20,14 +20,14 @@ class AwResourceContext : public content::ResourceContext { public: explicit AwResourceContext(net::URLRequestContextGetter* getter); - virtual ~AwResourceContext(); + ~AwResourceContext() override; void SetExtraHeaders(const GURL& url, const std::string& headers); std::string GetExtraHeaders(const GURL& url); // content::ResourceContext implementation. - virtual net::HostResolver* GetHostResolver() override; - virtual net::URLRequestContext* GetRequestContext() override; + net::HostResolver* GetHostResolver() override; + net::URLRequestContext* GetRequestContext() override; private: net::URLRequestContextGetter* getter_;
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.h b/android_webview/browser/aw_ssl_host_state_delegate.h index 1297af9..bc3e1a8 100644 --- a/android_webview/browser/aw_ssl_host_state_delegate.h +++ b/android_webview/browser/aw_ssl_host_state_delegate.h
@@ -41,7 +41,7 @@ class AwSSLHostStateDelegate : public content::SSLHostStateDelegate { public: AwSSLHostStateDelegate(); - virtual ~AwSSLHostStateDelegate(); + ~AwSSLHostStateDelegate() override; // Records that |cert| is permitted to be used for |host| in the future, for // a specified |error| type.
diff --git a/android_webview/browser/aw_web_resource_response.cc b/android_webview/browser/aw_web_resource_response.cc index 78a30a8..44f2aa8 100644 --- a/android_webview/browser/aw_web_resource_response.cc +++ b/android_webview/browser/aw_web_resource_response.cc
@@ -22,33 +22,32 @@ DCHECK(aw_web_resource_response_); } - virtual scoped_ptr<InputStream> OpenInputStream(JNIEnv* env, - const GURL& url) override { + scoped_ptr<InputStream> OpenInputStream(JNIEnv* env, + const GURL& url) override { return aw_web_resource_response_->GetInputStream(env).Pass(); } - virtual void OnInputStreamOpenFailed(net::URLRequest* request, - bool* restart) override { + void OnInputStreamOpenFailed(net::URLRequest* request, + bool* restart) override { *restart = false; } - virtual bool GetMimeType(JNIEnv* env, - net::URLRequest* request, - android_webview::InputStream* stream, - std::string* mime_type) override { + bool GetMimeType(JNIEnv* env, + net::URLRequest* request, + android_webview::InputStream* stream, + std::string* mime_type) override { return aw_web_resource_response_->GetMimeType(env, mime_type); } - virtual bool GetCharset(JNIEnv* env, - net::URLRequest* request, - android_webview::InputStream* stream, - std::string* charset) override { + bool GetCharset(JNIEnv* env, + net::URLRequest* request, + android_webview::InputStream* stream, + std::string* charset) override { return aw_web_resource_response_->GetCharset(env, charset); } - virtual void AppendResponseHeaders( - JNIEnv* env, - net::HttpResponseHeaders* headers) override { + void AppendResponseHeaders(JNIEnv* env, + net::HttpResponseHeaders* headers) override { int status_code; std::string reason_phrase; if (aw_web_resource_response_->GetStatusInfo(
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h index bf2b23d..c016cf1 100644 --- a/android_webview/browser/browser_view_renderer.h +++ b/android_webview/browser/browser_view_renderer.h
@@ -32,7 +32,7 @@ BrowserViewRendererClient* client, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); - virtual ~BrowserViewRenderer(); + ~BrowserViewRenderer() override; SharedRendererState* GetAwDrawGLViewContext(); bool RequestDrawGL(bool wait_for_completion); @@ -80,24 +80,23 @@ void TrimMemory(const int level, const bool visible); // SynchronousCompositorClient overrides. - virtual void DidInitializeCompositor( + void DidInitializeCompositor( content::SynchronousCompositor* compositor) override; - virtual void DidDestroyCompositor(content::SynchronousCompositor* compositor) - override; - virtual void SetContinuousInvalidate(bool invalidate) override; - virtual void DidUpdateContent() override; - virtual gfx::Vector2dF GetTotalRootLayerScrollOffset() override; - virtual void UpdateRootLayerState( - const gfx::Vector2dF& total_scroll_offset_dip, - const gfx::Vector2dF& max_scroll_offset_dip, - const gfx::SizeF& scrollable_size_dip, - float page_scale_factor, - float min_page_scale_factor, - float max_page_scale_factor) override; - virtual bool IsExternalFlingActive() const override; - virtual void DidOverscroll(gfx::Vector2dF accumulated_overscroll, - gfx::Vector2dF latest_overscroll_delta, - gfx::Vector2dF current_fling_velocity) override; + void DidDestroyCompositor( + content::SynchronousCompositor* compositor) override; + void SetContinuousInvalidate(bool invalidate) override; + void DidUpdateContent() override; + gfx::Vector2dF GetTotalRootLayerScrollOffset() override; + void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset_dip, + const gfx::Vector2dF& max_scroll_offset_dip, + const gfx::SizeF& scrollable_size_dip, + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) override; + bool IsExternalFlingActive() const override; + void DidOverscroll(gfx::Vector2dF accumulated_overscroll, + gfx::Vector2dF latest_overscroll_delta, + gfx::Vector2dF current_fling_velocity) override; void UpdateParentDrawConstraints(); void DidSkipCommitFrame();
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h index bd361b7..0b092ed 100644 --- a/android_webview/browser/deferred_gpu_command_service.h +++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -36,11 +36,11 @@ static void SetInstance(); static DeferredGpuCommandService* GetInstance(); - virtual void ScheduleTask(const base::Closure& task) override; - virtual void ScheduleIdleWork(const base::Closure& task) override; - virtual bool UseVirtualizedGLContexts() override; - virtual scoped_refptr<gpu::gles2::ShaderTranslatorCache> - shader_translator_cache() override; + void ScheduleTask(const base::Closure& task) override; + void ScheduleIdleWork(const base::Closure& task) override; + bool UseVirtualizedGLContexts() override; + scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache() + override; void RunTasks(); // If |is_idle| is false, this will only run older idle tasks. @@ -50,11 +50,11 @@ // idle tasks during the idle run. void PerformAllIdleWork(); - virtual void AddRef() const override; - virtual void Release() const override; + void AddRef() const override; + void Release() const override; protected: - virtual ~DeferredGpuCommandService(); + ~DeferredGpuCommandService() override; friend class base::RefCountedThreadSafe<DeferredGpuCommandService>; private:
diff --git a/android_webview/browser/find_helper.h b/android_webview/browser/find_helper.h index eabf1975..198d947 100644 --- a/android_webview/browser/find_helper.h +++ b/android_webview/browser/find_helper.h
@@ -25,7 +25,7 @@ }; explicit FindHelper(content::WebContents* web_contents); - virtual ~FindHelper(); + ~FindHelper() override; // Sets the listener to receive find result updates. // Does not own the listener and must set to NULL when invalid.
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 671b3ca2..67a9f90 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h
@@ -31,7 +31,7 @@ public cc::DelegatedFrameResourceCollectionClient { public: explicit HardwareRenderer(SharedRendererState* state); - virtual ~HardwareRenderer(); + ~HardwareRenderer() override; void DrawGL(bool stencil_enabled, int framebuffer_binding_ext, @@ -39,34 +39,33 @@ void CommitFrame(); // cc::LayerTreeHostClient overrides. - virtual void WillBeginMainFrame(int frame_id) override {} - virtual void DidBeginMainFrame() override; - virtual void BeginMainFrame(const cc::BeginFrameArgs& args) override {} - virtual void Layout() override {} - virtual void ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, - const gfx::Vector2dF& elastic_overscroll_delta, - float page_scale, - float top_controls_delta) override {} - virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, - float page_scale, - float top_controls_delta) override {} - virtual void RequestNewOutputSurface() override; - virtual void DidInitializeOutputSurface() override {} - virtual void DidFailToInitializeOutputSurface() override; - virtual void WillCommit() override {} - virtual void DidCommit() override {} - virtual void DidCommitAndDrawFrame() override {} - virtual void DidCompleteSwapBuffers() override {} - virtual void DidCompletePageScaleAnimation() override {} + void WillBeginMainFrame() override {} + void DidBeginMainFrame() override; + void BeginMainFrame(const cc::BeginFrameArgs& args) override {} + void Layout() override {} + void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, + const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) override {} + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float page_scale, + float top_controls_delta) override {} + void RequestNewOutputSurface() override; + void DidInitializeOutputSurface() override {} + void DidFailToInitializeOutputSurface() override; + void WillCommit() override {} + void DidCommit() override {} + void DidCommitAndDrawFrame() override {} + void DidCompleteSwapBuffers() override {} + void DidCompletePageScaleAnimation() override {} // cc::LayerTreeHostSingleThreadClient overrides. - virtual void DidPostSwapBuffers() override {} - virtual void DidAbortSwapBuffers() override {} + void DidPostSwapBuffers() override {} + void DidAbortSwapBuffers() override {} // cc::DelegatedFrameResourceCollectionClient overrides. - virtual void UnusedResourcesAreAvailable() override; + void UnusedResourcesAreAvailable() override; private: void SetFrameData();
diff --git a/android_webview/browser/icon_helper.h b/android_webview/browser/icon_helper.h index 287be27f..dc9a1d63f 100644 --- a/android_webview/browser/icon_helper.h +++ b/android_webview/browser/icon_helper.h
@@ -37,14 +37,14 @@ }; explicit IconHelper(content::WebContents* web_contents); - virtual ~IconHelper(); + ~IconHelper() override; void SetListener(Listener* listener); // From WebContentsObserver - virtual void DidUpdateFaviconURL( + void DidUpdateFaviconURL( const std::vector<content::FaviconURL>& candidates) override; - virtual void DidStartNavigationToPendingEntry( + void DidStartNavigationToPendingEntry( const GURL& url, content::NavigationController::ReloadType reload_type) override;
diff --git a/android_webview/browser/net/android_stream_reader_url_request_job.h b/android_webview/browser/net/android_stream_reader_url_request_job.h index f3f230d2..903ba61 100644 --- a/android_webview/browser/net/android_stream_reader_url_request_job.h +++ b/android_webview/browser/net/android_stream_reader_url_request_job.h
@@ -79,20 +79,17 @@ scoped_ptr<Delegate> delegate); // URLRequestJob: - virtual void Start() override; - virtual void Kill() override; - virtual bool ReadRawData(net::IOBuffer* buf, - int buf_size, - int* bytes_read) override; - virtual void SetExtraRequestHeaders( - const net::HttpRequestHeaders& headers) override; - virtual bool GetMimeType(std::string* mime_type) const override; - virtual bool GetCharset(std::string* charset) override; - virtual int GetResponseCode() const override; - virtual void GetResponseInfo(net::HttpResponseInfo* info) override; + void Start() override; + void Kill() override; + bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override; + void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override; + bool GetMimeType(std::string* mime_type) const override; + bool GetCharset(std::string* charset) override; + int GetResponseCode() const override; + void GetResponseInfo(net::HttpResponseInfo* info) override; protected: - virtual ~AndroidStreamReaderURLRequestJob(); + ~AndroidStreamReaderURLRequestJob() override; // Gets the TaskRunner for the worker thread. // Overridden in unittests.
diff --git a/android_webview/browser/net/android_stream_reader_url_request_job_unittest.cc b/android_webview/browser/net/android_stream_reader_url_request_job_unittest.cc index 4b80c41f..b9332c5 100644 --- a/android_webview/browser/net/android_stream_reader_url_request_job_unittest.cc +++ b/android_webview/browser/net/android_stream_reader_url_request_job_unittest.cc
@@ -51,16 +51,16 @@ class NotImplInputStream : public InputStream { public: NotImplInputStream() {} - virtual ~NotImplInputStream() {} - virtual bool BytesAvailable(int* bytes_available) const override { + ~NotImplInputStream() override {} + bool BytesAvailable(int* bytes_available) const override { NOTIMPLEMENTED(); return false; } - virtual bool Skip(int64_t n, int64_t* bytes_skipped) override { + bool Skip(int64_t n, int64_t* bytes_skipped) override { NOTIMPLEMENTED(); return false; } - virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) override { + bool Read(net::IOBuffer* dest, int length, int* bytes_read) override { NOTIMPLEMENTED(); return false; } @@ -72,34 +72,32 @@ public: StreamReaderDelegate() {} - virtual scoped_ptr<InputStream> OpenInputStream( - JNIEnv* env, - const GURL& url) override { + scoped_ptr<InputStream> OpenInputStream(JNIEnv* env, + const GURL& url) override { return make_scoped_ptr<InputStream>(new NotImplInputStream()); } - virtual void OnInputStreamOpenFailed(net::URLRequest* request, - bool* restart) override { + void OnInputStreamOpenFailed(net::URLRequest* request, + bool* restart) override { *restart = false; } - virtual bool GetMimeType(JNIEnv* env, - net::URLRequest* request, - android_webview::InputStream* stream, - std::string* mime_type) override { + bool GetMimeType(JNIEnv* env, + net::URLRequest* request, + android_webview::InputStream* stream, + std::string* mime_type) override { return false; } - virtual bool GetCharset(JNIEnv* env, - net::URLRequest* request, - android_webview::InputStream* stream, - std::string* charset) override { + bool GetCharset(JNIEnv* env, + net::URLRequest* request, + android_webview::InputStream* stream, + std::string* charset) override { return false; } - virtual void AppendResponseHeaders( - JNIEnv* env, - net::HttpResponseHeaders* headers) override { + void AppendResponseHeaders(JNIEnv* env, + net::HttpResponseHeaders* headers) override { // no-op } }; @@ -108,9 +106,8 @@ public: NullStreamReaderDelegate() {} - virtual scoped_ptr<InputStream> OpenInputStream( - JNIEnv* env, - const GURL& url) override { + scoped_ptr<InputStream> OpenInputStream(JNIEnv* env, + const GURL& url) override { return make_scoped_ptr<InputStream>(NULL); } }; @@ -119,9 +116,8 @@ public: HeaderAlteringStreamReaderDelegate() {} - virtual void AppendResponseHeaders( - JNIEnv* env, - net::HttpResponseHeaders* headers) override { + void AppendResponseHeaders(JNIEnv* env, + net::HttpResponseHeaders* headers) override { headers->ReplaceStatusLine(kStatusLine); std::string headerLine(kCustomHeaderName); headerLine.append(": "); @@ -167,14 +163,14 @@ message_loop_proxy_ = base::MessageLoopProxy::current(); } - virtual scoped_ptr<InputStreamReader> CreateStreamReader( + scoped_ptr<InputStreamReader> CreateStreamReader( InputStream* stream) override { return stream_reader_.Pass(); } protected: - virtual ~TestStreamReaderJob() {} + ~TestStreamReaderJob() override {} - virtual base::TaskRunner* GetWorkerThreadRunner() override { + base::TaskRunner* GetWorkerThreadRunner() override { return message_loop_proxy_.get(); } @@ -187,7 +183,7 @@ AndroidStreamReaderURLRequestJobTest() {} protected: - virtual void SetUp() { + void SetUp() override { context_.set_job_factory(&factory_); context_.set_network_delegate(&network_delegate_); req_ = context_.CreateRequest(GURL("content://foo"),
diff --git a/android_webview/browser/net/aw_network_delegate.h b/android_webview/browser/net/aw_network_delegate.h index c925db9..da6723b8 100644 --- a/android_webview/browser/net/aw_network_delegate.h +++ b/android_webview/browser/net/aw_network_delegate.h
@@ -19,47 +19,44 @@ class AwNetworkDelegate : public net::NetworkDelegateImpl { public: AwNetworkDelegate(); - virtual ~AwNetworkDelegate(); + ~AwNetworkDelegate() override; private: // NetworkDelegate implementation. - virtual int OnBeforeURLRequest(net::URLRequest* request, - const net::CompletionCallback& callback, - GURL* new_url) override; - virtual int OnBeforeSendHeaders(net::URLRequest* request, - const net::CompletionCallback& callback, - net::HttpRequestHeaders* headers) override; - virtual void OnSendHeaders(net::URLRequest* request, - const net::HttpRequestHeaders& headers) override; - virtual int OnHeadersReceived( + int OnBeforeURLRequest(net::URLRequest* request, + const net::CompletionCallback& callback, + GURL* new_url) override; + int OnBeforeSendHeaders(net::URLRequest* request, + const net::CompletionCallback& callback, + net::HttpRequestHeaders* headers) override; + void OnSendHeaders(net::URLRequest* request, + const net::HttpRequestHeaders& headers) override; + int OnHeadersReceived( net::URLRequest* request, const net::CompletionCallback& callback, const net::HttpResponseHeaders* original_response_headers, scoped_refptr<net::HttpResponseHeaders>* override_response_headers, GURL* allowed_unsafe_redirect_url) override; - virtual void OnBeforeRedirect(net::URLRequest* request, - const GURL& new_location) override; - virtual void OnResponseStarted(net::URLRequest* request) override; - virtual void OnRawBytesRead(const net::URLRequest& request, - int bytes_read) override; - virtual void OnCompleted(net::URLRequest* request, bool started) override; - virtual void OnURLRequestDestroyed(net::URLRequest* request) override; - virtual void OnPACScriptError(int line_number, - const base::string16& error) override; - virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired( + void OnBeforeRedirect(net::URLRequest* request, + const GURL& new_location) override; + void OnResponseStarted(net::URLRequest* request) override; + void OnRawBytesRead(const net::URLRequest& request, int bytes_read) override; + void OnCompleted(net::URLRequest* request, bool started) override; + void OnURLRequestDestroyed(net::URLRequest* request) override; + void OnPACScriptError(int line_number, const base::string16& error) override; + net::NetworkDelegate::AuthRequiredResponse OnAuthRequired( net::URLRequest* request, const net::AuthChallengeInfo& auth_info, const AuthCallback& callback, net::AuthCredentials* credentials) override; - virtual bool OnCanGetCookies(const net::URLRequest& request, - const net::CookieList& cookie_list) override; - virtual bool OnCanSetCookie(const net::URLRequest& request, - const std::string& cookie_line, - net::CookieOptions* options) override; - virtual bool OnCanAccessFile(const net::URLRequest& request, - const base::FilePath& path) const override; - virtual bool OnCanThrottleRequest( - const net::URLRequest& request) const override; + bool OnCanGetCookies(const net::URLRequest& request, + const net::CookieList& cookie_list) override; + bool OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions* options) override; + bool OnCanAccessFile(const net::URLRequest& request, + const base::FilePath& path) const override; + bool OnCanThrottleRequest(const net::URLRequest& request) const override; DISALLOW_COPY_AND_ASSIGN(AwNetworkDelegate); };
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h index 50736ba..fbaf24a3 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.h +++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -39,9 +39,9 @@ scoped_ptr<net::ProxyConfigService> config_service); // net::URLRequestContextGetter implementation. - virtual net::URLRequestContext* GetURLRequestContext() override; - virtual scoped_refptr<base::SingleThreadTaskRunner> - GetNetworkTaskRunner() const override; + net::URLRequestContext* GetURLRequestContext() override; + scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() + const override; data_reduction_proxy::DataReductionProxyAuthRequestHandler* GetDataReductionProxyAuthRequestHandler() const; @@ -56,7 +56,7 @@ private: friend class AwBrowserContext; - virtual ~AwURLRequestContextGetter(); + ~AwURLRequestContextGetter() override; // Prior to GetURLRequestContext() being called, this is called to hand over // the objects that GetURLRequestContext() will later install into
diff --git a/android_webview/browser/net/aw_url_request_job_factory.h b/android_webview/browser/net/aw_url_request_job_factory.h index db1cfae6..458c1b02 100644 --- a/android_webview/browser/net/aw_url_request_job_factory.h +++ b/android_webview/browser/net/aw_url_request_job_factory.h
@@ -23,7 +23,7 @@ class AwURLRequestJobFactory : public net::URLRequestJobFactory { public: AwURLRequestJobFactory(); - virtual ~AwURLRequestJobFactory(); + ~AwURLRequestJobFactory() override; bool SetProtocolHandler(const std::string& scheme, ProtocolHandler* protocol_handler); @@ -43,9 +43,9 @@ net::URLRequest* request, net::NetworkDelegate* network_delegate) const override; - virtual bool IsHandledProtocol(const std::string& scheme) const override; - virtual bool IsHandledURL(const GURL& url) const override; - virtual bool IsSafeRedirectTarget(const GURL& location) const override; + bool IsHandledProtocol(const std::string& scheme) const override; + bool IsHandledURL(const GURL& url) const override; + bool IsSafeRedirectTarget(const GURL& location) const override; private: // By default calls are forwarded to this factory, to avoid having to
diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h index 03cd5dd6..442501da 100644 --- a/android_webview/browser/parent_output_surface.h +++ b/android_webview/browser/parent_output_surface.h
@@ -13,11 +13,11 @@ public: explicit ParentOutputSurface( scoped_refptr<cc::ContextProvider> context_provider); - virtual ~ParentOutputSurface(); + ~ParentOutputSurface() override; // OutputSurface overrides. - virtual void Reshape(const gfx::Size& size, float scale_factor) override {} - virtual void SwapBuffers(cc::CompositorFrame* frame) override; + void Reshape(const gfx::Size& size, float scale_factor) override {} + void SwapBuffers(cc::CompositorFrame* frame) override; using cc::OutputSurface::SetExternalStencilTest; void SetDrawConstraints(const gfx::Size& surface_size, const gfx::Rect& clip);
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.h b/android_webview/browser/renderer_host/aw_render_view_host_ext.h index a0d426bd..3abd8d8 100644 --- a/android_webview/browser/renderer_host/aw_render_view_host_ext.h +++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
@@ -45,7 +45,7 @@ // as it internally handles RenderViewHost instances changing underneath us. AwRenderViewHostExt( AwRenderViewHostExtClient* client, content::WebContents* contents); - virtual ~AwRenderViewHostExt(); + ~AwRenderViewHostExt() override; // |result| will be invoked with the outcome of the request. typedef base::Callback<void(bool)> DocumentHasImagesResult; @@ -82,13 +82,12 @@ private: // content::WebContentsObserver implementation. - virtual void RenderViewCreated(content::RenderViewHost* view_host) override; - virtual void RenderProcessGone(base::TerminationStatus status) override; - virtual void DidNavigateAnyFrame( - content::RenderFrameHost* render_frame_host, - const content::LoadCommittedDetails& details, - const content::FrameNavigateParams& params) override; - virtual bool OnMessageReceived(const IPC::Message& message) override; + void RenderViewCreated(content::RenderViewHost* view_host) override; + void RenderProcessGone(base::TerminationStatus status) override; + void DidNavigateAnyFrame(content::RenderFrameHost* render_frame_host, + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) override; + bool OnMessageReceived(const IPC::Message& message) override; void OnDocumentHasImagesResponse(int msg_id, bool has_images); void OnUpdateHitTestData(const AwHitTestData& hit_test_data);
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc index d5f1864..efe1707 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -63,12 +63,12 @@ IoThreadClientThrottle(int render_process_id, int render_frame_id, net::URLRequest* request); - virtual ~IoThreadClientThrottle(); + ~IoThreadClientThrottle() override; // From content::ResourceThrottle - virtual void WillStartRequest(bool* defer) override; - virtual void WillRedirectRequest(const GURL& new_url, bool* defer) override; - virtual const char* GetNameForLogging() const override; + void WillStartRequest(bool* defer) override; + void WillRedirectRequest(const GURL& new_url, bool* defer) override; + const char* GetNameForLogging() const override; void OnIoThreadClientReady(int new_render_process_id, int new_render_frame_id);
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h index 25ec4ff..dd08235a 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
@@ -29,13 +29,13 @@ static void ResourceDispatcherHostCreated(); // Overriden methods from ResourceDispatcherHostDelegate. - virtual void RequestBeginning( + void RequestBeginning( net::URLRequest* request, content::ResourceContext* resource_context, content::AppCacheService* appcache_service, content::ResourceType resource_type, ScopedVector<content::ResourceThrottle>* throttles) override; - virtual void DownloadStarting( + void DownloadStarting( net::URLRequest* request, content::ResourceContext* resource_context, int child_id, @@ -44,23 +44,21 @@ bool is_content_initiated, bool must_download, ScopedVector<content::ResourceThrottle>* throttles) override; - virtual content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( + content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( net::AuthChallengeInfo* auth_info, net::URLRequest* request) override; - virtual bool HandleExternalProtocol(const GURL& url, - int child_id, - int route_id) override; - virtual void OnResponseStarted( - net::URLRequest* request, - content::ResourceContext* resource_context, - content::ResourceResponse* response, - IPC::Sender* sender) override; + bool HandleExternalProtocol(const GURL& url, + int child_id, + int route_id) override; + void OnResponseStarted(net::URLRequest* request, + content::ResourceContext* resource_context, + content::ResourceResponse* response, + IPC::Sender* sender) override; - virtual void OnRequestRedirected( - const GURL& redirect_url, - net::URLRequest* request, - content::ResourceContext* resource_context, - content::ResourceResponse* response) override; + void OnRequestRedirected(const GURL& redirect_url, + net::URLRequest* request, + content::ResourceContext* resource_context, + content::ResourceResponse* response) override; void RemovePendingThrottleOnIoThread(IoThreadClientThrottle* throttle); @@ -74,7 +72,7 @@ friend struct base::DefaultLazyInstanceTraits< AwResourceDispatcherHostDelegate>; AwResourceDispatcherHostDelegate(); - virtual ~AwResourceDispatcherHostDelegate(); + ~AwResourceDispatcherHostDelegate() override; // These methods must be called on IO thread. void OnIoThreadClientReadyInternal(int new_render_process_id,
diff --git a/android_webview/browser/renderer_host/print_manager.h b/android_webview/browser/renderer_host/print_manager.h index fc869cdd..3cb4495 100644 --- a/android_webview/browser/renderer_host/print_manager.h +++ b/android_webview/browser/renderer_host/print_manager.h
@@ -47,7 +47,7 @@ int fd, PrintManagerDelegate* delegate); - virtual ~PrintManager(); + ~PrintManager() override; // Prints the current document immediately. Since the rendering is // asynchronous, the actual printing will not be completed on the return of @@ -69,7 +69,7 @@ PrintManagerDelegate* delegate); friend class content::WebContentsUserData<PrintManager>; - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; void OnDidGetPrintedPagesCount(int cookie, int number_pages); void OnDidGetDocumentCookie(int cookie); void OnPrintingFailed(int cookie);
diff --git a/android_webview/common/aw_content_client.h b/android_webview/common/aw_content_client.h index 55a84e0..0a3a343 100644 --- a/android_webview/common/aw_content_client.h +++ b/android_webview/common/aw_content_client.h
@@ -16,13 +16,13 @@ class AwContentClient : public content::ContentClient { public: // ContentClient implementation. - virtual std::string GetProduct() const override; - virtual std::string GetUserAgent() const override; - virtual base::string16 GetLocalizedString(int message_id) const override; - virtual base::StringPiece GetDataResource( + std::string GetProduct() const override; + std::string GetUserAgent() const override; + base::string16 GetLocalizedString(int message_id) const override; + base::StringPiece GetDataResource( int resource_id, ui::ScaleFactor scale_factor) const override; - virtual bool CanSendWhileSwappedOut(const IPC::Message* message) override; + bool CanSendWhileSwappedOut(const IPC::Message* message) override; }; } // namespace android_webview
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index ba765d9..9efefb7 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -94,7 +94,7 @@ private static final float ZOOM_CONTROLS_EPSILON = 0.007f; /** - * WebKit hit test related data strcutre. These are used to implement + * WebKit hit test related data structure. These are used to implement * getHitTestResult, requestFocusNodeHref, requestImageRef methods in WebView. * All values should be updated together. The native counterpart is * AwHitTestData. @@ -1803,11 +1803,12 @@ } /** - * Creates a message channel. + * Creates a message channel and asynchronously returns the ports that + * forms the ports for each end of the channel. * * @param callback The message channel created. */ - public void createMessageChannel(ValueCallback<MessageChannel> callback) { + public void createMessageChannel(ValueCallback<MessagePort[]> callback) { if (isDestroyed()) return; // Make sure the message port service is created. mBrowserContext.createMessagePortServiceIfNecessary(); @@ -2708,5 +2709,5 @@ String message, String sourceOrigin, String targetOrigin, int[] msgPorts); private native void nativeCreateMessageChannel(long nativeAwContents, - ValueCallback<MessageChannel> callback); + ValueCallback<MessagePort[]> callback); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java b/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java index c21546a..b4aae2d 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java +++ b/android_webview/java/src/org/chromium/android_webview/AwMessagePortService.java
@@ -142,8 +142,8 @@ @CalledByNative private void onMessageChannelCreated(int portId1, int portId2, - ValueCallback<MessageChannel> callback) { - callback.onReceiveValue(new MessageChannel(addPort(portId1), addPort(portId2))); + ValueCallback<MessagePort[]> callback) { + callback.onReceiveValue(new MessagePort[]{addPort(portId1), addPort(portId2)}); } // Called on IO thread.
diff --git a/android_webview/java/src/org/chromium/android_webview/MessageChannel.java b/android_webview/java/src/org/chromium/android_webview/MessageChannel.java deleted file mode 100644 index d2957ce..0000000 --- a/android_webview/java/src/org/chromium/android_webview/MessageChannel.java +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.android_webview; - -/** - * Represents the MessageChannel object. Inspired from - * http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels - */ -public class MessageChannel { - // The message ports of MessageChannel. - private MessagePort mPort1; - private MessagePort mPort2; - - public MessageChannel(MessagePort port1, MessagePort port2) { - mPort1 = port1; - mPort2 = port2; - } - - public MessagePort port1() { - return mPort1; - } - - public MessagePort port2() { - return mPort2; - } -}
diff --git a/android_webview/java/src/org/chromium/android_webview/MessagePort.java b/android_webview/java/src/org/chromium/android_webview/MessagePort.java index e040355..4025c45 100644 --- a/android_webview/java/src/org/chromium/android_webview/MessagePort.java +++ b/android_webview/java/src/org/chromium/android_webview/MessagePort.java
@@ -70,7 +70,11 @@ if (msgPorts != null) { portIds = new int[msgPorts.length]; for (int i = 0; i < msgPorts.length; i++) { - portIds[i] = msgPorts[i].portId(); + int sentId = msgPorts[i].portId(); + if (sentId == mPortId) { + throw new IllegalStateException("Source port cannot be transferred"); + } + portIds[i] = sentId; } } mMessagePortService.postMessage(mPortId, message, portIds);
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 4c3f945..e87ca2c 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
@@ -12,7 +12,6 @@ import static org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; import org.chromium.android_webview.AwContents; -import org.chromium.android_webview.MessageChannel; import org.chromium.android_webview.MessagePort; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.base.test.util.DisabledTest; @@ -146,23 +145,56 @@ @SmallTest @Feature({"AndroidWebView", "Android-PostMessage"}) - public void testTransferringSamePortTwiceNotAllowed() throws Throwable { + public void testTransferringSamePortTwiceViaPostMessageToFrameNotAllowed() throws Throwable { loadPage(TEST_PAGE); final CountDownLatch latch = new CountDownLatch(1); runTestOnUiThread(new Runnable() { @Override public void run() { - ValueCallback<MessageChannel> callback = new ValueCallback<MessageChannel>() { + ValueCallback<MessagePort[]> callback = new ValueCallback<MessagePort[]>() { @Override - public void onReceiveValue(MessageChannel channel) { + public void onReceiveValue(MessagePort[] channel) { mAwContents.postMessageToFrame(null, "1", SOURCE_ORIGIN, mWebServer.getBaseUrl(), - new MessagePort[]{channel.port2()}); + new MessagePort[]{channel[1]}); // retransfer the port. This should fail with an exception try { mAwContents.postMessageToFrame(null, "2", SOURCE_ORIGIN, mWebServer.getBaseUrl(), - new MessagePort[]{channel.port2()}); + new MessagePort[]{channel[1]}); + } catch (IllegalStateException ex) { + latch.countDown(); + return; + } + fail(); + } + }; + mAwContents.createMessageChannel(callback); + } + }); + boolean ignore = latch.await(TIMEOUT, java.util.concurrent.TimeUnit.MILLISECONDS); + } + + // channel[0] and channel[1] are entangled ports, establishing a channel. Verify + // it is not allowed to transfer channel[0] on channel[0].postMessage. + // TODO(sgurun) Note that the related case of posting channel[1] via + // channel[0].postMessage does not throw a JS exception at present. We do not throw + // an exception in this case either since the information of entangled port is not + // available at the source port. We need a new mechanism to implement to prevent + // this case. + @SmallTest + @Feature({"AndroidWebView", "Android-PostMessage"}) + public void testTransferSourcePortViaMessageChannelNotAllowed() throws Throwable { + loadPage(TEST_PAGE); + final CountDownLatch latch = new CountDownLatch(1); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + ValueCallback<MessagePort[]> callback = new ValueCallback<MessagePort[]>() { + @Override + public void onReceiveValue(MessagePort[] channel) { + try { + channel[0].postMessage("1", new MessagePort[]{channel[0]}); } catch (IllegalStateException ex) { latch.countDown(); return; @@ -178,14 +210,14 @@ private static class ChannelContainer { private boolean mReady; - private MessageChannel mChannel; + private MessagePort[] mChannel; private Object mLock = new Object(); private String mMessage; - public void set(MessageChannel channel) { + public void set(MessagePort[] channel) { mChannel = channel; } - public MessageChannel get() { + public MessagePort[] get() { return mChannel; } @@ -225,19 +257,19 @@ runTestOnUiThread(new Runnable() { @Override public void run() { - ValueCallback<MessageChannel> callback = new ValueCallback<MessageChannel>() { + ValueCallback<MessagePort[]> callback = new ValueCallback<MessagePort[]>() { @Override - public void onReceiveValue(MessageChannel channel) { + public void onReceiveValue(MessagePort[] channel) { // verify communication from JS to Java. channelContainer.set(channel); - channel.port1().setMessageHandler(new MessagePort.MessageHandler() { + channel[0].setMessageHandler(new MessagePort.MessageHandler() { @Override public void onMessage(String message) { channelContainer.setMessage(message); } }); mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, SOURCE_ORIGIN, - mWebServer.getBaseUrl(), new MessagePort[]{channel.port2()}); + mWebServer.getBaseUrl(), new MessagePort[]{channel[1]}); } }; mAwContents.createMessageChannel(callback); @@ -285,18 +317,18 @@ runTestOnUiThread(new Runnable() { @Override public void run() { - ValueCallback<MessageChannel> callback = new ValueCallback<MessageChannel>() { + ValueCallback<MessagePort[]> callback = new ValueCallback<MessagePort[]>() { @Override - public void onReceiveValue(MessageChannel channel) { - channel.port1().setMessageHandler(new MessagePort.MessageHandler() { + public void onReceiveValue(MessagePort[] channel) { + channel[0].setMessageHandler(new MessagePort.MessageHandler() { @Override public void onMessage(String message) { channelContainer.setMessage(message); } }); mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, SOURCE_ORIGIN, - mWebServer.getBaseUrl(), new MessagePort[]{channel.port2()}); - channel.port1().postMessage(hello, null); + mWebServer.getBaseUrl(), new MessagePort[]{channel[1]}); + channel[0].postMessage(hello, null); } }; mAwContents.createMessageChannel(callback); @@ -348,12 +380,12 @@ runTestOnUiThread(new Runnable() { @Override public void run() { - ValueCallback<MessageChannel> callback = new ValueCallback<MessageChannel>() { + ValueCallback<MessagePort[]> callback = new ValueCallback<MessagePort[]>() { @Override - public void onReceiveValue(MessageChannel channel) { + public void onReceiveValue(MessagePort[] channel) { mAwContents.postMessageToFrame(null, WEBVIEW_MESSAGE, SOURCE_ORIGIN, mWebServer.getBaseUrl(), - new MessagePort[]{channel.port1(), channel.port2()}); + new MessagePort[]{channel[0], channel[1]}); } }; mAwContents.createMessageChannel(callback);
diff --git a/android_webview/lib/aw_browser_dependency_factory_impl.h b/android_webview/lib/aw_browser_dependency_factory_impl.h index e0cf3b9d..c5ca0b1 100644 --- a/android_webview/lib/aw_browser_dependency_factory_impl.h +++ b/android_webview/lib/aw_browser_dependency_factory_impl.h
@@ -22,14 +22,14 @@ class AwBrowserDependencyFactoryImpl : public AwBrowserDependencyFactory { public: AwBrowserDependencyFactoryImpl(); - virtual ~AwBrowserDependencyFactoryImpl(); + ~AwBrowserDependencyFactoryImpl() override; // Sets this class as the singleton instance. static void InstallInstance(); // AwBrowserDependencyFactory - virtual content::BrowserContext* GetBrowserContext() override; - virtual content::WebContents* CreateWebContents() override; + content::BrowserContext* GetBrowserContext() override; + content::WebContents* CreateWebContents() override; private: DISALLOW_COPY_AND_ASSIGN(AwBrowserDependencyFactoryImpl);
diff --git a/android_webview/lib/main/aw_main_delegate.h b/android_webview/lib/main/aw_main_delegate.h index 167d9219..5e6eefc 100644 --- a/android_webview/lib/main/aw_main_delegate.h +++ b/android_webview/lib/main/aw_main_delegate.h
@@ -26,7 +26,7 @@ public JniDependencyFactory { public: AwMainDelegate(); - virtual ~AwMainDelegate(); + ~AwMainDelegate() override; private: // content::ContentMainDelegate implementation: @@ -48,9 +48,8 @@ AwWebPreferencesPopulater* CreateWebPreferencesPopulater() override; AwMessagePortService* CreateAwMessagePortService() override; #if defined(VIDEO_HOLE) - virtual content::ExternalVideoSurfaceContainer* - CreateExternalVideoSurfaceContainer( - content::WebContents* web_contents) override; + content::ExternalVideoSurfaceContainer* CreateExternalVideoSurfaceContainer( + content::WebContents* web_contents) override; #endif scoped_ptr<content::BrowserMainRunner> browser_runner_;
diff --git a/android_webview/native/android_protocol_handler.cc b/android_webview/native/android_protocol_handler.cc index 4bdf6ec..c80d9bd 100644 --- a/android_webview/native/android_protocol_handler.cc +++ b/android_webview/native/android_protocol_handler.cc
@@ -60,33 +60,31 @@ public: AndroidStreamReaderURLRequestJobDelegateImpl(); - virtual scoped_ptr<InputStream> OpenInputStream( - JNIEnv* env, - const GURL& url) override; + scoped_ptr<InputStream> OpenInputStream(JNIEnv* env, + const GURL& url) override; - virtual void OnInputStreamOpenFailed(net::URLRequest* request, - bool* restart) override; + void OnInputStreamOpenFailed(net::URLRequest* request, + bool* restart) override; - virtual bool GetMimeType(JNIEnv* env, - net::URLRequest* request, - InputStream* stream, - std::string* mime_type) override; + bool GetMimeType(JNIEnv* env, + net::URLRequest* request, + InputStream* stream, + std::string* mime_type) override; - virtual bool GetCharset(JNIEnv* env, - net::URLRequest* request, - InputStream* stream, - std::string* charset) override; + bool GetCharset(JNIEnv* env, + net::URLRequest* request, + InputStream* stream, + std::string* charset) override; - virtual void AppendResponseHeaders( - JNIEnv* env, - net::HttpResponseHeaders* headers) override; + void AppendResponseHeaders(JNIEnv* env, + net::HttpResponseHeaders* headers) override; - virtual ~AndroidStreamReaderURLRequestJobDelegateImpl(); + ~AndroidStreamReaderURLRequestJobDelegateImpl() override; }; class AndroidRequestInterceptorBase : public net::URLRequestInterceptor { public: - virtual net::URLRequestJob* MaybeInterceptRequest( + net::URLRequestJob* MaybeInterceptRequest( net::URLRequest* request, net::NetworkDelegate* network_delegate) const override; @@ -97,9 +95,8 @@ public: AssetFileRequestInterceptor(); - virtual ~AssetFileRequestInterceptor() override; - virtual bool ShouldHandleRequest( - const net::URLRequest* request) const override; + ~AssetFileRequestInterceptor() override; + bool ShouldHandleRequest(const net::URLRequest* request) const override; private: // file:///android_asset/ @@ -112,8 +109,7 @@ class ContentSchemeRequestInterceptor : public AndroidRequestInterceptorBase { public: ContentSchemeRequestInterceptor(); - virtual bool ShouldHandleRequest( - const net::URLRequest* request) const override; + bool ShouldHandleRequest(const net::URLRequest* request) const override; }; static ScopedJavaLocalRef<jobject> GetResourceContext(JNIEnv* env) {
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index dd85587..9881f8d 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h
@@ -50,50 +50,45 @@ class AwAutofillClient : public autofill::AutofillClient, public content::WebContentsUserData<AwAutofillClient> { public: - virtual ~AwAutofillClient(); + ~AwAutofillClient() override; void SetSaveFormData(bool enabled); bool GetSaveFormData(); // AutofillClient: - virtual autofill::PersonalDataManager* GetPersonalDataManager() override; - virtual scoped_refptr<autofill::AutofillWebDataService> GetDatabase() - override; - virtual PrefService* GetPrefs() override; + autofill::PersonalDataManager* GetPersonalDataManager() override; + scoped_refptr<autofill::AutofillWebDataService> GetDatabase() override; + PrefService* GetPrefs() override; IdentityProvider* GetIdentityProvider() override; - virtual void HideRequestAutocompleteDialog() override; - virtual void ShowAutofillSettings() override; - virtual void ShowUnmaskPrompt( + void HideRequestAutocompleteDialog() override; + void ShowAutofillSettings() override; + void ShowUnmaskPrompt( const autofill::CreditCard& card, base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override; - virtual void OnUnmaskVerificationResult(bool success) override; - virtual void ConfirmSaveCreditCard( - const base::Closure& save_card_callback) override; - virtual bool HasCreditCardScanFeature() override; - virtual void ScanCreditCard(const CreditCardScanCallback& callback) override; - virtual void ShowRequestAutocompleteDialog( - const autofill::FormData& form, - content::RenderFrameHost* rfh, - const ResultCallback& callback) override; - virtual void ShowAutofillPopup( + void OnUnmaskVerificationResult(bool success) override; + void ConfirmSaveCreditCard(const base::Closure& save_card_callback) override; + bool HasCreditCardScanFeature() override; + void ScanCreditCard(const CreditCardScanCallback& callback) override; + void ShowRequestAutocompleteDialog(const autofill::FormData& form, + content::RenderFrameHost* rfh, + const ResultCallback& callback) override; + void ShowAutofillPopup( const gfx::RectF& element_bounds, base::i18n::TextDirection text_direction, const std::vector<autofill::Suggestion>& suggestions, base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override; - virtual void UpdateAutofillPopupDataListValues( + void UpdateAutofillPopupDataListValues( const std::vector<base::string16>& values, const std::vector<base::string16>& labels) override; - virtual void HideAutofillPopup() override; - virtual bool IsAutocompleteEnabled() override; - virtual void DetectAccountCreationForms( + void HideAutofillPopup() override; + bool IsAutocompleteEnabled() override; + void DetectAccountCreationForms( content::RenderFrameHost* rfh, const std::vector<autofill::FormStructure*>& forms) override; - virtual void DidFillOrPreviewField( - const base::string16& autofilled_value, - const base::string16& profile_full_name) override; - virtual void OnFirstUserGestureObserved() override; - virtual void LinkClicked(const GURL& url, - WindowOpenDisposition disposition) override; + void DidFillOrPreviewField(const base::string16& autofilled_value, + const base::string16& profile_full_name) override; + void OnFirstUserGestureObserved() override; + void LinkClicked(const GURL& url, WindowOpenDisposition disposition) override; void SuggestionSelected(JNIEnv* env, jobject obj, jint position);
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 8987dc2..7110ebab 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h
@@ -69,7 +69,7 @@ static AwContents* FromID(int render_process_id, int render_view_id); AwContents(scoped_ptr<content::WebContents> web_contents); - virtual ~AwContents(); + ~AwContents() override; AwRenderViewHostExt* render_view_host_ext() { return render_view_host_ext_.get(); @@ -139,9 +139,8 @@ jstring origin); // PermissionRequestHandlerClient implementation. - virtual void OnPermissionRequest(AwPermissionRequest* request) override; - virtual void OnPermissionRequestCanceled( - AwPermissionRequest* request) override; + void OnPermissionRequest(AwPermissionRequest* request) override; + void OnPermissionRequestCanceled(AwPermissionRequest* request) override; PermissionRequestHandler* GetPermissionRequestHandler() { return permission_request_handler_.get(); @@ -153,17 +152,15 @@ jlong resources); // AwBrowserPermissionRequestDelegate implementation. - virtual void RequestProtectedMediaIdentifierPermission( + void RequestProtectedMediaIdentifierPermission( const GURL& origin, const base::Callback<void(bool)>& callback) override; - virtual void CancelProtectedMediaIdentifierPermissionRequests( + void CancelProtectedMediaIdentifierPermissionRequests( const GURL& origin) override; - virtual void RequestGeolocationPermission( + void RequestGeolocationPermission( const GURL& origin, const base::Callback<void(bool)>& callback) override; - virtual void CancelGeolocationPermissionRequests( - const GURL& origin) override; - + void CancelGeolocationPermissionRequests(const GURL& origin) override; // Find-in-page API and related methods. void FindAllAsync(JNIEnv* env, jobject obj, jstring search_string); @@ -175,36 +172,33 @@ bool AllowThirdPartyCookies(); // FindHelper::Listener implementation. - virtual void OnFindResultReceived(int active_ordinal, - int match_count, - bool finished) override; + void OnFindResultReceived(int active_ordinal, + int match_count, + bool finished) override; // IconHelper::Listener implementation. - virtual bool ShouldDownloadFavicon(const GURL& icon_url) override; - virtual void OnReceivedIcon(const GURL& icon_url, - const SkBitmap& bitmap) override; - virtual void OnReceivedTouchIconUrl(const std::string& url, - const bool precomposed) override; + bool ShouldDownloadFavicon(const GURL& icon_url) override; + void OnReceivedIcon(const GURL& icon_url, const SkBitmap& bitmap) override; + void OnReceivedTouchIconUrl(const std::string& url, + const bool precomposed) override; // AwRenderViewHostExtClient implementation. - virtual void OnWebLayoutPageScaleFactorChanged( - float page_scale_factor) override; - virtual void OnWebLayoutContentsSizeChanged( - const gfx::Size& contents_size) override; + void OnWebLayoutPageScaleFactorChanged(float page_scale_factor) override; + void OnWebLayoutContentsSizeChanged(const gfx::Size& contents_size) override; // BrowserViewRendererClient implementation. - virtual bool RequestDrawGL(bool wait_for_completion) override; - virtual void PostInvalidate() override; - virtual void InvalidateOnFunctorDestroy() override; - virtual void OnNewPicture() override; - virtual gfx::Point GetLocationOnScreen() override; - virtual void ScrollContainerViewTo(gfx::Vector2d new_value) override; - virtual bool IsFlingActive() const override; - virtual void UpdateScrollState(gfx::Vector2d max_scroll_offset, - gfx::SizeF contents_size_dip, - float page_scale_factor, - float min_page_scale_factor, - float max_page_scale_factor) override; - virtual void DidOverscroll(gfx::Vector2d overscroll_delta) override; + bool RequestDrawGL(bool wait_for_completion) override; + void PostInvalidate() override; + void InvalidateOnFunctorDestroy() override; + void OnNewPicture() override; + gfx::Point GetLocationOnScreen() override; + void ScrollContainerViewTo(gfx::Vector2d new_value) override; + bool IsFlingActive() const override; + void UpdateScrollState(gfx::Vector2d max_scroll_offset, + gfx::SizeF contents_size_dip, + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) override; + void DidOverscroll(gfx::Vector2d overscroll_delta) override; const BrowserViewRenderer* GetBrowserViewRenderer() const;
diff --git a/android_webview/native/aw_contents_client_bridge.h b/android_webview/native/aw_contents_client_bridge.h index d50fa62..2a5caba 100644 --- a/android_webview/native/aw_contents_client_bridge.h +++ b/android_webview/native/aw_contents_client_bridge.h
@@ -30,31 +30,31 @@ class AwContentsClientBridge : public AwContentsClientBridgeBase { public: AwContentsClientBridge(JNIEnv* env, jobject obj); - virtual ~AwContentsClientBridge(); + ~AwContentsClientBridge() override; // AwContentsClientBridgeBase implementation - virtual void AllowCertificateError(int cert_error, - net::X509Certificate* cert, - const GURL& request_url, - const base::Callback<void(bool)>& callback, - bool* cancel_request) override; - virtual void SelectClientCertificate( + void AllowCertificateError(int cert_error, + net::X509Certificate* cert, + const GURL& request_url, + const base::Callback<void(bool)>& callback, + bool* cancel_request) override; + void SelectClientCertificate( net::SSLCertRequestInfo* cert_request_info, const SelectCertificateCallback& callback) override; - virtual void RunJavaScriptDialog( + void RunJavaScriptDialog( content::JavaScriptMessageType message_type, const GURL& origin_url, const base::string16& message_text, const base::string16& default_prompt_text, const content::JavaScriptDialogManager::DialogClosedCallback& callback) override; - virtual void RunBeforeUnloadDialog( + void RunBeforeUnloadDialog( const GURL& origin_url, const base::string16& message_text, const content::JavaScriptDialogManager::DialogClosedCallback& callback) override; - virtual bool ShouldOverrideUrlLoading(const base::string16& url) override; + bool ShouldOverrideUrlLoading(const base::string16& url) override; // Methods called from Java. void ProceedSslError(JNIEnv* env, jobject obj, jboolean proceed, jint id);
diff --git a/android_webview/native/aw_contents_client_bridge_unittest.cc b/android_webview/native/aw_contents_client_bridge_unittest.cc index e6714bb7..b301f919 100644 --- a/android_webview/native/aw_contents_client_bridge_unittest.cc +++ b/android_webview/native/aw_contents_client_bridge_unittest.cc
@@ -41,7 +41,7 @@ // Callback method called when a cert is selected. void CertSelected(X509Certificate* cert); protected: - virtual void SetUp(); + void SetUp() override; void TestCertType(SSLClientCertType type, const std::string& expected_name); // Create the TestBrowserThreads. Just instantiate the member variable. content::TestBrowserThreadBundle thread_bundle_;
diff --git a/android_webview/native/aw_contents_io_thread_client_impl.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc index 4f7ce44..69003ae 100644 --- a/android_webview/native/aw_contents_io_thread_client_impl.cc +++ b/android_webview/native/aw_contents_io_thread_client_impl.cc
@@ -116,9 +116,9 @@ ClientMapEntryUpdater(JNIEnv* env, WebContents* web_contents, jobject jdelegate); - virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) override; - virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; - virtual void WebContentsDestroyed() override; + void RenderFrameCreated(RenderFrameHost* render_frame_host) override; + void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; + void WebContentsDestroyed() override; private: JavaObjectWeakGlobalRef jdelegate_;
diff --git a/android_webview/native/aw_contents_io_thread_client_impl.h b/android_webview/native/aw_contents_io_thread_client_impl.h index 4c9d5551..320d35b 100644 --- a/android_webview/native/aw_contents_io_thread_client_impl.h +++ b/android_webview/native/aw_contents_io_thread_client_impl.h
@@ -42,26 +42,26 @@ // Java object. AwContentsIoThreadClientImpl(bool pending_associate, const base::android::JavaRef<jobject>& jclient); - virtual ~AwContentsIoThreadClientImpl() override; + ~AwContentsIoThreadClientImpl() override; // Implementation of AwContentsIoThreadClient. - virtual bool PendingAssociation() const override; - virtual CacheMode GetCacheMode() const override; - virtual scoped_ptr<AwWebResourceResponse> ShouldInterceptRequest( + bool PendingAssociation() const override; + CacheMode GetCacheMode() const override; + scoped_ptr<AwWebResourceResponse> ShouldInterceptRequest( const GURL& location, const net::URLRequest* request) override; - virtual bool ShouldBlockContentUrls() const override; - virtual bool ShouldBlockFileUrls() const override; - virtual bool ShouldAcceptThirdPartyCookies() const override; - virtual bool ShouldBlockNetworkLoads() const override; - virtual void NewDownload(const GURL& url, - const std::string& user_agent, - const std::string& content_disposition, - const std::string& mime_type, - int64 content_length) override; - virtual void NewLoginRequest(const std::string& realm, - const std::string& account, - const std::string& args) override; + bool ShouldBlockContentUrls() const override; + bool ShouldBlockFileUrls() const override; + bool ShouldAcceptThirdPartyCookies() const override; + bool ShouldBlockNetworkLoads() const override; + void NewDownload(const GURL& url, + const std::string& user_agent, + const std::string& content_disposition, + const std::string& mime_type, + int64 content_length) override; + void NewLoginRequest(const std::string& realm, + const std::string& account, + const std::string& args) override; private: bool pending_association_;
diff --git a/android_webview/native/aw_dev_tools_server.cc b/android_webview/native/aw_dev_tools_server.cc index 9c96694..52d474ed 100644 --- a/android_webview/native/aw_dev_tools_server.cc +++ b/android_webview/native/aw_dev_tools_server.cc
@@ -42,7 +42,7 @@ AwDevToolsServerDelegate() { } - virtual ~AwDevToolsServerDelegate() {} + ~AwDevToolsServerDelegate() override {} // DevToolsHttpProtocolHandler::Delegate overrides. std::string GetDiscoveryPageHTML() override; @@ -81,7 +81,7 @@ private: // content::DevToolsHttpHandler::ServerSocketFactory. - virtual scoped_ptr<net::ServerSocket> CreateForHttpServer() override { + scoped_ptr<net::ServerSocket> CreateForHttpServer() override { scoped_ptr<net::ServerSocket> socket( new net::UnixDomainServerSocket( base::Bind(&content::CanUserConnectToDevTools),
diff --git a/android_webview/native/aw_http_auth_handler.h b/android_webview/native/aw_http_auth_handler.h index c063702..79b7406e 100644 --- a/android_webview/native/aw_http_auth_handler.h +++ b/android_webview/native/aw_http_auth_handler.h
@@ -32,10 +32,10 @@ AwHttpAuthHandler(AwLoginDelegate* login_delegate, net::AuthChallengeInfo* auth_info, bool first_auth_attempt); - virtual ~AwHttpAuthHandler(); + ~AwHttpAuthHandler() override; // from AwHttpAuthHandler - virtual bool HandleOnUIThread(content::WebContents* web_contents) override; + bool HandleOnUIThread(content::WebContents* web_contents) override; void Proceed(JNIEnv* env, jobject obj, jstring username, jstring password); void Cancel(JNIEnv* env, jobject obj);
diff --git a/android_webview/native/aw_media_url_interceptor.h b/android_webview/native/aw_media_url_interceptor.h index a6370a9..332fd37 100644 --- a/android_webview/native/aw_media_url_interceptor.h +++ b/android_webview/native/aw_media_url_interceptor.h
@@ -15,10 +15,10 @@ // Interceptor to handle urls for media assets in the apk. class AwMediaUrlInterceptor : public media::MediaUrlInterceptor { public: - virtual bool Intercept(const std::string& url, - int* fd, - int64* offset, - int64* size) const override; + bool Intercept(const std::string& url, + int* fd, + int64* offset, + int64* size) const override; }; } // namespace android_webview
diff --git a/android_webview/native/aw_message_port_service_impl.h b/android_webview/native/aw_message_port_service_impl.h index 757d75d..f72f80e 100644 --- a/android_webview/native/aw_message_port_service_impl.h +++ b/android_webview/native/aw_message_port_service_impl.h
@@ -26,7 +26,7 @@ static AwMessagePortServiceImpl* GetInstance(); AwMessagePortServiceImpl(); - ~AwMessagePortServiceImpl(); + ~AwMessagePortServiceImpl() override; void Init(JNIEnv* env, jobject object); void CreateMessageChannel(JNIEnv* env, jobject callback,
diff --git a/android_webview/native/aw_pdf_exporter.h b/android_webview/native/aw_pdf_exporter.h index 9ead85e..1321354 100644 --- a/android_webview/native/aw_pdf_exporter.h +++ b/android_webview/native/aw_pdf_exporter.h
@@ -30,7 +30,7 @@ jobject obj, content::WebContents* web_contents); - virtual ~AwPdfExporter(); + ~AwPdfExporter() override; void ExportToPdf(JNIEnv* env, jobject obj, @@ -38,8 +38,8 @@ jobject cancel_signal); // Implement PrintManagerDelegate methods - virtual void DidExportPdf(bool success) override; - virtual bool IsCancelled() override; + void DidExportPdf(bool success) override; + bool IsCancelled() override; private: void CreatePdfSettings(JNIEnv* env, jobject obj);
diff --git a/android_webview/native/aw_quota_manager_bridge_impl.h b/android_webview/native/aw_quota_manager_bridge_impl.h index b327df1e..dc7f20f3 100644 --- a/android_webview/native/aw_quota_manager_bridge_impl.h +++ b/android_webview/native/aw_quota_manager_bridge_impl.h
@@ -56,7 +56,7 @@ private: explicit AwQuotaManagerBridgeImpl(AwBrowserContext* browser_context); - virtual ~AwQuotaManagerBridgeImpl(); + ~AwQuotaManagerBridgeImpl() override; content::StoragePartition* GetStoragePartition() const;
diff --git a/android_webview/native/aw_settings.h b/android_webview/native/aw_settings.h index 141320d..581a6cd 100644 --- a/android_webview/native/aw_settings.h +++ b/android_webview/native/aw_settings.h
@@ -25,7 +25,7 @@ static AwSettings* FromWebContents(content::WebContents* web_contents); AwSettings(JNIEnv* env, jobject obj, content::WebContents* web_contents); - virtual ~AwSettings(); + ~AwSettings() override; // Called from Java. Methods with "Locked" suffix require that the settings // access lock is held during their execution. @@ -46,9 +46,8 @@ void UpdateEverything(); // WebContentsObserver overrides: - virtual void RenderViewCreated( - content::RenderViewHost* render_view_host) override; - virtual void WebContentsDestroyed() override; + void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void WebContentsDestroyed() override; bool renderer_prefs_initialized_;
diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc index 2f43de1ae..acece1b 100644 --- a/android_webview/native/aw_web_contents_delegate.cc +++ b/android_webview/native/aw_web_contents_delegate.cc
@@ -125,7 +125,7 @@ void AwWebContentsDelegate::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { JNIEnv* env = AttachCurrentThread();
diff --git a/android_webview/native/aw_web_contents_delegate.h b/android_webview/native/aw_web_contents_delegate.h index 8a17a3e..96cd32575 100644 --- a/android_webview/native/aw_web_contents_delegate.h +++ b/android_webview/native/aw_web_contents_delegate.h
@@ -18,46 +18,44 @@ : public web_contents_delegate_android::WebContentsDelegateAndroid { public: AwWebContentsDelegate(JNIEnv* env, jobject obj); - virtual ~AwWebContentsDelegate(); - virtual content::JavaScriptDialogManager* GetJavaScriptDialogManager( + ~AwWebContentsDelegate() override; + content::JavaScriptDialogManager* GetJavaScriptDialogManager( content::WebContents* source) override; - virtual void FindReply(content::WebContents* web_contents, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) override; - virtual void CanDownload(content::RenderViewHost* source, - const GURL& url, - const std::string& request_method, - const base::Callback<void(bool)>& callback) override; - virtual void RunFileChooser( - content::WebContents* web_contents, - const content::FileChooserParams& params) override; - virtual void AddNewContents(content::WebContents* source, - content::WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture, - bool* was_blocked) override; + void FindReply(content::WebContents* web_contents, + int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) override; + void CanDownload(content::RenderViewHost* source, + const GURL& url, + const std::string& request_method, + const base::Callback<void(bool)>& callback) override; + void RunFileChooser(content::WebContents* web_contents, + const content::FileChooserParams& params) override; + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) override; - virtual void WebContentsCreated(content::WebContents* source_contents, - int opener_render_frame_id, - const base::string16& frame_name, - const GURL& target_url, - content::WebContents* new_contents) override; + void WebContentsCreated(content::WebContents* source_contents, + int opener_render_frame_id, + const base::string16& frame_name, + const GURL& target_url, + content::WebContents* new_contents) override; - virtual void CloseContents(content::WebContents* source) override; - virtual void ActivateContents(content::WebContents* contents) override; - virtual void RequestMediaAccessPermission( + void CloseContents(content::WebContents* source) override; + void ActivateContents(content::WebContents* contents) override; + void RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) override; - virtual void EnterFullscreenModeForTab(content::WebContents* web_contents, - const GURL& origin) override; - virtual void ExitFullscreenModeForTab( - content::WebContents* web_contents) override; - virtual bool IsFullscreenForTabOrPending( + void EnterFullscreenModeForTab(content::WebContents* web_contents, + const GURL& origin) override; + void ExitFullscreenModeForTab(content::WebContents* web_contents) override; + bool IsFullscreenForTabOrPending( const content::WebContents* web_contents) const override; private:
diff --git a/android_webview/native/aw_web_contents_view_delegate.h b/android_webview/native/aw_web_contents_view_delegate.h index 95fd0d6a..c4b438a 100644 --- a/android_webview/native/aw_web_contents_view_delegate.h +++ b/android_webview/native/aw_web_contents_view_delegate.h
@@ -22,13 +22,12 @@ static content::WebContentsViewDelegate* Create( content::WebContents* web_contents); - virtual ~AwWebContentsViewDelegate(); + ~AwWebContentsViewDelegate() override; // content::WebContentsViewDelegate implementation. - virtual content::WebDragDestDelegate* GetDragDestDelegate() override; - virtual void ShowContextMenu( - content::RenderFrameHost* render_frame_host, - const content::ContextMenuParams& params) override; + content::WebDragDestDelegate* GetDragDestDelegate() override; + void ShowContextMenu(content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params) override; private: AwWebContentsViewDelegate(content::WebContents* web_contents);
diff --git a/android_webview/native/aw_web_preferences_populater_impl.h b/android_webview/native/aw_web_preferences_populater_impl.h index 9831b04..8b02845 100644 --- a/android_webview/native/aw_web_preferences_populater_impl.h +++ b/android_webview/native/aw_web_preferences_populater_impl.h
@@ -15,11 +15,11 @@ class AwWebPreferencesPopulaterImpl : public AwWebPreferencesPopulater { public: AwWebPreferencesPopulaterImpl(); - virtual ~AwWebPreferencesPopulaterImpl(); + ~AwWebPreferencesPopulaterImpl() override; // AwWebPreferencesPopulater - virtual void PopulateFor(content::WebContents* web_contents, - content::WebPreferences* web_prefs) override; + void PopulateFor(content::WebContents* web_contents, + content::WebPreferences* web_prefs) override; }; } // namespace android_webview
diff --git a/android_webview/native/aw_web_resource_response_impl.h b/android_webview/native/aw_web_resource_response_impl.h index a33db6eb..842a2cbd 100644 --- a/android_webview/native/aw_web_resource_response_impl.h +++ b/android_webview/native/aw_web_resource_response_impl.h
@@ -23,17 +23,16 @@ // It is expected that |obj| is an instance of the Java-side // org.chromium.android_webview.AwWebResourceResponse class. AwWebResourceResponseImpl(const base::android::JavaRef<jobject>& obj); - virtual ~AwWebResourceResponseImpl(); + ~AwWebResourceResponseImpl() override; - virtual scoped_ptr<InputStream> GetInputStream(JNIEnv* env) const override; - virtual bool GetMimeType(JNIEnv* env, std::string* mime_type) const override; - virtual bool GetCharset(JNIEnv* env, std::string* charset) const override; - virtual bool GetStatusInfo(JNIEnv* env, - int* status_code, - std::string* reason_phrase) const override; - virtual bool GetResponseHeaders( - JNIEnv* env, - net::HttpResponseHeaders* headers) const override; + scoped_ptr<InputStream> GetInputStream(JNIEnv* env) const override; + bool GetMimeType(JNIEnv* env, std::string* mime_type) const override; + bool GetCharset(JNIEnv* env, std::string* charset) const override; + bool GetStatusInfo(JNIEnv* env, + int* status_code, + std::string* reason_phrase) const override; + bool GetResponseHeaders(JNIEnv* env, + net::HttpResponseHeaders* headers) const override; private: base::android::ScopedJavaGlobalRef<jobject> java_object_;
diff --git a/android_webview/native/external_video_surface_container_impl.h b/android_webview/native/external_video_surface_container_impl.h index ff741d8..29e7889 100644 --- a/android_webview/native/external_video_surface_container_impl.h +++ b/android_webview/native/external_video_surface_container_impl.h
@@ -23,15 +23,15 @@ ExternalVideoSurfaceContainerImpl(content::WebContents* contents); // ExternalVideoSurfaceContainer implementation. - virtual void RequestExternalVideoSurface( + void RequestExternalVideoSurface( int player_id, const SurfaceCreatedCB& surface_created_cb, const SurfaceDestroyedCB& surface_destroyed_cb) override; - virtual int GetCurrentPlayerId() override; - virtual void ReleaseExternalVideoSurface(int player_id) override; - virtual void OnFrameInfoUpdated() override; - virtual void OnExternalVideoSurfacePositionChanged( - int player_id, const gfx::RectF& rect) override; + int GetCurrentPlayerId() override; + void ReleaseExternalVideoSurface(int player_id) override; + void OnFrameInfoUpdated() override; + void OnExternalVideoSurfacePositionChanged(int player_id, + const gfx::RectF& rect) override; // Methods called from Java. void SurfaceCreated( @@ -39,7 +39,7 @@ void SurfaceDestroyed(JNIEnv* env, jobject obj, jint player_id); private: - virtual ~ExternalVideoSurfaceContainerImpl(); + ~ExternalVideoSurfaceContainerImpl() override; base::android::ScopedJavaGlobalRef<jobject> jobject_;
diff --git a/android_webview/native/input_stream_impl.h b/android_webview/native/input_stream_impl.h index 4a950e8..aebd7ac 100644 --- a/android_webview/native/input_stream_impl.h +++ b/android_webview/native/input_stream_impl.h
@@ -26,15 +26,16 @@ // |stream| should be an instance of the InputStream Java class. // |stream| can't be null. InputStreamImpl(const base::android::JavaRef<jobject>& stream); - virtual ~InputStreamImpl(); + ~InputStreamImpl() override; // Gets the underlying Java object. Guaranteed non-NULL. const jobject jobj() const { return jobject_.obj(); } // InputStream implementation. - virtual bool BytesAvailable(int* bytes_available) const override; - virtual bool Skip(int64_t n, int64_t* bytes_skipped) override; - virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) override; + bool BytesAvailable(int* bytes_available) const override; + bool Skip(int64_t n, int64_t* bytes_skipped) override; + bool Read(net::IOBuffer* dest, int length, int* bytes_read) override; + protected: // Parameterless constructor exposed for testing. InputStreamImpl();
diff --git a/android_webview/native/input_stream_unittest.cc b/android_webview/native/input_stream_unittest.cc index ec4faf6..95d7bf5f 100644 --- a/android_webview/native/input_stream_unittest.cc +++ b/android_webview/native/input_stream_unittest.cc
@@ -35,7 +35,7 @@ InputStreamTest() { } protected: - virtual void SetUp() { + void SetUp() override { env_ = AttachCurrentThread(); ASSERT_THAT(env_, NotNull()); ASSERT_TRUE(android_webview::RegisterInputStream(env_));
diff --git a/android_webview/native/permission/media_access_permission_request.h b/android_webview/native/permission/media_access_permission_request.h index 080d7f3..01bc83e4 100644 --- a/android_webview/native/permission/media_access_permission_request.h +++ b/android_webview/native/permission/media_access_permission_request.h
@@ -17,12 +17,12 @@ public: MediaAccessPermissionRequest(const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback); - virtual ~MediaAccessPermissionRequest(); + ~MediaAccessPermissionRequest() override; // AwPermissionRequestDelegate implementation. - virtual const GURL& GetOrigin() override; - virtual int64 GetResources() override; - virtual void NotifyRequestResult(bool allowed) override; + const GURL& GetOrigin() override; + int64 GetResources() override; + void NotifyRequestResult(bool allowed) override; private: friend class TestMediaAccessPermissionRequest;
diff --git a/android_webview/native/permission/media_access_permission_request_unittest.cc b/android_webview/native/permission/media_access_permission_request_unittest.cc index 32a1906..a2ba5aa 100644 --- a/android_webview/native/permission/media_access_permission_request_unittest.cc +++ b/android_webview/native/permission/media_access_permission_request_unittest.cc
@@ -23,7 +23,7 @@ class MediaAccessPermissionRequestTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { audio_device_id_ = "audio"; video_device_id_ = "video"; first_audio_device_id_ = "audio1";
diff --git a/android_webview/native/permission/permission_request_handler.h b/android_webview/native/permission/permission_request_handler.h index 2318b57..7b264f7 100644 --- a/android_webview/native/permission/permission_request_handler.h +++ b/android_webview/native/permission/permission_request_handler.h
@@ -27,7 +27,7 @@ public: PermissionRequestHandler(PermissionRequestHandlerClient* client, content::WebContents* aw_contents); - virtual ~PermissionRequestHandler(); + ~PermissionRequestHandler() override; // Send the given |request| to PermissionRequestHandlerClient. void SendRequest(scoped_ptr<AwPermissionRequestDelegate> request); @@ -39,7 +39,7 @@ void PreauthorizePermission(const GURL& origin, int64 resources); // WebContentsObserver - virtual void NavigationEntryCommitted( + void NavigationEntryCommitted( const content::LoadCommittedDetails& load_details) override; private:
diff --git a/android_webview/native/permission/permission_request_handler_unittest.cc b/android_webview/native/permission/permission_request_handler_unittest.cc index 775e5fb..0afad0742 100644 --- a/android_webview/native/permission/permission_request_handler_unittest.cc +++ b/android_webview/native/permission/permission_request_handler_unittest.cc
@@ -21,19 +21,13 @@ callback_(callback) {} // Get the origin which initiated the permission request. - virtual const GURL& GetOrigin() override { - return origin_; - } + const GURL& GetOrigin() override { return origin_; } // Get the resources the origin wanted to access. - virtual int64 GetResources() override { - return resources_; - } + int64 GetResources() override { return resources_; } // Notify the permission request is allowed or not. - virtual void NotifyRequestResult(bool allowed) override { - callback_.Run(allowed); - } + void NotifyRequestResult(bool allowed) override { callback_.Run(allowed); } private: GURL origin_; @@ -57,14 +51,13 @@ TestPermissionRequestHandlerClient() : request_(NULL) {} - virtual void OnPermissionRequest(AwPermissionRequest* request) override { + void OnPermissionRequest(AwPermissionRequest* request) override { request_ = request; requested_permission_ = Permission(request->GetOrigin(), request->GetResources()); } - virtual void OnPermissionRequestCanceled( - AwPermissionRequest* request) override{ + void OnPermissionRequestCanceled(AwPermissionRequest* request) override { canceled_permission_ = Permission(request->GetOrigin(), request->GetResources()); } @@ -129,7 +122,7 @@ } protected: - virtual void SetUp() override { + void SetUp() override { testing::Test::SetUp(); origin_ = GURL("http://www.google.com"); resources_ =
diff --git a/android_webview/native/permission/simple_permission_request.h b/android_webview/native/permission/simple_permission_request.h index c232bdf1..ba6b8708 100644 --- a/android_webview/native/permission/simple_permission_request.h +++ b/android_webview/native/permission/simple_permission_request.h
@@ -17,12 +17,12 @@ SimplePermissionRequest(const GURL& origin, int64 resources, const base::Callback<void(bool)>& callback); - virtual ~SimplePermissionRequest(); + ~SimplePermissionRequest() override; // AwPermissionRequestDelegate implementation. - virtual const GURL& GetOrigin() override; - virtual int64 GetResources() override; - virtual void NotifyRequestResult(bool allowed) override; + const GURL& GetOrigin() override; + int64 GetResources() override; + void NotifyRequestResult(bool allowed) override; private: const GURL origin_;
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h index f6ffcbff..c16b506 100644 --- a/android_webview/renderer/aw_content_renderer_client.h +++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -19,36 +19,33 @@ class AwContentRendererClient : public content::ContentRendererClient { public: AwContentRendererClient(); - virtual ~AwContentRendererClient(); + ~AwContentRendererClient() override; // ContentRendererClient implementation. - virtual void RenderThreadStarted() override; - virtual void RenderFrameCreated(content::RenderFrame* render_frame) override; - virtual void RenderViewCreated(content::RenderView* render_view) override; - virtual bool HasErrorPage(int http_status_code, - std::string* error_domain) override; - virtual void GetNavigationErrorStrings( - content::RenderView* render_view, - blink::WebFrame* frame, - const blink::WebURLRequest& failed_request, - const blink::WebURLError& error, - std::string* error_html, - base::string16* error_description) override; - virtual unsigned long long VisitedLinkHash(const char* canonical_url, - size_t length) override; - virtual bool IsLinkVisited(unsigned long long link_hash) override; - virtual void AddKeySystems( - std::vector<media::KeySystemInfo>* key_systems) override; + void RenderThreadStarted() override; + void RenderFrameCreated(content::RenderFrame* render_frame) override; + void RenderViewCreated(content::RenderView* render_view) override; + bool HasErrorPage(int http_status_code, std::string* error_domain) override; + void GetNavigationErrorStrings(content::RenderView* render_view, + blink::WebFrame* frame, + const blink::WebURLRequest& failed_request, + const blink::WebURLError& error, + std::string* error_html, + base::string16* error_description) override; + unsigned long long VisitedLinkHash(const char* canonical_url, + size_t length) override; + bool IsLinkVisited(unsigned long long link_hash) override; + void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override; - virtual bool HandleNavigation(content::RenderFrame* render_frame, - content::DocumentState* document_state, - int opener_id, - blink::WebFrame* frame, - const blink::WebURLRequest& request, - blink::WebNavigationType type, - blink::WebNavigationPolicy default_policy, - bool is_redirect) override; - virtual bool ShouldOverridePageVisibilityState( + bool HandleNavigation(content::RenderFrame* render_frame, + content::DocumentState* document_state, + int opener_id, + blink::WebFrame* frame, + const blink::WebURLRequest& request, + blink::WebNavigationType type, + blink::WebNavigationPolicy default_policy, + bool is_redirect) override; + bool ShouldOverridePageVisibilityState( const content::RenderFrame* render_frame, blink::WebPageVisibilityState* override_state) override;
diff --git a/android_webview/renderer/aw_message_port_client.h b/android_webview/renderer/aw_message_port_client.h index e83641e..bd21472 100644 --- a/android_webview/renderer/aw_message_port_client.h +++ b/android_webview/renderer/aw_message_port_client.h
@@ -19,7 +19,7 @@ explicit AwMessagePortClient(content::RenderFrame* render_frame); private: - virtual ~AwMessagePortClient(); + ~AwMessagePortClient() override; // RenderFrameObserver bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/android_webview/renderer/aw_permission_client.h b/android_webview/renderer/aw_permission_client.h index e3a4bfa..e5c036d 100644 --- a/android_webview/renderer/aw_permission_client.h +++ b/android_webview/renderer/aw_permission_client.h
@@ -16,8 +16,8 @@ public: explicit AwPermissionClient(content::RenderFrame* render_view); - private: - virtual ~AwPermissionClient(); + private: + ~AwPermissionClient() override; // blink::WebPermissionClient implementation. virtual bool allowDisplayingInsecureContent(
diff --git a/android_webview/renderer/aw_render_frame_ext.h b/android_webview/renderer/aw_render_frame_ext.h index 40141bc7..0643f7f8 100644 --- a/android_webview/renderer/aw_render_frame_ext.h +++ b/android_webview/renderer/aw_render_frame_ext.h
@@ -17,10 +17,10 @@ AwRenderFrameExt(content::RenderFrame* render_frame); private: - virtual ~AwRenderFrameExt(); + ~AwRenderFrameExt() override; // RenderFrame::Observer: - virtual void DidCommitProvisionalLoad(bool is_new_navigation) override; + void DidCommitProvisionalLoad(bool is_new_navigation) override; DISALLOW_COPY_AND_ASSIGN(AwRenderFrameExt); };
diff --git a/android_webview/renderer/aw_render_process_observer.h b/android_webview/renderer/aw_render_process_observer.h index 5c39787b..b2df85d 100644 --- a/android_webview/renderer/aw_render_process_observer.h +++ b/android_webview/renderer/aw_render_process_observer.h
@@ -16,11 +16,11 @@ class AwRenderProcessObserver : public content::RenderProcessObserver { public: AwRenderProcessObserver(); - virtual ~AwRenderProcessObserver(); + ~AwRenderProcessObserver() override; // content::RenderProcessObserver implementation. - virtual bool OnControlMessageReceived(const IPC::Message& message) override; - virtual void WebKitInitialized() override; + bool OnControlMessageReceived(const IPC::Message& message) override; + void WebKitInitialized() override; private: void OnClearCache();
diff --git a/android_webview/renderer/aw_render_view_ext.h b/android_webview/renderer/aw_render_view_ext.h index 29f6442..58db3d8 100644 --- a/android_webview/renderer/aw_render_view_ext.h +++ b/android_webview/renderer/aw_render_view_ext.h
@@ -32,14 +32,14 @@ private: AwRenderViewExt(content::RenderView* render_view); - virtual ~AwRenderViewExt(); + ~AwRenderViewExt() override; // RenderView::Observer: - virtual bool OnMessageReceived(const IPC::Message& message) override; - virtual void FocusedNodeChanged(const blink::WebNode& node) override; - virtual void DidCommitCompositorFrame() override; - virtual void DidUpdateLayout() override; - virtual void Navigate(const GURL& url) override; + bool OnMessageReceived(const IPC::Message& message) override; + void FocusedNodeChanged(const blink::WebNode& node) override; + void DidCommitCompositorFrame() override; + void DidUpdateLayout() override; + void Navigate(const GURL& url) override; void OnDocumentHasImagesRequest(int id);
diff --git a/android_webview/renderer/print_render_frame_observer.h b/android_webview/renderer/print_render_frame_observer.h index 95248ac8..1b99c384 100644 --- a/android_webview/renderer/print_render_frame_observer.h +++ b/android_webview/renderer/print_render_frame_observer.h
@@ -14,10 +14,10 @@ explicit PrintRenderFrameObserver(content::RenderFrame* render_view); private: - virtual ~PrintRenderFrameObserver(); + ~PrintRenderFrameObserver() override; // RenderFrameObserver implementation. - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; // IPC handlers void OnPrintNodeUnderContextMenu();
diff --git a/apps/custom_launcher_page_contents.cc b/apps/custom_launcher_page_contents.cc index 150bfcf7..20744b3 100644 --- a/apps/custom_launcher_page_contents.cc +++ b/apps/custom_launcher_page_contents.cc
@@ -71,13 +71,13 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { app_delegate_->AddNewContents(new_contents->GetBrowserContext(), new_contents, disposition, - initial_pos, + initial_rect, user_gesture, was_blocked); }
diff --git a/apps/custom_launcher_page_contents.h b/apps/custom_launcher_page_contents.h index 95c7c65..919bbe3 100644 --- a/apps/custom_launcher_page_contents.h +++ b/apps/custom_launcher_page_contents.h
@@ -48,7 +48,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; bool IsPopupOrPanel(const content::WebContents* source) const override;
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index fec5025..f1c5eb1 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -32,7 +32,6 @@ "//net", "//skia", "//third_party/icu", - "//ui/accelerometer", "//ui/accessibility", "//ui/app_list", "//ui/aura", @@ -40,6 +39,7 @@ "//ui/compositor", "//ui/events", "//ui/events:events_base", + "//ui/events:gesture_detection", "//ui/events/devices", "//ui/gfx", "//ui/gfx/geometry", @@ -70,7 +70,6 @@ "//build/config/linux:xfixes", ] deps += [ - "//ui/events:gesture_detection", "//ui/events/platform", "//ui/gfx/x", ] @@ -84,7 +83,10 @@ } if (use_ozone) { - deps += [ "//ui/ozone" ] + deps += [ + "//ui/events/ozone:events_ozone", + "//ui/ozone", + ] } if (is_chromeos) { @@ -260,7 +262,6 @@ "//skia", "//testing/gtest", "//third_party/icu", - "//ui/accelerometer", "//ui/accessibility", "//ui/aura", "//ui/aura:test_support",
diff --git a/ash/ash.gyp b/ash/ash.gyp index cd614a6..8861a16 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp
@@ -884,7 +884,6 @@ '../skia/skia.gyp:skia', '../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icuuc', - '../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer', '../ui/accessibility/accessibility.gyp:accessibility', '../ui/app_list/app_list.gyp:app_list', '../ui/aura/aura.gyp:aura', @@ -934,6 +933,7 @@ }], ['use_ozone==1', { 'dependencies': [ + '../ui/events/ozone/events_ozone.gyp:events_ozone', '../ui/ozone/ozone.gyp:ozone', ], }], @@ -1063,7 +1063,6 @@ '../testing/gtest.gyp:gtest', '../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icuuc', - '../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer', '../ui/accessibility/accessibility.gyp:accessibility', '../ui/app_list/app_list.gyp:app_list', '../ui/aura/aura.gyp:aura',
diff --git a/ash/content/display/screen_orientation_controller_chromeos.cc b/ash/content/display/screen_orientation_controller_chromeos.cc index 34398a2..a80a1b8 100644 --- a/ash/content/display/screen_orientation_controller_chromeos.cc +++ b/ash/content/display/screen_orientation_controller_chromeos.cc
@@ -12,10 +12,12 @@ #include "base/auto_reset.h" #include "base/command_line.h" #include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "content/public/browser/screen_orientation_provider.h" #include "content/public/browser/web_contents.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" +#include "ui/chromeos/accelerometer/accelerometer_util.h" #include "ui/gfx/display.h" #include "ui/gfx/geometry/size.h" #include "ui/wm/public/activation_client.h" @@ -145,16 +147,16 @@ } void ScreenOrientationController::OnAccelerometerUpdated( - const ui::AccelerometerUpdate& update) { + const chromeos::AccelerometerUpdate& update) { if (rotation_locked_ && !CanRotateInLockedState()) return; - if (!update.has(ui::ACCELEROMETER_SOURCE_SCREEN)) + if (!update.has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) return; // Ignore the reading if it appears unstable. The reading is considered // unstable if it deviates too much from gravity - if (chromeos::AccelerometerReader::IsReadingStable( - update, ui::ACCELEROMETER_SOURCE_SCREEN)) { - HandleScreenRotation(update.get(ui::ACCELEROMETER_SOURCE_SCREEN)); + if (ui::IsAccelerometerReadingStable(update, + chromeos::ACCELEROMETER_SOURCE_SCREEN)) { + HandleScreenRotation(update.get(chromeos::ACCELEROMETER_SOURCE_SCREEN)); } } @@ -314,8 +316,8 @@ } void ScreenOrientationController::HandleScreenRotation( - const gfx::Vector3dF& lid) { - gfx::Vector3dF lid_flattened(lid.x(), lid.y(), 0.0f); + const chromeos::AccelerometerReading& lid) { + gfx::Vector3dF lid_flattened(lid.x, lid.y, 0.0f); float lid_flattened_length = lid_flattened.Length(); // When the lid is close to being flat, don't change rotation as it is too // sensitive to slight movements.
diff --git a/ash/content/display/screen_orientation_controller_chromeos.h b/ash/content/display/screen_orientation_controller_chromeos.h index b8cdd86..43fa886 100644 --- a/ash/content/display/screen_orientation_controller_chromeos.h +++ b/ash/content/display/screen_orientation_controller_chromeos.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "content/public/browser/screen_orientation_delegate.h" #include "third_party/WebKit/public/platform/WebScreenOrientationLockType.h" #include "ui/aura/window_observer.h" @@ -80,7 +81,8 @@ void OnWindowDestroying(aura::Window* window) override; // chromeos::AccelerometerReader::Observer: - void OnAccelerometerUpdated(const ui::AccelerometerUpdate& update) override; + void OnAccelerometerUpdated( + const chromeos::AccelerometerUpdate& update) override; // content::ScreenOrientationDelegate: bool FullScreenRequired(content::WebContents* web_contents) override; @@ -126,7 +128,7 @@ // Detect screen rotation from |lid| accelerometer and automatically rotate // screen. - void HandleScreenRotation(const gfx::Vector3dF& lid); + void HandleScreenRotation(const chromeos::AccelerometerReading& lid); // Checks DisplayManager for registered rotation lock, and rotation, // preferences. These are then applied.
diff --git a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc index bd9d64e9..03e4e826 100644 --- a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc +++ b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_browser_context.h" @@ -71,8 +72,8 @@ } void TriggerLidUpdate(const gfx::Vector3dF& lid) { - ui::AccelerometerUpdate update; - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), lid.z()); + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), lid.z()); Shell::GetInstance()->screen_orientation_controller()->OnAccelerometerUpdated( update); }
diff --git a/ash/display/display_change_observer_chromeos.cc b/ash/display/display_change_observer_chromeos.cc index 2a8c8bb..de481949 100644 --- a/ash/display/display_change_observer_chromeos.cc +++ b/ash/display/display_change_observer_chromeos.cc
@@ -280,4 +280,10 @@ void DisplayChangeObserver::OnKeyboardDeviceConfigurationChanged() { } +void DisplayChangeObserver::OnMouseDeviceConfigurationChanged() { +} + +void DisplayChangeObserver::OnTouchpadDeviceConfigurationChanged() { +} + } // namespace ash
diff --git a/ash/display/display_change_observer_chromeos.h b/ash/display/display_change_observer_chromeos.h index a32afc5..228adb27 100644 --- a/ash/display/display_change_observer_chromeos.h +++ b/ash/display/display_change_observer_chromeos.h
@@ -50,6 +50,8 @@ // Overriden from ui::InputDeviceEventObserver: void OnTouchscreenDeviceConfigurationChanged() override; void OnKeyboardDeviceConfigurationChanged() override; + void OnMouseDeviceConfigurationChanged() override; + void OnTouchpadDeviceConfigurationChanged() override; // Overriden from ShellObserver: void OnAppTerminating() override;
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index c74103a..5846b63 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -246,7 +246,8 @@ return false; alignment_ = alignment; - if (state_.is_screen_locked || state_.is_adding_user_screen) { + if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked() || + state_.is_adding_user_screen) { // The shelf will itself move to the bottom while locked. If a request is // sent to move while being locked, we postpone the move until the lock // screen goes away. @@ -264,7 +265,8 @@ // bottom alignment. Note: We cannot use state_.is_screen_locked here since // that flag gets set later than the SessionStateDelegate reports a locked // screen which leads in - if (state_.is_screen_locked || state_.is_adding_user_screen) + if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked() || + state_.is_adding_user_screen) return SHELF_ALIGNMENT_BOTTOM; return alignment_; }
diff --git a/ash/system/chromeos/session/tray_session_length_limit_unittest.cc b/ash/system/chromeos/session/tray_session_length_limit_unittest.cc index e1152ce6..da203a54 100644 --- a/ash/system/chromeos/session/tray_session_length_limit_unittest.cc +++ b/ash/system/chromeos/session/tray_session_length_limit_unittest.cc
@@ -30,7 +30,10 @@ system_tray->AddTrayItem(tray_session_length_limit_); } - void TearDown() override { AshTestBase::TearDown(); } + void TearDown() override { + ClearSessionLengthLimit(); + AshTestBase::TearDown(); + } protected: void UpdateSessionLengthLimitInMin(int mins) { @@ -47,7 +50,7 @@ if ((*iter)->id() == TraySessionLengthLimit::kNotificationId) return *iter; } - return NULL; + return nullptr; } void ClearSessionLengthLimit() { @@ -120,8 +123,6 @@ } TEST_F(TraySessionLengthLimitTest, RemoveNotification) { - message_center::Notification* notification; - // Limit is 15 min. UpdateSessionLengthLimitInMin(15); EXPECT_TRUE(GetNotification()); @@ -137,7 +138,7 @@ // Limit is 3 min. The notification should re-appear and should be re-read // because of state change. UpdateSessionLengthLimitInMin(3); - notification = GetNotification(); + message_center::Notification* notification = GetNotification(); EXPECT_TRUE(notification); EXPECT_TRUE(notification->rich_notification_data(). should_make_spoken_feedback_for_popup_updates);
diff --git a/ash/virtual_keyboard_controller.cc b/ash/virtual_keyboard_controller.cc index 3ecc0bc2..d043dd3 100644 --- a/ash/virtual_keyboard_controller.cc +++ b/ash/virtual_keyboard_controller.cc
@@ -67,6 +67,12 @@ UpdateDevices(); } +void VirtualKeyboardController::OnMouseDeviceConfigurationChanged() { +} + +void VirtualKeyboardController::OnTouchpadDeviceConfigurationChanged() { +} + void VirtualKeyboardController::ToggleIgnoreExternalKeyboard() { ignore_external_keyboard_ = !ignore_external_keyboard_; UpdateKeyboardEnabled();
diff --git a/ash/virtual_keyboard_controller.h b/ash/virtual_keyboard_controller.h index 83b9fce..301eb0b 100644 --- a/ash/virtual_keyboard_controller.h +++ b/ash/virtual_keyboard_controller.h
@@ -28,6 +28,8 @@ // ui::InputDeviceObserver: void OnTouchscreenDeviceConfigurationChanged() override; void OnKeyboardDeviceConfigurationChanged() override; + void OnMouseDeviceConfigurationChanged() override; + void OnTouchpadDeviceConfigurationChanged() override; // Toggles whether the presense of an external keyboard should be ignored // when determining whether or not to show the on-screen keyboard.
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc index 1463a50..ee503a3 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -30,12 +30,14 @@ #if defined(OS_CHROMEOS) #include "chromeos/dbus/dbus_thread_manager.h" +#include "ui/chromeos/accelerometer/accelerometer_util.h" #endif // OS_CHROMEOS namespace ash { namespace { +#if defined(OS_CHROMEOS) // The hinge angle at which to enter maximize mode. const float kEnterMaximizeModeAngle = 200.0f; @@ -49,6 +51,7 @@ // vice versa). const float kMinStableAngle = 20.0f; const float kMaxStableAngle = 340.0f; +#endif // OS_CHROMEOS // The time duration to consider the lid to be recently opened. // This is used to prevent entering maximize mode if an erroneous accelerometer @@ -57,6 +60,7 @@ const base::TimeDelta kLidRecentlyOpenedDuration = base::TimeDelta::FromSeconds(2); +#if defined(OS_CHROMEOS) // When the device approaches vertical orientation (i.e. portrait orientation) // the accelerometers for the base and lid approach the same values (i.e. // gravity pointing in the direction of the hinge). When this happens we cannot @@ -65,13 +69,25 @@ // detect hinge angle in m/s^2. const float kHingeAngleDetectionThreshold = 2.5f; -#if defined(OS_CHROMEOS) // The maximum deviation between the magnitude of the two accelerometers under -// which to detect hinge angle and screen rotation in m/s^2. These -// accelerometers are attached to the same physical device and so should be -// under the same acceleration. +// which to detect hinge angle in m/s^2. These accelerometers are attached to +// the same physical device and so should be under the same acceleration. const float kNoisyMagnitudeDeviation = 1.0f; -#endif + +// The angle between chromeos::AccelerometerReadings are considered stable if +// their magnitudes do not differ greatly. This returns false if the deviation +// between the screen and keyboard accelerometers is too high. +bool IsAngleBetweenAccelerometerReadingsStable( + const chromeos::AccelerometerUpdate& update) { + return std::abs( + ui::ConvertAccelerometerReadingToVector3dF( + update.get(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) + .Length() - + ui::ConvertAccelerometerReadingToVector3dF( + update.get(chromeos::ACCELEROMETER_SOURCE_SCREEN)).Length()) <= + kNoisyMagnitudeDeviation; +} +#endif // OS_CHROMEOS } // namespace @@ -131,32 +147,28 @@ #if defined(OS_CHROMEOS) void MaximizeModeController::OnAccelerometerUpdated( - const ui::AccelerometerUpdate& update) { + const chromeos::AccelerometerUpdate& update) { bool first_accelerometer_update = !have_seen_accelerometer_data_; have_seen_accelerometer_data_ = true; - if (!update.has(ui::ACCELEROMETER_SOURCE_SCREEN)) + if (!update.has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) return; // Whether or not we enter maximize mode affects whether we handle screen // rotation, so determine whether to enter maximize mode first. - if (!update.has(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) { + if (!update.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) { if (first_accelerometer_update) EnterMaximizeMode(); - } else if (chromeos::AccelerometerReader::IsReadingStable( - update, ui::ACCELEROMETER_SOURCE_SCREEN) && - chromeos::AccelerometerReader::IsReadingStable( - update, ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) && - std::abs(update.get(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) - .Length() - - update.get(ui::ACCELEROMETER_SOURCE_SCREEN).Length()) <= - kNoisyMagnitudeDeviation) { - // update.has(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) + } else if (ui::IsAccelerometerReadingStable( + update, chromeos::ACCELEROMETER_SOURCE_SCREEN) && + ui::IsAccelerometerReadingStable( + update, chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) && + IsAngleBetweenAccelerometerReadingsStable(update)) { + // update.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) // Ignore the reading if it appears unstable. The reading is considered // unstable if it deviates too much from gravity and/or the magnitude of the // reading from the lid differs too much from the reading from the base. - HandleHingeRotation(update.get(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD), - update.get(ui::ACCELEROMETER_SOURCE_SCREEN)); + HandleHingeRotation(update); } } @@ -176,15 +188,16 @@ const base::TimeDelta& sleep_duration) { last_touchview_transition_time_ = base::Time::Now(); } -#endif // OS_CHROMEOS -void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, - const gfx::Vector3dF& lid) { +void MaximizeModeController::HandleHingeRotation( + const chromeos::AccelerometerUpdate& update) { static const gfx::Vector3dF hinge_vector(1.0f, 0.0f, 0.0f); // Ignore the component of acceleration parallel to the hinge for the purposes // of hinge angle calculation. - gfx::Vector3dF base_flattened(base); - gfx::Vector3dF lid_flattened(lid); + gfx::Vector3dF base_flattened(ui::ConvertAccelerometerReadingToVector3dF( + update.get(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD))); + gfx::Vector3dF lid_flattened(ui::ConvertAccelerometerReadingToVector3dF( + update.get(chromeos::ACCELEROMETER_SOURCE_SCREEN))); base_flattened.set_x(0.0f); lid_flattened.set_x(0.0f); @@ -235,6 +248,7 @@ #endif } } +#endif // OS_CHROMEOS void MaximizeModeController::EnterMaximizeMode() { if (IsMaximizeModeWindowManagerEnabled())
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h index 5e0a9e9..f7959661 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.h +++ b/ash/wm/maximize_mode/maximize_mode_controller.h
@@ -14,6 +14,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "chromeos/dbus/power_manager_client.h" #endif // OS_CHROMEOS @@ -81,7 +82,8 @@ #if defined(OS_CHROMEOS) // chromeos::AccelerometerReader::Observer: - void OnAccelerometerUpdated(const ui::AccelerometerUpdate& update) override; + void OnAccelerometerUpdated( + const chromeos::AccelerometerUpdate& update) override; // PowerManagerClient::Observer: void LidEventReceived(bool open, const base::TimeTicks& time) override; @@ -99,10 +101,11 @@ // artificially and deterministically control the current time. void SetTickClockForTest(scoped_ptr<base::TickClock> tick_clock); - // Detect hinge rotation from |base| and |lid| accelerometers and - // automatically start / stop maximize mode. - void HandleHingeRotation(const gfx::Vector3dF& base, - const gfx::Vector3dF& lid); +#if defined(OS_CHROMEOS) + // Detect hinge rotation from base and lid accelerometers and automatically + // start / stop maximize mode. + void HandleHingeRotation(const chromeos::AccelerometerUpdate& update); +#endif // Returns true if the lid was recently opened. bool WasLidOpenedRecently() const;
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc index bed2585..b3f0434 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -17,7 +17,7 @@ #include "base/command_line.h" #include "base/test/simple_test_tick_clock.h" #include "chromeos/accelerometer/accelerometer_reader.h" -#include "ui/accelerometer/accelerometer_types.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "ui/events/event_handler.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/vector3d_f.h" @@ -77,18 +77,19 @@ } void TriggerLidUpdate(const gfx::Vector3dF& lid) { - ui::AccelerometerUpdate update; - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), lid.z()); + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), + lid.z()); maximize_mode_controller()->OnAccelerometerUpdated(update); } void TriggerBaseAndLidUpdate(const gfx::Vector3dF& base, const gfx::Vector3dF& lid) { - ui::AccelerometerUpdate update; - update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, - base.x(), base.y(), base.z()); - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, - lid.x(), lid.y(), lid.z()); + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, base.x(), + base.y(), base.z()); + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), + lid.z()); maximize_mode_controller()->OnAccelerometerUpdated(update); }
diff --git a/base/BUILD.gn b/base/BUILD.gn index c1df2ec..43f92f50 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -171,11 +171,6 @@ "debug/stack_trace_win.cc", "debug/task_annotator.cc", "debug/task_annotator.h", - "debug/trace_event.h", - "debug/trace_event_argument.h", - "debug/trace_event_impl.h", - "debug/trace_event_synthetic_delay.h", - "debug/trace_event_win.h", "deferred_sequenced_task_runner.cc", "deferred_sequenced_task_runner.h", "environment.cc",
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java index 602358b..2168c218 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java +++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -175,18 +175,12 @@ String apkFilePath = null; boolean useMapExecSupportFallback = false; - // If the Android build version pre-dates KitKat and the device - // manufacturer is Samsung, skip the check for mmap exec support and - // return false. This avoids triggering a warning on these devices. - // The version check is included because these devices do not show - // the warning on later OS builds. + // If manufacturer is Samsung then skip the mmap exec check. // // For more, see: // https://code.google.com/p/chromium/issues/detail?id=448084 final String manufacturer = android.os.Build.MANUFACTURER; - final int version = android.os.Build.VERSION.SDK_INT; if (manufacturer != null - && version < android.os.Build.VERSION_CODES.KITKAT && manufacturer.toLowerCase(Locale.ENGLISH).contains("samsung")) { Log.w(TAG, "Suppressed load from APK support check on this device"); sProbeMapApkWithExecPermission = false;
diff --git a/base/base.gypi b/base/base.gypi index d4dd4dc..73c6c3b 100644 --- a/base/base.gypi +++ b/base/base.gypi
@@ -173,11 +173,6 @@ 'debug/stack_trace_win.cc', 'debug/task_annotator.cc', 'debug/task_annotator.h', - 'debug/trace_event.h', - 'debug/trace_event_argument.h', - 'debug/trace_event_impl.h', - 'debug/trace_event_synthetic_delay.h', - 'debug/trace_event_win.h', 'deferred_sequenced_task_runner.cc', 'deferred_sequenced_task_runner.h', 'environment.cc',
diff --git a/base/base.isolate b/base/base.isolate index 021c01c..5220887 100644 --- a/base/base.isolate +++ b/base/base.isolate
@@ -9,13 +9,20 @@ '../third_party/icu/icu.isolate', ], 'conditions': [ - ['OS=="linux" and asan==1 and chromeos==0', { + ['use_custom_libcxx==1', { 'variables': { 'files': [ '<(PRODUCT_DIR)/lib/libc++.so', ], }, }], + ['use_instrumented_libraries==1', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/instrumented_libraries/', + ], + }, + }], ['OS=="mac" and asan==1', { 'variables': { 'files': [ @@ -30,7 +37,7 @@ ], }, }], - ['OS=="linux" and asan==1', { + ['OS=="linux" and (asan==1 or lsan==1 or msan==1 or tsan==1)', { 'variables': { 'files': [ # For llvm-symbolizer. @@ -38,7 +45,7 @@ ], }, }], - ['asan==1', { + ['asan==1 or lsan==1 or msan==1 or tsan==1', { 'variables': { 'files': [ '../tools/valgrind/asan/', @@ -53,23 +60,35 @@ ], }, }], + # Copy the VS runtime DLLs into the isolate so that they + # don't have to be preinstalled on the target machine. + ['OS=="win" and component=="shared_library" and CONFIGURATION_NAME=="Debug"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp120d.dll', + '<(PRODUCT_DIR)/x64/msvcr120d.dll', + ], + }, + }], + ['OS=="win" and component=="shared_library" and CONFIGURATION_NAME=="Release"', { + 'variables': { + 'files': [ + '<(PRODUCT_DIR)/x64/msvcp120.dll', + '<(PRODUCT_DIR)/x64/msvcr120.dll', + ], + }, + }], ['OS=="win" and component=="shared_library" and (CONFIGURATION_NAME=="Debug" or CONFIGURATION_NAME=="Debug_x64")', { 'variables': { 'files': [ - # Copy the VS runtime DLLs into the isolate so that they - # don't have to be preinstalled on the target machine. '<(PRODUCT_DIR)/msvcp120d.dll', '<(PRODUCT_DIR)/msvcr120d.dll', - '<(PRODUCT_DIR)/x64/msvcp120d.dll', - '<(PRODUCT_DIR)/x64/msvcr120d.dll', ], }, }], ['OS=="win" and component=="shared_library" and (CONFIGURATION_NAME=="Release" or CONFIGURATION_NAME=="Release_x64")', { 'variables': { 'files': [ - # Copy the VS runtime DLLs into the isolate so that they - # don't have to be preinstalled on the target machine. '<(PRODUCT_DIR)/msvcp120.dll', '<(PRODUCT_DIR)/msvcr120.dll', ],
diff --git a/base/base_unittests.isolate b/base/base_unittests.isolate index f561d20..fca76d5 100644 --- a/base/base_unittests.isolate +++ b/base/base_unittests.isolate
@@ -20,6 +20,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -51,6 +53,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h index 572f285b..fb271b6d 100644 --- a/base/debug/stack_trace.h +++ b/base/debug/stack_trace.h
@@ -17,6 +17,7 @@ #if defined(OS_WIN) struct _EXCEPTION_POINTERS; +struct _CONTEXT; #endif namespace base { @@ -54,6 +55,7 @@ // Note: this function will throw an import not found (StackWalk64) exception // on system without dbghelp 5.1. StackTrace(const _EXCEPTION_POINTERS* exception_pointers); + StackTrace(const _CONTEXT* context); #endif // Copying and assignment are allowed with the default functions. @@ -76,6 +78,10 @@ std::string ToString() const; private: +#if defined(OS_WIN) + void InitTrace(_CONTEXT* context_record); +#endif + // From http://msdn.microsoft.com/en-us/library/bb204633.aspx, // the sum of FramesToSkip and FramesToCapture must be less than 63, // so set it to 62. Even if on POSIX it could be a larger value, it usually
diff --git a/base/debug/stack_trace_win.cc b/base/debug/stack_trace_win.cc index 8df6fc6..27661edc 100644 --- a/base/debug/stack_trace_win.cc +++ b/base/debug/stack_trace_win.cc
@@ -214,24 +214,35 @@ #endif StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) { - // When walking an exception stack, we need to use StackWalk64(). - count_ = 0; // StackWalk64() may modify context record passed to it, so we will // use a copy. CONTEXT context_record = *exception_pointers->ContextRecord; + InitTrace(&context_record); +} + +StackTrace::StackTrace(const CONTEXT* context) { + // StackWalk64() may modify context record passed to it, so we will + // use a copy. + CONTEXT context_record = *context; + InitTrace(&context_record); +} + +void StackTrace::InitTrace(CONTEXT* context_record) { + // When walking an exception stack, we need to use StackWalk64(). + count_ = 0; // Initialize stack walking. STACKFRAME64 stack_frame; memset(&stack_frame, 0, sizeof(stack_frame)); #if defined(_WIN64) int machine_type = IMAGE_FILE_MACHINE_AMD64; - stack_frame.AddrPC.Offset = context_record.Rip; - stack_frame.AddrFrame.Offset = context_record.Rbp; - stack_frame.AddrStack.Offset = context_record.Rsp; + stack_frame.AddrPC.Offset = context_record->Rip; + stack_frame.AddrFrame.Offset = context_record->Rbp; + stack_frame.AddrStack.Offset = context_record->Rsp; #else int machine_type = IMAGE_FILE_MACHINE_I386; - stack_frame.AddrPC.Offset = context_record.Eip; - stack_frame.AddrFrame.Offset = context_record.Ebp; - stack_frame.AddrStack.Offset = context_record.Esp; + stack_frame.AddrPC.Offset = context_record->Eip; + stack_frame.AddrFrame.Offset = context_record->Ebp; + stack_frame.AddrStack.Offset = context_record->Esp; #endif stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrFrame.Mode = AddrModeFlat; @@ -240,7 +251,7 @@ GetCurrentProcess(), GetCurrentThread(), &stack_frame, - &context_record, + context_record, NULL, &SymFunctionTableAccess64, &SymGetModuleBase64,
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h deleted file mode 100644 index 7d97e168..0000000 --- a/base/debug/trace_event.h +++ /dev/null
@@ -1,14 +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. - -// In the process of moving the trace event files. Right now the headers -// are being forwarded. In next CLs the change will get completed -// TODO(ssid): https://code.google.com/p/chromium/issues/detail?id=451032 - -#ifndef BASE_DEBUG_TRACE_EVENT_H_ -#define BASE_DEBUG_TRACE_EVENT_H_ - -#include "base/trace_event/trace_event.h" - -#endif // BASE_DEBUG_TRACE_EVENT_H_
diff --git a/base/debug/trace_event_argument.h b/base/debug/trace_event_argument.h deleted file mode 100644 index 167b46c9..0000000 --- a/base/debug/trace_event_argument.h +++ /dev/null
@@ -1,14 +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. - -// In the process of moving the trace event files. Right now the headers -// are being forwarded. In next CLs the change will get completed -// TODO(ssid): https://code.google.com/p/chromium/issues/detail?id=451032 - -#ifndef BASE_DEBUG_TRACE_EVENT_ARGUMENT_H_ -#define BASE_DEBUG_TRACE_EVENT_ARGUMENT_H_ - -#include "base/trace_event/trace_event_argument.h" - -#endif // BASE_DEBUG_TRACE_EVENT_ARGUMENT_H_
diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h deleted file mode 100644 index a619d290..0000000 --- a/base/debug/trace_event_impl.h +++ /dev/null
@@ -1,14 +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. - -// In the process of moving the trace event files. Right now the headers -// are being forwarded. In next CLs the change will get completed -// TODO(ssid): https://code.google.com/p/chromium/issues/detail?id=451032 - -#ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ -#define BASE_DEBUG_TRACE_EVENT_IMPL_H_ - -#include "base/trace_event/trace_event_impl.h" - -#endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_
diff --git a/base/debug/trace_event_synthetic_delay.h b/base/debug/trace_event_synthetic_delay.h deleted file mode 100644 index 1f1eafb5..0000000 --- a/base/debug/trace_event_synthetic_delay.h +++ /dev/null
@@ -1,14 +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. - -// In the process of moving the trace event files. Right now the headers -// are being forwarded. In next CLs the change will get completed -// TODO(ssid): https://code.google.com/p/chromium/issues/detail?id=451032 - -#ifndef BASE_DEBUG_TRACE_EVENT_SYNTHETIC_DELAY_H_ -#define BASE_DEBUG_TRACE_EVENT_SYNTHETIC_DELAY_H_ - -#include "base/trace_event/trace_event_synthetic_delay.h" - -#endif // BASE_DEBUG_TRACE_EVENT_SYNTHETIC_DELAY_H_
diff --git a/base/debug/trace_event_win.h b/base/debug/trace_event_win.h deleted file mode 100644 index 473e174e..0000000 --- a/base/debug/trace_event_win.h +++ /dev/null
@@ -1,14 +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. - -// In the process of moving the trace event files. Right now the headers -// are being forwarded. In next CLs the change will get completed -// TODO(ssid): https://code.google.com/p/chromium/issues/detail?id=451032 - -#ifndef BASE_DEBUG_TRACE_EVENT_WIN_H_ -#define BASE_DEBUG_TRACE_EVENT_WIN_H_ - -#include "base/trace_event/trace_event_win.h" - -#endif // BASE_DEBUG_TRACE_EVENT_WIN_H_
diff --git a/base/message_loop/incoming_task_queue.cc b/base/message_loop/incoming_task_queue.cc index 9e5b013..07de4a15 100644 --- a/base/message_loop/incoming_task_queue.cc +++ b/base/message_loop/incoming_task_queue.cc
@@ -4,6 +4,8 @@ #include "base/message_loop/incoming_task_queue.h" +#include <limits> + #include "base/location.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" @@ -15,6 +17,12 @@ namespace { +// Delays larger than this many microseconds are often bogus, and a warning +// should be emitted in debug builds to warn developers. +// http://crbug.com/450045 +const int kTaskDelayWarningThresholdInMicroseconds = + std::numeric_limits<int>::max() / 2; // A little less than 18 minutes. + // Returns true if MessagePump::ScheduleWork() must be called one // time for every task that is added to the MessageLoop incoming queue. bool AlwaysNotifyPump(MessageLoop::Type type) { @@ -43,6 +51,11 @@ const Closure& task, TimeDelta delay, bool nestable) { + DLOG_IF(WARNING, + delay.InMicroseconds() > kTaskDelayWarningThresholdInMicroseconds) + << "Requesting super-long task delay period of " << delay.InMicroseconds() + << " usec from here: " << from_here.ToString(); + AutoLock locked(incoming_queue_lock_); PendingTask pending_task( from_here, task, CalculateDelayedRuntime(delay), nestable);
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 24db543..86771e43 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -5,7 +5,6 @@ #include "base/message_loop/message_loop.h" #include <algorithm> -#include <limits> #include "base/bind.h" #include "base/compiler_specific.h" @@ -44,12 +43,6 @@ LazyInstance<base::ThreadLocalPointer<MessageLoop> >::Leaky lazy_tls_ptr = LAZY_INSTANCE_INITIALIZER; -// Delays larger than this many microseconds are likely bogus, and a warning -// should be emitted in debug builds to warn developers. -// http://crbug.com/450045 -const int kTaskDelayWarningThresholdInMicroseconds = - std::numeric_limits<int>::max() / 2; - // Logical events for Histogram profiling. Run with -message-loop-histogrammer // to get an accounting of messages and actions taken on each thread. const int kTaskRunEvent = 0x1; @@ -286,10 +279,6 @@ const Closure& task, TimeDelta delay) { DCHECK(!task.is_null()) << from_here.ToString(); - DLOG_IF(WARNING, - delay.InMicroseconds() > kTaskDelayWarningThresholdInMicroseconds) - << "Requesting super-long task delay period of " << delay.InMicroseconds() - << " usec from " << from_here.ToString(); incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, true); } @@ -305,10 +294,6 @@ const Closure& task, TimeDelta delay) { DCHECK(!task.is_null()) << from_here.ToString(); - DLOG_IF(WARNING, - delay.InMicroseconds() > kTaskDelayWarningThresholdInMicroseconds) - << "Requesting super-long task delay period of " << delay.InMicroseconds() - << " usec from " << from_here.ToString(); incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false); }
diff --git a/base/test/test_support_ios.mm b/base/test/test_support_ios.mm index 67fae06f1..3b31da6 100644 --- a/base/test/test_support_ios.mm +++ b/base/test/test_support_ios.mm
@@ -11,6 +11,7 @@ #include "base/message_loop/message_loop.h" #include "base/message_loop/message_pump_default.h" #include "base/test/test_suite.h" +#include "testing/coverage_util_ios.h" // Springboard will kill any iOS app that fails to check in after launch within // a given time. Starting a UIApplication before invoking TestSuite::Run @@ -165,6 +166,8 @@ UIApplication* application = [UIApplication sharedApplication]; [application _terminateWithStatus:exitStatus]; + coverage_util::FlushCoverageDataIfNecessary(); + exit(exitStatus); }
diff --git a/build/PRESUBMIT.py b/build/PRESUBMIT.py new file mode 100644 index 0000000..3c70193 --- /dev/null +++ b/build/PRESUBMIT.py
@@ -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. + +WHITELIST = [ r'.+_test.py$' ] + + +def _RunTests(input_api, output_api): + return (input_api.canned_checks.RunUnitTestsInDirectory( + input_api, output_api, '.', whitelist=[r'.+_test.py$'])) + + +def CheckChangeOnUpload(input_api, output_api): + return _RunTests(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return _RunTests(input_api, output_api)
diff --git a/build/all.gyp b/build/all.gyp index 90c01205..8556aa7 100644 --- a/build/all.gyp +++ b/build/all.gyp
@@ -750,7 +750,6 @@ 'dependencies': [ '../chrome/chrome_syzygy.gyp:chrome_dll_syzygy', '../content/content_shell_and_tests.gyp:content_shell_syzyasan', - '../pdf/pdf.gyp:pdf_syzyasan', ], 'conditions': [ ['chrome_multiple_dll==1', {
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index 7f3a868..d1daaf2 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -62,6 +62,7 @@ output_api, unit_tests=[ J('pylib', 'device', 'device_utils_test.py'), + J('pylib', 'device', 'logcat_monitor_test.py'), J('pylib', 'gtest', 'gtest_test_instance_test.py'), J('pylib', 'instrumentation', 'instrumentation_test_instance_test.py'),
diff --git a/build/android/adb_gdb b/build/android/adb_gdb index 97d37db..c71b816 100755 --- a/build/android/adb_gdb +++ b/build/android/adb_gdb
@@ -26,6 +26,7 @@ TMPDIR= GDBSERVER_PIDFILE= TARGET_GDBSERVER= +COMMAND_PREFIX= clean_exit () { if [ "$TMPDIR" ]; then @@ -36,7 +37,7 @@ fi if [ "$TARGET_GDBSERVER" ]; then log "Removing target gdbserver binary: $TARGET_GDBSERVER." - "$ADB" shell run-as "$PACKAGE_NAME" rm "$TARGET_GDBSERVER" >/dev/null 2>&1 + "$ADB" shell "$COMMAND_PREFIX" rm "$TARGET_GDBSERVER" >/dev/null 2>&1 fi log "Cleaning up: $TMPDIR" rm -rf "$TMPDIR" @@ -908,7 +909,7 @@ # Push gdbserver to the device log "Pushing gdbserver $GDBSERVER to $TARGET_GDBSERVER" adb push $GDBSERVER $TMP_TARGET_GDBSERVER &>/dev/null -adb shell run-as $PACKAGE_NAME cp $TMP_TARGET_GDBSERVER . +adb shell $COMMAND_PREFIX cp $TMP_TARGET_GDBSERVER $TARGET_GDBSERVER adb shell rm $TMP_TARGET_GDBSERVER fail_panic "Could not copy gdbserver to the device!"
diff --git a/build/android/findbugs_filter/findbugs_known_bugs.txt b/build/android/findbugs_filter/findbugs_known_bugs.txt index 5ec1107d..09c12b2 100644 --- a/build/android/findbugs_filter/findbugs_known_bugs.txt +++ b/build/android/findbugs_filter/findbugs_known_bugs.txt
@@ -5,4 +5,3 @@ M D UuF: Unused public or protected field: org.chromium.chrome.browser.document.PendingDocumentData.webContents In PendingDocumentData.java M D UuF: Unused public or protected field: org.chromium.chrome.browser.document.PendingDocumentData.originalIntent In PendingDocumentData.java M D UuF: Unused public or protected field: org.chromium.chrome.browser.document.PendingDocumentData.url In PendingDocumentData.java -M D UuF: Unused public or protected field: org.chromium.chrome.browser.document.PendingDocumentData.userGesture In PendingDocumentData.java
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py index 1dbb1d8..7d11671 100644 --- a/build/android/pylib/device/adb_wrapper.py +++ b/build/android/pylib/device/adb_wrapper.py
@@ -285,7 +285,8 @@ cmd, 'path does not specify an accessible directory in the device', device_serial=self._device_serial) - def Logcat(self, filter_spec=None, timeout=None): + def Logcat(self, clear=False, dump=False, filter_spec=None, + logcat_format=None, timeout=None): """Get an iterator over the logcat output. Args: @@ -296,6 +297,12 @@ logcat output line by line. """ cmd = ['logcat'] + if clear: + cmd.append('-c') + if dump: + cmd.append('-d') + if logcat_format: + cmd.extend(['-v', logcat_format]) if filter_spec is not None: cmd.append(filter_spec) return self._IterRunDeviceAdbCmd(cmd, timeout)
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py index 805df65..a5ce11e6 100644 --- a/build/android/pylib/device/device_utils.py +++ b/build/android/pylib/device/device_utils.py
@@ -6,7 +6,7 @@ Eventually, this will be based on adb_wrapper. """ -# pylint: disable=W0613 +# pylint: disable=unused-argument import logging import multiprocessing @@ -24,6 +24,7 @@ from pylib.device import decorators from pylib.device import device_errors from pylib.device import intent +from pylib.device import logcat_monitor from pylib.device.commands import install_commands from pylib.utils import apk_helper from pylib.utils import device_temp_file @@ -350,11 +351,13 @@ @decorators.WithTimeoutAndRetriesDefaults( REBOOT_DEFAULT_TIMEOUT, REBOOT_DEFAULT_RETRIES) - def Reboot(self, block=True, timeout=None, retries=None): + def Reboot(self, block=True, wifi=False, timeout=None, retries=None): """Reboot the device. Args: block: A boolean indicating if we should wait for the reboot to complete. + wifi: A boolean indicating if we should wait for wifi to be enabled after + the reboot. The option has no effect unless |block| is also True. timeout: timeout in seconds retries: number of retries @@ -369,7 +372,7 @@ self._cache = {} timeout_retry.WaitFor(device_offline, wait_period=1) if block: - self.WaitUntilFullyBooted() + self.WaitUntilFullyBooted(wifi=wifi) INSTALL_DEFAULT_TIMEOUT = 4 * _DEFAULT_TIMEOUT INSTALL_DEFAULT_RETRIES = _DEFAULT_RETRIES @@ -1288,6 +1291,19 @@ """ return self.old_interface.GetMemoryUsageForPid(pid) + @decorators.WithTimeoutAndRetriesFromInstance() + def GetLogcatMonitor(self, timeout=None, retries=None, *args, **kwargs): + """Returns a new LogcatMonitor associated with this device. + + Parameters passed to this function are passed directly to + |logcat_monitor.LogcatMonitor| and are documented there. + + Args: + timeout: timeout in seconds + retries: number of retries + """ + return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) + def __str__(self): """Returns the device serial.""" return self.adb.GetDeviceSerial()
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py index 68c8b716..9d41741 100755 --- a/build/android/pylib/device/device_utils_test.py +++ b/build/android/pylib/device/device_utils_test.py
@@ -457,9 +457,17 @@ self.call.adb.Reboot(), (self.call.device.IsOnline(), True), (self.call.device.IsOnline(), False), - self.call.device.WaitUntilFullyBooted()): + self.call.device.WaitUntilFullyBooted(wifi=False)): self.device.Reboot(block=True) + def testReboot_blockUntilWifi(self): + with self.assertCalls( + self.call.adb.Reboot(), + (self.call.device.IsOnline(), True), + (self.call.device.IsOnline(), False), + self.call.device.WaitUntilFullyBooted(wifi=True)): + self.device.Reboot(block=True, wifi=True) + class DeviceUtilsInstallTest(DeviceUtilsNewImplTest):
diff --git a/build/android/pylib/device/logcat_monitor.py b/build/android/pylib/device/logcat_monitor.py new file mode 100644 index 0000000..7ede49c5 --- /dev/null +++ b/build/android/pylib/device/logcat_monitor.py
@@ -0,0 +1,143 @@ +# 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. + +# pylint: disable=unused-argument + +import collections +import itertools +import logging +import subprocess +import tempfile +import time +import re + +from pylib.device import adb_wrapper +from pylib.device import decorators +from pylib.device import device_errors + + +class LogcatMonitor(object): + + # Format: <DATE> <TIME> <PID> <TID> <LEVEL> <COMPONENT>: <MESSAGE> + _THREADTIME_RE_FORMAT = r'\S* +\S* +(%s) +(%s) +(%s) +(%s): +(%s)$' + + def __init__(self, adb, clear=True): + """Create a LogcatMonitor instance. + + Args: + adb: An instance of adb_wrapper.AdbWrapper. + clear: If True, clear the logcat when monitoring starts. + """ + if isinstance(adb, adb_wrapper.AdbWrapper): + self._adb = adb + else: + raise ValueError('Unsupported type passed for argument "device"') + self._clear = clear + self._logcat_out = None + self._logcat_out_file = None + self._logcat_proc = None + + @decorators.WithTimeoutAndRetriesDefaults(10, 0) + def WaitFor(self, success_regex, failure_regex=None, timeout=None, + retries=None): + """Wait for a matching logcat line or until a timeout occurs. + + This will attempt to match lines in the logcat against both |success_regex| + and |failure_regex| (if provided). Note that this calls re.search on each + logcat line, not re.match, so the provided regular expressions don't have + to match an entire line. + + Args: + success_regex: The regular expression to search for. + failure_regex: An optional regular expression that, if hit, causes this + to stop looking for a match. Can be None. + timeout: timeout in seconds + retries: number of retries + + Returns: + A match object if |success_regex| matches a part of a logcat line, or + None if |failure_regex| matches a part of a logcat line. + Raises: + CommandFailedError on logcat failure (NOT on a |failure_regex| match). + CommandTimeoutError if no logcat line matching either |success_regex| or + |failure_regex| is found in |timeout| seconds. + DeviceUnreachableError if the device becomes unreachable. + """ + if isinstance(success_regex, basestring): + success_regex = re.compile(success_regex) + if isinstance(failure_regex, basestring): + failure_regex = re.compile(failure_regex) + + logging.debug('Waiting %d seconds for "%s"', timeout, success_regex.pattern) + + # NOTE This will continue looping until: + # - success_regex matches a line, in which case the match object is + # returned. + # - failure_regex matches a line, in which case None is returned + # - the timeout is hit, in which case a CommandTimeoutError is raised. + for l in self._adb.Logcat(): + m = success_regex.search(l) + if m: + return m + if failure_regex and failure_regex.search(l): + return None + + def FindAll(self, message_regex, proc_id=None, thread_id=None, log_level=None, + component=None): + """Finds all lines in the logcat that match the provided constraints. + + Args: + message_regex: The regular expression that the <message> section must + match. + proc_id: The process ID to match. If None, matches any process ID. + thread_id: The thread ID to match. If None, matches any thread ID. + log_level: The log level to match. If None, matches any log level. + component: The component to match. If None, matches any component. + + Returns: + An iterable containing objects with five attributes: + |proc_id|: the process ID + |thread_id|: the thread ID + |log_level|: the log level + |component|: the component + |message|: the logcat message + """ + LogcatLine = collections.namedtuple( + 'LogcatLine', + ['proc_id', 'thread_id', 'log_level', 'component', 'message']) + + if proc_id is None: + proc_id = r'\d+' + if thread_id is None: + thread_id = r'\d+' + if log_level is None: + log_level = r'[VDIWEF]' + if component is None: + component = r'[^\s:]+' + threadtime_re = re.compile( + type(self)._THREADTIME_RE_FORMAT % ( + proc_id, thread_id, log_level, component, message_regex)) + + regexed_lines = ( + re.match(threadtime_re, l) + for l in self._adb.Logcat(dump=True, logcat_format='threadtime')) + only_matches = (m for m in regexed_lines if m) + return (LogcatLine(*m.group(1, 2, 3, 4, 5)) for m in only_matches) + + def Start(self): + """Starts the logcat monitor. + + Clears the logcat if |clear| was set in |__init__|. + """ + if self._clear: + self._adb.Logcat(clear=True) + + def __enter__(self): + """Starts the logcat monitor.""" + self.Start() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """Stops the logcat monitor.""" + pass
diff --git a/build/android/pylib/device/logcat_monitor_test.py b/build/android/pylib/device/logcat_monitor_test.py new file mode 100755 index 0000000..7a6bf56d --- /dev/null +++ b/build/android/pylib/device/logcat_monitor_test.py
@@ -0,0 +1,164 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import itertools +import os +import sys +import unittest + +from pylib import constants +from pylib.device import adb_wrapper +from pylib.device import decorators +from pylib.device import logcat_monitor + +sys.path.append(os.path.join( + constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) +import mock # pylint: disable=F0401 + + +class LogcatMonitorTest(unittest.TestCase): + + _TEST_THREADTIME_LOGCAT_DATA = [ + '01-01 01:02:03.456 7890 0987 V LogcatMonitorTest: ' + 'verbose logcat monitor test message 1', + '01-01 01:02:03.457 8901 1098 D LogcatMonitorTest: ' + 'debug logcat monitor test message 2', + '01-01 01:02:03.458 9012 2109 I LogcatMonitorTest: ' + 'info logcat monitor test message 3', + '01-01 01:02:03.459 0123 3210 W LogcatMonitorTest: ' + 'warning logcat monitor test message 4', + '01-01 01:02:03.460 1234 4321 E LogcatMonitorTest: ' + 'error logcat monitor test message 5', + '01-01 01:02:03.461 2345 5432 F LogcatMonitorTest: ' + 'fatal logcat monitor test message 6', + '01-01 01:02:03.462 3456 6543 D LogcatMonitorTest: ' + 'ignore me',] + + def _createTestLog(self, raw_logcat=None): + test_adb = adb_wrapper.AdbWrapper('0123456789abcdef') + test_adb.Logcat = mock.Mock(return_value=(l for l in raw_logcat)) + test_log = logcat_monitor.LogcatMonitor(test_adb, clear=False) + return test_log + + def assertIterEqual(self, expected_iter, actual_iter): + for expected, actual in itertools.izip_longest(expected_iter, actual_iter): + self.assertIsNotNone( + expected, + msg='actual has unexpected elements starting with %s' % str(actual)) + self.assertIsNotNone( + actual, + msg='actual is missing elements starting with %s' % str(expected)) + self.assertEqual(actual.proc_id, expected[0]) + self.assertEqual(actual.thread_id, expected[1]) + self.assertEqual(actual.log_level, expected[2]) + self.assertEqual(actual.component, expected[3]) + self.assertEqual(actual.message, expected[4]) + + with self.assertRaises(StopIteration): + next(actual_iter) + with self.assertRaises(StopIteration): + next(expected_iter) + + def testWaitFor_success(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_match = test_log.WaitFor(r'.*(fatal|error) logcat monitor.*', None) + self.assertTrue(actual_match) + self.assertEqual( + '01-01 01:02:03.460 1234 4321 E LogcatMonitorTest: ' + 'error logcat monitor test message 5', + actual_match.group(0)) + self.assertEqual('error', actual_match.group(1)) + + def testWaitFor_failure(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_match = test_log.WaitFor( + r'.*My Success Regex.*', r'.*(fatal|error) logcat monitor.*') + self.assertIsNone(actual_match) + + def testFindAll_defaults(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + expected_results = [ + ('7890', '0987', 'V', 'LogcatMonitorTest', + 'verbose logcat monitor test message 1'), + ('8901', '1098', 'D', 'LogcatMonitorTest', + 'debug logcat monitor test message 2'), + ('9012', '2109', 'I', 'LogcatMonitorTest', + 'info logcat monitor test message 3'), + ('0123', '3210', 'W', 'LogcatMonitorTest', + 'warning logcat monitor test message 4'), + ('1234', '4321', 'E', 'LogcatMonitorTest', + 'error logcat monitor test message 5'), + ('2345', '5432', 'F', 'LogcatMonitorTest', + 'fatal logcat monitor test message 6')] + actual_results = test_log.FindAll(r'\S* logcat monitor test message \d') + self.assertIterEqual(iter(expected_results), actual_results) + + def testFindAll_defaults_miss(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + expected_results = [] + actual_results = test_log.FindAll(r'\S* nothing should match this \d') + self.assertIterEqual(iter(expected_results), actual_results) + + def testFindAll_filterProcId(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_results = test_log.FindAll( + r'\S* logcat monitor test message \d', proc_id=1234) + expected_results = [ + ('1234', '4321', 'E', 'LogcatMonitorTest', + 'error logcat monitor test message 5')] + self.assertIterEqual(iter(expected_results), actual_results) + + def testFindAll_filterThreadId(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_results = test_log.FindAll( + r'\S* logcat monitor test message \d', thread_id=2109) + expected_results = [ + ('9012', '2109', 'I', 'LogcatMonitorTest', + 'info logcat monitor test message 3')] + self.assertIterEqual(iter(expected_results), actual_results) + + def testFindAll_filterLogLevel(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_results = test_log.FindAll( + r'\S* logcat monitor test message \d', log_level=r'[DW]') + expected_results = [ + ('8901', '1098', 'D', 'LogcatMonitorTest', + 'debug logcat monitor test message 2'), + ('0123', '3210', 'W', 'LogcatMonitorTest', + 'warning logcat monitor test message 4'),] + self.assertIterEqual(iter(expected_results), actual_results) + + def testFindAll_filterComponent(self): + test_log = self._createTestLog( + raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA) + actual_results = test_log.FindAll(r'.*', component='LogcatMonitorTest') + expected_results = [ + ('7890', '0987', 'V', 'LogcatMonitorTest', + 'verbose logcat monitor test message 1'), + ('8901', '1098', 'D', 'LogcatMonitorTest', + 'debug logcat monitor test message 2'), + ('9012', '2109', 'I', 'LogcatMonitorTest', + 'info logcat monitor test message 3'), + ('0123', '3210', 'W', 'LogcatMonitorTest', + 'warning logcat monitor test message 4'), + ('1234', '4321', 'E', 'LogcatMonitorTest', + 'error logcat monitor test message 5'), + ('2345', '5432', 'F', 'LogcatMonitorTest', + 'fatal logcat monitor test message 6'), + ('3456', '6543', 'D', 'LogcatMonitorTest', + 'ignore me'),] + self.assertIterEqual(iter(expected_results), actual_results) + + +if __name__ == '__main__': + unittest.main(verbosity=2) +
diff --git a/build/android/pylib/gtest/filter/unit_tests_disabled b/build/android/pylib/gtest/filter/unit_tests_disabled index 93defbe..c7851fd 100644 --- a/build/android/pylib/gtest/filter/unit_tests_disabled +++ b/build/android/pylib/gtest/filter/unit_tests_disabled
@@ -1,10 +1,5 @@ # List of suppressions -# crbug.com/139429 -BrowserMainTest.WarmConnectionFieldTrial_Invalid -BrowserMainTest.WarmConnectionFieldTrial_Random -BrowserMainTest.WarmConnectionFieldTrial_WarmestSocket - # The UDP related tests currently do not work on Android because # we lack a UDP forwarder tool. NetworkStatsTestUDP.*
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py index 424dcb3b..fb9557e 100644 --- a/build/android/pylib/instrumentation/test_runner.py +++ b/build/android/pylib/instrumentation/test_runner.py
@@ -51,6 +51,7 @@ super(TestRunner, self).__init__(device, test_options.tool, test_options.cleanup_test_files) self._lighttp_port = constants.LIGHTTPD_RANDOM_PORT_FIRST + shard_index + self._logcat_monitor = None self.coverage_device_file = None self.coverage_dir = test_options.coverage_dir @@ -174,9 +175,10 @@ """ if not self._IsPerfTest(test): return - self.device.old_interface.Adb().SendCommand( - 'shell rm ' + TestRunner._DEVICE_PERF_OUTPUT_SEARCH_PREFIX) - self.device.old_interface.StartMonitoringLogcat() + self.device.RunShellCommand( + ['rm', TestRunner._DEVICE_PERF_OUTPUT_SEARCH_PREFIX]) + self._logcat_monitor = self.device.GetLogcatMonitor() + self._logcat_monitor.Start() def TestTeardown(self, test, result): """Cleans up the test harness after running a particular test. @@ -219,9 +221,8 @@ raw_test_name = test.split('#')[1] # Wait and grab annotation data so we can figure out which traces to parse - regex = self.device.old_interface.WaitForLogMatch( - re.compile(r'\*\*PERFANNOTATION\(' + raw_test_name + r'\)\:(.*)'), - None) + regex = self._logcat_monitor.WaitFor( + re.compile(r'\*\*PERFANNOTATION\(' + raw_test_name + r'\)\:(.*)')) # If the test is set to run on a specific device type only (IE: only # tablet or phone) and it is being run on the wrong device, the test
diff --git a/build/android/pylib/linker/test_case.py b/build/android/pylib/linker/test_case.py index 13f68cb..8ebf803 100644 --- a/build/android/pylib/linker/test_case.py +++ b/build/android/pylib/linker/test_case.py
@@ -42,6 +42,7 @@ from pylib import constants from pylib.base import base_test_result +from pylib.device import device_errors from pylib.device import intent @@ -70,10 +71,11 @@ #_LOGCAT_FILTERS = ['*:v'] ## DEBUG # Regular expression used to match status lines in logcat. -re_status_line = re.compile(r'(BROWSER|RENDERER)_LINKER_TEST: (FAIL|SUCCESS)') +_RE_BROWSER_STATUS_LINE = re.compile(r' BROWSER_LINKER_TEST: (FAIL|SUCCESS)$') +_RE_RENDERER_STATUS_LINE = re.compile(r' RENDERER_LINKER_TEST: (FAIL|SUCCESS)$') # Regular expression used to mach library load addresses in logcat. -re_library_address = re.compile( +_RE_LIBRARY_ADDRESS = re.compile( r'(BROWSER|RENDERER)_LIBRARY_ADDRESS: (\S+) ([0-9A-Fa-f]+)') @@ -109,46 +111,6 @@ return configs[0] -def _WriteCommandLineFile(device, command_line, command_line_file): - """Create a command-line file on the device. This does not use FlagChanger - because its implementation assumes the device has 'su', and thus does - not work at all with production devices.""" - device.RunShellCommand( - 'echo "%s" > %s' % (command_line, command_line_file)) - - -def _CheckLinkerTestStatus(logcat): - """Parse the content of |logcat| and checks for both a browser and - renderer status line. - - Args: - logcat: A string to parse. Can include line separators. - - Returns: - A tuple, result[0] is True if there is a complete match, then - result[1] and result[2] will be True or False to reflect the - test status for the browser and renderer processes, respectively. - """ - browser_found = False - renderer_found = False - for m in re_status_line.finditer(logcat): - process_type, status = m.groups() - if process_type == 'BROWSER': - browser_found = True - browser_success = (status == 'SUCCESS') - elif process_type == 'RENDERER': - renderer_found = True - renderer_success = (status == 'SUCCESS') - else: - assert False, 'Invalid process type ' + process_type - - if browser_found and renderer_found: - return (True, browser_success, renderer_success) - - # Didn't find anything. - return (False, None, None) - - def _StartActivityAndWaitForLinkerTestStatus(device, timeout): """Force-start an activity and wait up to |timeout| seconds until the full linker test status lines appear in the logcat, recorded through |device|. @@ -159,38 +121,30 @@ A (status, logs) tuple, where status is a ResultType constant, and logs if the final logcat output as a string. """ - # 1. Start recording logcat with appropriate filters. - device.old_interface.StartRecordingLogcat( - clear=True, filters=_LOGCAT_FILTERS) - try: + # 1. Start recording logcat with appropriate filters. + with device.GetLogcatMonitor(filters=_LOGCAT_FILTERS) as logmon: + # 2. Force-start activity. device.StartActivity( intent.Intent(package=_PACKAGE_NAME, activity=_ACTIVITY_NAME), force_stop=True) # 3. Wait up to |timeout| seconds until the test status is in the logcat. - num_tries = 0 - max_tries = timeout - found = False - while num_tries < max_tries: - time.sleep(1) - num_tries += 1 - found, browser_ok, renderer_ok = _CheckLinkerTestStatus( - device.old_interface.GetCurrentRecordedLogcat()) - if found: - break + result = ResultType.PASS + try: + browser_match = logmon.WaitFor(_RE_BROWSER_STATUS_LINE, timeout=timeout) + logging.debug('Found browser match: %s', browser_match.group(0)) + renderer_match = logmon.WaitFor(_RE_RENDERER_STATUS_LINE, + timeout=timeout) + logging.debug('Found renderer match: %s', renderer_match.group(0)) + if (browser_match.group(1) != 'SUCCESS' + or renderer_match.group(1) != 'SUCCESS'): + result = ResultType.FAIL + except device_errors.CommandTimeoutError: + result = ResultType.TIMEOUT - finally: - logs = device.old_interface.StopRecordingLogcat() - - if num_tries >= max_tries: - return ResultType.TIMEOUT, logs - - if browser_ok and renderer_ok: - return ResultType.PASS, logs - - return ResultType.FAIL, logs + return result, '\n'.join(device.adb.Logcat(dump=True)) class LibraryLoadMap(dict): @@ -226,7 +180,7 @@ """ browser_libs = LibraryLoadMap() renderer_libs = LibraryLoadMap() - for m in re_library_address.finditer(logs): + for m in _RE_LIBRARY_ADDRESS.finditer(logs): process_type, lib_name, lib_address = m.groups() lib_address = int(lib_address, 16) if process_type == 'BROWSER': @@ -323,7 +277,7 @@ command_line_flags = '' if self.is_low_memory: command_line_flags = '--low-memory-device' - _WriteCommandLineFile(device, command_line_flags, _COMMAND_LINE_FILE) + device.WriteFile(_COMMAND_LINE_FILE, command_line_flags) # Run the test. status, logs = self._RunTest(device)
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py index a701d95..cc39112 100644 --- a/build/android/pylib/remote/device/remote_device_environment.py +++ b/build/android/pylib/remote/device/remote_device_environment.py
@@ -4,6 +4,8 @@ """Environment setup and teardown for remote devices.""" +import distutils.version +import json import logging import os import random @@ -28,50 +30,138 @@ error_func: error to show when using bad command line arguments. """ super(RemoteDeviceEnvironment, self).__init__() - - if args.api_key_file: - with open(args.api_key_file) as api_key_file: - self._api_key = api_key_file.read().strip() - elif args.api_key: - self._api_key = args.api_key - else: - error_func('Must set api key with --api-key or --api-key-file') - - if args.api_secret_file: - with open(args.api_secret_file) as api_secret_file: - self._api_secret = api_secret_file.read().strip() - elif args.api_secret: - self._api_secret = args.api_secret - else: - error_func('Must set api secret with --api-secret or --api-secret-file') - - if not args.api_protocol: - error_func('Must set api protocol with --api-protocol. Example: http') - self._api_protocol = args.api_protocol - - if not args.api_address: - error_func('Must set api address with --api-address') - self._api_address = args.api_address - - if not args.api_port: - error_func('Must set api port with --api-port.') - self._api_port = args.api_port - - self._access_token = '' - self._results_path = args.results_path - self._remote_device = args.remote_device - self._remote_device_os = args.remote_device_os - self._runner_package = args.runner_package - self._runner_type = args.runner_type - self._device = '' - self._verbose_count = args.verbose_count + self._access_token = None + self._device = None self._device_type = args.device_type + self._verbose_count = args.verbose_count self._timeouts = { 'queueing': 60 * 10, 'installing': 60 * 10, 'in-progress': 60 * 30, 'unknown': 60 * 5 } + # Example config file: + # { + # "remote_device": ["Galaxy S4", "Galaxy S3"], + # "remote_device_os": ["4.4.2", "4.4.4"], + # "remote_device_minimum_os": "4.4.2", + # "api_address": "www.example.com", + # "api_port": "80", + # "api_protocol": "http", + # "api_secret": "apisecret", + # "api_key": "apikey", + # "timeouts": { + # "queueing": 600, + # "installing": 600, + # "in-progress": 1800, + # "unknown": 300 + # } + # } + if args.remote_device_file: + with open(args.remote_device_file) as device_file: + device_json = json.load(device_file) + else: + device_json = {} + + self._api_address = device_json.get('api_address', None) + self._api_key = device_json.get('api_key', None) + self._api_port = device_json.get('api_port', None) + self._api_protocol = device_json.get('api_protocol', None) + self._api_secret = device_json.get('api_secret', None) + self._device_oem = device_json.get('device_oem', None) + self._device_type = device_json.get('device_type', 'Android') + self._remote_device = device_json.get('remote_device', None) + self._remote_device_minimum_os = device_json.get( + 'remote_device_minimum_os', None) + self._remote_device_os = device_json.get('remote_device_os', None) + self._results_path = device_json.get('results_path', None) + self._runner_package = device_json.get('runner_package', None) + self._runner_type = device_json.get('runner_type', None) + if 'timeouts' in device_json: + for key in device_json['timeouts']: + self._timeouts[key] = device_json['timeouts'][key] + + def command_line_override( + file_value, cmd_line_value, desc, print_value=True): + if cmd_line_value: + if file_value and file_value != cmd_line_value: + if print_value: + logging.info('Overriding %s from %s to %s', + desc, file_value, cmd_line_value) + else: + logging.info('overriding %s', desc) + return cmd_line_value + return file_value + + self._api_address = command_line_override( + self._api_address, args.api_address, 'api_address') + self._api_port = command_line_override( + self._api_port, args.api_port, 'api_port') + self._api_protocol = command_line_override( + self._api_protocol, args.api_protocol, 'api_protocol') + self._device_oem = command_line_override( + self._device_oem, args.device_oem, 'device_oem') + self._device_type = command_line_override( + self._device_type, args.device_type, 'device_type') + self._remote_device = command_line_override( + self._remote_device, args.remote_device, 'remote_device') + self._remote_device_minimum_os = command_line_override( + self._remote_device_minimum_os, args.remote_device_minimum_os, + 'remote_device_minimum_os') + self._remote_device_os = command_line_override( + self._remote_device_os, args.remote_device_os, 'remote_device_os') + self._results_path = command_line_override( + self._results_path, args.results_path, 'results_path') + self._runner_package = command_line_override( + self._runner_package, args.runner_package, 'runner_package') + self._runner_type = command_line_override( + self._runner_type, args.runner_type, 'runner_type') + + if args.api_key_file: + with open(args.api_key_file) as api_key_file: + temp_key = api_key_file.read().strip() + self._api_key = command_line_override( + self._api_key, temp_key, 'api_key', print_value=False) + self._api_key = command_line_override( + self._api_key, args.api_key, 'api_key', print_value=False) + + if args.api_secret_file: + with open(args.api_secret_file) as api_secret_file: + temp_secret = api_secret_file.read().strip() + self._api_secret = command_line_override( + self._api_secret, temp_secret, 'api_secret', print_value=False) + self._api_secret = command_line_override( + self._api_secret, args.api_secret, 'api_secret', print_value=False) + + if not self._api_address: + error_func('Must set api address with --api-address' + ' or in --remote-device-file.') + if not self._api_key: + error_func('Must set api key with --api-key, --api-key-file' + ' or in --remote-device-file') + if not self._api_port: + error_func('Must set api port with --api-port' + ' or in --remote-device-file') + if not self._api_protocol: + error_func('Must set api protocol with --api-protocol' + ' or in --remote-device-file. Example: http') + if not self._api_secret: + error_func('Must set api secret with --api-secret, --api-secret-file' + ' or in --remote-device-file') + + logging.info('Api address: %s', self._api_address) + logging.info('Api port: %s', self._api_port) + logging.info('Api protocol: %s', self._api_protocol) + logging.info('Remote device: %s', self._remote_device) + logging.info('Remote device minimum OS: %s', + self._remote_device_minimum_os) + logging.info('Remote device OS: %s', self._remote_device_os) + logging.info('Remote device OEM: %s', self._device_oem) + logging.info('Remote device type: %s', self._device_type) + logging.info('Results Path: %s', self._results_path) + logging.info('Runner package: %s', self._runner_package) + logging.info('Runner type: %s', self._runner_type) + logging.info('Timeouts: %s', self._timeouts) if not args.trigger and not args.collect: self._trigger = True @@ -150,10 +240,16 @@ for device in device_list: if device['os_name'] != self._device_type: continue - if self._remote_device and device['name'] != self._remote_device: + if self._remote_device and device['name'] not in self._remote_device: continue if (self._remote_device_os - and device['os_version'] != self._remote_device_os): + and device['os_version'] not in self._remote_device_os): + continue + if self._device_oem and device['brand'] not in self._device_oem: + continue + if (self._remote_device_minimum_os + and distutils.version.LooseVersion(device['os_version']) + < distutils.version.LooseVersion(self._remote_device_minimum_os)): continue if ((self._remote_device and self._remote_device_os) or device['available_devices_count']):
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py index 0b2deae..91701b0 100644 --- a/build/android/pylib/remote/device/remote_device_test_run.py +++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -49,7 +49,7 @@ if self._env.trigger: self._TriggerSetUp() elif self._env.collect: - assert isinstance(self._env.trigger, basestring), ( + assert isinstance(self._env.collect, basestring), ( 'File for storing test_run_id must be a string.') with open(self._env.collect, 'r') as persisted_data_file: persisted_data = json.loads(persisted_data_file.read())
diff --git a/build/android/pylib/uirobot/uirobot_test_instance.py b/build/android/pylib/uirobot/uirobot_test_instance.py index f73c569e6..e3f6eb7 100644 --- a/build/android/pylib/uirobot/uirobot_test_instance.py +++ b/build/android/pylib/uirobot/uirobot_test_instance.py
@@ -3,6 +3,8 @@ # found in the LICENSE file. import os +import json +import logging from pylib import constants from pylib.base import test_instance @@ -20,16 +22,27 @@ if not args.app_under_test: error_func('Must set --app-under-test.') self._app_under_test = args.app_under_test + self._minutes = args.minutes - if args.device_type == 'Android': + if args.remote_device_file: + with open(args.remote_device_file) as remote_device_file: + device_json = json.load(remote_device_file) + else: + device_json = {} + device_type = device_json.get('device_type', 'Android') + if args.device_type: + if device_type and device_type != args.device_type: + logging.info('Overriding device_type from %s to %s', + device_type, args.device_type) + device_type = args.device_type + + if device_type == 'Android': self._suite = 'Android Uirobot' self._package_name = apk_helper.GetPackageName(self._app_under_test) - - elif args.device_type == 'iOS': + elif device_type == 'iOS': self._suite = 'iOS Uirobot' self._package_name = self._app_under_test - self._minutes = args.minutes #override def TestType(self):
diff --git a/build/android/pylib/utils/isolator.py b/build/android/pylib/utils/isolator.py index afbee2a..845d093 100644 --- a/build/android/pylib/utils/isolator.py +++ b/build/android/pylib/utils/isolator.py
@@ -33,8 +33,12 @@ 'fastbuild': '0', 'icu_use_data_file_flag': '1', 'lsan': '0', + 'msan': '0', # TODO(maruel): This may not always be true. 'target_arch': 'arm', + 'tsan': '0', + 'use_custom_libcxx': '0', + 'use_instrumented_libraries': '0', 'use_openssl': '0', 'use_ozone': '0', 'v8_use_external_startup_data': '0',
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index bc0980e..cc7bbee6 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -121,28 +121,40 @@ def AddRemoteDeviceOptions(parser): group = parser.add_argument_group('Remote Device Options') - group.add_argument('--trigger', default='', + group.add_argument('--trigger', help=('Only triggers the test if set. Stores test_run_id ' 'in given file path. ')) - group.add_argument('--collect', default='', + group.add_argument('--collect', help=('Only collects the test results if set. ' 'Gets test_run_id from given file path.')) - group.add_argument('--remote-device', default='', + group.add_argument('--remote-device', action='append', help='Device type to run test on.') - group.add_argument('--remote-device-os', default='', - help='OS to have on the device.') - group.add_argument('--results-path', default='', + group.add_argument('--results-path', help='File path to download results to.') group.add_argument('--api-protocol', help='HTTP protocol to use. (http or https)') - group.add_argument('--api-address', help='Address to send HTTP requests.') - group.add_argument('--api-port', help='Port to send HTTP requests to.') - group.add_argument('--runner-type', default='', + group.add_argument('--api-address', + help='Address to send HTTP requests.') + group.add_argument('--api-port', + help='Port to send HTTP requests to.') + group.add_argument('--runner-type', help='Type of test to run as.') - group.add_argument('--runner-package', help='Package name of test.') - group.add_argument('--device-type', default='Android', + group.add_argument('--runner-package', + help='Package name of test.') + group.add_argument('--device-type', choices=constants.VALID_DEVICE_TYPES, help=('Type of device to run on. iOS or android')) + group.add_argument('--device-oem', action='append', + help='Device OEM to run on.') + group.add_argument('--remote-device-file', + help=('File with JSON to select remote device. ' + 'Overrides all other flags.')) + + device_os_group = group.add_mutually_exclusive_group() + device_os_group.add_argument('--remote-device-minimum-os', + help='Minimum OS on device.') + device_os_group.add_argument('--remote-device-os', action='append', + help='OS to have on the device.') api_secret_group = group.add_mutually_exclusive_group() api_secret_group.add_argument('--api-secret', default='', @@ -513,7 +525,8 @@ """Adds uirobot test options to |option_parser|.""" group = parser.add_argument_group('Uirobot Test Options') - group.add_argument('--app-under-test', help='APK to run tests on.') + group.add_argument('--app-under-test', required=True, + help='APK to run tests on.') group.add_argument( '--minutes', default=5, type=int, help='Number of minutes to run uirobot test [default: %default].')
diff --git a/build/gyp_chromium b/build/gyp_chromium index 1112575..3d527aa 100755 --- a/build/gyp_chromium +++ b/build/gyp_chromium
@@ -7,6 +7,7 @@ # This script is wrapper for Chromium that adds some support for how GYP # is invoked by Chromium beyond what can be done in the gclient hooks. +import argparse import glob import gyp_environment import os @@ -124,15 +125,10 @@ env_items = ProcessGypDefinesItems( shlex.split(os.environ.get('GYP_DEFINES', ''))) - # GYP defines from the command line. We can't use optparse since we want - # to ignore all arguments other than "-D". - cmdline_input_items = [] - for i in range(len(sys.argv))[1:]: - if sys.argv[i].startswith('-D'): - if sys.argv[i] == '-D' and i + 1 < len(sys.argv): - cmdline_input_items += [sys.argv[i + 1]] - elif len(sys.argv[i]) > 2: - cmdline_input_items += [sys.argv[i][2:]] + # GYP defines from the command line. + parser = argparse.ArgumentParser() + parser.add_argument('-D', dest='defines', action='append', default=[]) + cmdline_input_items = parser.parse_known_args()[0].defines cmdline_items = ProcessGypDefinesItems(cmdline_input_items) vars_dict = dict(supp_items + env_items + cmdline_items) @@ -141,21 +137,21 @@ def GetOutputDirectory(): """Returns the output directory that GYP will use.""" - # GYP generator flags from the command line. We can't use optparse since we - # want to ignore all arguments other than "-G". - needle = '-Goutput_dir=' - cmdline_input_items = [] - for item in sys.argv[1:]: - if item.startswith(needle): - return item[len(needle):] - env_items = shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', '')) + # Handle command line generator flags. + parser = argparse.ArgumentParser() + parser.add_argument('-G', dest='genflags', default=[], action='append') + genflags = parser.parse_known_args()[0].genflags + + # Handle generator flags from the environment. + genflags += shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', '')) + needle = 'output_dir=' - for item in env_items: + for item in genflags: if item.startswith(needle): return item[len(needle):] - return "out" + return 'out' def additional_include_files(supplemental_files, args=[]):
diff --git a/build/gyp_chromium_test.py b/build/gyp_chromium_test.py new file mode 100755 index 0000000..0c0e479 --- /dev/null +++ b/build/gyp_chromium_test.py
@@ -0,0 +1,66 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys +import unittest + +SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) +SRC_DIR = os.path.dirname(SCRIPT_DIR) + +sys.path.append(os.path.join(SRC_DIR, 'third_party', 'pymock')) + +import mock + +# TODO(sbc): Make gyp_chromium more testable by putting the code in +# a .py file. +gyp_chromium = __import__('gyp_chromium') + + +class TestGetOutputDirectory(unittest.TestCase): + @mock.patch('os.environ', {}) + @mock.patch('sys.argv', [__file__]) + def testDefaultValue(self): + self.assertEqual(gyp_chromium.GetOutputDirectory(), 'out') + + @mock.patch('os.environ', {'GYP_GENERATOR_FLAGS': 'output_dir=envfoo'}) + @mock.patch('sys.argv', [__file__]) + def testEnvironment(self): + self.assertEqual(gyp_chromium.GetOutputDirectory(), 'envfoo') + + @mock.patch('os.environ', {'GYP_GENERATOR_FLAGS': 'output_dir=envfoo'}) + @mock.patch('sys.argv', [__file__, '-Goutput_dir=cmdfoo']) + def testGFlagOverridesEnv(self): + self.assertEqual(gyp_chromium.GetOutputDirectory(), 'cmdfoo') + + @mock.patch('os.environ', {}) + @mock.patch('sys.argv', [__file__, '-G', 'output_dir=foo']) + def testGFlagWithSpace(self): + self.assertEqual(gyp_chromium.GetOutputDirectory(), 'foo') + + +class TestGetGypVars(unittest.TestCase): + @mock.patch('os.environ', {}) + def testDefault(self): + self.assertEqual(gyp_chromium.GetGypVars([]), {}) + + @mock.patch('os.environ', {}) + @mock.patch('sys.argv', [__file__, '-D', 'foo=bar']) + def testDFlags(self): + self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': 'bar'}) + + @mock.patch('os.environ', {}) + @mock.patch('sys.argv', [__file__, '-D', 'foo']) + def testDFlagsNoValue(self): + self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': '1'}) + + @mock.patch('os.environ', {}) + @mock.patch('sys.argv', [__file__, '-D', 'foo=bar', '-Dbaz']) + def testDFlagMulti(self): + self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': 'bar', 'baz': '1'}) + + +if __name__ == '__main__': + unittest.main()
diff --git a/build/isolate.gypi b/build/isolate.gypi index e6d2f98..d7070fe 100644 --- a/build/isolate.gypi +++ b/build/isolate.gypi
@@ -74,24 +74,28 @@ # the .isolate file but are not considered relative paths. '--extra-variable', 'version_full=<(version_full)', - '--config-variable', 'OS=<(OS)', '--config-variable', 'CONFIGURATION_NAME=<(CONFIGURATION_NAME)', + '--config-variable', 'OS=<(OS)', '--config-variable', 'asan=<(asan)', '--config-variable', 'chromeos=<(chromeos)', '--config-variable', 'component=<(component)', + '--config-variable', 'disable_nacl=<(disable_nacl)', '--config-variable', 'fastbuild=<(fastbuild)', + '--config-variable', 'icu_use_data_file_flag=<(icu_use_data_file_flag)', # TODO(kbr): move this to chrome_tests.gypi:gles2_conform_tests_run # once support for user-defined config variables is added. '--config-variable', 'internal_gles2_conform_tests=<(internal_gles2_conform_tests)', - '--config-variable', 'icu_use_data_file_flag=<(icu_use_data_file_flag)', - '--config-variable', 'v8_use_external_startup_data=<(v8_use_external_startup_data)', - '--config-variable', 'lsan=<(lsan)', '--config-variable', 'libpeer_target_type=<(libpeer_target_type)', - '--config-variable', 'use_openssl=<(use_openssl)', + '--config-variable', 'lsan=<(lsan)', + '--config-variable', 'msan=<(msan)', '--config-variable', 'target_arch=<(target_arch)', + '--config-variable', 'tsan=<(tsan)', + '--config-variable', 'use_custom_libcxx=<(use_custom_libcxx)', + '--config-variable', 'use_instrumented_libraries=<(use_instrumented_libraries)', + '--config-variable', 'use_openssl=<(use_openssl)', '--config-variable', 'use_ozone=<(use_ozone)', - '--config-variable', 'disable_nacl=<(disable_nacl)', + '--config-variable', 'v8_use_external_startup_data=<(v8_use_external_startup_data)', ], 'conditions': [ # Note: When gyp merges lists, it appends them to the old value.
diff --git a/cc/base/synced_property.h b/cc/base/synced_property.h index 8b554c62..6b02e7a6 100644 --- a/cc/base/synced_property.h +++ b/cc/base/synced_property.h
@@ -24,7 +24,7 @@ template <typename T> class SyncedProperty : public base::RefCounted<SyncedProperty<T>> { public: - SyncedProperty() {} + SyncedProperty() : clobber_active_value_(false) {} // Returns the canonical value for the specified tree, including the sum of // all deltas. The pending tree should use this for activation purposes and @@ -84,6 +84,7 @@ active_base_ = pending_base_; active_delta_ = PendingDelta(); sent_delta_ = T::Identity(); + clobber_active_value_ = false; return true; } @@ -105,7 +106,13 @@ // The new delta we would use if we decide to activate now. This delta // excludes the amount that we expect the main thread to reflect back at the // impl thread during the commit. - T PendingDelta() const { return active_delta_.InverseCombine(sent_delta_); } + T PendingDelta() const { + if (clobber_active_value_) + return T::Identity(); + return active_delta_.InverseCombine(sent_delta_); + } + + void set_clobber_active_value() { clobber_active_value_ = true; } private: // Value last committed to the pending tree. @@ -117,6 +124,9 @@ // The value sent to the main thread (on the last BeginFrame); this is always // identity outside of the BeginFrame-to-activation interval. T sent_delta_; + // When true the pending delta is always identity so that it does not change + // and will clobber the active value on push. + bool clobber_active_value_; friend class base::RefCounted<SyncedProperty<T>>; ~SyncedProperty() {}
diff --git a/webkit/common/gpu/context_provider_web_context.h b/cc/blink/context_provider_web_context.h similarity index 63% rename from webkit/common/gpu/context_provider_web_context.h rename to cc/blink/context_provider_web_context.h index c9c666cd..21d1df3 100644 --- a/webkit/common/gpu/context_provider_web_context.h +++ b/cc/blink/context_provider_web_context.h
@@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_WEB_CONTEXT_H_ -#define WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_WEB_CONTEXT_H_ +#ifndef CC_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_ +#define CC_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_ #include "cc/output/context_provider.h" namespace blink { class WebGraphicsContext3D; } -namespace webkit { -namespace gpu { +namespace cc_blink { class ContextProviderWebContext : public cc::ContextProvider { public: @@ -20,7 +19,6 @@ ~ContextProviderWebContext() override {} }; -} // namespace gpu -} // namespace webkit +} // namespace cc_blink -#endif // WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_WEB_CONTEXT_H_ +#endif // CC_BLINK_CONTEXT_PROVIDER_WEB_CONTEXT_H_
diff --git a/cc/cc_unittests.isolate b/cc/cc_unittests.isolate index 4e5ac92c..5d652d9b0 100644 --- a/cc/cc_unittests.isolate +++ b/cc/cc_unittests.isolate
@@ -22,6 +22,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -46,6 +48,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.so', @@ -62,6 +66,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.dll',
diff --git a/cc/debug/devtools_instrumentation.h b/cc/debug/devtools_instrumentation.h index cfe3e5a2..73788a52 100644 --- a/cc/debug/devtools_instrumentation.h +++ b/cc/debug/devtools_instrumentation.h
@@ -6,6 +6,7 @@ #define CC_DEBUG_DEVTOOLS_INSTRUMENTATION_H_ #include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" namespace cc { namespace devtools_instrumentation { @@ -14,6 +15,7 @@ const char kCategory[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline"); const char kCategoryFrame[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame"); +const char kData[] = "data"; const char kFrameId[] = "frameId"; const char kLayerId[] = "layerId"; const char kLayerTreeId[] = "layerTreeId"; @@ -23,7 +25,9 @@ const char kBeginFrame[] = "BeginFrame"; const char kActivateLayerTree[] = "ActivateLayerTree"; const char kRequestMainThreadFrame[] = "RequestMainThreadFrame"; +const char kBeginMainThreadFrame[] = "BeginMainThreadFrame"; const char kDrawFrame[] = "DrawFrame"; +const char kCompositeLayers[] = "CompositeLayers"; } // namespace internal const char kPaintSetup[] = "PaintSetup"; @@ -77,6 +81,20 @@ DISALLOW_COPY_AND_ASSIGN(ScopedLayerTreeTask); }; +struct ScopedCommitTrace { + public: + explicit ScopedCommitTrace(int layer_tree_host_id) { + TRACE_EVENT_BEGIN1(internal::kCategory, internal::kCompositeLayers, + internal::kLayerTreeId, layer_tree_host_id); + } + ~ScopedCommitTrace() { + TRACE_EVENT_END0(internal::kCategory, internal::kCompositeLayers); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedCommitTrace); +}; + struct ScopedLayerObjectTracker : public base::debug::TraceScopedTrackableObject<int> { explicit ScopedLayerObjectTracker(int layer_id) @@ -124,6 +142,21 @@ layer_tree_host_id); } +inline scoped_refptr<base::debug::ConvertableToTraceFormat> +BeginMainThreadFrameData(int frame_id) { + scoped_refptr<base::debug::TracedValue> value = + new base::debug::TracedValue(); + value->SetInteger("frameId", frame_id); + return value; +} + +inline void WillBeginMainThreadFrame(int layer_tree_host_id, int frame_id) { + TRACE_EVENT_INSTANT2( + internal::kCategoryFrame, internal::kBeginMainThreadFrame, + TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id, + internal::kData, BeginMainThreadFrameData(frame_id)); +} + } // namespace devtools_instrumentation } // namespace cc
diff --git a/cc/debug/frame_timing_request.h b/cc/debug/frame_timing_request.h index 7ab97de..0937998 100644 --- a/cc/debug/frame_timing_request.h +++ b/cc/debug/frame_timing_request.h
@@ -5,6 +5,7 @@ #ifndef CC_DEBUG_FRAME_TIMING_REQUEST_H_ #define CC_DEBUG_FRAME_TIMING_REQUEST_H_ +#include "cc/base/cc_export.h" #include "ui/gfx/geometry/rect.h" namespace cc { @@ -13,12 +14,15 @@ // given rect (in layer space) and an associated request id. When this request // is propagated to the active LayerImpl, it will cause events to be saved in // FrameTimingTracker, which in turn can be consumed by the requester. -class FrameTimingRequest { +class CC_EXPORT FrameTimingRequest { public: FrameTimingRequest(); FrameTimingRequest(int64_t request_id, const gfx::Rect& rect); + // Return the ID for the request. int64_t id() const { return id_; } + + // Return the layer space rect for this request. const gfx::Rect& rect() const { return rect_; } private:
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index face433..cff75e7 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -978,10 +978,14 @@ layer->SetClipChildren(nullptr); } - layer->PushScrollOffsetFromMainThread(scroll_offset_); - if (layer_animation_controller_->scroll_offset_animation_was_interrupted() && - layer->IsActive()) - layer->SetScrollDelta(gfx::Vector2dF()); + // When a scroll offset animation is interrupted the new scroll position on + // the pending tree will clobber any impl-side scrolling occuring on the + // active tree. To do so, avoid scrolling the pending tree along with it + // instead of trying to undo that scrolling later. + if (layer_animation_controller_->scroll_offset_animation_was_interrupted()) + layer->PushScrollOffsetFromMainThreadAndClobberActiveValue(scroll_offset_); + else + layer->PushScrollOffsetFromMainThread(scroll_offset_); layer->SetScrollCompensationAdjustment(ScrollCompensationAdjustment()); // Wrap the copy_requests_ in a PostTask to the main thread.
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 55ffa7f..50501a9 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -1080,6 +1080,12 @@ PushScrollOffset(&scroll_offset); } +void LayerImpl::PushScrollOffsetFromMainThreadAndClobberActiveValue( + const gfx::ScrollOffset& scroll_offset) { + scroll_offset_->set_clobber_active_value(); + PushScrollOffset(&scroll_offset); +} + gfx::ScrollOffset LayerImpl::PullDeltaForMainThread() { RefreshFromScrollDelegate(); @@ -1140,8 +1146,6 @@ } if (IsActive()) { changed |= scroll_offset_->PushPendingToActive(); - if (layer_animation_controller_->scroll_offset_animation_was_interrupted()) - SetScrollDelta(gfx::Vector2dF()); } if (changed)
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index f46c16e..40e295f 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -399,6 +399,11 @@ void SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset); void PushScrollOffsetFromMainThread(const gfx::ScrollOffset& scroll_offset); + // This method is similar to PushScrollOffsetFromMainThread but will cause the + // scroll offset given to clobber any scroll changes on the active tree in the + // time until this value is pushed to the active tree. + void PushScrollOffsetFromMainThreadAndClobberActiveValue( + const gfx::ScrollOffset& scroll_offset); gfx::ScrollOffset PullDeltaForMainThread(); gfx::ScrollOffset CurrentScrollOffset() const; gfx::ScrollOffset BaseScrollOffset() const;
diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc index 4168253..46c3a7d 100644 --- a/cc/output/overlay_candidate.cc +++ b/cc/output/overlay_candidate.cc
@@ -24,7 +24,7 @@ gfx::OverlayTransform OverlayCandidate::GetOverlayTransform( const gfx::Transform& quad_transform, bool flipped) { - if (!quad_transform.IsIdentityOrTranslation()) + if (!quad_transform.IsPositiveScaleOrTranslation()) return gfx::OVERLAY_TRANSFORM_INVALID; return flipped ? gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL @@ -32,9 +32,105 @@ } // static +gfx::OverlayTransform OverlayCandidate::ModifyTransform( + gfx::OverlayTransform in, + gfx::OverlayTransform delta) { + // There are 8 different possible transforms. We can characterize these + // by looking at where the origin moves and the direction the horizontal goes. + // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical). + // NONE: TL, H + // FLIP_VERTICAL: BL, H + // FLIP_HORIZONTAL: TR, H + // ROTATE_90: TR, V + // ROTATE_180: BR, H + // ROTATE_270: BL, V + // Missing transforms: TL, V & BR, V + // Basic combinations: + // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H) + // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H) + // Rotate + Rotate simply adds values. + // Rotate 90/270 + flip is invalid because we can only have verticals with + // the origin in TR or BL. + if (delta == gfx::OVERLAY_TRANSFORM_NONE) + return in; + switch (in) { + case gfx::OVERLAY_TRANSFORM_NONE: + return delta; + case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: + switch (delta) { + case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: + return gfx::OVERLAY_TRANSFORM_NONE; + case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + return gfx::OVERLAY_TRANSFORM_ROTATE_180; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } + break; + case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + switch (delta) { + case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + return gfx::OVERLAY_TRANSFORM_NONE; + case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: + return gfx::OVERLAY_TRANSFORM_ROTATE_180; + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } + break; + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + switch (delta) { + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + return gfx::OVERLAY_TRANSFORM_ROTATE_180; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::OVERLAY_TRANSFORM_ROTATE_270; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + return gfx::OVERLAY_TRANSFORM_NONE; + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } + break; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + switch (delta) { + case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL: + return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL; + case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL: + return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL; + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + return gfx::OVERLAY_TRANSFORM_ROTATE_270; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::OVERLAY_TRANSFORM_NONE; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + return gfx::OVERLAY_TRANSFORM_ROTATE_90; + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } + break; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + switch (delta) { + case gfx::OVERLAY_TRANSFORM_ROTATE_90: + return gfx::OVERLAY_TRANSFORM_NONE; + case gfx::OVERLAY_TRANSFORM_ROTATE_180: + return gfx::OVERLAY_TRANSFORM_ROTATE_90; + case gfx::OVERLAY_TRANSFORM_ROTATE_270: + return gfx::OVERLAY_TRANSFORM_ROTATE_180; + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } + break; + default: + return gfx::OVERLAY_TRANSFORM_INVALID; + } +} + +// static gfx::Rect OverlayCandidate::GetOverlayRect(const gfx::Transform& quad_transform, const gfx::Rect& rect) { - DCHECK(quad_transform.IsIdentityOrTranslation()); + DCHECK(quad_transform.IsPositiveScaleOrTranslation()); gfx::RectF float_rect(rect); quad_transform.TransformRect(&float_rect);
diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h index 9a1e534e..28ae8cb7 100644 --- a/cc/output/overlay_candidate.h +++ b/cc/output/overlay_candidate.h
@@ -20,6 +20,10 @@ static gfx::OverlayTransform GetOverlayTransform( const gfx::Transform& quad_transform, bool flipped); + // Apply transform |delta| to |in| and return the resulting transform, + // or OVERLAY_TRANSFORM_INVALID. + static gfx::OverlayTransform ModifyTransform(gfx::OverlayTransform in, + gfx::OverlayTransform delta); static gfx::Rect GetOverlayRect(const gfx::Transform& quad_transform, const gfx::Rect& rect);
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc index 98d77ad4..9a95206 100644 --- a/cc/output/overlay_strategy_single_on_top.cc +++ b/cc/output/overlay_strategy_single_on_top.cc
@@ -4,8 +4,13 @@ #include "cc/output/overlay_strategy_single_on_top.h" +#include <limits> + #include "cc/quads/draw_quad.h" +#include "cc/quads/solid_color_draw_quad.h" +#include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" +#include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/transform.h" @@ -17,6 +22,103 @@ : capability_checker_(capability_checker), resource_provider_(resource_provider) {} +bool OverlayStrategySingleOnTop::IsOverlayQuad(const DrawQuad* draw_quad) { + unsigned int resource_id; + switch (draw_quad->material) { + case DrawQuad::TEXTURE_CONTENT: + resource_id = TextureDrawQuad::MaterialCast(draw_quad)->resource_id; + break; + case DrawQuad::STREAM_VIDEO_CONTENT: + resource_id = StreamVideoDrawQuad::MaterialCast(draw_quad)->resource_id; + break; + default: + return false; + } + return resource_provider_->AllowOverlay(resource_id); +} + +bool OverlayStrategySingleOnTop::GetTextureQuadInfo( + const TextureDrawQuad& quad, + OverlayCandidate* quad_info) { + gfx::OverlayTransform overlay_transform = + OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped); + if (quad.background_color != SK_ColorTRANSPARENT || + quad.premultiplied_alpha || + overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID) + return false; + quad_info->resource_id = quad.resource_id; + quad_info->transform = overlay_transform; + quad_info->uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right); + return true; +} + +bool OverlayStrategySingleOnTop::GetVideoQuadInfo( + const StreamVideoDrawQuad& quad, + OverlayCandidate* quad_info) { + gfx::OverlayTransform overlay_transform = + OverlayCandidate::GetOverlayTransform(quad.quadTransform(), false); + if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID) + return false; + if (!quad.matrix.IsScaleOrTranslation()) { + // We cannot handle anything other than scaling & translation for texture + // coordinates yet. + return false; + } + quad_info->resource_id = quad.resource_id; + quad_info->transform = overlay_transform; + + gfx::Point3F uv0 = gfx::Point3F(0, 0, 0); + gfx::Point3F uv1 = gfx::Point3F(1, 1, 0); + quad.matrix.TransformPoint(&uv0); + quad.matrix.TransformPoint(&uv1); + gfx::Vector3dF delta = uv1 - uv0; + if (delta.x() < 0) { + quad_info->transform = OverlayCandidate::ModifyTransform( + quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL); + float x0 = uv0.x(); + uv0.set_x(uv1.x()); + uv1.set_x(x0); + delta.set_x(-delta.x()); + } + + if (delta.y() < 0) { + // In this situation, uv0y < uv1y. Since we overlay inverted, a request + // to invert the source texture means we can just output the texture + // normally and it will be correct. + quad_info->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y()); + } else { + quad_info->transform = OverlayCandidate::ModifyTransform( + quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL); + quad_info->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y()); + } + return true; +} + +bool OverlayStrategySingleOnTop::GetCandidateQuadInfo( + const DrawQuad& draw_quad, + OverlayCandidate* quad_info) { + // All quad checks. + if (draw_quad.needs_blending || draw_quad.shared_quad_state->opacity != 1.f || + draw_quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) + return false; + + if (draw_quad.material == DrawQuad::TEXTURE_CONTENT) { + const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(&draw_quad); + if (!GetTextureQuadInfo(quad, quad_info)) + return false; + } else if (draw_quad.material == DrawQuad::STREAM_VIDEO_CONTENT) { + const StreamVideoDrawQuad& quad = + *StreamVideoDrawQuad::MaterialCast(&draw_quad); + if (!GetVideoQuadInfo(quad, quad_info)) + return false; + } + + quad_info->format = RGBA_8888; + quad_info->display_rect = OverlayCandidate::GetOverlayRect( + draw_quad.quadTransform(), draw_quad.rect); + return true; +} + bool OverlayStrategySingleOnTop::Attempt( RenderPassList* render_passes_in_draw_order, OverlayCandidateList* candidate_list) { @@ -27,15 +129,12 @@ RenderPass* root_render_pass = render_passes_in_draw_order->back(); DCHECK(root_render_pass); + OverlayCandidate candidate; QuadList& quad_list = root_render_pass->quad_list; auto candidate_iterator = quad_list.end(); for (auto it = quad_list.begin(); it != quad_list.end(); ++it) { const DrawQuad* draw_quad = *it; - if (draw_quad->material == DrawQuad::TEXTURE_CONTENT) { - const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(draw_quad); - if (!resource_provider_->AllowOverlay(quad.resource_id)) { - continue; - } + if (IsOverlayQuad(draw_quad)) { // Check that no prior quads overlap it. bool intersects = false; gfx::RectF rect = draw_quad->rect; @@ -49,7 +148,7 @@ break; } } - if (intersects) + if (intersects || !GetCandidateQuadInfo(*draw_quad, &candidate)) continue; candidate_iterator = it; break; @@ -57,34 +156,14 @@ } if (candidate_iterator == quad_list.end()) return false; - const TextureDrawQuad& quad = - *TextureDrawQuad::MaterialCast(*candidate_iterator); - - // Simple quads only. - gfx::OverlayTransform overlay_transform = - OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped); - if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID || - !quad.quadTransform().IsIdentityOrTranslation() || quad.needs_blending || - quad.shared_quad_state->opacity != 1.f || - quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode || - quad.premultiplied_alpha || quad.background_color != SK_ColorTRANSPARENT) - return false; // Add our primary surface. OverlayCandidateList candidates; OverlayCandidate main_image; main_image.display_rect = root_render_pass->output_rect; - main_image.format = RGBA_8888; candidates.push_back(main_image); // Add the overlay. - OverlayCandidate candidate; - candidate.transform = overlay_transform; - candidate.display_rect = - OverlayCandidate::GetOverlayRect(quad.quadTransform(), quad.rect); - candidate.uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right); - candidate.format = RGBA_8888; - candidate.resource_id = quad.resource_id; candidate.plane_z_order = 1; candidates.push_back(candidate);
diff --git a/cc/output/overlay_strategy_single_on_top.h b/cc/output/overlay_strategy_single_on_top.h index e5518cc..f92e104 100644 --- a/cc/output/overlay_strategy_single_on_top.h +++ b/cc/output/overlay_strategy_single_on_top.h
@@ -14,6 +14,8 @@ namespace cc { class OverlayCandidateValidator; +class StreamVideoDrawQuad; +class TextureDrawQuad; class CC_EXPORT OverlayStrategySingleOnTop : public OverlayProcessor::Strategy { public: @@ -23,6 +25,15 @@ OverlayCandidateList* candidate_list) override; private: + bool IsOverlayQuad(const DrawQuad* draw_quad); + bool GetCandidateQuadInfo(const DrawQuad& draw_quad, + OverlayCandidate* quad_info); + + bool GetTextureQuadInfo(const TextureDrawQuad& quad, + OverlayCandidate* quad_info); + bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad, + OverlayCandidate* quad_info); + OverlayCandidateValidator* capability_checker_; ResourceProvider* resource_provider_; DISALLOW_COPY_AND_ASSIGN(OverlayStrategySingleOnTop);
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 8fa35cb..4682679 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc
@@ -11,6 +11,7 @@ #include "cc/output/overlay_strategy_single_on_top.h" #include "cc/quads/checkerboard_draw_quad.h" #include "cc/quads/render_pass.h" +#include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/resources/resource_provider.h" #include "cc/resources/texture_mailbox.h" @@ -32,6 +33,16 @@ const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64); const gfx::PointF kUVTopLeft(0.1f, 0.2f); const gfx::PointF kUVBottomRight(1.0f, 1.0f); +const gfx::Transform kNormalTransform = + gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y. +const gfx::Transform kXMirrorTransform = + gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y. +const gfx::Transform kYMirrorTransform = + gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y. +const gfx::Transform kBothMirrorTransform = + gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y. +const gfx::Transform kSwapTransform = + gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x. void MailboxReleased(unsigned sync_point, bool lost_resource, @@ -173,6 +184,22 @@ return overlay_quad; } +StreamVideoDrawQuad* CreateCandidateVideoQuadAt( + ResourceProvider* resource_provider, + const SharedQuadState* shared_quad_state, + RenderPass* render_pass, + const gfx::Rect& rect, + const gfx::Transform& transform) { + ResourceProvider::ResourceId resource_id = CreateResource(resource_provider); + + StreamVideoDrawQuad* overlay_quad = + render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>(); + overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id, + transform); + + return overlay_quad; +} + TextureDrawQuad* CreateFullscreenCandidateQuad( ResourceProvider* resource_provider, const SharedQuadState* shared_quad_state, @@ -181,6 +208,15 @@ resource_provider, shared_quad_state, render_pass, kOverlayRect); } +StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad( + ResourceProvider* resource_provider, + const SharedQuadState* shared_quad_state, + RenderPass* render_pass, + const gfx::Transform& transform) { + return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state, + render_pass, kOverlayRect, transform); +} + void CreateCheckeredQuadAt(ResourceProvider* resource_provider, const SharedQuadState* shared_quad_state, RenderPass* render_pass, @@ -484,13 +520,13 @@ EXPECT_EQ(0U, candidate_list.size()); } -TEST_F(SingleOverlayOnTopTest, RejectTransform) { +TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateFullscreenCandidateQuad(resource_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); - pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f, - 2.f); + pass->shared_quad_state_list.back() + ->content_to_target_transform.RotateAboutXAxis(45.f); RenderPassList pass_list; pass_list.push_back(pass.Pass()); @@ -500,6 +536,39 @@ EXPECT_EQ(0U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get()); + pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f, + -1.0f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(0U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) { + gfx::Rect rect = kOverlayRect; + rect.set_width(rect.width() / 2); + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateCandidateQuadAt(resource_provider_.get(), + pass->shared_quad_state_list.back(), pass.get(), rect); + pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f, + 1.0f); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) { scoped_ptr<RenderPass> pass = CreateRenderPass(); CreateCheckeredQuadAt(resource_provider_.get(), @@ -523,6 +592,76 @@ EXPECT_EQ(2U, candidate_list.size()); } +TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get(), kSwapTransform); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(0U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get(), kXMirrorTransform); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get(), kBothMirrorTransform); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get(), kNormalTransform); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + +TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) { + scoped_ptr<RenderPass> pass = CreateRenderPass(); + CreateFullscreenCandidateVideoQuad(resource_provider_.get(), + pass->shared_quad_state_list.back(), + pass.get(), kYMirrorTransform); + + RenderPassList pass_list; + pass_list.push_back(pass.Pass()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(2U, candidate_list.size()); +} + class OverlayInfoRendererGL : public GLRenderer { public: OverlayInfoRendererGL(RendererClient* client,
diff --git a/cc/resources/gpu_rasterizer.cc b/cc/resources/gpu_rasterizer.cc index 3fdc8bb..369f12cf 100644 --- a/cc/resources/gpu_rasterizer.cc +++ b/cc/resources/gpu_rasterizer.cc
@@ -31,22 +31,22 @@ ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, - bool tile_prepare_enabled, + bool threaded_gpu_rasterization_enabled, int msaa_sample_count) { return make_scoped_ptr<GpuRasterizer>(new GpuRasterizer( context_provider, resource_provider, use_distance_field_text, - tile_prepare_enabled, msaa_sample_count)); + threaded_gpu_rasterization_enabled, msaa_sample_count)); } GpuRasterizer::GpuRasterizer(ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_distance_field_text, - bool tile_prepare_enabled, + bool threaded_gpu_rasterization_enabled, int msaa_sample_count) : context_provider_(context_provider), resource_provider_(resource_provider), use_distance_field_text_(use_distance_field_text), - tile_prepare_enabled_(tile_prepare_enabled), + threaded_gpu_rasterization_enabled_(threaded_gpu_rasterization_enabled), msaa_sample_count_(msaa_sample_count) { DCHECK(context_provider_); } @@ -55,8 +55,7 @@ } PrepareTilesMode GpuRasterizer::GetPrepareTilesMode() { - return tile_prepare_enabled_ ? PrepareTilesMode::PREPARE_PRIORITIZED_TILES - : PrepareTilesMode::PREPARE_NONE; + return PrepareTilesMode::PREPARE_NONE; } void GpuRasterizer::RasterizeTiles(
diff --git a/cc/resources/gpu_rasterizer.h b/cc/resources/gpu_rasterizer.h index 206b051d..79a05969 100644 --- a/cc/resources/gpu_rasterizer.h +++ b/cc/resources/gpu_rasterizer.h
@@ -22,11 +22,12 @@ public: ~GpuRasterizer() override; - static scoped_ptr<GpuRasterizer> Create(ContextProvider* context_provider, - ResourceProvider* resource_provider, - bool use_distance_field_text, - bool tile_prepare_enabled, - int msaa_sample_count); + static scoped_ptr<GpuRasterizer> Create( + ContextProvider* context_provider, + ResourceProvider* resource_provider, + bool use_distance_field_text, + bool threaded_gpu_rasterization_enabled, + int msaa_sample_count); PrepareTilesMode GetPrepareTilesMode() override; void RasterizeTiles( const TileVector& tiles, @@ -38,7 +39,7 @@ GpuRasterizer(ContextProvider* context_provider, ResourceProvider* resource_provider, bool use_distance_filed_text, - bool tile_prepare_enabled, + bool threaded_gpu_rasterization_enabled, int msaa_sample_count); using ScopedResourceWriteLocks = @@ -55,7 +56,7 @@ SkMultiPictureDraw multi_picture_draw_; bool use_distance_field_text_; - bool tile_prepare_enabled_; + bool threaded_gpu_rasterization_enabled_; int msaa_sample_count_; DISALLOW_COPY_AND_ASSIGN(GpuRasterizer);
diff --git a/cc/resources/rasterizer.h b/cc/resources/rasterizer.h index 95b9ce2..43df0b0 100644 --- a/cc/resources/rasterizer.h +++ b/cc/resources/rasterizer.h
@@ -16,7 +16,6 @@ enum class PrepareTilesMode { RASTERIZE_PRIORITIZED_TILES, - PREPARE_PRIORITIZED_TILES, PREPARE_NONE };
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc index c245bd63..9b200e9 100644 --- a/cc/scheduler/begin_frame_source.cc +++ b/cc/scheduler/begin_frame_source.cc
@@ -414,11 +414,10 @@ } } -void BeginFrameSourceMultiplexer::SetNeedsBeginFrames(bool needs_begin_frames) { - DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetNeedsBeginFrames", - "active_source", - active_source_, - "needs_begin_frames", +void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange( + bool needs_begin_frames) { + DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange", + "active_source", active_source_, "needs_begin_frames", needs_begin_frames); if (active_source_) { active_source_->SetNeedsBeginFrames(needs_begin_frames);
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h index 299db8e3..1612a286 100644 --- a/cc/scheduler/begin_frame_source.h +++ b/cc/scheduler/begin_frame_source.h
@@ -138,7 +138,7 @@ // BeginFrameSource bool NeedsBeginFrames() const override; - void SetNeedsBeginFrames(bool needs_begin_frames) override; + void SetNeedsBeginFrames(bool needs_begin_frames) final; void DidFinishFrame(size_t remaining_frames) override {} void AddObserver(BeginFrameObserver* obs) final; void RemoveObserver(BeginFrameObserver* obs) final; @@ -261,9 +261,11 @@ // BeginFrameSource bool NeedsBeginFrames() const override; - void SetNeedsBeginFrames(bool needs_begin_frames) override; void DidFinishFrame(size_t remaining_frames) override; + // BeginFrameSourceMixIn + void OnNeedsBeginFramesChange(bool needs_begin_frames) override; + // Tracing void AsValueInto(base::debug::TracedValue* dict) const override;
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index aa153c6..5b7f6b7 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -282,7 +282,6 @@ bool ShouldAnimate() const; bool ShouldBeginOutputSurfaceCreation() const; - bool ShouldDrawForced() const; bool ShouldDraw() const; bool ShouldActivatePendingTree() const; bool ShouldSendBeginMainFrame() const;
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index 25f3114..065aa38 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc
@@ -46,7 +46,11 @@ current_frame_ = frame.Pass(); factory_->ReceiveFromChild( current_frame_->delegated_frame_data->resource_list); - ++frame_index_; + // Empty frames shouldn't be drawn and shouldn't contribute damage, so don't + // increment frame index for them. + if (!current_frame_ || + !current_frame_->delegated_frame_data->render_pass_list.empty()) + ++frame_index_; if (previous_frame) { ReturnedResourceArray previous_resources;
diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc index ed6763d1..068fe03 100644 --- a/cc/surfaces/surface_display_output_surface.cc +++ b/cc/surfaces/surface_display_output_surface.cc
@@ -25,6 +25,9 @@ capabilities_.delegated_rendering = true; capabilities_.max_frames_pending = 1; capabilities_.can_force_reclaim_resources = true; + // Frame always needs to be swapped because forced resource reclaiming + // destroys the Display's copy. + capabilities_.draw_and_swap_full_viewport_every_frame = true; } SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() {
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index b5c2a63..b9c6bf5 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc
@@ -360,6 +360,21 @@ } } +TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { + SurfaceId surface_id(6); + factory_.Create(surface_id); + Surface* surface = manager_.GetSurfaceForId(surface_id); + ASSERT_NE(nullptr, surface); + EXPECT_EQ(2, surface->frame_index()); + scoped_ptr<CompositorFrame> frame(new CompositorFrame); + frame->delegated_frame_data.reset(new DelegatedFrameData); + + factory_.SubmitFrame(surface_id, frame.Pass(), + SurfaceFactory::DrawCallback()); + EXPECT_EQ(2, surface->frame_index()); + factory_.Destroy(surface_id); +} + void DrawCallback(uint32* execute_count, SurfaceDrawStatus* result, SurfaceDrawStatus drawn) {
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h index 5f7afa5..8fcafdb7 100644 --- a/cc/test/fake_layer_tree_host_client.h +++ b/cc/test/fake_layer_tree_host_client.h
@@ -30,7 +30,7 @@ void SetLayerTreeHost(LayerTreeHost* host) { host_ = host; } // LayerTreeHostClient implementation. - void WillBeginMainFrame(int frame_id) override {} + void WillBeginMainFrame() override {} void DidBeginMainFrame() override {} void BeginMainFrame(const BeginFrameArgs& args) override {} void Layout() override {}
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index d02b5104..5f69c354 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -381,9 +381,7 @@ } ~LayerTreeHostClientForTesting() override {} - void WillBeginMainFrame(int frame_id) override { - test_hooks_->WillBeginMainFrame(); - } + void WillBeginMainFrame() override { test_hooks_->WillBeginMainFrame(); } void DidBeginMainFrame() override { test_hooks_->DidBeginMainFrame(); }
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 0f48cb20..2567122 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -222,6 +222,12 @@ contents_texture_manager_->ClearAllMemory(resource_provider); } +void LayerTreeHost::WillBeginMainFrame() { + devtools_instrumentation::WillBeginMainThreadFrame(id(), + source_frame_number()); + client_->WillBeginMainFrame(); +} + void LayerTreeHost::DidBeginMainFrame() { client_->DidBeginMainFrame(); }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 7db722f6..f41e023 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -110,9 +110,7 @@ void SetLayerTreeHostClientReady(); // LayerTreeHost interface to Proxy. - void WillBeginMainFrame() { - client_->WillBeginMainFrame(source_frame_number_); - } + void WillBeginMainFrame(); void DidBeginMainFrame(); void BeginMainFrame(const BeginFrameArgs& args); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time);
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index ac025f2..a712534 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h
@@ -22,7 +22,7 @@ class LayerTreeHostClient { public: - virtual void WillBeginMainFrame(int frame_id) = 0; + virtual void WillBeginMainFrame() = 0; // Marks finishing compositing-related tasks on the main thread. In threaded // mode, this corresponds to DidCommit(). virtual void BeginMainFrame(const BeginFrameArgs& args) = 0;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 398ef81..53eb58b 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -229,7 +229,8 @@ gpu_memory_buffer_manager_(gpu_memory_buffer_manager), id_(id), requires_high_res_to_draw_(false), - is_likely_to_require_a_draw_(false) { + is_likely_to_require_a_draw_(false), + frame_timing_tracker_(FrameTimingTracker::Create()) { DCHECK(proxy_->IsImplThread()); DidVisibilityChange(this, visible_); animation_registrar_->set_supports_scroll_animations( @@ -674,6 +675,7 @@ if (root_surface_has_contributing_layers && root_surface_has_no_visible_damage && active_tree_->LayersWithCopyOutputRequest().empty() && + !output_surface_->capabilities().can_force_reclaim_resources && !hud_wants_to_draw_) { TRACE_EVENT0("cc", "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); @@ -813,6 +815,18 @@ *it, occlusion_tracker, &append_quads_data); + + // For layers that represent themselves, add composite frame timing + // requests if the visible rect intersects the requested rect. + for (const auto& request : it->frame_timing_requests()) { + const gfx::Rect& request_content_rect = + it->LayerRectToContentRect(request.rect()); + if (request_content_rect.Intersects(it->visible_content_rect())) { + frame->composite_events.push_back( + FrameTimingTracker::FrameAndRectIds( + active_tree_->source_frame_number(), request.id())); + } + } } ++layers_drawn; @@ -1438,6 +1452,11 @@ TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); DCHECK(CanDraw()); + if (!frame->composite_events.empty()) { + frame_timing_tracker_->SaveTimeStamps(frame_begin_time, + frame->composite_events); + } + if (frame->has_no_damage) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); DCHECK(!output_surface_->capabilities() @@ -1959,7 +1978,8 @@ ContextProvider* context_provider = output_surface_->context_provider(); if (use_gpu_rasterization_ && context_provider) { return GpuRasterizer::Create(context_provider, resource_provider_.get(), - settings_.use_distance_field_text, false, + settings_.use_distance_field_text, + settings_.threaded_gpu_rasterization_enabled, settings_.gpu_rasterization_msaa_sample_count); } return SoftwareRasterizer::Create();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index eb84c54..f9cf55c6 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -18,6 +18,7 @@ #include "cc/animation/scrollbar_animation_controller.h" #include "cc/base/cc_export.h" #include "cc/base/synced_property.h" +#include "cc/debug/frame_timing_tracker.h" #include "cc/debug/micro_benchmark_controller_impl.h" #include "cc/input/input_handler.h" #include "cc/input/layer_scroll_offset_delegate.h" @@ -185,6 +186,7 @@ std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; + std::vector<FrameTimingTracker::FrameAndRectIds> composite_events; RenderPassList render_passes; RenderPassIdHashMap render_passes_by_id; const LayerImplList* render_surface_layer_list; @@ -514,6 +516,10 @@ bool prepare_tiles_needed() const { return tile_priorities_dirty_; } + FrameTimingTracker* frame_timing_tracker() { + return frame_timing_tracker_.get(); + } + protected: LayerTreeHostImpl( const LayerTreeSettings& settings, @@ -732,6 +738,8 @@ bool requires_high_res_to_draw_; bool is_likely_to_require_a_draw_; + scoped_ptr<FrameTimingTracker> frame_timing_tracker_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); };
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index a3c37ed..35828e3f 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2068,7 +2068,7 @@ } void AfterTest() override { - EXPECT_GE(3, num_will_begin_impl_frame_); + EXPECT_GE(num_will_begin_impl_frame_, 3); EXPECT_EQ(2, num_send_begin_main_frame_); } @@ -6120,6 +6120,73 @@ MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestOneActivatePerPrepareTiles); +class LayerTreeHostTestFrameTimingRequestsSaveTimestamps + : public LayerTreeHostTest { + public: + LayerTreeHostTestFrameTimingRequestsSaveTimestamps() + : check_results_on_commit_(false) {} + + void SetupTree() override { + scoped_refptr<FakePictureLayer> root_layer = + FakePictureLayer::Create(&client_); + root_layer->SetBounds(gfx::Size(200, 200)); + root_layer->SetIsDrawable(true); + + scoped_refptr<FakePictureLayer> child_layer = + FakePictureLayer::Create(&client_); + child_layer->SetBounds(gfx::Size(1500, 1500)); + child_layer->SetIsDrawable(true); + + std::vector<FrameTimingRequest> requests; + requests.push_back(FrameTimingRequest(1, gfx::Rect(0, 0, 100, 100))); + requests.push_back(FrameTimingRequest(2, gfx::Rect(300, 0, 100, 100))); + child_layer->SetFrameTimingRequests(requests); + + root_layer->AddChild(child_layer); + layer_tree_host()->SetRootLayer(root_layer); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { + if (!check_results_on_commit_) + return; + + // Since in reality, the events will be read by LayerTreeHost during commit, + // we check the requests here to ensure that they are correct at the next + // commit time (as opposed to checking in DrawLayers for instance). + // TODO(vmpstr): Change this to read things from the main thread when this + // information is propagated to the main thread (not yet implemented). + FrameTimingTracker* tracker = host_impl->frame_timing_tracker(); + scoped_ptr<FrameTimingTracker::CompositeTimingSet> timing_set = + tracker->GroupCountsByRectId(); + EXPECT_EQ(1u, timing_set->size()); + auto rect_1_it = timing_set->find(1); + EXPECT_TRUE(rect_1_it != timing_set->end()); + const auto& timing_events = rect_1_it->second; + EXPECT_EQ(1u, timing_events.size()); + EXPECT_EQ(host_impl->active_tree()->source_frame_number(), + timing_events[0].frame_id); + EXPECT_GT(timing_events[0].timestamp, base::TimeTicks()); + + EndTest(); + } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + check_results_on_commit_ = true; + PostSetNeedsCommitToMainThread(); + } + + void AfterTest() override {} + + private: + FakeContentLayerClient client_; + bool check_results_on_commit_; +}; + +MULTI_THREAD_IMPL_TEST_F(LayerTreeHostTestFrameTimingRequestsSaveTimestamps); + class LayerTreeHostTestActivationCausesPrepareTiles : public LayerTreeHostTest { public: LayerTreeHostTestActivationCausesPrepareTiles()
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index bbdfe6b..e36f6a0 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1096,13 +1096,21 @@ host_impl->BlockNotifyReadyToActivateForTesting(false); } + void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + if (!host_impl->settings().impl_side_painting) + return; + if (host_impl->pending_tree()->source_frame_number() != 1) + return; + LayerImpl* scroll_layer_impl = + host_impl->pending_tree()->root_layer()->children()[0]; + EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); + } + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->active_tree()->source_frame_number() != 1) + return; LayerImpl* scroll_layer_impl = host_impl->active_tree()->root_layer()->children()[0]; - if (scroll_layer_impl->layer_animation_controller()->GetAnimation( - Animation::ScrollOffset)) - return; - EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); EndTest(); }
diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc index 75eda92..260bfbe 100644 --- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc +++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
@@ -54,7 +54,7 @@ ~LayerTreeHostNoMessageLoopTest() override {} // LayerTreeHostClient overrides. - void WillBeginMainFrame(int frame_id) override {} + void WillBeginMainFrame() override {} void BeginMainFrame(const BeginFrameArgs& args) override {} void DidBeginMainFrame() override {} void Layout() override {}
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index d578daf7..07dfc29d 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc
@@ -30,6 +30,7 @@ gpu_rasterization_enabled(false), gpu_rasterization_forced(false), gpu_rasterization_msaa_sample_count(0), + threaded_gpu_rasterization_enabled(false), create_low_res_tiling(false), scrollbar_animator(NoAnimator), scrollbar_fade_delay_ms(0),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 597a2797..5eacdf8 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -36,6 +36,7 @@ bool gpu_rasterization_enabled; bool gpu_rasterization_forced; int gpu_rasterization_msaa_sample_count; + bool threaded_gpu_rasterization_enabled; bool create_low_res_tiling; enum ScrollbarAnimator {
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index dc58d39a..f913c1f 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -7,6 +7,7 @@ #include "base/auto_reset.h" #include "base/trace_event/trace_event.h" #include "cc/debug/benchmark_instrumentation.h" +#include "cc/debug/devtools_instrumentation.h" #include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/quads/draw_quad.h" @@ -204,6 +205,8 @@ commit_requested_ = false; layer_tree_host_->WillCommit(); + devtools_instrumentation::ScopedCommitTrace commit_task( + layer_tree_host_->id()); // Commit immediately. {
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 88f1314..5ee43aba 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc
@@ -796,6 +796,8 @@ bool updated = layer_tree_host()->UpdateLayers(queue.get()); layer_tree_host()->WillCommit(); + devtools_instrumentation::ScopedCommitTrace commit_task( + layer_tree_host()->id()); // Before calling animate, we set main().animate_requested to false. If it is // true now, it means SetNeedAnimate was called again, but during a state when
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 65106a2..6deb300 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -45,6 +45,10 @@ "app/chrome_crash_reporter_client.h", "app/chrome_exe.rc", "app/chrome_exe_main_win.cc", + "app/chrome_watcher_client_win.cc", + "app/chrome_watcher_client_win.h", + "app/chrome_watcher_command_line_win.cc", + "app/chrome_watcher_command_line_win.h", "app/client_util.cc", "app/client_util.h", "app/chrome_watcher_command_line_win.cc", @@ -150,10 +154,8 @@ # TODO(GYP) some stuff from GYP including chrome_multiple_dll. } - if (!is_mac) { - # On Mac this is done in chrome_dll.gypi. - datadeps += [ "//pdf" ] - # TODO(GYP) pdf linux symbols + if (enable_plugins) { + deps += [ "//pdf" ] } } } # !is_android @@ -237,6 +239,10 @@ #}], # TODO(GYP) Lots of other stuff in the OS=="mac" block. } + + if (enable_plugins) { + deps += [ "//pdf" ] + } } } @@ -268,6 +274,7 @@ if (!is_ios) { deps += [ "//chrome/browser/devtools", + "//chrome/child", "//chrome/plugin", "//chrome/renderer", "//chrome/utility", @@ -685,6 +692,7 @@ deps = [ "//chrome/browser", "//chrome/browser/ui", + "//chrome/child", "//chrome/plugin", "//chrome/renderer", "//chrome/utility",
diff --git a/chrome/DEPS b/chrome/DEPS index 9c95992..e014b07f 100644 --- a/chrome/DEPS +++ b/chrome/DEPS
@@ -2,6 +2,7 @@ "+crypto", "+gpu", "+net", + "+pdf", "+printing", "+sql", # Browser, renderer, common and tests access V8 for various purposes.
diff --git a/chrome/VERSION b/chrome/VERSION index 1c3b91a..fdcf034 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=42 MINOR=0 -BUILD=2294 +BUILD=2296 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index f171e3c..2e86b19 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -114,7 +114,6 @@ } # GYP: //chrome/chrome_browser.gypi:activity_type_ids_java -# GYP: //chrome/chrome_browser.gypi:add_web_contents_result_java # GYP: //chrome/chrome_browser.gypi:profile_account_management_metrics_java # GYP: //chrome/chrome_browser.gypi:profile_sync_service_model_type_selection_java # GYP: //chrome/chrome_browser.gypi:tab_load_status_java @@ -122,7 +121,6 @@ java_cpp_enum("chrome_android_java_enums_srcjar") { sources = [ "//chrome/browser/android/activity_type_ids.h", - "//chrome/browser/android/chrome_web_contents_delegate_android.h", "//chrome/browser/android/tab_android.h", "//chrome/browser/profiles/profile_metrics.h", "//chrome/browser/sync/profile_sync_service_android.cc", @@ -130,7 +128,6 @@ ] outputs = [ "org/chromium/chrome/browser/ActivityTypeIds.java", - "org/chromium/chrome/browser/AddWebContentsResult.java", "org/chromium/chrome/browser/TabLoadStatus.java", "org/chromium/chrome/browser/profiles/ProfileAccountManagementMetrics.java", "org/chromium/chrome/browser/sync/ModelTypeSelection.java",
diff --git a/chrome/android/java/res/drawable-hdpi/btn_toolbar_stop.png b/chrome/android/java/res/drawable-hdpi/btn_toolbar_stop.png deleted file mode 100644 index 315727c..0000000 --- a/chrome/android/java/res/drawable-hdpi/btn_toolbar_stop.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/cvc_icon.png b/chrome/android/java/res/drawable-hdpi/cvc_icon.png new file mode 100644 index 0000000..31c60334 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/cvc_icon.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/cvc_icon_amex.png b/chrome/android/java/res/drawable-hdpi/cvc_icon_amex.png new file mode 100644 index 0000000..31c60334 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/cvc_icon_amex.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_toolbar_stop.png b/chrome/android/java/res/drawable-mdpi/btn_toolbar_stop.png deleted file mode 100644 index 6e95c99..0000000 --- a/chrome/android/java/res/drawable-mdpi/btn_toolbar_stop.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/cvc_icon.png b/chrome/android/java/res/drawable-mdpi/cvc_icon.png new file mode 100644 index 0000000..8a733dd --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/cvc_icon.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/cvc_icon_amex.png b/chrome/android/java/res/drawable-mdpi/cvc_icon_amex.png new file mode 100644 index 0000000..8a733dd --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/cvc_icon_amex.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_toolbar_stop.png b/chrome/android/java/res/drawable-xhdpi/btn_toolbar_stop.png deleted file mode 100644 index 4c8d6ea..0000000 --- a/chrome/android/java/res/drawable-xhdpi/btn_toolbar_stop.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/cvc_icon.png b/chrome/android/java/res/drawable-xhdpi/cvc_icon.png new file mode 100644 index 0000000..49ac310a --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/cvc_icon.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/cvc_icon_amex.png b/chrome/android/java/res/drawable-xhdpi/cvc_icon_amex.png new file mode 100644 index 0000000..49ac310a --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/cvc_icon_amex.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_toolbar_stop.png b/chrome/android/java/res/drawable-xxhdpi/btn_toolbar_stop.png deleted file mode 100644 index 958a384..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/btn_toolbar_stop.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/cvc_icon.png b/chrome/android/java/res/drawable-xxhdpi/cvc_icon.png new file mode 100644 index 0000000..c8cf4f2 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/cvc_icon.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/cvc_icon_amex.png b/chrome/android/java/res/drawable-xxhdpi/cvc_icon_amex.png new file mode 100644 index 0000000..c8cf4f2 --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/cvc_icon_amex.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_toolbar_stop.png b/chrome/android/java/res/drawable-xxxhdpi/btn_toolbar_stop.png deleted file mode 100644 index d14521b0..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/btn_toolbar_stop.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/cvc_icon.png b/chrome/android/java/res/drawable-xxxhdpi/cvc_icon.png new file mode 100644 index 0000000..f41859d --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/cvc_icon.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/cvc_icon_amex.png b/chrome/android/java/res/drawable-xxxhdpi/cvc_icon_amex.png new file mode 100644 index 0000000..f41859d --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/cvc_icon_amex.png Binary files differ
diff --git a/ui/android/java/res/layout/autofill_card_unmask_prompt.xml b/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml similarity index 89% rename from ui/android/java/res/layout/autofill_card_unmask_prompt.xml rename to chrome/android/java/res/layout/autofill_card_unmask_prompt.xml index 360e216..2ab4a361 100644 --- a/ui/android/java/res/layout/autofill_card_unmask_prompt.xml +++ b/chrome/android/java/res/layout/autofill_card_unmask_prompt.xml
@@ -47,10 +47,17 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" android:ems="4" android:hint="@string/card_unmask_input_hint" /> + <ImageView + android:id="@+id/cvc_hint_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginStart="8dp" + android:layout_marginEnd="16dp" /> + <ProgressBar style="@android:style/Widget.ProgressBar.Small" android:id="@+id/verification_progress_bar"
diff --git a/chrome/android/java/res/layout/autofill_credit_card_editor.xml b/chrome/android/java/res/layout/autofill_credit_card_editor.xml index c1153fb..2211041 100644 --- a/chrome/android/java/res/layout/autofill_credit_card_editor.xml +++ b/chrome/android/java/res/layout/autofill_credit_card_editor.xml
@@ -52,6 +52,7 @@ <TextView android:layout_width="match_parent" android:layout_height="wrap_content" + android:focusable="true" android:paddingTop="10dp" android:textAppearance="@style/PreferenceFloatLabelTextAppearance" android:text="@string/autofill_credit_card_editor_expiration_date" /> @@ -66,16 +67,14 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:paddingTop="8dp" - android:contentDescription="@string/accessibility_autofill_cc_month" /> + android:paddingTop="8dp" /> <Spinner android:id="@+id/autofill_credit_card_editor_year_spinner" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:paddingTop="8dp" - android:contentDescription="@string/accessibility_autofill_cc_year" /> + android:paddingTop="8dp" /> </LinearLayout> </LinearLayout>
diff --git a/chrome/android/java/res/layout/autofill_profile_editor.xml b/chrome/android/java/res/layout/autofill_profile_editor.xml index 75a750c..6f06d18 100644 --- a/chrome/android/java/res/layout/autofill_profile_editor.xml +++ b/chrome/android/java/res/layout/autofill_profile_editor.xml
@@ -25,13 +25,13 @@ <TextView android:layout_width="match_parent" android:layout_height="wrap_content" + android:focusable="true" android:textAppearance="@style/PreferenceFloatLabelTextAppearance" android:text="@string/autofill_profile_editor_country" /> <Spinner android:id="@+id/countries" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:contentDescription="@string/autofill_profile_editor_country" /> + android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/autofill_profile_widget_root"
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 76bf0ea08..cd157eb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java
@@ -28,9 +28,9 @@ } @CalledByNative - public int addNewContents(WebContents sourceWebContents, WebContents webContents, + public boolean addNewContents(WebContents sourceWebContents, WebContents webContents, int disposition, Rect initialPosition, boolean userGesture) { - return AddWebContentsResult.STOP_LOAD_AND_DELETE; + return false; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java index a7b4eb36..9652a85 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java
@@ -9,8 +9,8 @@ import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; -import org.chromium.ui.autofill.CardUnmaskPrompt; -import org.chromium.ui.autofill.CardUnmaskPrompt.CardUnmaskPromptDelegate; +import org.chromium.chrome.browser.ResourceId; +import org.chromium.chrome.browser.autofill.CardUnmaskPrompt.CardUnmaskPromptDelegate; import org.chromium.ui.base.WindowAndroid; /** @@ -22,7 +22,8 @@ private final CardUnmaskPrompt mCardUnmaskPrompt; public CardUnmaskBridge(long nativeCardUnmaskPromptViewAndroid, String title, - String instructions, boolean shouldRequestExpirationDate, WindowAndroid windowAndroid) { + String instructions, int iconId, boolean shouldRequestExpirationDate, + WindowAndroid windowAndroid) { mNativeCardUnmaskPromptViewAndroid = nativeCardUnmaskPromptViewAndroid; Activity activity = windowAndroid.getActivity().get(); if (activity == null) { @@ -36,15 +37,16 @@ } }); } else { - mCardUnmaskPrompt = new CardUnmaskPrompt( - activity, this, title, instructions, shouldRequestExpirationDate); + mCardUnmaskPrompt = new CardUnmaskPrompt(activity, this, title, instructions, + ResourceId.mapToDrawableId(iconId), shouldRequestExpirationDate); } } @CalledByNative private static CardUnmaskBridge create(long nativeUnmaskPrompt, String title, - String instructions, boolean shouldRequestExpirationDate, WindowAndroid windowAndroid) { - return new CardUnmaskBridge(nativeUnmaskPrompt, title, instructions, + String instructions, int iconId, boolean shouldRequestExpirationDate, + WindowAndroid windowAndroid) { + return new CardUnmaskBridge(nativeUnmaskPrompt, title, instructions, iconId, shouldRequestExpirationDate, windowAndroid); }
diff --git a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java similarity index 95% rename from ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java rename to chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index e9c0a0d9..76349d6 100644 --- a/ui/android/java/src/org/chromium/ui/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.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.ui.autofill; +package org.chromium.chrome.browser.autofill; import android.app.AlertDialog; import android.content.Context; @@ -16,11 +16,12 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; +import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Spinner; import android.widget.TextView; -import org.chromium.ui.R; +import org.chromium.chrome.R; import java.text.NumberFormat; import java.util.Calendar; @@ -62,7 +63,7 @@ } public CardUnmaskPrompt(Context context, CardUnmaskPromptDelegate delegate, String title, - String instructions, boolean shouldRequestExpirationDate) { + String instructions, int drawableId, boolean shouldRequestExpirationDate) { mDelegate = delegate; LayoutInflater inflater = LayoutInflater.from(context); @@ -74,6 +75,7 @@ mYearSpinner = (Spinner) v.findViewById(R.id.expiration_year); mVerificationProgressBar = (ProgressBar) v.findViewById(R.id.verification_progress_bar); mVerificationView = (TextView) v.findViewById(R.id.verification_message); + ((ImageView) v.findViewById(R.id.cvc_hint_image)).setImageResource(drawableId); mDialog = new AlertDialog.Builder(context) .setTitle(title) @@ -207,7 +209,7 @@ private boolean areInputsValid() { if (mShouldRequestExpirationDate && (mMonthSpinner.getSelectedItemPosition() == 0 - || mYearSpinner.getSelectedItemPosition() == 0)) { + || mYearSpinner.getSelectedItemPosition() == 0)) { return false; } return mDelegate.checkUserInputValidity(mCardUnmaskInput.getText().toString());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/PendingDocumentData.java b/chrome/android/java/src/org/chromium/chrome/browser/document/PendingDocumentData.java index 8fac76b..62711bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/PendingDocumentData.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/PendingDocumentData.java
@@ -29,9 +29,6 @@ /** HTTP "referer". */ public Referrer referrer; - /** The original intent. */ + /** The original intent */ public Intent originalIntent; - - /** Whether there was a user gesture during the navigation. */ - public boolean userGesture; } \ No newline at end of file
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 new file mode 100644 index 0000000..f66455b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBar.java
@@ -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. + +package org.chromium.chrome.browser.infobar; + +import android.graphics.Bitmap; +import android.widget.TextView; + +/** + * Infobar informing the user about an app related to this page. + */ +public class AppBannerInfoBar extends ConfirmInfoBar { + /** Web app: URL pointing to the web app. */ + private final String mAppUrl; + + public AppBannerInfoBar(long nativeInfoBar, String appTitle, Bitmap iconBitmap, + String installText, String url) { + super(nativeInfoBar, null, 0, iconBitmap, appTitle, null, installText, null); + mAppUrl = url; + } + + @Override + public void createContent(InfoBarLayout layout) { + TextView url = new TextView(layout.getContext()); + url.setText(mAppUrl); + layout.setCustomContent(url); + super.createContent(layout); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java new file mode 100644 index 0000000..9573af6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java
@@ -0,0 +1,28 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.infobar; + +import android.graphics.Bitmap; + +import org.chromium.base.CalledByNative; + +/** + * Handles creation of AppBannerInfoBars. + */ +public class AppBannerInfoBarDelegate { + private AppBannerInfoBarDelegate() { + } + + @CalledByNative + private static AppBannerInfoBarDelegate create() { + return new AppBannerInfoBarDelegate(); + } + + @CalledByNative + private InfoBar showInfoBar( + long nativeInfoBar, String appTitle, Bitmap iconBitmap, String buttonText, String url) { + return new AppBannerInfoBar(nativeInfoBar, appTitle, iconBitmap, buttonText, url); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java index 5191847..c6d17f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java
@@ -60,6 +60,8 @@ } } + private String mCurrentBestLanguageCode; + /** * @return The CLDR region code for the default locale. */ @@ -97,21 +99,30 @@ } /** - * Returns the UI components for the CLDR countryCode provided. + * Returns the UI components for the CLDR countryCode and languageCode provided. If no language + * code is provided, the application's default locale is used instead. Also stores the + * currentBestLanguageCode, retrievable via getCurrentBestLanguageCode, to be used when saving + * an autofill profile. * * @param countryCode The CLDR code used to retrieve address components. + * @param languageCode The language code associated with the saved autofill profile that ui + * components are being retrieved for; can be null if ui components are + * being retrieved for a new profile. * @return A list containing pairs where the first element in the pair is an Integer * representing the component id (one of the constants in AddressField), and the second * element in the pair is the localized component name (intended for use as labels in * the UI). The ordering in the list of pairs specifies the order these components * should appear in the UI. */ - static List<Pair<Integer, String>> getAddressUiComponents(String countryCode) { + List<Pair<Integer, String>> getAddressUiComponents(String countryCode, + String languageCode) { List<Integer> componentIds = new ArrayList<Integer>(); List<String> componentNames = new ArrayList<String>(); List<Pair<Integer, String>> uiComponents = new ArrayList<Pair<Integer, String>>(); - nativeGetAddressUiComponents(countryCode, componentIds, componentNames); + mCurrentBestLanguageCode = + nativeGetAddressUiComponents(countryCode, languageCode, componentIds, + componentNames); for (int i = 0; i < componentIds.size(); i++) { uiComponents.add(new Pair<Integer, String>(componentIds.get(i), componentNames.get(i))); @@ -120,6 +131,14 @@ return uiComponents; } + /** + * @return The language code associated with the most recently retrieved address ui components. + * Will return null if getAddressUiComponents() has not been called yet. + */ + String getCurrentBestLanguageCode() { + return mCurrentBestLanguageCode; + } + @CalledByNative private static void stringArrayToList(String[] array, List<String> list) { for (String s : array) { @@ -137,6 +156,6 @@ private static native String nativeGetDefaultCountryCode(); private static native void nativeGetSupportedCountries(List<String> countryCodes, List<String> countryNames); - private static native void nativeGetAddressUiComponents(String countryCode, - List<Integer> componentIds, List<String> componentNames); + private static native String nativeGetAddressUiComponents(String countryCode, + String languageCode, List<Integer> componentIds, List<String> componentNames); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java index 1e3e9316..aeda56e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
@@ -51,6 +51,8 @@ private Spinner mCountriesSpinner; private ViewGroup mWidgetRoot; private FloatLabelLayout[] mAddressFields; + private AutofillProfileBridge mAutofillProfileBridge; + private boolean mUseSavedProfileLanguage; @Override public void onCreate(Bundle savedState) { @@ -86,6 +88,8 @@ mWidgetRoot = (ViewGroup) v.findViewById(R.id.autofill_profile_widget_root); mCountriesSpinner = (Spinner) v.findViewById(R.id.countries); + mAutofillProfileBridge = new AutofillProfileBridge(); + populateCountriesSpinner(); createAndPopulateEditFields(); hookupSaveCancelDeleteButtons(v); @@ -123,6 +127,7 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (position != mCurrentCountryPos) { mCurrentCountryPos = position; + mUseSavedProfileLanguage = false; // If all fields are empty (e.g. the user just entered the form and the first thing // they did was select a country), focus on the first form element. Otherwise, don't. resetFormFields(position, allFieldsEmpty()); @@ -161,6 +166,7 @@ } mLanguageCodeString = profile.getLanguageCode(); + mUseSavedProfileLanguage = true; mCurrentCountryPos = mCountryCodes.indexOf(profile.getCountryCode()); if (mCurrentCountryPos == -1) { @@ -213,8 +219,12 @@ mWidgetRoot.removeAllViews(); // Get address fields for the selected country. - List<Pair<Integer, String>> fields = AutofillProfileBridge.getAddressUiComponents( - mCountryCodes.get(countryCodeIndex)); + List<Pair<Integer, String>> fields = mAutofillProfileBridge.getAddressUiComponents( + mCountryCodes.get(countryCodeIndex), + mLanguageCodeString); + if (!mUseSavedProfileLanguage) { + mLanguageCodeString = mAutofillProfileBridge.getCurrentBestLanguageCode(); + } // Create form fields and focus the first field if autoFocusFirstField is true. boolean firstField = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index efbdb22c..82de70c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -46,7 +46,7 @@ import org.chromium.chrome.browser.sync.GoogleServiceAuthError; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener; -import org.chromium.sync.notifier.SyncStatusHelper; +import org.chromium.sync.AndroidSyncSettings; import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.sync.signin.ChromeSigninController; @@ -388,7 +388,7 @@ ProfileAccountManagementMetrics.CLICK_PRIMARY_ACCOUNT, mGaiaServiceType); - if (SyncStatusHelper.get(activity).isMasterSyncAutomaticallyEnabled()) { + if (AndroidSyncSettings.get(activity).isMasterSyncEnabled()) { getDelegate().openSyncCustomizationFragment(activity, account); } else { Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); @@ -470,7 +470,7 @@ ChromeSigninController signinController = ChromeSigninController.get(activity); if (!signinController.isSignedIn()) return ""; - SyncStatusHelper syncStatusHelper = SyncStatusHelper.get(activity); + AndroidSyncSettings androidSyncSettings = AndroidSyncSettings.get(activity); ProfileSyncService profileSyncService = ProfileSyncService.get(activity); Resources res = activity.getResources(); @@ -478,7 +478,7 @@ return res.getString(R.string.kids_account); } - if (!syncStatusHelper.isMasterSyncAutomaticallyEnabled()) { + if (!androidSyncSettings.isMasterSyncEnabled()) { return res.getString(R.string.sync_android_master_sync_disabled); } @@ -486,7 +486,7 @@ return res.getString(profileSyncService.getAuthError().getMessage()); } - if (syncStatusHelper.isSyncEnabled()) { + if (androidSyncSettings.isSyncEnabled()) { if (!profileSyncService.isSyncInitialized()) { return res.getString(R.string.sync_setup_progress); } @@ -504,7 +504,7 @@ } } - return syncStatusHelper.isSyncEnabled(signinController.getSignedInUser()) + return androidSyncSettings.isSyncEnabled(signinController.getSignedInUser()) ? res.getString(R.string.sync_is_enabled) : res.getString(R.string.sync_is_disabled); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java index 7181960a..472d592 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncNotificationController.java
@@ -18,7 +18,6 @@ import org.chromium.chrome.browser.notifications.NotificationConstants; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.sync.AndroidSyncSettings; -import org.chromium.sync.notifier.SyncStatusHelper; /** * {@link SyncNotificationController} provides functionality for displaying Android notifications @@ -45,22 +44,6 @@ mAccountManagementFragment = accountManagementFragment; } - /** - * Deprecated for having unnecessary args; use the first constructor. - */ - @Deprecated - public SyncNotificationController(Context context, - GoogleServicesNotificationController controller, ProfileSyncService profileSyncService, - SyncStatusHelper syncStatusHelper, Class<? extends Activity> passphraseRequestActivity, - Class<? extends Fragment> accountManagementFragment) { - mApplicationContext = context.getApplicationContext(); - mNotificationController = controller; - mProfileSyncService = profileSyncService; - mAndroidSyncSettings = AndroidSyncSettings.get(context); - mPassphraseRequestActivity = passphraseRequestActivity; - mAccountManagementFragment = accountManagementFragment; - } - public void displayAndroidMasterSyncDisabledNotification() { String masterSyncDisabled = GoogleServicesNotificationController.formatMessageParts(mApplicationContext,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabList.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabList.java index b4f32e0..106f7e2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabList.java
@@ -11,6 +11,7 @@ * well as a currently selected tab (see {@link #index}). */ public interface TabList { + // Keep this in sync with chrome/browser/ui/android/tab_model/tab_model.cc public static final int INVALID_TAB_INDEX = -1; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/FloatLabelLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/FloatLabelLayout.java index 33eafd0..f182417c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/FloatLabelLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/FloatLabelLayout.java
@@ -96,6 +96,7 @@ mLabel.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); mLabel.setVisibility(INVISIBLE); mLabel.setText(mHint); + mLabel.setFocusable(true); ViewCompat.setPivotX(mLabel, 0f); ViewCompat.setPivotY(mLabel, 0f);
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 19f8bf3..117bc2d 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -167,12 +167,6 @@ <message name="IDS_ACCESSIBILITY_AUTOFILL_CC_NUMBER_TEXTBOX" desc="Content description for text input field containing a credit card number."> Card number </message> - <message name="IDS_ACCESSIBILITY_AUTOFILL_CC_MONTH" desc="Content description for text input field containing a credit card expiration month."> - Card expiration month - </message> - <message name="IDS_ACCESSIBILITY_AUTOFILL_CC_YEAR" desc="Content description for text input field containing a credit card expiration year."> - Card expiration year - </message> <!-- Autofill/Wallet integration preferences --> <message name="IDS_AUTOFILL_WALLET_TITLE" desc="Title for Autofill Wallet settings, which controls import of Wallet cards.">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java index de5c5f4..73cf1a5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/RepostFormWarningTest.java
@@ -8,6 +8,7 @@ import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.shell.ChromeShellTab; import org.chromium.chrome.shell.ChromeShellTestBase; @@ -51,8 +52,12 @@ } /** Verifies that confirming the form reload performs the reload. */ + /* @MediumTest @Feature({"Navigation"}) + crbug.com/454834 + */ + @DisabledTest public void testFormResubmissionContinue() throws Throwable { // Load the url posting data for the first time. postNavigation(); @@ -78,8 +83,12 @@ * after the "Cancel" button is clicked to verify that the load was not triggered, which blocks * for CallbackHelper's default timeout upon each execution. */ + /* @SmallTest @Feature({"Navigation"}) + crbug.com/454834 + */ + @DisabledTest public void testFormResubmissionCancel() throws Throwable { // Load the url posting data for the first time. postNavigation();
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java index 6d23697..35b8e4f 100644 --- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java +++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java
@@ -50,7 +50,7 @@ mProgressDrawable.setLevel(100 * mProgress); if (mLoading) { mStopReloadButton.setImageResource( - R.drawable.btn_toolbar_stop); + R.drawable.btn_close); } else { mStopReloadButton.setImageResource(R.drawable.btn_toolbar_reload); ApiCompatibilityUtils.postOnAnimationDelayed(ChromeShellToolbar.this,
diff --git a/chrome/android/shell/res/layout/chrome_shell_activity.xml b/chrome/android/shell/res/layout/chrome_shell_activity.xml index fb0ef50..c6050111 100644 --- a/chrome/android/shell/res/layout/chrome_shell_activity.xml +++ b/chrome/android/shell/res/layout/chrome_shell_activity.xml
@@ -27,7 +27,7 @@ android:id="@+id/stop_reload_button" android:layout_width="38dp" android:layout_height="38dp" - android:src="@drawable/btn_toolbar_stop" + android:src="@drawable/btn_close" android:background="?attr/selectableItemBackground" android:scaleType="center"/> <EditText android:id="@+id/url"
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 1d397e01..0c93b0d 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -304,6 +304,7 @@ deps = [ "//base", "//chrome/browser", + "//chrome/child", "//chrome/common", "//chrome/plugin", "//chrome/renderer",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index c137446..08a8ab3 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+breakpad", "+chrome/browser", + "+chrome/child", "+chrome/chrome_watcher", "+chrome/installer", "+chrome/plugin/chrome_content_plugin_client.h",
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index e62085d..7a84022 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -119,12 +119,14 @@ #include "remoting/client/plugin/pepper_entrypoints.h" #endif -#if !defined(CHROME_MULTIPLE_DLL_CHILD) -base::LazyInstance<chrome::ChromeContentBrowserClient> - g_chrome_content_browser_client = LAZY_INSTANCE_INITIALIZER; +#if defined(ENABLE_PLUGINS) && (defined(CHROME_MULTIPLE_DLL_CHILD) || \ + !defined(CHROME_MULTIPLE_DLL_BROWSER)) +#include "pdf/pdf.h" #endif #if !defined(CHROME_MULTIPLE_DLL_BROWSER) +#include "chrome/child/pdf_child_init.h" + base::LazyInstance<ChromeContentRendererClient> g_chrome_content_renderer_client = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<ChromeContentUtilityClient> @@ -133,6 +135,11 @@ g_chrome_content_plugin_client = LAZY_INSTANCE_INITIALIZER; #endif +#if !defined(CHROME_MULTIPLE_DLL_CHILD) +base::LazyInstance<chrome::ChromeContentBrowserClient> + g_chrome_content_browser_client = LAZY_INSTANCE_INITIALIZER; +#endif + #if defined(OS_POSIX) base::LazyInstance<chrome::ChromeCrashReporterClient>::Leaky g_chrome_crash_client = LAZY_INSTANCE_INITIALIZER; @@ -775,6 +782,8 @@ process_type == switches::kZygoteProcess) { ChromeContentUtilityClient::PreSandboxStartup(); } + + chrome::InitializePDF(); #endif } @@ -822,6 +831,12 @@ nacl_plugin::PPP_InitializeModule, nacl_plugin::PPP_ShutdownModule); #endif +#if defined(ENABLE_PLUGINS) + ChromeContentClient::SetPDFEntryFunctions( + chrome_pdf::PPP_GetInterface, + chrome_pdf::PPP_InitializeModule, + chrome_pdf::PPP_ShutdownModule); +#endif #endif }
diff --git a/chrome/app/chrome_watcher_client_unittest_win.cc b/chrome/app/chrome_watcher_client_unittest_win.cc new file mode 100644 index 0000000..5b916138 --- /dev/null +++ b/chrome/app/chrome_watcher_client_unittest_win.cc
@@ -0,0 +1,270 @@ +// 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/app/chrome_watcher_client_win.h" + +#include <windows.h> +#include <string> +#include "base/base_switches.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/process/process_handle.h" +#include "base/strings/string16.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/multiprocess_test.h" +#include "base/threading/simple_thread.h" +#include "base/time/time.h" +#include "base/win/scoped_handle.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/multiprocess_func_list.h" + +namespace { + +const char kParentHandle[] = "parent-handle"; +const char kEventHandle[] = "event-handle"; +const char kNamedEventSuffix[] = "named-event-suffix"; + +const base::char16 kExitEventBaseName[] = L"ChromeWatcherClientTestExitEvent_"; +const base::char16 kInitializeEventBaseName[] = + L"ChromeWatcherClientTestInitializeEvent_"; + +base::win::ScopedHandle InterpretHandleSwitch(base::CommandLine& cmd_line, + const char* switch_name) { + std::string str_handle = + cmd_line.GetSwitchValueASCII(switch_name); + if (str_handle.empty()) { + LOG(ERROR) << "Switch " << switch_name << " unexpectedly absent."; + return base::win::ScopedHandle(); + } + + unsigned int_handle = 0; + if (!base::StringToUint(str_handle, &int_handle)) { + LOG(ERROR) << "Switch " << switch_name << " has invalid value " + << str_handle; + return base::win::ScopedHandle(); + } + + return base::win::ScopedHandle( + reinterpret_cast<base::ProcessHandle>(int_handle)); +} + +// Simulates a Chrome watcher process. Exits when the global exit event is +// signaled. Signals the "on initialized" event (passed on the command-line) +// when the global initialization event is signaled. +MULTIPROCESS_TEST_MAIN(ChromeWatcherClientTestProcess) { + base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + + base::string16 named_event_suffix = + base::ASCIIToUTF16(cmd_line->GetSwitchValueASCII(kNamedEventSuffix)); + if (named_event_suffix.empty()) { + LOG(ERROR) << "Switch " << kNamedEventSuffix << " unexpectedly absent."; + return 1; + } + + base::win::ScopedHandle exit_event(::CreateEvent( + NULL, FALSE, FALSE, (kExitEventBaseName + named_event_suffix).c_str())); + if (!exit_event.IsValid()) { + LOG(ERROR) << "Failed to create event named " + << kExitEventBaseName + named_event_suffix; + return 1; + } + + base::win::ScopedHandle initialize_event( + ::CreateEvent(NULL, FALSE, FALSE, + (kInitializeEventBaseName + named_event_suffix).c_str())); + if (!initialize_event.IsValid()) { + LOG(ERROR) << "Failed to create event named " + << kInitializeEventBaseName + named_event_suffix; + return 1; + } + + base::win::ScopedHandle parent_process( + InterpretHandleSwitch(*cmd_line, kParentHandle)); + if (!parent_process.IsValid()) + return 1; + + base::win::ScopedHandle on_initialized_event( + InterpretHandleSwitch(*cmd_line, kEventHandle)); + if (!on_initialized_event.IsValid()) + return 1; + + while (true) { + // We loop as a convenient way to continue waiting for the exit_event after + // the initialize_event is signaled. We expect to get initialize_event zero + // or one times before exit_event, never more. + HANDLE handles[] = {exit_event.Get(), initialize_event.Get()}; + DWORD result = + ::WaitForMultipleObjects(arraysize(handles), handles, FALSE, INFINITE); + switch (result) { + case WAIT_OBJECT_0: + // exit_event + return 0; + case WAIT_OBJECT_0 + 1: + // initialize_event + ::SetEvent(on_initialized_event.Get()); + break; + case WAIT_FAILED: + PLOG(ERROR) << "Unexpected failure in WaitForMultipleObjects."; + return 1; + default: + NOTREACHED() << "Unexpected result from WaitForMultipleObjects: " + << result; + return 1; + } + } +} + +// Implements a thread to launch the ChromeWatcherClient and block on +// EnsureInitialized. Provides various helpers to interact with the +// ChromeWatcherClient. +class ChromeWatcherClientThread : public base::SimpleThread { + public: + ChromeWatcherClientThread() + : client_(base::Bind(&ChromeWatcherClientThread::GenerateCommandLine, + base::Unretained(this))), + complete_(false, false), + result_(false), + SimpleThread("ChromeWatcherClientTest thread") {} + + // Waits up to |timeout| for the call to EnsureInitialized to complete. If it + // does, sets |result| to the return value of EnsureInitialized and returns + // true. Otherwise returns false. + bool WaitForResultWithTimeout(base::TimeDelta timeout, bool* result) { + if (!complete_.TimedWait(timeout)) + return false; + *result = result_; + return true; + } + + // Waits indefinitely for the call to WaitForInitialization to complete. + // Returns the return value of WaitForInitialization. + bool WaitForResult() { + complete_.Wait(); + return result_; + } + + ChromeWatcherClient& client() { return client_; } + + base::string16 NamedEventSuffix() { + return base::UintToString16(base::GetCurrentProcId()); + } + + // base::SimpleThread implementation. + void Run() override { + result_ = client_.LaunchWatcher(); + if (result_) + result_ = client_.EnsureInitialized(); + complete_.Signal(); + } + + private: + // Returns a command line to launch back into ChromeWatcherClientTestProcess. + base::CommandLine GenerateCommandLine(HANDLE parent_handle, + HANDLE on_initialized_event) { + base::CommandLine ret = base::GetMultiProcessTestChildBaseCommandLine(); + ret.AppendSwitchASCII(switches::kTestChildProcess, + "ChromeWatcherClientTestProcess"); + ret.AppendSwitchASCII(kEventHandle, + base::UintToString(reinterpret_cast<unsigned int>( + on_initialized_event))); + ret.AppendSwitchASCII( + kParentHandle, + base::UintToString(reinterpret_cast<unsigned int>(parent_handle))); + ret.AppendSwitchASCII(kNamedEventSuffix, + base::UTF16ToASCII(NamedEventSuffix())); + return ret; + } + + // The instance under test. + ChromeWatcherClient client_; + // Signaled when WaitForInitialization returns. + base::WaitableEvent complete_; + // The return value of WaitForInitialization. + bool result_; + + DISALLOW_COPY_AND_ASSIGN(ChromeWatcherClientThread); +}; + +} // namespace + +class ChromeWatcherClientTest : public testing::Test { + protected: + // Sends a signal to the simulated watcher process to exit. Returns true if + // successful. + bool SignalExit() { return ::SetEvent(exit_event_.Get()) != FALSE; } + + // Sends a signal to the simulated watcher process to signal its + // "initialization". Returns true if successful. + bool SignalInitialize() { + return ::SetEvent(initialize_event_.Get()) != FALSE; + } + + // The helper thread, which also provides access to the ChromeWatcherClient. + ChromeWatcherClientThread& thread() { return thread_; } + + // testing::Test implementation. + void SetUp() override { + exit_event_.Set(::CreateEvent( + NULL, FALSE, FALSE, + (kExitEventBaseName + thread_.NamedEventSuffix()).c_str())); + ASSERT_TRUE(exit_event_.IsValid()); + initialize_event_.Set(::CreateEvent( + NULL, FALSE, FALSE, + (kInitializeEventBaseName + thread_.NamedEventSuffix()).c_str())); + ASSERT_TRUE(initialize_event_.IsValid()); + } + + void TearDown() override { + // Even if we never launched, the following is harmless. + SignalExit(); + int exit_code = 0; + thread_.client().WaitForExit(&exit_code); + thread_.Join(); + } + + private: + // Used to launch and block on the Chrome watcher process in a background + // thread. + ChromeWatcherClientThread thread_; + // Used to signal the Chrome watcher process to exit. + base::win::ScopedHandle exit_event_; + // Used to signal the Chrome watcher process to signal its own + // initialization.. + base::win::ScopedHandle initialize_event_; +}; + +TEST_F(ChromeWatcherClientTest, SuccessTest) { + thread().Start(); + bool result = false; + // Give a broken implementation a chance to exit unexpectedly. + ASSERT_FALSE(thread().WaitForResultWithTimeout( + base::TimeDelta::FromMilliseconds(100), &result)); + ASSERT_TRUE(SignalInitialize()); + ASSERT_TRUE(thread().WaitForResult()); + // The watcher should still be running. Give a broken implementation a chance + // to exit unexpectedly, then signal it to exit. + int exit_code = 0; + ASSERT_FALSE(thread().client().WaitForExitWithTimeout( + base::TimeDelta::FromMilliseconds(100), &exit_code)); + SignalExit(); + ASSERT_TRUE(thread().client().WaitForExit(&exit_code)); + ASSERT_EQ(0, exit_code); +} + +TEST_F(ChromeWatcherClientTest, FailureTest) { + thread().Start(); + bool result = false; + // Give a broken implementation a chance to exit unexpectedly. + ASSERT_FALSE(thread().WaitForResultWithTimeout( + base::TimeDelta::FromMilliseconds(100), &result)); + ASSERT_TRUE(SignalExit()); + ASSERT_FALSE(thread().WaitForResult()); + int exit_code = 0; + ASSERT_TRUE( + thread().client().WaitForExitWithTimeout(base::TimeDelta(), &exit_code)); + ASSERT_EQ(0, exit_code); +}
diff --git a/chrome/app/chrome_watcher_client_win.cc b/chrome/app/chrome_watcher_client_win.cc new file mode 100644 index 0000000..89f0709 --- /dev/null +++ b/chrome/app/chrome_watcher_client_win.cc
@@ -0,0 +1,103 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/app/chrome_watcher_client_win.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "components/browser_watcher/watcher_client_win.h" + +namespace { + +// Because we can only bind parameters from the left, |parent_process| must be +// the last parameter of the method that we bind int a +// BrowserWatcherClient::CommandLineGenerator. The ChromeWatcherClient API is +// more intuitive if the ChromeWatcherClient::CommandLineGenerator takes +// |parent_process| as its second (of three) parameters, so we use this +// intermediate function to swap the order. +base::CommandLine InvokeCommandLineGenerator( + const ChromeWatcherClient::CommandLineGenerator& command_line_generator, + HANDLE on_initialized_event, + HANDLE parent_process) { + return command_line_generator.Run(parent_process, on_initialized_event); +} + +} // namespace + +ChromeWatcherClient::ChromeWatcherClient( + const CommandLineGenerator& command_line_generator) + : command_line_generator_(command_line_generator) { +} + +ChromeWatcherClient::~ChromeWatcherClient() { +} + +bool ChromeWatcherClient::LaunchWatcher() { + // Create an inheritable event that the child process will signal when it has + // completed initialization. + SECURITY_ATTRIBUTES on_initialized_event_attributes = { + sizeof(SECURITY_ATTRIBUTES), // nLength + nullptr, // lpSecurityDescriptor + TRUE // bInheritHandle + }; + on_initialized_event_.Set(::CreateEvent(&on_initialized_event_attributes, + TRUE, // manual reset + FALSE, nullptr)); + if (!on_initialized_event_.IsValid()) { + DPLOG(ERROR) << "Failed to create an event."; + return false; + } + + // Configure the basic WatcherClient, binding in the initialization event + // HANDLE. + browser_watcher::WatcherClient watcher_client( + base::Bind(&InvokeCommandLineGenerator, command_line_generator_, + on_initialized_event_.Get())); + // Indicate that the event HANDLE should be inherited. + watcher_client.AddInheritedHandle(on_initialized_event_.Get()); + // Launch the watcher. + watcher_client.LaunchWatcher(); + // Grab a handle to the watcher so that we may later wait on its + // initialization. + process_ = watcher_client.process().Duplicate(); + if (!process_.IsValid()) + on_initialized_event_.Close(); + return process_.IsValid(); +} + +bool ChromeWatcherClient::EnsureInitialized() { + if (!process_.IsValid()) + return false; + + DCHECK(on_initialized_event_.IsValid()); + + HANDLE handles[] = {on_initialized_event_.Get(), process_.Handle()}; + DWORD result = ::WaitForMultipleObjects(arraysize(handles), handles, + FALSE, INFINITE); + + switch (result) { + case WAIT_OBJECT_0: + return true; + case WAIT_OBJECT_0 + 1: + LOG(ERROR) << "Chrome watcher process failed to launch."; + return false; + case WAIT_FAILED: + DPLOG(ERROR) << "Failure while waiting on Chrome watcher process launch."; + return false; + default: + NOTREACHED() << "Unexpected result while waiting on Chrome watcher " + "process launch: " << result; + return false; + } +} + +bool ChromeWatcherClient::WaitForExit(int* exit_code) { + return process_.IsValid() && process_.WaitForExit(exit_code); +} + +bool ChromeWatcherClient::WaitForExitWithTimeout(base::TimeDelta timeout, + int* exit_code) { + return process_.IsValid() && + process_.WaitForExitWithTimeout(timeout, exit_code); +}
diff --git a/chrome/app/chrome_watcher_client_win.h b/chrome/app/chrome_watcher_client_win.h new file mode 100644 index 0000000..aaa8d140 --- /dev/null +++ b/chrome/app/chrome_watcher_client_win.h
@@ -0,0 +1,62 @@ +// 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_APP_CHROME_WATCHER_CLIENT_WIN_H_ +#define CHROME_APP_CHROME_WATCHER_CLIENT_WIN_H_ + +#include <windows.h> + +#include "base/callback.h" +#include "base/command_line.h" +#include "base/macros.h" +#include "base/process/process.h" +#include "base/time/time.h" +#include "base/win/scoped_handle.h" + +// Launches a Chrome watcher process and permits the client to wait until the +// process is fully initialized. +class ChromeWatcherClient { + public: + // A CommandLineGenerator generates command lines that will launch a separate + // process and pass the supplied HANDLE values to WatcherMain in that process. + // The first HANDLE is the process that the watcher process should watch. The + // second HANDLE is an event that should be signaled when the watcher process + // is fully initialized. The process will be launched such that the HANDLEs + // are inherited by the new process. + typedef base::Callback<base::CommandLine(HANDLE, HANDLE)> + CommandLineGenerator; + + // Constructs an instance that launches its watcher process using the command + // line generated by |command_line_generator|. + explicit ChromeWatcherClient( + const CommandLineGenerator& command_line_generator); + + ~ChromeWatcherClient(); + + // Launches the watcher process such that the child process is able to inherit + // a handle to the current process. Returns true if the process is + // successfully launched. + bool LaunchWatcher(); + + // Blocks until the process, previously launched by LaunchWatcher, is either + // fully initialized or has terminated. Returns true if the process + // successfully initializes. May be called multiple times. + bool EnsureInitialized(); + + // Waits for the process to exit. Returns true on success. It is up to the + // client to somehow signal the process to exit. + bool WaitForExit(int* exit_code); + + // Same as WaitForExit() but only waits for up to |timeout|. + bool WaitForExitWithTimeout(base::TimeDelta timeout, int* exit_code); + + private: + CommandLineGenerator command_line_generator_; + base::win::ScopedHandle on_initialized_event_; + base::Process process_; + + DISALLOW_COPY_AND_ASSIGN(ChromeWatcherClient); +}; + +#endif // CHROME_APP_CHROME_WATCHER_CLIENT_WIN_H_
diff --git a/chrome/app/chrome_watcher_command_line_unittest_win.cc b/chrome/app/chrome_watcher_command_line_unittest_win.cc index 0cf6927..771094f0 100644 --- a/chrome/app/chrome_watcher_command_line_unittest_win.cc +++ b/chrome/app/chrome_watcher_command_line_unittest_win.cc
@@ -4,6 +4,8 @@ #include "chrome/app/chrome_watcher_command_line_win.h" +#include <windows.h> + #include "base/command_line.h" #include "base/files/file_path.h" #include "base/process/process_handle.h" @@ -11,10 +13,19 @@ #include "testing/gtest/include/gtest/gtest.h" TEST(ChromeWatcherCommandLineTest, BasicTest) { + // Ownership of these handles is passed to the ScopedHandles below via + // InterpretChromeWatcherCommandLine(). base::ProcessHandle current = nullptr; ASSERT_TRUE(base::OpenProcessHandle(base::GetCurrentProcId(), ¤t)); - base::CommandLine cmd_line = - GenerateChromeWatcherCommandLine(base::FilePath(L"example.exe"), current); - base::win::ScopedHandle result = InterpretChromeWatcherCommandLine(cmd_line); - ASSERT_EQ(current, result.Get()); + HANDLE event = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); + + base::CommandLine cmd_line = GenerateChromeWatcherCommandLine( + base::FilePath(L"example.exe"), current, event); + + base::win::ScopedHandle current_result; + base::win::ScopedHandle event_result; + ASSERT_TRUE(InterpretChromeWatcherCommandLine(cmd_line, ¤t_result, + &event_result)); + ASSERT_EQ(current, current_result.Get()); + ASSERT_EQ(event, event_result.Get()); }
diff --git a/chrome/app/chrome_watcher_command_line_win.cc b/chrome/app/chrome_watcher_command_line_win.cc index 0093863..1eaf1a66 100644 --- a/chrome/app/chrome_watcher_command_line_win.cc +++ b/chrome/app/chrome_watcher_command_line_win.cc
@@ -14,41 +14,91 @@ #include "chrome/common/chrome_switches.h" namespace { + +const char kOnIninitializedEventHandleSwitch[] = "on-initialized-event-handle"; const char kParentHandleSwitch[] = "parent-handle"; + +void AppendHandleSwitch(const std::string& switch_name, + HANDLE handle, + base::CommandLine* command_line) { + command_line->AppendSwitchASCII( + switch_name, base::UintToString(reinterpret_cast<unsigned int>(handle))); +} + +HANDLE ReadHandleFromSwitch(const base::CommandLine& command_line, + const std::string& switch_name) { + std::string switch_string = command_line.GetSwitchValueASCII(switch_name); + unsigned int switch_uint = 0; + if (switch_string.empty() || + !base::StringToUint(switch_string, &switch_uint)) { + DLOG(ERROR) << "Missing or invalid " << switch_name << " argument."; + return nullptr; + } + return reinterpret_cast<HANDLE>(switch_uint); +} + } // namespace base::CommandLine GenerateChromeWatcherCommandLine( const base::FilePath& chrome_exe, - HANDLE parent_process) { + HANDLE parent_process, + HANDLE on_initialized_event) { base::CommandLine command_line(chrome_exe); command_line.AppendSwitchASCII(switches::kProcessType, "watcher"); - command_line.AppendSwitchASCII( - kParentHandleSwitch, - base::UintToString(reinterpret_cast<unsigned int>(parent_process))); + AppendHandleSwitch(kOnIninitializedEventHandleSwitch, on_initialized_event, + &command_line); + AppendHandleSwitch(kParentHandleSwitch, parent_process, &command_line); return command_line; } -base::win::ScopedHandle InterpretChromeWatcherCommandLine( - const base::CommandLine& command_line) { - std::string parent_handle_str = - command_line.GetSwitchValueASCII(kParentHandleSwitch); - unsigned parent_handle_uint = 0; - if (parent_handle_str.empty() || - !base::StringToUint(parent_handle_str, &parent_handle_uint)) { - LOG(ERROR) << "Missing or invalid " << kParentHandleSwitch << " argument."; - return base::win::ScopedHandle(); +bool InterpretChromeWatcherCommandLine( + const base::CommandLine& command_line, + base::win::ScopedHandle* parent_process, + base::win::ScopedHandle* on_initialized_event) { + DCHECK(on_initialized_event); + DCHECK(parent_process); + + // For consistency, always close any existing HANDLEs here. + on_initialized_event->Close(); + parent_process->Close(); + + HANDLE parent_handle = + ReadHandleFromSwitch(command_line, kParentHandleSwitch); + HANDLE on_initialized_event_handle = + ReadHandleFromSwitch(command_line, kOnIninitializedEventHandleSwitch); + + if (parent_handle) { + // Initial test of the handle, a zero PID indicates invalid handle, or not + // a process handle. In this case, parsing fails and we avoid closing the + // handle. + DWORD process_pid = ::GetProcessId(parent_handle); + if (process_pid == 0) { + DLOG(ERROR) << "Invalid " << kParentHandleSwitch + << " argument. Can't get parent PID."; + } else { + parent_process->Set(parent_handle); + } } - HANDLE parent_process = reinterpret_cast<HANDLE>(parent_handle_uint); - // Initial test of the handle, a zero PID indicates invalid handle, or not - // a process handle. In this case, parsing fails and we avoid closing the - // handle. - DWORD process_pid = ::GetProcessId(parent_process); - if (process_pid == 0) { - LOG(ERROR) << "Invalid " << kParentHandleSwitch - << " argument. Can't get parent PID."; - return base::win::ScopedHandle(); + if (on_initialized_event_handle) { + DWORD result = ::WaitForSingleObject(on_initialized_event_handle, 0); + if (result == WAIT_FAILED) { + DPLOG(ERROR) + << "Unexpected error while testing the initialization event."; + } else if (result != WAIT_TIMEOUT) { + DLOG(ERROR) << "Unexpected result while testing the initialization event " + "with WaitForSingleObject: " << result; + } else { + on_initialized_event->Set(on_initialized_event_handle); + } } - return base::win::ScopedHandle(parent_process); + if (!on_initialized_event->IsValid() || !parent_process->IsValid()) { + // If one was valid and not the other, free the valid one. + on_initialized_event->Close(); + parent_process->Close(); + return false; + } + + return true; }
diff --git a/chrome/app/chrome_watcher_command_line_win.h b/chrome/app/chrome_watcher_command_line_win.h index 30ff988..4b4596a 100644 --- a/chrome/app/chrome_watcher_command_line_win.h +++ b/chrome/app/chrome_watcher_command_line_win.h
@@ -15,15 +15,21 @@ } // namespace base // Generates a CommandLine that will launch |chrome_exe| in Chrome Watcher mode -// to observe |parent_process|. +// to observe |parent_process|. The watcher process will signal +// |on_initialized_event| when its initialization is complete. base::CommandLine GenerateChromeWatcherCommandLine( const base::FilePath& chrome_exe, - HANDLE parent_process); + HANDLE parent_process, + HANDLE on_initialized_event); // Interprets the Command Line used to launch a Chrome Watcher process and -// extracts the parent process HANDLE. Verifies that the handle is usable in -// this process before returning it, and returns NULL in case of a failure. -base::win::ScopedHandle InterpretChromeWatcherCommandLine( - const base::CommandLine& command_line); +// extracts the parent process and initialization event HANDLEs. Verifies that +// the handles are usable in this process before returning them. Returns true if +// both handles are successfully parsed and false otherwise. If only one of the +// handles can be parsed, it will be closed. +bool InterpretChromeWatcherCommandLine( + const base::CommandLine& command_line, + base::win::ScopedHandle* parent_process, + base::win::ScopedHandle* on_initialized_event); #endif // CHROME_APP_CHROME_WATCHER_COMMAND_LINE_WIN_H_
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 9ca874c..a3c1b9bb 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -6035,11 +6035,11 @@ System time </message> - <message name="IDS_FLAGS_ENABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_NAME" desc="Title for the flag to enable/disable user setting to automatically update timezone by user geolocation."> - Automatically resolve timezone by geolocation + <message name="IDS_FLAGS_DISABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_NAME" desc="Title for the flag to disable automatic timezone update on user location change."> + Disable automatic timezone update by geolocation </message> - <message name="IDS_FLAGS_ENABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION" desc="Description for the flag to enable/disable user setting to automatically update timezone by user geolocation."> - If enabled, in chrome://settings a new option becomes available which allows automatically updating the timezone by the current geolocation. + <message name="IDS_FLAGS_DISABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION" desc="Description for the flag to disable user setting to automatically update timezone by user geolocation."> + If set, automatic timezone update by the current geolocation is turned off. </message> <message name="IDS_OPTIONS_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION" desc="Label for checkbox to allow automatic timezone update by user geolocation."> Automatically resolve timezone by geolocation
diff --git a/chrome/app/client_util.cc b/chrome/app/client_util.cc index 4316226..738ae9e 100644 --- a/chrome/app/client_util.cc +++ b/chrome/app/client_util.cc
@@ -21,6 +21,7 @@ #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" #include "chrome/app/chrome_crash_reporter_client.h" +#include "chrome/app/chrome_watcher_client_win.h" #include "chrome/app/chrome_watcher_command_line_win.h" #include "chrome/app/client_util.h" #include "chrome/app/image_pre_reader_win.h" @@ -33,7 +34,6 @@ #include "chrome/installer/util/google_update_settings.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/util_constants.h" -#include "components/browser_watcher/watcher_client_win.h" #include "components/crash/app/breakpad_win.h" #include "components/crash/app/crash_reporter_client.h" #include "components/metrics/client_info.h" @@ -179,10 +179,12 @@ } if (process_type_ == "watcher") { - base::win::ScopedHandle parent_process = - InterpretChromeWatcherCommandLine(cmd_line); - if (!parent_process.IsValid()) + base::win::ScopedHandle parent_process; + base::win::ScopedHandle on_initialized_event; + if (!InterpretChromeWatcherCommandLine(cmd_line, &parent_process, + &on_initialized_event)) { return chrome::RESULT_CODE_UNSUPPORTED_PARAM; + } // Intentionally leaked. HMODULE watcher_dll = Load(&version, &file); @@ -193,7 +195,7 @@ reinterpret_cast<ChromeWatcherMainFunction>( ::GetProcAddress(watcher_dll, kChromeWatcherDLLEntrypoint)); return watcher_main(chrome::kBrowserExitCodesRegistryPath, - parent_process.Take()); + parent_process.Take(), on_initialized_event.Take()); } // Initialize the sandbox services. @@ -260,8 +262,7 @@ if (g_chrome_crash_client.Get().GetCollectStatsConsent()) { base::char16 exe_path[MAX_PATH]; ::GetModuleFileNameW(nullptr, exe_path, arraysize(exe_path)); - - browser_watcher::WatcherClient watcher_client(base::Bind( + ChromeWatcherClient watcher_client(base::Bind( &GenerateChromeWatcherCommandLine, base::FilePath(exe_path))); watcher_client.LaunchWatcher(); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index e266b56..72ac2c8 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5406,6 +5406,14 @@ </message> </if> + <!-- chrome://md-settings/ - the Material Design Settings page --> + <message name="IDS_FLAGS_ENABLE_MATERIAL_DESIGN_SETTINGS_NAME" desc="Name for the flag to enable the material design Settings page."> + Enable Material Design settings + </message> + <message name="IDS_FLAGS_ENABLE_MATERIAL_DESIGN_SETTINGS_DESCRIPTION" desc="Description for the flag to enable the material design Settings page."> + If enabled, the chrome://md-settings/ URL loads the Material Design settings page. + </message> + <!-- Packaged Apps --> <message name="IDS_APP_INSTALL_TITLE" desc="Caption for installing an ephemeral app"> Install app @@ -6300,6 +6308,12 @@ <message name="IDS_FLAGS_ENABLE_SAVE_PASSOWRD_ON_IN_PAGE_NAVIGATION_DESCRIPTION" desc="Description of the flag to enable showing of password save prompt on in-page navigations"> Enable showing of the password prompt on in-page navigations. This allows for saving passwords on more pages but might sometimes trigger the prompt on unsuccessful login attempts. </message> + <message name="IDS_FLAGS_ENABLE_AFFILIATION_BASED_MATCHING_NAME" desc="Name of the flag to enable affiliation based matching, so that credentials stored for an Android application will also be considered matches for, and be filled into corresponding websites (so-called 'affiliated' websites)."> + Enable affiliation based matching in password manager. + </message> + <message name="IDS_FLAGS_ENABLE_AFFILIATION_BASED_MATCHING_DESCRIPTION" desc="Description of the flag to enable affiliation based matching, so that credentials stored for an Android application will also be considered matches for, and be filled into corresponding websites (so-called 'affiliated' websites)."> + Allow credentials stored for Android applications to be filled into corresponding websites. + </message> <message name="IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_NAME" desc="Name of the flag specifying how the browser will handle autofilling the users sync credential."> Autofill sync credential </message> @@ -6664,21 +6678,6 @@ <message name="IDS_FLAGS_OUT_OF_PROCESS_PDF_DESCRIPTION" desc="Description for the flag to enable out of process PDF."> Enable the out of process PDF plugin. </message> - <message name="IDS_FLAGS_TOUCH_SCROLLING_MODE_NAME" desc="Title for the flag to change the touch scrolling mode."> - Touch scrolling mode. - </message> - <message name="IDS_FLAGS_TOUCH_SCROLLING_MODE_DESCRIPTION" desc="Description for the flag to control touch scrolling mode."> - Change the touch event behavior while scrolling. "touchcancel" is what Chrome has historically used, and "async-touchmove" is the new preferred mode. - </message> - <message name="IDS_FLAGS_TOUCH_SCROLLING_MODE_TOUCHCANCEL" desc="Name for the touchcancel scrolling mode"> - touchcancel - </message> - <message name="IDS_FLAGS_TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE" desc="Name for the async-touchmove scrolling mode"> - async-touchmove - </message> - <message name="IDS_FLAGS_TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE" desc="Name for the sync-touchmove scrolling mode"> - sync-touchmove - </message> <message name="IDS_FLAGS_DISABLE_THREADED_SCROLLING_NAME" desc="Title for the flag to disable threaded scrolling."> Disable threaded scrolling. </message> @@ -15264,12 +15263,6 @@ <message name="IDS_EASY_UNLOCK_SETUP_ERROR_FINDING_PHONE" desc="A generic catch-all error message to display when something goes wrong after the user clicks 'Find my phone' during Easy Unlock setup. Note that the <a> element surrounds a link; these HTML elements should be preserved in the translation."> Can’t find your phone. Make sure you’re using a compatible Android phone that’s turned on and within arm’s reach. <a>Learn more</a> </message> - <message name="IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_CONNECTION_FAILED" desc="The error message to display when the Bluetooth connection between the phone and the Chromebook is disconnected during Easy Unlock setup. Note that the <a> element surrounds a link; these HTML elements should be preserved in the translation."> - Couldn’t establish a connection with your phone. Make sure Bluetooth is turned on for both of your devices. <a>Learn more</a> - </message> - <message name="IDS_EASY_UNLOCK_SETUP_ERROR_CONNECT_TO_PHONE_TIMEOUT" desc="The error message to display when the Chromebook is unable to establish connection to the phone within a reasonable amount of time. Note that the <a> element surrounds a link; these HTML elements should be preserved in the translation."> - Couldn’t establish a connection with your phone. Make sure you’re using a compatible Android phone that is turned on and within arm’s reach. <a>Learn more</a> - </message> <message name="IDS_EASY_UNLOCK_SETUP_ERROR_SYNC_PHONE_STATE_FAILED" desc="The error message to display when the Chromebook fails to sync the phone's state."> Smart Lock is currently unavailable. Please try again later. </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7359d61..5a65805e 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1016,10 +1016,10 @@ "chromeos/login/ui/mock_login_display_host.h", "chromeos/login/users/avatar/mock_user_image_manager.cc", "chromeos/login/users/avatar/mock_user_image_manager.h", + "chromeos/login/users/fake_chrome_user_manager.cc", + "chromeos/login/users/fake_chrome_user_manager.h", "chromeos/login/users/fake_supervised_user_manager.cc", "chromeos/login/users/fake_supervised_user_manager.h", - "chromeos/login/users/fake_user_manager.cc", - "chromeos/login/users/fake_user_manager.h", "chromeos/login/users/mock_user_manager.cc", "chromeos/login/users/mock_user_manager.h", "chromeos/net/network_portal_detector_test_utils.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b002070e..79c734b7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -334,19 +334,6 @@ { IDS_FLAGS_ORIGIN_CHIP_ON_SRP, switches::kEnableOriginChipOnSrp, ""} }; -const Experiment::Choice kTouchScrollingModeChoices[] = { - { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, - { IDS_FLAGS_TOUCH_SCROLLING_MODE_TOUCHCANCEL, - switches::kTouchScrollingMode, - switches::kTouchScrollingModeTouchcancel }, - { IDS_FLAGS_TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE, - switches::kTouchScrollingMode, - switches::kTouchScrollingModeAsyncTouchmove }, - { IDS_FLAGS_TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE, - switches::kTouchScrollingMode, - switches::kTouchScrollingModeSyncTouchmove }, -}; - const Experiment::Choice kExtensionContentVerificationChoices[] = { { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_BOOTSTRAP, @@ -1051,6 +1038,15 @@ autofill::switches::kEnablePasswordSaveOnInPageNavigation) }, { + "enable-affiliation-based-matching", + IDS_FLAGS_ENABLE_AFFILIATION_BASED_MATCHING_NAME, + IDS_FLAGS_ENABLE_AFFILIATION_BASED_MATCHING_DESCRIPTION, + kOsWin | kOsLinux | kOsCrOS | kOsMac | kOsAndroid, + ENABLE_DISABLE_VALUE_TYPE( + password_manager::switches::kEnableAffiliationBasedMatching, + password_manager::switches::kDisableAffiliationBasedMatching) + }, + { "enable-deferred-image-decoding", IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_NAME, IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_DESCRIPTION, @@ -1761,13 +1757,6 @@ }, #endif { - "touch-scrolling-mode", - IDS_FLAGS_TOUCH_SCROLLING_MODE_NAME, - IDS_FLAGS_TOUCH_SCROLLING_MODE_DESCRIPTION, - kOsWin | kOsLinux | kOsCrOS | kOsAndroid, - MULTI_VALUE_TYPE(kTouchScrollingModeChoices) - }, - { "disable-threaded-scrolling", IDS_FLAGS_DISABLE_THREADED_SCROLLING_NAME, IDS_FLAGS_DISABLE_THREADED_SCROLLING_DESCRIPTION, @@ -1981,6 +1970,14 @@ SINGLE_VALUE_TYPE( switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval) }, + { + "enable-md-settings", + IDS_FLAGS_ENABLE_MATERIAL_DESIGN_SETTINGS_NAME, + IDS_FLAGS_ENABLE_MATERIAL_DESIGN_SETTINGS_DESCRIPTION, + kOsDesktop, + SINGLE_VALUE_TYPE( + switches::kEnableMaterialDesignSettings) + }, #endif #if defined(OS_CHROMEOS) { @@ -2148,11 +2145,11 @@ #endif // defined(OS_MACOSX) #if defined(OS_CHROMEOS) { - "enable-timezone-tracking", - IDS_FLAGS_ENABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_NAME, - IDS_FLAGS_ENABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION, + "disable-timezone-tracking", + IDS_FLAGS_DISABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_NAME, + IDS_FLAGS_DISABLE_RESOLVE_TIMEZONE_BY_GEOLOCATION_DESCRIPTION, kOsCrOS, - SINGLE_VALUE_TYPE(chromeos::switches::kEnableTimeZoneTrackingOption) + SINGLE_VALUE_TYPE(chromeos::switches::kDisableTimeZoneTrackingOption) }, #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/android/accessibility/font_size_prefs_android.h b/chrome/browser/android/accessibility/font_size_prefs_android.h index 05985c66..af8f75d6 100644 --- a/chrome/browser/android/accessibility/font_size_prefs_android.h +++ b/chrome/browser/android/accessibility/font_size_prefs_android.h
@@ -64,8 +64,8 @@ static bool Register(JNIEnv* env); // FontSizePrefs::Observer implementation. - virtual void OnChangeFontSize(float font) override; - virtual void OnChangeForceEnableZoom(bool enabled) override; + void OnChangeFontSize(float font) override; + void OnChangeForceEnableZoom(bool enabled) override; private: base::android::ScopedJavaGlobalRef<jobject> java_ref_;
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate.cc b/chrome/browser/android/banners/app_banner_infobar_delegate.cc index 0cd6679..dfa580f 100644 --- a/chrome/browser/android/banners/app_banner_infobar_delegate.cc +++ b/chrome/browser/android/banners/app_banner_infobar_delegate.cc
@@ -6,25 +6,26 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/ui/android/infobars/app_banner_infobar.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_manager.h" #include "ui/base/l10n/l10n_util.h" namespace banners { infobars::InfoBar* AppBannerInfoBarDelegate::CreateForWebApp( - InfoBarService* infobar_service, - const AppDelegate* helper, + infobars::InfoBarManager* infobar_manager, + const AppDelegate* app_delegate, const base::string16& app_name, const GURL& url) { - AppBannerInfoBarDelegate* const delegate = new AppBannerInfoBarDelegate( - helper, + scoped_ptr<AppBannerInfoBarDelegate> delegate(new AppBannerInfoBarDelegate( + app_delegate, app_name, - url); + url)); - return infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar( - scoped_ptr<ConfirmInfoBarDelegate>(delegate))); + return infobar_manager->AddInfoBar( + make_scoped_ptr(new AppBannerInfoBar(delegate.Pass(), url))); } AppBannerInfoBarDelegate::AppBannerInfoBarDelegate(
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate.h b/chrome/browser/android/banners/app_banner_infobar_delegate.h index 5f95a7e9..01fddc6 100644 --- a/chrome/browser/android/banners/app_banner_infobar_delegate.h +++ b/chrome/browser/android/banners/app_banner_infobar_delegate.h
@@ -10,7 +10,9 @@ #include "ui/gfx/image/image.h" #include "url/gurl.h" -class InfoBarService; +namespace infobars { +class InfoBarManager; +} // namespace infobars namespace banners { @@ -33,10 +35,13 @@ // Creates a banner for the current page. // May return nullptr if the the infobar couldn't be created. - static infobars::InfoBar* CreateForWebApp(InfoBarService* infobar_service, - const AppDelegate* helper, - const base::string16& app_title, - const GURL& url); + static infobars::InfoBar* CreateForWebApp( + infobars::InfoBarManager* infobar_manager, + const AppDelegate* delegate, + const base::string16& app_title, + const GURL& url); + + ~AppBannerInfoBarDelegate() override; // Changes the label of the button. void SetButtonLabel(const std::string& button_text); @@ -57,8 +62,6 @@ const base::string16& app_title, const GURL& url); - ~AppBannerInfoBarDelegate() override; - const AppDelegate* delegate_; base::string16 app_title_; GURL url_; @@ -69,4 +72,6 @@ } // namespace banners +bool RegisterAppBannerInfoBarDelegate(JNIEnv* env); + #endif // CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/android/banners/app_banner_manager.cc b/chrome/browser/android/banners/app_banner_manager.cc index 316a036d..cbd87921 100644 --- a/chrome/browser/android/banners/app_banner_manager.cc +++ b/chrome/browser/android/banners/app_banner_manager.cc
@@ -9,9 +9,13 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/metrics/histogram.h" +#include "base/threading/worker_pool.h" #include "chrome/browser/android/banners/app_banner_infobar_delegate.h" #include "chrome/browser/android/banners/app_banner_metrics_ids.h" #include "chrome/browser/android/banners/app_banner_utilities.h" +#include "chrome/browser/android/manifest_icon_selector.h" +#include "chrome/browser/android/shortcut_helper.h" +#include "chrome/browser/android/shortcut_info.h" #include "chrome/browser/banners/app_banner_settings_helper.h" #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" #include "chrome/browser/infobars/infobar_service.h" @@ -28,6 +32,7 @@ #include "jni/AppBannerManager_jni.h" #include "net/base/load_flags.h" #include "ui/gfx/android/java_bitmap.h" +#include "ui/gfx/screen.h" using base::android::ConvertJavaStringToUTF8; using base::android::ConvertUTF8ToJavaString; @@ -75,7 +80,7 @@ return; if (!manifest_.IsEmpty()) { - // TODO(dfalcantara): Trigger shortcut creation. + InstallManifestApp(manifest_, *app_icon_.get()); } } @@ -125,8 +130,10 @@ if (web_contents()->IsBeingDestroyed()) return; - if (manifest.IsEmpty()) { - // No manifest, see if there is a play store meta tag. + if (manifest.IsEmpty() + || !manifest.start_url.is_valid() + || (manifest.name.is_null() && manifest.short_name.is_null())) { + // No usable manifest, see if there is a play store meta tag. Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(), validated_url_, kBannerTag)); @@ -139,17 +146,13 @@ // Create an infobar to promote the manifest's app. manifest_ = manifest; - /* TODO(dfalcantara): Use after landing https://crrev.com/880203004. GURL icon_url = - ManifestIconSelector::FindBestMatchingIcon(manifest.icons, - GetPreferredIconSize(), - web_contents()); + ManifestIconSelector::FindBestMatchingIcon( + manifest.icons, + GetPreferredIconSize(), + gfx::Screen::GetScreenFor(web_contents()->GetNativeView())); if (icon_url.is_empty()) return; - */ - if (manifest.icons.empty()) - return; - GURL icon_url = manifest.icons.back().src; FetchIcon(icon_url); } @@ -268,6 +271,20 @@ return Java_AppBannerManager_getPreferredIconSize(env, jobj.obj()); } +// static +void AppBannerManager::InstallManifestApp(const content::Manifest& manifest, + const SkBitmap& icon) { + ShortcutInfo info; + info.UpdateFromManifest(manifest); + + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap, + info, + icon), + true); +} + void RecordDismissEvent(JNIEnv* env, jclass clazz, jint metric) { banners::TrackDismissEvent(metric); }
diff --git a/chrome/browser/android/banners/app_banner_manager.h b/chrome/browser/android/banners/app_banner_manager.h index dd30b13e..12ae72a3 100644 --- a/chrome/browser/android/banners/app_banner_manager.h +++ b/chrome/browser/android/banners/app_banner_manager.h
@@ -64,7 +64,7 @@ public AppBannerInfoBarDelegate::AppDelegate { public: AppBannerManager(JNIEnv* env, jobject obj); - virtual ~AppBannerManager(); + ~AppBannerManager() override; // Destroys the AppBannerManager. void Destroy(JNIEnv* env, jobject obj); @@ -87,21 +87,26 @@ // Returns |false| if this couldn't be kicked off. bool FetchIcon(const GURL& image_url); + // Installs the app defined by the manifest. + // TODO(dfalcantara): Fold into Install() when more CLs land. + static void InstallManifestApp(const content::Manifest& manifest, + const SkBitmap& icon); + // WebContentsObserver overrides. - virtual void DidNavigateMainFrame( + void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) override; - virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) override; - virtual bool OnMessageReceived(const IPC::Message& message) override; + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override; + bool OnMessageReceived(const IPC::Message& message) override; // BitmapFetcherDelegate overrides. - virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override; + void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override; // AppBannerInfoBarDelegate::AppDelegate overrides. - virtual void Block() const override; - virtual void Install() const override; - virtual gfx::Image GetIcon() const override; + void Block() const override; + void Install() const override; + gfx::Image GetIcon() const override; private: // Gets the preferred icon size for the banner icons.
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.h b/chrome/browser/android/bookmarks/bookmarks_bridge.h index cb182cf..8a283e8 100644 --- a/chrome/browser/android/bookmarks/bookmarks_bridge.h +++ b/chrome/browser/android/bookmarks/bookmarks_bridge.h
@@ -152,7 +152,7 @@ base::string16 GetTitle(const BookmarkNode* node) const; private: - virtual ~BookmarksBridge(); + ~BookmarksBridge() override; base::android::ScopedJavaLocalRef<jobject> CreateJavaBookmark( const BookmarkNode* node);
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim.h b/chrome/browser/android/bookmarks/partner_bookmarks_shim.h index 75461b78..cddfb02 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim.h +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim.h
@@ -121,7 +121,7 @@ private: explicit PartnerBookmarksShim(PrefService* prefs); - virtual ~PartnerBookmarksShim(); + ~PartnerBookmarksShim() override; const BookmarkNode* GetNodeByID(const BookmarkNode* parent, int64 id) const; void ReloadNodeMapping();
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc index 304fc64..ecafdbd 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
@@ -60,7 +60,7 @@ protected: // testing::Test - virtual void SetUp() override { + void SetUp() override { profile_.reset(new TestingProfile()); profile_->CreateBookmarkModel(true); @@ -68,7 +68,7 @@ bookmarks::test::WaitForBookmarkModelToLoad(model_); } - virtual void TearDown() override { + void TearDown() override { PartnerBookmarksShim::ClearInBrowserContextForTesting(profile_.get()); PartnerBookmarksShim::ClearPartnerModelForTesting(); PartnerBookmarksShim::EnablePartnerBookmarksEditing();
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index 5163dac..584af842 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/android/accessibility/font_size_prefs_android.h" #include "chrome/browser/android/accessibility_util.h" #include "chrome/browser/android/appmenu/app_menu_drag_helper.h" +#include "chrome/browser/android/banners/app_banner_infobar_delegate.h" #include "chrome/browser/android/banners/app_banner_manager.h" #include "chrome/browser/android/bookmarks/bookmarks_bridge.h" #include "chrome/browser/android/bookmarks/partner_bookmarks_reader.h" @@ -128,6 +129,7 @@ {"AndroidProfileOAuth2TokenService", AndroidProfileOAuth2TokenService::Register}, {"AnswersImageBridge", RegisterAnswersImageBridge}, + {"AppBannerInfoBarDelegate", RegisterAppBannerInfoBarDelegate}, {"AppBannerManager", banners::RegisterAppBannerManager}, {"ApplicationLifetime", RegisterApplicationLifetimeAndroid}, {"AutocompleteControllerAndroid", RegisterAutocompleteControllerAndroid},
diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.cc b/chrome/browser/android/chrome_web_contents_delegate_android.cc index 0372797..6a71f28 100644 --- a/chrome/browser/android/chrome_web_contents_delegate_android.cc +++ b/chrome/browser/android/chrome_web_contents_delegate_android.cc
@@ -308,7 +308,7 @@ WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { // No code for this yet. @@ -320,8 +320,7 @@ JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); - AddWebContentsResult add_result = - ADD_WEB_CONTENTS_RESULT_STOP_LOAD_AND_DELETE; + bool handled = false; if (!obj.is_null()) { ScopedJavaLocalRef<jobject> jsource; if (source) @@ -330,21 +329,19 @@ if (new_contents) jnew_contents = new_contents->GetJavaWebContents(); - add_result = static_cast<AddWebContentsResult>( - Java_ChromeWebContentsDelegateAndroid_addNewContents( - env, - obj.obj(), - jsource.obj(), - jnew_contents.obj(), - static_cast<jint>(disposition), - NULL, - user_gesture)); + handled = Java_ChromeWebContentsDelegateAndroid_addNewContents( + env, + obj.obj(), + jsource.obj(), + jnew_contents.obj(), + static_cast<jint>(disposition), + NULL, + user_gesture); } if (was_blocked) - *was_blocked = !(add_result == ADD_WEB_CONTENTS_RESULT_PROCEED); - - if (add_result == ADD_WEB_CONTENTS_RESULT_STOP_LOAD_AND_DELETE) + *was_blocked = !handled; + if (!handled) delete new_contents; }
diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.h b/chrome/browser/android/chrome_web_contents_delegate_android.h index 2ca7b8c..c1c6811 100644 --- a/chrome/browser/android/chrome_web_contents_delegate_android.h +++ b/chrome/browser/android/chrome_web_contents_delegate_android.h
@@ -27,16 +27,6 @@ namespace chrome { namespace android { -// An enum with the result of calling AddNewContents() in Java. -// -// A Java counterpart will be generated for this enum. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser -enum AddWebContentsResult { - ADD_WEB_CONTENTS_RESULT_PROCEED, - ADD_WEB_CONTENTS_RESULT_STOP_LOAD, - ADD_WEB_CONTENTS_RESULT_STOP_LOAD_AND_DELETE -}; - // Chromium Android specific WebContentsDelegate. // Should contain any WebContentsDelegate implementations required by // the Chromium Android port but not to be shared with WebView. @@ -45,53 +35,52 @@ public content::NotificationObserver { public: ChromeWebContentsDelegateAndroid(JNIEnv* env, jobject obj); - virtual ~ChromeWebContentsDelegateAndroid(); + ~ChromeWebContentsDelegateAndroid() override; - virtual void LoadingStateChanged(content::WebContents* source, - bool to_different_document) override; - virtual void RunFileChooser(content::WebContents* web_contents, - const content::FileChooserParams& params) - override; - virtual void CloseContents(content::WebContents* web_contents) override; - virtual void FindReply(content::WebContents* web_contents, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) override; - virtual void FindMatchRectsReply(content::WebContents* web_contents, - int version, - const std::vector<gfx::RectF>& rects, - const gfx::RectF& active_rect) override; - virtual content::JavaScriptDialogManager* - GetJavaScriptDialogManager(content::WebContents* source) override; - virtual void RequestMediaAccessPermission( + void LoadingStateChanged(content::WebContents* source, + bool to_different_document) override; + void RunFileChooser(content::WebContents* web_contents, + const content::FileChooserParams& params) override; + void CloseContents(content::WebContents* web_contents) override; + void FindReply(content::WebContents* web_contents, + int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) override; + void FindMatchRectsReply(content::WebContents* web_contents, + int version, + const std::vector<gfx::RectF>& rects, + const gfx::RectF& active_rect) override; + content::JavaScriptDialogManager* GetJavaScriptDialogManager( + content::WebContents* source) override; + void RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) override; - virtual bool CheckMediaAccessPermission( - content::WebContents* web_contents, - const GURL& security_origin, - content::MediaStreamType type) override; - virtual bool RequestPpapiBrokerPermission( + bool CheckMediaAccessPermission(content::WebContents* web_contents, + const GURL& security_origin, + content::MediaStreamType type) override; + bool RequestPpapiBrokerPermission( content::WebContents* web_contents, const GURL& url, const base::FilePath& plugin_path, const base::Callback<void(bool)>& callback) override; - virtual content::WebContents* OpenURLFromTab( + content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; - virtual void AddNewContents(content::WebContents* source, - content::WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture, - bool* was_blocked) override; + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) override; + private: // NotificationObserver implementation. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; void OnFindResultAvailable(content::WebContents* web_contents, const FindNotificationDetails* find_result);
diff --git a/chrome/browser/android/dev_tools_manager_delegate_android.cc b/chrome/browser/android/dev_tools_manager_delegate_android.cc index a5ea927..b7561ad 100644 --- a/chrome/browser/android/dev_tools_manager_delegate_android.cc +++ b/chrome/browser/android/dev_tools_manager_delegate_android.cc
@@ -55,17 +55,17 @@ class TargetBase : public content::DevToolsTarget { public: // content::DevToolsTarget implementation: - virtual std::string GetParentId() const override { return std::string(); } + std::string GetParentId() const override { return std::string(); } - virtual std::string GetTitle() const override { return title_; } + std::string GetTitle() const override { return title_; } - virtual std::string GetDescription() const override { return std::string(); } + std::string GetDescription() const override { return std::string(); } - virtual GURL GetURL() const override { return url_; } + GURL GetURL() const override { return url_; } - virtual GURL GetFaviconURL() const override { return favicon_url_; } + GURL GetFaviconURL() const override { return favicon_url_; } - virtual base::TimeTicks GetLastActivityTime() const override { + base::TimeTicks GetLastActivityTime() const override { return last_activity_time_; } @@ -110,15 +110,11 @@ } // content::DevToolsTarget implementation: - virtual std::string GetId() const override { - return base::IntToString(tab_id_); - } + std::string GetId() const override { return base::IntToString(tab_id_); } - virtual std::string GetType() const override { - return kTargetTypePage; - } + std::string GetType() const override { return kTargetTypePage; } - virtual bool IsAttached() const override { + bool IsAttached() const override { TabModel* model; int index; if (!FindTab(&model, &index)) @@ -129,7 +125,7 @@ return DevToolsAgentHost::IsDebuggerAttached(web_contents); } - virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { + scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { TabModel* model; int index; if (!FindTab(&model, &index)) @@ -151,7 +147,7 @@ return DevToolsAgentHost::GetOrCreateFor(web_contents); } - virtual bool Activate() const override { + bool Activate() const override { TabModel* model; int index; if (!FindTab(&model, &index)) @@ -160,7 +156,7 @@ return true; } - virtual bool Close() const override { + bool Close() const override { TabModel* model; int index; if (!FindTab(&model, &index)) @@ -207,11 +203,9 @@ } // content::DevToolsTarget implementation: - virtual std::string GetId() const override { - return agent_host_->GetId(); - } + std::string GetId() const override { return agent_host_->GetId(); } - virtual std::string GetType() const override { + std::string GetType() const override { switch (agent_host_->GetType()) { case DevToolsAgentHost::TYPE_WEB_CONTENTS: if (TabModelList::begin() == TabModelList::end()) { @@ -228,21 +222,15 @@ return kTargetTypeOther; } - virtual bool IsAttached() const override { - return agent_host_->IsAttached(); - } + bool IsAttached() const override { return agent_host_->IsAttached(); } - virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { + scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { return agent_host_; } - virtual bool Activate() const override { - return agent_host_->Activate(); - } + bool Activate() const override { return agent_host_->Activate(); } - virtual bool Close() const override { - return agent_host_->Close(); - } + bool Close() const override { return agent_host_->Close(); } private: scoped_refptr<DevToolsAgentHost> agent_host_;
diff --git a/chrome/browser/android/dev_tools_manager_delegate_android.h b/chrome/browser/android/dev_tools_manager_delegate_android.h index 7e1f459e..1a0f51e4 100644 --- a/chrome/browser/android/dev_tools_manager_delegate_android.h +++ b/chrome/browser/android/dev_tools_manager_delegate_android.h
@@ -14,20 +14,19 @@ class DevToolsManagerDelegateAndroid : public content::DevToolsManagerDelegate { public: DevToolsManagerDelegateAndroid(); - virtual ~DevToolsManagerDelegateAndroid(); + ~DevToolsManagerDelegateAndroid() override; // content::DevToolsManagerDelegate implementation. - virtual void Inspect(content::BrowserContext* browser_context, - content::DevToolsAgentHost* agent_host) override; - virtual void DevToolsAgentStateChanged(content::DevToolsAgentHost* agent_host, - bool attached) override; - virtual base::DictionaryValue* HandleCommand( + void Inspect(content::BrowserContext* browser_context, + content::DevToolsAgentHost* agent_host) override; + void DevToolsAgentStateChanged(content::DevToolsAgentHost* agent_host, + bool attached) override; + base::DictionaryValue* HandleCommand( content::DevToolsAgentHost* agent_host, base::DictionaryValue* command_dict) override; - virtual scoped_ptr<content::DevToolsTarget> CreateNewTarget( - const GURL& url) override; - virtual void EnumerateTargets(TargetCallback callback) override; - virtual std::string GetPageThumbnailData(const GURL& url) override; + scoped_ptr<content::DevToolsTarget> CreateNewTarget(const GURL& url) override; + void EnumerateTargets(TargetCallback callback) override; + std::string GetPageThumbnailData(const GURL& url) override; private: scoped_ptr<DevToolsNetworkProtocolHandler> network_protocol_handler_;
diff --git a/chrome/browser/android/dom_distiller/feedback_reporter_android.h b/chrome/browser/android/dom_distiller/feedback_reporter_android.h index 284da3b..7af1562f 100644 --- a/chrome/browser/android/dom_distiller/feedback_reporter_android.h +++ b/chrome/browser/android/dom_distiller/feedback_reporter_android.h
@@ -23,7 +23,7 @@ class FeedbackReporterAndroid : content::WebContentsObserver { public: FeedbackReporterAndroid(JNIEnv* env, jobject obj); - virtual ~FeedbackReporterAndroid(); + ~FeedbackReporterAndroid() override; // Destroys the FeedbackReporterAndroid. void Destroy(JNIEnv* env, jobject obj); @@ -32,7 +32,7 @@ void ReplaceWebContents(JNIEnv* env, jobject obj, jobject jweb_contents); // WebContentsObserver implementation: - virtual void DidNavigateMainFrame( + void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) override;
diff --git a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h b/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h index ce88776..8018b4c 100644 --- a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h +++ b/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.h
@@ -21,7 +21,7 @@ class EnhancedBookmarksBridge : public BookmarkServerServiceObserver { public: EnhancedBookmarksBridge(JNIEnv* env, jobject obj, Profile* profile); - virtual ~EnhancedBookmarksBridge(); + ~EnhancedBookmarksBridge() override; void Destroy(JNIEnv*, jobject); base::android::ScopedJavaLocalRef<jstring> GetBookmarkDescription( @@ -73,7 +73,7 @@ // BookmarkServerServiceObserver // Called on changes to cluster data or search results are returned. - virtual void OnChange(BookmarkServerService* service) override; + void OnChange(BookmarkServerService* service) override; private: bool IsEditable(const BookmarkNode* node) const;
diff --git a/chrome/browser/android/foreign_session_helper.h b/chrome/browser/android/foreign_session_helper.h index 0f1ad00..5f79bd40 100644 --- a/chrome/browser/android/foreign_session_helper.h +++ b/chrome/browser/android/foreign_session_helper.h
@@ -37,14 +37,14 @@ void DeleteForeignSession(JNIEnv* env, jobject obj, jstring session_tag); // NotificationObserver implemenation - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; static bool RegisterForeignSessionHelper(JNIEnv* env); private: - virtual ~ForeignSessionHelper(); + ~ForeignSessionHelper() override; Profile* profile_; // weak base::android::ScopedJavaGlobalRef<jobject> callback_;
diff --git a/chrome/browser/android/intercept_download_resource_throttle.h b/chrome/browser/android/intercept_download_resource_throttle.h index f476a87..6ecfb439 100644 --- a/chrome/browser/android/intercept_download_resource_throttle.h +++ b/chrome/browser/android/intercept_download_resource_throttle.h
@@ -25,11 +25,11 @@ int request_id); // content::ResourceThrottle implementation: - virtual void WillProcessResponse(bool* defer) override; - virtual const char* GetNameForLogging() const override; + void WillProcessResponse(bool* defer) override; + const char* GetNameForLogging() const override; private: - virtual ~InterceptDownloadResourceThrottle(); + ~InterceptDownloadResourceThrottle() override; void ProcessDownloadRequest(); // Set to true when if we want chrome to handle the download.
diff --git a/chrome/browser/android/logo_bridge.cc b/chrome/browser/android/logo_bridge.cc index b673ebca..6c97a04 100644 --- a/chrome/browser/android/logo_bridge.cc +++ b/chrome/browser/android/logo_bridge.cc
@@ -53,11 +53,11 @@ j_logo_observer_.Reset(env, j_logo_observer); } - virtual ~LogoObserverAndroid() {} + ~LogoObserverAndroid() override {} // seach_provider_logos::LogoObserver: - virtual void OnLogoAvailable(const search_provider_logos::Logo* logo, - bool from_cache) override { + void OnLogoAvailable(const search_provider_logos::Logo* logo, + bool from_cache) override { if (!logo_bridge_) return; @@ -67,9 +67,7 @@ env, j_logo_observer_.obj(), j_logo.obj(), from_cache); } - virtual void OnObserverRemoved() override { - delete this; - } + void OnObserverRemoved() override { delete this; } private: // The associated LogoBridge. We won't call back to Java if the LogoBridge has
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc index f9d3252..ac0351c 100644 --- a/chrome/browser/android/logo_service.cc +++ b/chrome/browser/android/logo_service.cc
@@ -5,11 +5,10 @@ #include "chrome/browser/android/logo_service.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/google/google_profile_helper.h" #include "chrome/browser/image_decoder.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" -#include "components/google/core/browser/google_util.h" +#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/search_engines/template_url_service.h" #include "components/search_provider_logos/google_logo_api.h" @@ -23,7 +22,6 @@ namespace { -const char kGoogleDoodleURLPath[] = "async/newtab_mobile"; const char kCachedLogoDirectory[] = "Search Logo"; const int kDecodeLogoTimeoutSeconds = 30; @@ -31,16 +29,14 @@ // https://www.google.com/async/newtab_mobile. This depends on the user's // Google domain. GURL GetGoogleDoodleURL(Profile* profile) { - // SetPathStr() requires its argument to stay in scope as long as - // |replacements| is, so a std::string is needed, instead of a char*. - std::string path = kGoogleDoodleURLPath; + GURL google_base_url(UIThreadSearchTermsData(profile).GoogleBaseURLValue()); + const char kGoogleDoodleURLPath[] = "async/newtab_mobile"; + // The string passed to SetPathStr() must stay alive until after + // ReplaceComponents(), so declare it on the stack here instead of inline. + std::string path(kGoogleDoodleURLPath); GURL::Replacements replacements; replacements.SetPathStr(path); - - GURL base_url(google_util::CommandLineGoogleBaseURL()); - if (!base_url.is_valid()) - base_url = google_profile_helper::GetGoogleHomePageURL(profile); - return base_url.ReplaceComponents(replacements); + return google_base_url.ReplaceComponents(replacements); } class LogoDecoderDelegate : public ImageDecoder::Delegate { @@ -62,18 +58,16 @@ base::TimeDelta::FromSeconds(kDecodeLogoTimeoutSeconds)); } - virtual ~LogoDecoderDelegate() { - image_decoder_->set_delegate(NULL); - } + ~LogoDecoderDelegate() override { image_decoder_->set_delegate(NULL); } // ImageDecoder::Delegate: - virtual void OnImageDecoded(const ImageDecoder* decoder, - const SkBitmap& decoded_image) override { + void OnImageDecoded(const ImageDecoder* decoder, + const SkBitmap& decoded_image) override { image_decoded_callback_.Run(decoded_image); delete this; } - virtual void OnDecodeImageFailed(const ImageDecoder* decoder) override { + void OnDecodeImageFailed(const ImageDecoder* decoder) override { image_decoded_callback_.Run(SkBitmap()); delete this; } @@ -89,10 +83,10 @@ class ChromeLogoDelegate : public search_provider_logos::LogoDelegate { public: ChromeLogoDelegate() {} - virtual ~ChromeLogoDelegate() {} + ~ChromeLogoDelegate() override {} // search_provider_logos::LogoDelegate: - virtual void DecodeUntrustedImage( + void DecodeUntrustedImage( const scoped_refptr<base::RefCountedString>& encoded_image, base::Callback<void(const SkBitmap&)> image_decoded_callback) override { scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
diff --git a/chrome/browser/android/logo_service.h b/chrome/browser/android/logo_service.h index fe4075b..441c6e2 100644 --- a/chrome/browser/android/logo_service.h +++ b/chrome/browser/android/logo_service.h
@@ -22,7 +22,7 @@ class LogoService : public KeyedService { public: explicit LogoService(Profile* profile); - virtual ~LogoService(); + ~LogoService() override; // Gets the logo for the default search provider and notifies |observer| // with the results. @@ -46,10 +46,10 @@ friend struct DefaultSingletonTraits<LogoServiceFactory>; LogoServiceFactory(); - virtual ~LogoServiceFactory(); + ~LogoServiceFactory() override; // BrowserContextKeyedServiceFactory: - virtual KeyedService* BuildServiceInstanceFor( + KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override; };
diff --git a/chrome/browser/android/manifest_icon_selector.cc b/chrome/browser/android/manifest_icon_selector.cc new file mode 100644 index 0000000..4f4cdca --- /dev/null +++ b/chrome/browser/android/manifest_icon_selector.cc
@@ -0,0 +1,151 @@ +// 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/manifest_icon_selector.h" + +#include <limits> + +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/web_contents.h" +#include "net/base/mime_util.h" +#include "ui/gfx/screen.h" + +using content::Manifest; + +ManifestIconSelector::ManifestIconSelector(float preferred_icon_size_in_pixels) + : preferred_icon_size_in_pixels_(preferred_icon_size_in_pixels) { +} + +bool ManifestIconSelector::IconSizesContainsPreferredSize( + const std::vector<gfx::Size>& sizes) { + for (size_t i = 0; i < sizes.size(); ++i) { + if (sizes[i].height() != sizes[i].width()) + continue; + if (sizes[i].width() == preferred_icon_size_in_pixels_) + return true; + } + + return false; +} + +GURL ManifestIconSelector::FindBestMatchingIconForDensity( + const std::vector<content::Manifest::Icon>& icons, + float density) { + GURL url; + int best_delta = std::numeric_limits<int>::min(); + + for (size_t i = 0; i < icons.size(); ++i) { + if (icons[i].density != density) + continue; + + const std::vector<gfx::Size>& sizes = icons[i].sizes; + for (size_t j = 0; j < sizes.size(); ++j) { + if (sizes[j].height() != sizes[j].width()) + continue; + int delta = sizes[j].width() - preferred_icon_size_in_pixels_; + if (delta == 0) + return icons[i].src; + if (best_delta > 0 && delta < 0) + continue; + if ((best_delta > 0 && delta < best_delta) || + (best_delta < 0 && delta > best_delta)) { + url = icons[i].src; + best_delta = delta; + } + } + } + + return url; +} + +GURL ManifestIconSelector::FindBestMatchingIcon( + const std::vector<content::Manifest::Icon>& unfiltered_icons, + float density) { + GURL url; + std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons); + + // The first pass is to find the ideal icon. That icon is of the right size + // with the default density or the device's density. + for (size_t i = 0; i < icons.size(); ++i) { + if (icons[i].density == density && + IconSizesContainsPreferredSize(icons[i].sizes)) { + return icons[i].src; + } + + // If there is an icon with the right size but not the right density, keep + // it on the side and only use it if nothing better is found. + if (icons[i].density == Manifest::Icon::kDefaultDensity && + IconSizesContainsPreferredSize(icons[i].sizes)) { + url = icons[i].src; + } + } + + // The second pass is to find an icon with 'any'. The current device scale + // factor is preferred. Otherwise, the default scale factor is used. + for (size_t i = 0; i < icons.size(); ++i) { + if (icons[i].density == density && + IconSizesContainsAny(icons[i].sizes)) { + return icons[i].src; + } + + // If there is an icon with 'any' but not the right density, keep it on the + // side and only use it if nothing better is found. + if (icons[i].density == Manifest::Icon::kDefaultDensity && + IconSizesContainsAny(icons[i].sizes)) { + url = icons[i].src; + } + } + + // The last pass will try to find the best suitable icon for the device's + // scale factor. If none, another pass will be run using kDefaultDensity. + if (!url.is_valid()) + url = FindBestMatchingIconForDensity(icons, density); + if (!url.is_valid()) + url = FindBestMatchingIconForDensity(icons, + Manifest::Icon::kDefaultDensity); + + return url; +} + + +// static +bool ManifestIconSelector::IconSizesContainsAny( + const std::vector<gfx::Size>& sizes) { + for (size_t i = 0; i < sizes.size(); ++i) { + if (sizes[i].IsEmpty()) + return true; + } + + return false; +} + +// static +std::vector<Manifest::Icon> ManifestIconSelector::FilterIconsByType( + const std::vector<content::Manifest::Icon>& icons) { + std::vector<Manifest::Icon> result; + + for (size_t i = 0; i < icons.size(); ++i) { + if (icons[i].type.is_null() || + net::IsSupportedImageMimeType( + base::UTF16ToUTF8(icons[i].type.string()))) { + result.push_back(icons[i]); + } + } + + return result; +} + +// static +GURL ManifestIconSelector::FindBestMatchingIcon( + const std::vector<Manifest::Icon>& unfiltered_icons, + const float preferred_icon_size_in_dp, + const gfx::Screen* screen) { + const float device_scale_factor = + screen->GetPrimaryDisplay().device_scale_factor(); + const float preferred_icon_size_in_pixels = + preferred_icon_size_in_dp * device_scale_factor; + + ManifestIconSelector selector(preferred_icon_size_in_pixels); + return selector.FindBestMatchingIcon(unfiltered_icons, device_scale_factor); +}
diff --git a/chrome/browser/android/manifest_icon_selector.h b/chrome/browser/android/manifest_icon_selector.h new file mode 100644 index 0000000..ef3ad27 --- /dev/null +++ b/chrome/browser/android/manifest_icon_selector.h
@@ -0,0 +1,79 @@ +// 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_MANIFEST_ICON_SELECTOR_H_ +#define CHROME_BROWSER_ANDROID_MANIFEST_ICON_SELECTOR_H_ + +#include "base/basictypes.h" +#include "content/public/common/manifest.h" +#include "url/gurl.h" + +namespace content { +class WebContents; +} // namespace content + +namespace IPC { +class Message; +} // namespace IPC + +namespace gfx { +class Screen; +} + +// Selects the icon most closely matching the size constraints. This follows +// very basic heuristics -- improvements are welcome. +class ManifestIconSelector { + public: + // Runs the algorithm to find the best matching icon in the icons listed in + // the Manifest. + // + // Size is defined in Android's density-independent pixels (dp): + // http://developer.android.com/guide/practices/screens_support.html + // If/when this class is generalized, it may be a good idea to switch this to + // taking in pixels, instead. + // + // Returns the icon url if a suitable icon is found. An empty URL otherwise. + static GURL FindBestMatchingIcon( + const std::vector<content::Manifest::Icon>& icons, + float preferred_icon_size_in_dp, + const gfx::Screen* screen); + + private: + explicit ManifestIconSelector(float preferred_icon_size_in_pixels); + virtual ~ManifestIconSelector() {} + + // Runs the algorithm to find the best matching icon in the icons listed in + // the Manifest. + // Returns the icon url if a suitable icon is found. An empty URL otherwise. + GURL FindBestMatchingIcon( + const std::vector<content::Manifest::Icon>& icons, + float density); + + // Runs an algorithm only based on icon declared sizes. It will try to find + // size that is the closest to preferred_icon_size_in_pixels_ but bigger than + // preferred_icon_size_in_pixels_ if possible. + // Returns the icon url if a suitable icon is found. An empty URL otherwise. + GURL FindBestMatchingIconForDensity( + const std::vector<content::Manifest::Icon>& icons, + float density); + + // Returns whether the |preferred_icon_size_in_pixels_| is in |sizes|. + bool IconSizesContainsPreferredSize(const std::vector<gfx::Size>& sizes); + + // Returns an array containing the items in |icons| without the unsupported + // image MIME types. + static std::vector<content::Manifest::Icon> FilterIconsByType( + const std::vector<content::Manifest::Icon>& icons); + + // Returns whether the 'any' (ie. gfx::Size(0,0)) is in |sizes|. + static bool IconSizesContainsAny(const std::vector<gfx::Size>& sizes); + + const int preferred_icon_size_in_pixels_; + + friend class ManifestIconSelectorTest; + + DISALLOW_COPY_AND_ASSIGN(ManifestIconSelector); +}; + +#endif // CHROME_BROWSER_ANDROID_MANIFEST_ICON_SELECTOR_H_
diff --git a/chrome/browser/android/shortcut_helper_unittest.cc b/chrome/browser/android/manifest_icon_selector_unittest.cc similarity index 81% rename from chrome/browser/android/shortcut_helper_unittest.cc rename to chrome/browser/android/manifest_icon_selector_unittest.cc index 76e1a5e..b2cafbc 100644 --- a/chrome/browser/android/shortcut_helper_unittest.cc +++ b/chrome/browser/android/manifest_icon_selector_unittest.cc
@@ -1,55 +1,60 @@ -// 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. -#include "chrome/browser/android/shortcut_helper.h" +#include "chrome/browser/android/manifest_icon_selector.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "content/public/browser/web_contents.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/screen.h" #include "ui/gfx/screen_type_delegate.h" -// A dummy implementation of gfx::Screen, since ShortcutHelper needs access to -// a gfx::Display's device scale factor. +namespace { + +const int kPreferredIconSize = 48; + +} + +// A dummy implementation of gfx::Screen, since ManifestIconSelector needs +// access to a gfx::Display's device scale factor. // This is inspired by web_contents_video_capture_device_unittest.cc // A bug has been opened to merge all those mocks: http://crbug.com/417227 class FakeScreen : public gfx::Screen { public: FakeScreen() : display_(0x1337, gfx::Rect(0, 0, 2560, 1440)) { } - virtual ~FakeScreen() {} + ~FakeScreen() override {} void SetDisplayDeviceScaleFactor(float device_scale_factor) { display_.set_device_scale_factor(device_scale_factor); } // gfx::Screen implementation (only what's needed for testing). - virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } - virtual gfx::NativeWindow GetWindowUnderCursor() override { return NULL; } - virtual gfx::NativeWindow GetWindowAtScreenPoint( - const gfx::Point& point) override { return NULL; } - virtual int GetNumDisplays() const override { return 1; } - virtual std::vector<gfx::Display> GetAllDisplays() const override { + gfx::Point GetCursorScreenPoint() override { return gfx::Point(); } + gfx::NativeWindow GetWindowUnderCursor() override { return nullptr; } + gfx::NativeWindow GetWindowAtScreenPoint( + const gfx::Point& point) override { return nullptr; } + int GetNumDisplays() const override { return 1; } + std::vector<gfx::Display> GetAllDisplays() const override { return std::vector<gfx::Display>(1, display_); } - virtual gfx::Display GetDisplayNearestWindow( + gfx::Display GetDisplayNearestWindow( gfx::NativeView view) const override { return display_; } - virtual gfx::Display GetDisplayNearestPoint( + gfx::Display GetDisplayNearestPoint( const gfx::Point& point) const override { return display_; } - virtual gfx::Display GetDisplayMatching( + gfx::Display GetDisplayMatching( const gfx::Rect& match_rect) const override { return display_; } - virtual gfx::Display GetPrimaryDisplay() const override { + gfx::Display GetPrimaryDisplay() const override { return display_; } - virtual void AddObserver(gfx::DisplayObserver* observer) override {} - virtual void RemoveObserver(gfx::DisplayObserver* observer) override {} + void AddObserver(gfx::DisplayObserver* observer) override {} + void RemoveObserver(gfx::DisplayObserver* observer) override {} private: gfx::Display display_; @@ -57,59 +62,24 @@ DISALLOW_COPY_AND_ASSIGN(FakeScreen); }; -class ShortcutHelperTest : public ChromeRenderViewHostTestHarness { +class ManifestIconSelectorTest : public testing::Test { protected: - ShortcutHelperTest() : shortcut_helper_(NULL) {} - virtual ~ShortcutHelperTest() {} - - static jobject CreateShortcutHelperJava(JNIEnv* env) { - jclass clazz = env->FindClass("org/chromium/chrome/browser/ShortcutHelper"); - jmethodID constructor = - env->GetMethodID(clazz, "<init>", - "(Landroid/content/Context;" - "Lorg/chromium/chrome/browser/Tab;)V"); - return env->NewObject(clazz, constructor, jobject(), jobject()); - } - - void ResetShorcutHelper() { - if (shortcut_helper_) - delete shortcut_helper_; - - JNIEnv* env = base::android::AttachCurrentThread(); - shortcut_helper_ = - new ShortcutHelper(env, CreateShortcutHelperJava(env), web_contents()); - } - - virtual void SetUp() override { - gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, &fake_screen_); - ASSERT_EQ(&fake_screen_, gfx::Screen::GetNativeScreen()); - - ChromeRenderViewHostTestHarness::SetUp(); - - ResetShorcutHelper(); - } - - virtual void TearDown() override { - delete shortcut_helper_; - shortcut_helper_ = NULL; - - ChromeRenderViewHostTestHarness::TearDown(); - - gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL); - } + ManifestIconSelectorTest() {} + ~ManifestIconSelectorTest() override {} GURL FindBestMatchingIcon(const std::vector<content::Manifest::Icon>& icons) { - return shortcut_helper_->FindBestMatchingIcon(icons); + return ManifestIconSelector::FindBestMatchingIcon( + icons, + GetPreferredIconSizeInDp(), + &fake_screen_); } void SetDisplayDeviceScaleFactor(float device_scale_factor) { fake_screen_.SetDisplayDeviceScaleFactor(device_scale_factor); - - ResetShorcutHelper(); } static int GetPreferredIconSizeInDp() { - return ShortcutHelper::kPreferredIconSizeInDp; + return kPreferredIconSize; } static content::Manifest::Icon CreateIcon( @@ -128,20 +98,19 @@ } private: - ShortcutHelper* shortcut_helper_; FakeScreen fake_screen_; - DISALLOW_COPY_AND_ASSIGN(ShortcutHelperTest); + DISALLOW_COPY_AND_ASSIGN(ManifestIconSelectorTest); }; -TEST_F(ShortcutHelperTest, NoIcons) { +TEST_F(ManifestIconSelectorTest, NoIcons) { // No icons should return the empty URL. std::vector<content::Manifest::Icon> icons; GURL url = FindBestMatchingIcon(icons); EXPECT_TRUE(url.is_empty()); } -TEST_F(ShortcutHelperTest, NoSizes) { +TEST_F(ManifestIconSelectorTest, NoSizes) { // Icon with no sizes are ignored. std::vector<content::Manifest::Icon> icons; icons.push_back( @@ -151,7 +120,7 @@ EXPECT_TRUE(url.is_empty()); } -TEST_F(ShortcutHelperTest, MIMETypeFiltering) { +TEST_F(ManifestIconSelectorTest, MIMETypeFiltering) { // Icons with type specified to a MIME type that isn't a valid image MIME type // are ignored. std::vector<gfx::Size> sizes; @@ -187,7 +156,7 @@ EXPECT_EQ("http://foo.com/icon.png", url.spec()); } -TEST_F(ShortcutHelperTest, PreferredSizeOfCurrentDensityIsUsedFirst) { +TEST_F(ManifestIconSelectorTest, PreferredSizeOfCurrentDensityIsUsedFirst) { // This test has three icons each are marked with sizes set to the preferred // icon size for the associated density. std::vector<gfx::Size> sizes_1; @@ -220,7 +189,7 @@ EXPECT_EQ("http://foo.com/icon_x3.png", url.spec()); } -TEST_F(ShortcutHelperTest, PreferredSizeOfDefaultDensityIsUsedSecond) { +TEST_F(ManifestIconSelectorTest, PreferredSizeOfDefaultDensityIsUsedSecond) { // This test has three icons. The first one is of density zero and is marked // with three sizes which are the preferred icon size for density 1, 2 and 3. // The icon for density 2 and 3 have a size set to 2x2 and 3x3. @@ -258,7 +227,7 @@ EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); } -TEST_F(ShortcutHelperTest, DeviceDensityFirst) { +TEST_F(ManifestIconSelectorTest, DeviceDensityFirst) { // If there is no perfect icon but an icon of the current device density is // present, it will be picked. // This test has three icons each are marked with sizes set to the preferred @@ -284,7 +253,7 @@ EXPECT_EQ("http://foo.com/icon_x3.png", url.spec()); } -TEST_F(ShortcutHelperTest, DeviceDensityFallback) { +TEST_F(ManifestIconSelectorTest, DeviceDensityFallback) { // If there is no perfect icon but and no icon of the current display density, // an icon of density 1.0 will be used. std::vector<gfx::Size> sizes; @@ -299,7 +268,7 @@ EXPECT_EQ("http://foo.com/icon_x1.png", url.spec()); } -TEST_F(ShortcutHelperTest, DoNotUseOtherDensities) { +TEST_F(ManifestIconSelectorTest, DoNotUseOtherDensities) { // If there are only icons of densities that are not the current display // density or the default density, they are ignored. std::vector<gfx::Size> sizes; @@ -313,7 +282,7 @@ EXPECT_TRUE(url.is_empty()); } -TEST_F(ShortcutHelperTest, NotSquareIconsAreIgnored) { +TEST_F(ManifestIconSelectorTest, NotSquareIconsAreIgnored) { std::vector<gfx::Size> sizes; sizes.push_back(gfx::Size(20, 2)); @@ -324,8 +293,8 @@ EXPECT_TRUE(url.is_empty()); } -TEST_F(ShortcutHelperTest, ClosestIconToPreferred) { - // This test verifies ShortcutHelper::FindBestMatchingIcon by passing +TEST_F(ManifestIconSelectorTest, ClosestIconToPreferred) { + // This test verifies ManifestIconSelector::FindBestMatchingIcon by passing // different icon sizes and checking which one is picked. // The Device Scale Factor is 1.0 and the preferred icon size is returned by // GetPreferredIconSizeInDp(). @@ -441,7 +410,7 @@ } } -TEST_F(ShortcutHelperTest, UseAnyIfNoPreferredSize) { +TEST_F(ManifestIconSelectorTest, UseAnyIfNoPreferredSize) { // 'any' (ie. gfx::Size(0,0)) should be used if there is no icon of a // preferred size. An icon with the current device scale factor is preferred // over one with the default density.
diff --git a/chrome/browser/android/most_visited_sites.h b/chrome/browser/android/most_visited_sites.h index b01c56e..6e5a7f52a 100644 --- a/chrome/browser/android/most_visited_sites.h +++ b/chrome/browser/android/most_visited_sites.h
@@ -45,7 +45,7 @@ void RecordOpenedMostVisitedItem(JNIEnv* env, jobject obj, jint index); // ProfileSyncServiceObserver implementation. - virtual void OnStateChanged() override; + void OnStateChanged() override; // Registers JNI methods. static bool Register(JNIEnv* env); @@ -57,7 +57,7 @@ SUGGESTIONS_SERVICE }; - virtual ~MostVisitedSites(); + ~MostVisitedSites() override; void QueryMostVisitedURLs(); // Initialize the query to Top Sites. Called if the SuggestionsService is not
diff --git a/chrome/browser/android/omnibox/answers_image_bridge.cc b/chrome/browser/android/omnibox/answers_image_bridge.cc index 09860af1..41d215d 100644 --- a/chrome/browser/android/omnibox/answers_image_bridge.cc +++ b/chrome/browser/android/omnibox/answers_image_bridge.cc
@@ -31,11 +31,11 @@ java_answers_image_observer_.Reset(env, java_answers_image_observer); } - virtual ~AnswersImageObserverAndroid() {} + ~AnswersImageObserverAndroid() override {} // AnswersImageObserver: - virtual void OnImageChanged(BitmapFetcherService::RequestId request_id, - const SkBitmap& answers_image) override { + void OnImageChanged(BitmapFetcherService::RequestId request_id, + const SkBitmap& answers_image) override { DCHECK(!answers_image.empty()); JNIEnv* env = base::android::AttachCurrentThread();
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index bcac0f2..7a85f8a 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -73,11 +73,11 @@ explicit ZeroSuggestPrefetcher(Profile* profile); private: - virtual ~ZeroSuggestPrefetcher(); + ~ZeroSuggestPrefetcher() override; void SelfDestruct(); // AutocompleteControllerDelegate: - virtual void OnResultChanged(bool default_match_changed) override; + void OnResultChanged(bool default_match_changed) override; scoped_ptr<AutocompleteController> controller_; base::OneShotTimer<ZeroSuggestPrefetcher> expire_timer_;
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.h b/chrome/browser/android/omnibox/autocomplete_controller_android.h index d8e150f6..6ae205c6 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.h +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.h
@@ -71,7 +71,7 @@ jlong elapsed_time_since_input_change); // KeyedService: - virtual void Shutdown() override; + void Shutdown() override; class Factory : public BrowserContextKeyedServiceFactory { public: @@ -82,26 +82,26 @@ static Factory* GetInstance(); protected: - virtual content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; private: friend struct DefaultSingletonTraits<Factory>; Factory(); - virtual ~Factory(); + ~Factory() override; // BrowserContextKeyedServiceFactory - virtual KeyedService* BuildServiceInstanceFor( + KeyedService* BuildServiceInstanceFor( content::BrowserContext* profile) const override; }; private: - virtual ~AutocompleteControllerAndroid(); + ~AutocompleteControllerAndroid() override; void InitJNI(JNIEnv* env, jobject obj); // AutocompleteControllerDelegate implementation. - virtual void OnResultChanged(bool default_match_changed) override; + void OnResultChanged(bool default_match_changed) override; // Notifies the Java AutocompleteController that suggestions were received // based on the text the user typed in last.
diff --git a/chrome/browser/android/password_ui_view_android.h b/chrome/browser/android/password_ui_view_android.h index 35071a3..2d826d9 100644 --- a/chrome/browser/android/password_ui_view_android.h +++ b/chrome/browser/android/password_ui_view_android.h
@@ -21,18 +21,17 @@ class PasswordUIViewAndroid : public PasswordUIView { public: PasswordUIViewAndroid(JNIEnv* env, jobject); - virtual ~PasswordUIViewAndroid(); + ~PasswordUIViewAndroid() override; // PasswordUIView implementation. - virtual Profile* GetProfile() override; - virtual void ShowPassword(size_t index, const base::string16& password_value) - override; - virtual void SetPasswordList( + Profile* GetProfile() override; + void ShowPassword(size_t index, + const base::string16& password_value) override; + void SetPasswordList( const ScopedVector<autofill::PasswordForm>& password_list, bool show_passwords) override; - virtual void SetPasswordExceptionList( - const ScopedVector<autofill::PasswordForm>& password_exception_list) - override; + void SetPasswordExceptionList(const ScopedVector<autofill::PasswordForm>& + password_exception_list) override; // Calls from Java. base::android::ScopedJavaLocalRef<jobject> GetSavedPasswordEntry(
diff --git a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc index b4ffde3..d284d5d 100644 --- a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc +++ b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc
@@ -47,10 +47,10 @@ static jstring GetDefaultCountryCode(JNIEnv* env, jclass clazz) { - std::string defaultCountryCode = + std::string default_country_code = autofill::AutofillCountry::CountryCodeForLocale( g_browser_process->GetApplicationLocale()); - return ConvertUTF8ToJavaString(env, defaultCountryCode).Release(); + return ConvertUTF8ToJavaString(env, default_country_code).Release(); } static void GetSupportedCountries(JNIEnv* env, @@ -76,9 +76,10 @@ j_country_name_list); } -static void GetAddressUiComponents(JNIEnv* env, +static jstring GetAddressUiComponents(JNIEnv* env, jclass clazz, jstring j_country_code, + jstring j_language_code, jobject j_id_list, jobject j_name_list) { std::string best_language_tag; @@ -87,10 +88,18 @@ ::i18n::addressinput::Localization localization; localization.SetGetter(l10n_util::GetStringUTF8); + std::string language_code; + if (j_language_code != NULL) { + language_code = ConvertJavaStringToUTF8(env, j_language_code); + } + if (language_code.empty()) { + language_code = g_browser_process->GetApplicationLocale(); + } + std::vector<::i18n::addressinput::AddressUiComponent> ui_components = ::i18n::addressinput::BuildComponents( ConvertJavaStringToUTF8(env, j_country_code), localization, - g_browser_process->GetApplicationLocale(), &best_language_tag); + language_code, &best_language_tag); for (auto ui_component : ui_components) { component_labels.push_back(ui_component.name); @@ -136,6 +145,8 @@ ToJavaArrayOfStrings( env, component_labels).obj(), j_name_list); + + return ConvertUTF8ToJavaString(env, best_language_tag).Release(); } // static
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc index c37b4e0b..b0e8aec 100644 --- a/chrome/browser/android/preferences/pref_service_bridge.cc +++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -284,7 +284,7 @@ : weak_chrome_native_preferences_(env, obj) { } - virtual void OnBrowsingDataRemoverDone() override { + void OnBrowsingDataRemoverDone() override { // Just as a BrowsingDataRemover deletes itself when done, we delete ourself // when done. No need to remove ourself as an observer given the lifetime // of BrowsingDataRemover.
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc index 07adbf4b..d21bf9d 100644 --- a/chrome/browser/android/preferences/website_preference_bridge.cc +++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -366,7 +366,7 @@ private: friend class base::RefCountedThreadSafe<SiteDataDeleteHelper>; - virtual ~SiteDataDeleteHelper() {} + ~SiteDataDeleteHelper() override {} Profile* profile_;
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.h b/chrome/browser/android/provider/bookmark_model_observer_task.h index 64385545..eeb644d 100644 --- a/chrome/browser/android/provider/bookmark_model_observer_task.h +++ b/chrome/browser/android/provider/bookmark_model_observer_task.h
@@ -28,33 +28,32 @@ public bookmarks::BookmarkModelObserver { public: explicit BookmarkModelObserverTask(bookmarks::BookmarkModel* bookmark_model); - virtual ~BookmarkModelObserverTask(); + ~BookmarkModelObserverTask() override; // bookmarks::BookmarkModelObserver: - virtual void BookmarkModelLoaded(bookmarks::BookmarkModel* model, - bool ids_reassigned) override; - virtual void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const BookmarkNode* old_parent, - int old_index, - const BookmarkNode* new_parent, - int new_index) override; - virtual void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, - int index) override; - virtual void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node, + void BookmarkModelLoaded(bookmarks::BookmarkModel* model, + bool ids_reassigned) override; + void BookmarkNodeMoved(bookmarks::BookmarkModel* model, + const BookmarkNode* old_parent, + int old_index, + const BookmarkNode* new_parent, + int new_index) override; + void BookmarkNodeAdded(bookmarks::BookmarkModel* model, + const BookmarkNode* parent, + int index) override; + void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, + const BookmarkNode* parent, + int old_index, + const BookmarkNode* node, + const std::set<GURL>& removed_urls) override; + void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, const std::set<GURL>& removed_urls) override; - virtual void BookmarkAllUserNodesRemoved( - bookmarks::BookmarkModel* model, - const std::set<GURL>& removed_urls) override; - virtual void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - virtual void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; - virtual void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, - const BookmarkNode* node) override; + void BookmarkNodeChanged(bookmarks::BookmarkModel* model, + const BookmarkNode* node) override; + void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, + const BookmarkNode* node) override; + void BookmarkNodeChildrenReordered(bookmarks::BookmarkModel* model, + const BookmarkNode* node) override; private: DISALLOW_COPY_AND_ASSIGN(BookmarkModelObserverTask);
diff --git a/chrome/browser/android/provider/chrome_browser_provider.cc b/chrome/browser/android/provider/chrome_browser_provider.cc index 946e353..6191d63 100644 --- a/chrome/browser/android/provider/chrome_browser_provider.cc +++ b/chrome/browser/android/provider/chrome_browser_provider.cc
@@ -248,7 +248,7 @@ : BookmarkModelObserverTask(model), deleted_(0), id_to_delete_(kInvalidBookmarkId) {} - virtual ~RemoveBookmarkTask() {} + ~RemoveBookmarkTask() override {} int Run(const int64 id) { id_to_delete_ = id; @@ -267,12 +267,11 @@ } // Verify that the bookmark was actually removed. Called synchronously. - virtual void BookmarkNodeRemoved( - BookmarkModel* bookmark_model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node, - const std::set<GURL>& removed_urls) override { + void BookmarkNodeRemoved(BookmarkModel* bookmark_model, + const BookmarkNode* parent, + int old_index, + const BookmarkNode* node, + const std::set<GURL>& removed_urls) override { if (bookmark_model == model() && node->id() == id_to_delete_) ++deleted_; } @@ -290,7 +289,7 @@ explicit RemoveAllUserBookmarksTask(BookmarkModel* model) : BookmarkModelObserverTask(model) {} - virtual ~RemoveAllUserBookmarksTask() {} + ~RemoveAllUserBookmarksTask() override {} void Run() { RunOnUIThreadBlocking::Run( @@ -313,7 +312,7 @@ : BookmarkModelObserverTask(model), updated_(0), id_to_update_(kInvalidBookmarkId){} - virtual ~UpdateBookmarkTask() {} + ~UpdateBookmarkTask() override {} int Run(const int64 id, const base::string16& title, @@ -355,8 +354,8 @@ } // Verify that the bookmark was actually updated. Called synchronously. - virtual void BookmarkNodeChanged(BookmarkModel* bookmark_model, - const BookmarkNode* node) override { + void BookmarkNodeChanged(BookmarkModel* bookmark_model, + const BookmarkNode* node) override { if (bookmark_model == model() && node->id() == id_to_update_) ++updated_; }
diff --git a/chrome/browser/android/provider/chrome_browser_provider.h b/chrome/browser/android/provider/chrome_browser_provider.h index a2ff280..3fc4312b 100644 --- a/chrome/browser/android/provider/chrome_browser_provider.h +++ b/chrome/browser/android/provider/chrome_browser_provider.h
@@ -172,14 +172,13 @@ jstring url); private: - virtual ~ChromeBrowserProvider(); + ~ChromeBrowserProvider() override; // Override bookmarks::BaseBookmarkModelObserver. - virtual void BookmarkModelChanged() override; - virtual void ExtensiveBookmarkChangesBeginning( + void BookmarkModelChanged() override; + void ExtensiveBookmarkChangesBeginning( bookmarks::BookmarkModel* model) override; - virtual void ExtensiveBookmarkChangesEnded( - bookmarks::BookmarkModel* model) override; + void ExtensiveBookmarkChangesEnded(bookmarks::BookmarkModel* model) override; // Deals with updates to the history service. void OnHistoryChanged();
diff --git a/chrome/browser/android/recently_closed_tabs_bridge.h b/chrome/browser/android/recently_closed_tabs_bridge.h index ac11f3f..01eb50d 100644 --- a/chrome/browser/android/recently_closed_tabs_bridge.h +++ b/chrome/browser/android/recently_closed_tabs_bridge.h
@@ -34,16 +34,16 @@ // Observer callback for TabRestoreServiceObserver. Notifies the registered // callback that the recently closed tabs list has changed. - virtual void TabRestoreServiceChanged(TabRestoreService* service) override; + void TabRestoreServiceChanged(TabRestoreService* service) override; // Observer callback when our associated TabRestoreService is destroyed. - virtual void TabRestoreServiceDestroyed(TabRestoreService* service) override; + void TabRestoreServiceDestroyed(TabRestoreService* service) override; // Registers JNI methods. static bool Register(JNIEnv* env); private: - virtual ~RecentlyClosedTabsBridge(); + ~RecentlyClosedTabsBridge() override; // Construct and initialize tab_restore_service_ if it's NULL. // tab_restore_service_ may still be NULL, however, in incognito mode.
diff --git a/chrome/browser/android/resource_id.h b/chrome/browser/android/resource_id.h index 661f7efd..8f7fe09 100644 --- a/chrome/browser/android/resource_id.h +++ b/chrome/browser/android/resource_id.h
@@ -51,5 +51,7 @@ DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_MASTERCARD, R.drawable.mc_card) DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_VISA, R.drawable.visa_card) DEFINE_RESOURCE_ID(IDR_AUTOFILL_CC_SCAN_NEW, android.R.drawable.ic_menu_camera) +DEFINE_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT, R.drawable.cvc_icon) +DEFINE_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_AMEX, R.drawable.cvc_icon_amex) #endif // CHROME_BROWSER_ANDROID_RESOURCE_ID_H_
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index 7661e84a..0131235 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -15,6 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" #include "base/threading/worker_pool.h" +#include "chrome/browser/android/manifest_icon_selector.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/favicon/favicon_service.h" #include "chrome/browser/favicon/favicon_service_factory.h" @@ -30,6 +31,7 @@ #include "content/public/common/manifest.h" #include "jni/ShortcutHelper_jni.h" #include "net/base/mime_util.h" +#include "third_party/WebKit/public/platform/WebScreenOrientationLockType.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/color_analysis.h" @@ -58,10 +60,8 @@ content::WebContents* web_contents) : WebContentsObserver(web_contents), java_ref_(env, obj), - url_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( - web_contents->GetURL())), - display_(content::Manifest::DISPLAY_MODE_BROWSER), - orientation_(blink::WebScreenOrientationLockDefault), + shortcut_info_(dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( + web_contents->GetURL())), add_shortcut_requested_(false), manifest_icon_status_(MANIFEST_ICON_STATUS_NONE), preferred_icon_size_in_px_(kPreferredIconSizeInDp * @@ -87,12 +87,12 @@ web_app_info.description = web_app_info.description.substr(0, chrome::kMaxMetaTagAttributeLength); - title_ = web_app_info.title.empty() ? web_contents()->GetTitle() - : web_app_info.title; + shortcut_info_.title = web_app_info.title.empty() ? web_contents()->GetTitle() + : web_app_info.title; if (web_app_info.mobile_capable == WebApplicationInfo::MOBILE_CAPABLE || web_app_info.mobile_capable == WebApplicationInfo::MOBILE_CAPABLE_APPLE) { - display_ = content::Manifest::DISPLAY_MODE_STANDALONE; + shortcut_info_.display = content::Manifest::DISPLAY_MODE_STANDALONE; } // Record what type of shortcut was added by the user. @@ -115,161 +115,18 @@ weak_ptr_factory_.GetWeakPtr())); } -bool ShortcutHelper::IconSizesContainsPreferredSize( - const std::vector<gfx::Size>& sizes) const { - for (size_t i = 0; i < sizes.size(); ++i) { - if (sizes[i].height() != sizes[i].width()) - continue; - if (sizes[i].width() == preferred_icon_size_in_px_) - return true; - } - - return false; -} - -bool ShortcutHelper::IconSizesContainsAny( - const std::vector<gfx::Size>& sizes) const { - for (size_t i = 0; i < sizes.size(); ++i) { - if (sizes[i].IsEmpty()) - return true; - } - - return false; -} - -GURL ShortcutHelper::FindBestMatchingIcon( - const std::vector<Manifest::Icon>& icons, float density) const { - GURL url; - int best_delta = std::numeric_limits<int>::min(); - - for (size_t i = 0; i < icons.size(); ++i) { - if (icons[i].density != density) - continue; - - const std::vector<gfx::Size>& sizes = icons[i].sizes; - for (size_t j = 0; j < sizes.size(); ++j) { - if (sizes[j].height() != sizes[j].width()) - continue; - int delta = sizes[j].width() - preferred_icon_size_in_px_; - if (delta == 0) - return icons[i].src; - if (best_delta > 0 && delta < 0) - continue; - if ((best_delta > 0 && delta < best_delta) || - (best_delta < 0 && delta > best_delta)) { - url = icons[i].src; - best_delta = delta; - } - } - } - - return url; -} - -// static -std::vector<Manifest::Icon> ShortcutHelper::FilterIconsByType( - const std::vector<Manifest::Icon>& icons) { - std::vector<Manifest::Icon> result; - - for (size_t i = 0; i < icons.size(); ++i) { - if (icons[i].type.is_null() || - net::IsSupportedImageMimeType( - base::UTF16ToUTF8(icons[i].type.string()))) { - result.push_back(icons[i]); - } - } - - return result; -} - -GURL ShortcutHelper::FindBestMatchingIcon( - const std::vector<Manifest::Icon>& unfiltered_icons) const { - const float device_scale_factor = - gfx::Screen::GetScreenFor(web_contents()->GetNativeView())-> - GetPrimaryDisplay().device_scale_factor(); - - GURL url; - std::vector<Manifest::Icon> icons = FilterIconsByType(unfiltered_icons); - - // The first pass is to find the ideal icon. That icon is of the right size - // with the default density or the device's density. - for (size_t i = 0; i < icons.size(); ++i) { - if (icons[i].density == device_scale_factor && - IconSizesContainsPreferredSize(icons[i].sizes)) { - return icons[i].src; - } - - // If there is an icon with the right size but not the right density, keep - // it on the side and only use it if nothing better is found. - if (icons[i].density == Manifest::Icon::kDefaultDensity && - IconSizesContainsPreferredSize(icons[i].sizes)) { - url = icons[i].src; - } - } - - // The second pass is to find an icon with 'any'. The current device scale - // factor is preferred. Otherwise, the default scale factor is used. - for (size_t i = 0; i < icons.size(); ++i) { - if (icons[i].density == device_scale_factor && - IconSizesContainsAny(icons[i].sizes)) { - return icons[i].src; - } - - // If there is an icon with 'any' but not the right density, keep it on the - // side and only use it if nothing better is found. - if (icons[i].density == Manifest::Icon::kDefaultDensity && - IconSizesContainsAny(icons[i].sizes)) { - url = icons[i].src; - } - } - - // The last pass will try to find the best suitable icon for the device's - // scale factor. If none, another pass will be run using kDefaultDensity. - if (!url.is_valid()) - url = FindBestMatchingIcon(icons, device_scale_factor); - if (!url.is_valid()) - url = FindBestMatchingIcon(icons, Manifest::Icon::kDefaultDensity); - - return url; -} - void ShortcutHelper::OnDidGetManifest(const content::Manifest& manifest) { if (!manifest.IsEmpty()) { content::RecordAction( base::UserMetricsAction("webapps.AddShortcut.Manifest")); } - // Set the title based on the manifest value, if any. - if (!manifest.short_name.is_null()) - title_ = manifest.short_name.string(); - else if (!manifest.name.is_null()) - title_ = manifest.name.string(); + shortcut_info_.UpdateFromManifest(manifest); - // Set the url based on the manifest value, if any. - if (manifest.start_url.is_valid()) - url_ = manifest.start_url; - - // Set the display based on the manifest value, if any. - if (manifest.display != content::Manifest::DISPLAY_MODE_UNSPECIFIED) - display_ = manifest.display; - - // 'fullscreen' and 'minimal-ui' are not yet supported, fallback to the right - // mode in those cases. - if (manifest.display == content::Manifest::DISPLAY_MODE_FULLSCREEN) - display_ = content::Manifest::DISPLAY_MODE_STANDALONE; - if (manifest.display == content::Manifest::DISPLAY_MODE_MINIMAL_UI) - display_ = content::Manifest::DISPLAY_MODE_BROWSER; - - // Set the orientation based on the manifest value, if any. - if (manifest.orientation != blink::WebScreenOrientationLockDefault) { - // Ignore the orientation if the display mode is different from - // 'standalone'. - // TODO(mlamouri): send a message to the developer console about this. - if (display_ == content::Manifest::DISPLAY_MODE_STANDALONE) - orientation_ = manifest.orientation; - } - - GURL icon_src = FindBestMatchingIcon(manifest.icons); + GURL icon_src = ManifestIconSelector::FindBestMatchingIcon( + manifest.icons, + kPreferredIconSizeInDp, + gfx::Screen::GetScreenFor(web_contents()->GetNativeView())); if (icon_src.is_valid()) { web_contents()->DownloadImage(icon_src, false, @@ -286,7 +143,7 @@ JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); ScopedJavaLocalRef<jstring> j_title = - base::android::ConvertUTF16ToJavaString(env, title_); + base::android::ConvertUTF16ToJavaString(env, shortcut_info_.title); Java_ShortcutHelper_onInitialized(env, j_obj.obj(), j_title.obj()); } @@ -342,7 +199,7 @@ base::string16 title = base::android::ConvertJavaStringToUTF16(env, jtitle); if (!title.empty()) - title_ = title; + shortcut_info_.title = title; switch (manifest_icon_status_) { case MANIFEST_ICON_STATUS_NONE: @@ -364,11 +221,8 @@ base::WorkerPool::PostTask( FROM_HERE, base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithSkBitmap, - url_, - title_, - display_, - manifest_icon_, - orientation_), + shortcut_info_, + manifest_icon_), true); Destroy(); @@ -391,7 +245,9 @@ // Using favicon if its size is not smaller than platform required size, // otherwise using the largest icon among all avaliable icons. int threshold_to_get_any_largest_icon = preferred_icon_size_in_px_ - 1; - favicon_service->GetLargestRawFaviconForPageURL(url_, icon_types, + favicon_service->GetLargestRawFaviconForPageURL( + shortcut_info_.url, + icon_types, threshold_to_get_any_largest_icon, base::Bind(&ShortcutHelper::OnDidGetFavicon, base::Unretained(this)), @@ -406,11 +262,8 @@ base::WorkerPool::PostTask( FROM_HERE, base::Bind(&ShortcutHelper::AddShortcutInBackgroundWithRawBitmap, - url_, - title_, - display_, - bitmap_result, - orientation_), + shortcut_info_, + bitmap_result), true); Destroy(); @@ -437,11 +290,8 @@ } void ShortcutHelper::AddShortcutInBackgroundWithRawBitmap( - const GURL& url, - const base::string16& title, - content::Manifest::DisplayMode display, - const favicon_base::FaviconRawBitmapResult& bitmap_result, - blink::WebScreenOrientationLockType orientation) { + const ShortcutInfo& info, + const favicon_base::FaviconRawBitmapResult& bitmap_result) { DCHECK(base::WorkerPool::RunsTasksOnCurrentThread()); SkBitmap icon_bitmap; @@ -451,16 +301,12 @@ &icon_bitmap); } - AddShortcutInBackgroundWithSkBitmap( - url, title, display, icon_bitmap, orientation); + AddShortcutInBackgroundWithSkBitmap(info, icon_bitmap); } void ShortcutHelper::AddShortcutInBackgroundWithSkBitmap( - const GURL& url, - const base::string16& title, - content::Manifest::DisplayMode display, - const SkBitmap& icon_bitmap, - blink::WebScreenOrientationLockType orientation) { + const ShortcutInfo& info, + const SkBitmap& icon_bitmap) { DCHECK(base::WorkerPool::RunsTasksOnCurrentThread()); SkColor color = color_utils::CalculateKMeanColorOfBitmap(icon_bitmap); @@ -471,9 +317,9 @@ // Send the data to the Java side to create the shortcut. JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jstring> java_url = - base::android::ConvertUTF8ToJavaString(env, url.spec()); + base::android::ConvertUTF8ToJavaString(env, info.url.spec()); ScopedJavaLocalRef<jstring> java_title = - base::android::ConvertUTF16ToJavaString(env, title); + base::android::ConvertUTF16ToJavaString(env, info.title); ScopedJavaLocalRef<jobject> java_bitmap; if (icon_bitmap.getSize()) java_bitmap = gfx::ConvertToJavaBitmap(&icon_bitmap); @@ -487,6 +333,6 @@ r_value, g_value, b_value, - display == content::Manifest::DISPLAY_MODE_STANDALONE, - orientation); + info.display == content::Manifest::DISPLAY_MODE_STANDALONE, + info.orientation); }
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h index 7c7b749..5b866df 100644 --- a/chrome/browser/android/shortcut_helper.h +++ b/chrome/browser/android/shortcut_helper.h
@@ -8,13 +8,12 @@ #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" #include "base/basictypes.h" -#include "base/strings/string16.h" #include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/android/shortcut_info.h" #include "chrome/common/web_application_info.h" #include "components/favicon_base/favicon_types.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/manifest.h" -#include "third_party/WebKit/public/platform/WebScreenOrientationLockType.h" namespace content { class WebContents; @@ -79,26 +78,20 @@ const favicon_base::FaviconRawBitmapResult& bitmap_result); // WebContentsObserver - virtual bool OnMessageReceived(const IPC::Message& message) override; - virtual void WebContentsDestroyed() override; + bool OnMessageReceived(const IPC::Message& message) override; + void WebContentsDestroyed() override; // Adds a shortcut to the launcher using a FaviconRawBitmapResult. // Must be called from a WorkerPool task. static void AddShortcutInBackgroundWithRawBitmap( - const GURL& url, - const base::string16& title, - content::Manifest::DisplayMode display, - const favicon_base::FaviconRawBitmapResult& bitmap_result, - blink::WebScreenOrientationLockType orientation); + const ShortcutInfo& info, + const favicon_base::FaviconRawBitmapResult& bitmap_result); // Adds a shortcut to the launcher using a SkBitmap. // Must be called from a WorkerPool task. static void AddShortcutInBackgroundWithSkBitmap( - const GURL& url, - const base::string16& title, - content::Manifest::DisplayMode display, - const SkBitmap& icon_bitmap, - blink::WebScreenOrientationLockType orientation); + const ShortcutInfo& info, + const SkBitmap& icon_bitmap); // Registers JNI hooks. static bool RegisterShortcutHelper(JNIEnv* env); @@ -110,43 +103,15 @@ MANIFEST_ICON_STATUS_DONE }; - virtual ~ShortcutHelper(); + ~ShortcutHelper() override; void Destroy(); - // Runs the algorithm to find the best matching icon in the icons listed in - // the Manifest. - // Returns the icon url if a suitable icon is found. An empty URL otherwise. - GURL FindBestMatchingIcon( - const std::vector<content::Manifest::Icon>& icons) const; - - // Runs an algorithm only based on icon declared sizes. It will try to find - // size that is the closest to preferred_icon_size_in_px_ but bigger than - // preferred_icon_size_in_px_ if possible. - // Returns the icon url if a suitable icon is found. An empty URL otherwise. - GURL FindBestMatchingIcon(const std::vector<content::Manifest::Icon>& icons, - float density) const; - - // Returns an array containing the items in |icons| without the unsupported - // image MIME types. - static std::vector<content::Manifest::Icon> FilterIconsByType( - const std::vector<content::Manifest::Icon>& icons); - - // Returns whether the preferred_icon_size_in_px_ is in the given |sizes|. - bool IconSizesContainsPreferredSize( - const std::vector<gfx::Size>& sizes) const; - - // Returns whether the 'any' (ie. gfx::Size(0,0)) is in the given |sizes|. - bool IconSizesContainsAny(const std::vector<gfx::Size>& sizes) const; - JavaObjectWeakGlobalRef java_ref_; - GURL url_; - base::string16 title_; - content::Manifest::DisplayMode display_; + ShortcutInfo shortcut_info_; SkBitmap manifest_icon_; base::CancelableTaskTracker cancelable_task_tracker_; - blink::WebScreenOrientationLockType orientation_; bool add_shortcut_requested_; @@ -156,7 +121,6 @@ base::WeakPtrFactory<ShortcutHelper> weak_ptr_factory_; - friend class ShortcutHelperTest; DISALLOW_COPY_AND_ASSIGN(ShortcutHelper); };
diff --git a/chrome/browser/android/shortcut_info.cc b/chrome/browser/android/shortcut_info.cc new file mode 100644 index 0000000..24406b8 --- /dev/null +++ b/chrome/browser/android/shortcut_info.cc
@@ -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. + +#include "chrome/browser/android/shortcut_info.h" + +ShortcutInfo::ShortcutInfo() + : display(content::Manifest::DISPLAY_MODE_BROWSER), + orientation(blink::WebScreenOrientationLockDefault) { +} + +ShortcutInfo::ShortcutInfo(const GURL& shortcut_url) + : url(shortcut_url), + display(content::Manifest::DISPLAY_MODE_BROWSER), + orientation(blink::WebScreenOrientationLockDefault) { +} + +void ShortcutInfo::UpdateFromManifest(const content::Manifest& manifest) { + if (!manifest.short_name.is_null()) + title = manifest.short_name.string(); + else if (!manifest.name.is_null()) + title = manifest.name.string(); + + // Set the url based on the manifest value, if any. + if (manifest.start_url.is_valid()) + url = manifest.start_url; + + // Set the display based on the manifest value, if any. + if (manifest.display != content::Manifest::DISPLAY_MODE_UNSPECIFIED) + display = manifest.display; + + // 'fullscreen' and 'minimal-ui' are not yet supported, fallback to the right + // mode in those cases. + if (manifest.display == content::Manifest::DISPLAY_MODE_FULLSCREEN) + display = content::Manifest::DISPLAY_MODE_STANDALONE; + if (manifest.display == content::Manifest::DISPLAY_MODE_MINIMAL_UI) + display = content::Manifest::DISPLAY_MODE_BROWSER; + + // Set the orientation based on the manifest value, if any. + if (manifest.orientation != blink::WebScreenOrientationLockDefault) { + // Ignore the orientation if the display mode is different from + // 'standalone'. + // TODO(mlamouri): send a message to the developer console about this. + if (display == content::Manifest::DISPLAY_MODE_STANDALONE) + orientation = manifest.orientation; + } +}
diff --git a/chrome/browser/android/shortcut_info.h b/chrome/browser/android/shortcut_info.h new file mode 100644 index 0000000..9415103 --- /dev/null +++ b/chrome/browser/android/shortcut_info.h
@@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_SHORTCUT_INFO_H_ +#define CHROME_BROWSER_ANDROID_SHORTCUT_INFO_H_ + +#include "base/strings/string16.h" +#include "content/public/common/manifest.h" +#include "third_party/WebKit/public/platform/WebScreenOrientationLockType.h" +#include "url/gurl.h" + +// Information needed to create a shortcut via ShortcutHelper. +struct ShortcutInfo { + ShortcutInfo(); + explicit ShortcutInfo(const GURL& shortcut_url); + + // Updates the info based on the given |manifest|. + void UpdateFromManifest(const content::Manifest& manifest); + + GURL url; + base::string16 title; + content::Manifest::DisplayMode display; + blink::WebScreenOrientationLockType orientation; +}; + +#endif // CHROME_BROWSER_ANDROID_SHORTCUT_INFO_H_
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc index c94d203..a2e96e8 100644 --- a/chrome/browser/android/signin/signin_manager_android.cc +++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -61,7 +61,7 @@ remover_->Remove(BrowsingDataRemover::REMOVE_ALL, BrowsingDataHelper::ALL); } - virtual ~ProfileDataRemover() {} + ~ProfileDataRemover() override {} void OnBrowsingDataRemoverDone() override { remover_->RemoveObserver(this);
diff --git a/chrome/browser/android/signin/signin_manager_android.h b/chrome/browser/android/signin/signin_manager_android.h index ce4a95d..23424f8 100644 --- a/chrome/browser/android/signin/signin_manager_android.h +++ b/chrome/browser/android/signin/signin_manager_android.h
@@ -67,7 +67,7 @@ jboolean IsSignedInOnNative(JNIEnv* env, jobject obj); private: - virtual ~SigninManagerAndroid(); + ~SigninManagerAndroid() override; #if defined(ENABLE_CONFIGURATION_POLICY) void OnPolicyRegisterDone(const std::string& dm_token,
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h index 57c019b..182e799 100644 --- a/chrome/browser/android/tab_android.h +++ b/chrome/browser/android/tab_android.h
@@ -71,7 +71,7 @@ static void AttachTabHelpers(content::WebContents* web_contents); TabAndroid(JNIEnv* env, jobject obj); - virtual ~TabAndroid(); + ~TabAndroid() override; base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); @@ -111,25 +111,25 @@ // CoreTabHelperDelegate ---------------------------------------------------- - virtual void SwapTabContents(content::WebContents* old_contents, - content::WebContents* new_contents, - bool did_start_load, - bool did_finish_load) override; + void SwapTabContents(content::WebContents* old_contents, + content::WebContents* new_contents, + bool did_start_load, + bool did_finish_load) override; // Overridden from InstantServiceObserver: void DefaultSearchProviderChanged() override; // Overridden from SearchTabHelperDelegate: - virtual void OnWebContentsInstantSupportDisabled( + void OnWebContentsInstantSupportDisabled( const content::WebContents* web_contents) override; // NotificationObserver ----------------------------------------------------- - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; // FaviconTabHelperObserver ----------------------------------------------- - virtual void OnFaviconAvailable(const gfx::Image& image) override; + void OnFaviconAvailable(const gfx::Image& image) override; // Methods called from Java via JNI -----------------------------------------
diff --git a/chrome/browser/android/thumbnail/thumbnail.h b/chrome/browser/android/thumbnail/thumbnail.h index 49de59c..79ed868 100644 --- a/chrome/browser/android/thumbnail/thumbnail.h +++ b/chrome/browser/android/thumbnail/thumbnail.h
@@ -42,7 +42,7 @@ float scale, ui::UIResourceProvider* ui_resource_provider, ThumbnailDelegate* thumbnail_delegate); - virtual ~Thumbnail(); + ~Thumbnail() override; TabId tab_id() const { return tab_id_; } base::Time time_stamp() const { return time_stamp_; } @@ -57,11 +57,11 @@ void CreateUIResource(); // content::UIResourceClient implementation. - virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, - bool resource_lost) override; + cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, + bool resource_lost) override; // ui::UIResourceClientAndroid implementation. - virtual void UIResourceIsInvalid() override; + void UIResourceIsInvalid() override; protected: Thumbnail(TabId tab_id,
diff --git a/chrome/browser/android/thumbnail/thumbnail_store.h b/chrome/browser/android/thumbnail/thumbnail_store.h index 94cdbba..8ad0c1a 100644 --- a/chrome/browser/android/thumbnail/thumbnail_store.h +++ b/chrome/browser/android/thumbnail/thumbnail_store.h
@@ -50,7 +50,7 @@ size_t write_queue_max_size, bool use_approximation_thumbnail); - virtual ~ThumbnailStore(); + ~ThumbnailStore() override; void SetUIResourceProvider(ui::UIResourceProvider* ui_resource_provider); @@ -72,7 +72,7 @@ post_decompress_callback); // ThumbnailDelegate implementation - virtual void InvalidateCachedThumbnail(Thumbnail* thumbnail) override; + void InvalidateCachedThumbnail(Thumbnail* thumbnail) override; private: class ThumbnailMetaData {
diff --git a/chrome/browser/android/webapps/single_tab_mode_tab_helper.h b/chrome/browser/android/webapps/single_tab_mode_tab_helper.h index a79fd2e..744aee3da 100644 --- a/chrome/browser/android/webapps/single_tab_mode_tab_helper.h +++ b/chrome/browser/android/webapps/single_tab_mode_tab_helper.h
@@ -30,7 +30,7 @@ // Checks if the ID pair is blocked from creating new windows. IO-thread only. static bool IsRegistered(int32 process_id, int32 routing_id); - virtual ~SingleTabModeTabHelper(); + ~SingleTabModeTabHelper() override; // Handles opening the given URL through the TabModel. void HandleOpenUrl(const BlockedWindowParams& params); @@ -40,10 +40,8 @@ void PermanentlyBlockAllNewWindows(); // content::WebContentsObserver - virtual void RenderViewCreated(content::RenderViewHost* render_view_host) - override; - virtual void RenderViewDeleted(content::RenderViewHost* render_view_host) - override; + void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void RenderViewDeleted(content::RenderViewHost* render_view_host) override; private: explicit SingleTabModeTabHelper(content::WebContents* web_contents);
diff --git a/chrome/browser/apps/app_shim/browser_app_shim.gypi b/chrome/browser/apps/app_shim/browser_app_shim.gypi index 4c6c9aa8..806ebe7a 100644 --- a/chrome/browser/apps/app_shim/browser_app_shim.gypi +++ b/chrome/browser/apps/app_shim/browser_app_shim.gypi
@@ -10,8 +10,9 @@ 'target_name': 'browser_app_shim', 'type': 'static_library', 'dependencies': [ - # Since browser_app_shim and browser depend on each other, we omit the - # dependency on browser here. + # Since browser_app_shim and chrome.gyp:browser depend on each other, + # we omit the dependency on browser here. + '../content/content.gyp:content_browser', '../content/content.gyp:content_common', ], 'sources': [
diff --git a/chrome/browser/apps/ephemeral_app_browsertest.cc b/chrome/browser/apps/ephemeral_app_browsertest.cc index 53c2991..d28dd32 100644 --- a/chrome/browser/apps/ephemeral_app_browsertest.cc +++ b/chrome/browser/apps/ephemeral_app_browsertest.cc
@@ -273,8 +273,8 @@ content::Source<extensions::CrxInstaller>(crx_installer)); ExtensionService* service = ExtensionSystem::Get(profile())->extension_service(); - EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true, - &crx_installer)); + EXPECT_TRUE(service->UpdateExtension( + extensions::CRXFileInfo(app_id, app_v2_path), true, &crx_installer)); windowed_observer.Wait(); return ExtensionRegistry::Get(profile())
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.h b/chrome/browser/autofill/android/personal_data_manager_android.h index b951ff2..ed818a3 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.h +++ b/chrome/browser/autofill/android/personal_data_manager_android.h
@@ -88,13 +88,13 @@ void ClearUnmaskedCache(JNIEnv* env, jobject unused_obj); // PersonalDataManagerObserver: - virtual void OnPersonalDataChanged() override; + void OnPersonalDataChanged() override; // Registers the JNI bindings for this class. static bool Register(JNIEnv* env); private: - virtual ~PersonalDataManagerAndroid(); + ~PersonalDataManagerAndroid() override; // Pointer to the java counterpart. JavaObjectWeakGlobalRef weak_java_obj_;
diff --git a/chrome/browser/background/background_contents.cc b/chrome/browser/background/background_contents.cc index 9d015339..7a1150b3 100644 --- a/chrome/browser/background/background_contents.cc +++ b/chrome/browser/background/background_contents.cc
@@ -118,11 +118,11 @@ void BackgroundContents::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { delegate_->AddWebContents( - new_contents, disposition, initial_pos, user_gesture, was_blocked); + new_contents, disposition, initial_rect, user_gesture, was_blocked); } bool BackgroundContents::IsNeverVisible(content::WebContents* web_contents) {
diff --git a/chrome/browser/background/background_contents.h b/chrome/browser/background/background_contents.h index 59711e4b..e7345e3 100644 --- a/chrome/browser/background/background_contents.h +++ b/chrome/browser/background/background_contents.h
@@ -36,7 +36,7 @@ // set to true if the popup gets blocked, and left unchanged otherwise. virtual void AddWebContents(content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) = 0; @@ -63,7 +63,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; bool IsNeverVisible(content::WebContents* web_contents) override;
diff --git a/chrome/browser/background/background_contents_service.cc b/chrome/browser/background/background_contents_service.cc index f502748..361107b 100644 --- a/chrome/browser/background/background_contents_service.cc +++ b/chrome/browser/background/background_contents_service.cc
@@ -767,7 +767,7 @@ void BackgroundContentsService::AddWebContents( WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { Browser* browser = chrome::FindLastActiveWithProfile( @@ -775,6 +775,6 @@ chrome::GetActiveDesktop()); if (browser) { chrome::AddWebContents(browser, NULL, new_contents, disposition, - initial_pos, user_gesture, was_blocked); + initial_rect, user_gesture, was_blocked); } }
diff --git a/chrome/browser/background/background_contents_service.h b/chrome/browser/background/background_contents_service.h index 81243bb..380982b 100644 --- a/chrome/browser/background/background_contents_service.h +++ b/chrome/browser/background/background_contents_service.h
@@ -91,7 +91,7 @@ // BackgroundContents::Delegate implementation. void AddWebContents(content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override;
diff --git a/chrome/browser/browser_process_platform_part_android.h b/chrome/browser/browser_process_platform_part_android.h index 7c764fad..9f8ee3c 100644 --- a/chrome/browser/browser_process_platform_part_android.h +++ b/chrome/browser/browser_process_platform_part_android.h
@@ -11,10 +11,10 @@ class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase { public: BrowserProcessPlatformPart(); - virtual ~BrowserProcessPlatformPart(); + ~BrowserProcessPlatformPart() override; // Overridden from BrowserProcessPlatformPartBase: - virtual void AttemptExit() override; + void AttemptExit() override; private: DISALLOW_COPY_AND_ASSIGN(BrowserProcessPlatformPart);
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index e9e9933..2b86dc0 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -553,10 +553,6 @@ // BrowserMainParts ------------------------------------------------------------ -// static -bool ChromeBrowserMainParts::disable_enforcing_cookie_policies_for_tests_ = - false; - ChromeBrowserMainParts::ChromeBrowserMainParts( const content::MainFunctionParams& parameters) : parameters_(parameters), @@ -577,8 +573,7 @@ // Chrome disallows cookies by default. All code paths that want to use // cookies need to go through one of Chrome's URLRequestContexts which have // a ChromeNetworkDelegate attached that selectively allows cookies again. - if (!disable_enforcing_cookie_policies_for_tests_) - net::URLRequest::SetDefaultCookiePolicyToBlock(); + net::URLRequest::SetDefaultCookiePolicyToBlock(); } ChromeBrowserMainParts::~ChromeBrowserMainParts() {
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h index aa9d6cc..5d60afa3 100644 --- a/chrome/browser/chrome_browser_main.h +++ b/chrome/browser/chrome_browser_main.h
@@ -185,10 +185,6 @@ // Members needed across shutdown methods. bool restart_last_session_; - // Tests can set this to true to disable restricting cookie access in the - // network stack, as this can only be done once. - static bool disable_enforcing_cookie_policies_for_tests_; - DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainParts); };
diff --git a/chrome/browser/chrome_browser_main_android.h b/chrome/browser/chrome_browser_main_android.h index f0d68d5..8781d982 100644 --- a/chrome/browser/chrome_browser_main_android.h +++ b/chrome/browser/chrome_browser_main_android.h
@@ -17,15 +17,15 @@ public: explicit ChromeBrowserMainPartsAndroid( const content::MainFunctionParams& parameters); - virtual ~ChromeBrowserMainPartsAndroid(); + ~ChromeBrowserMainPartsAndroid() override; // content::BrowserMainParts overrides. - virtual int PreCreateThreads() override; - virtual void PostProfileInit() override; - virtual void PreEarlyInitialization() override; + int PreCreateThreads() override; + void PostProfileInit() override; + void PreEarlyInitialization() override; // ChromeBrowserMainParts overrides. - virtual void ShowMissingLocaleMessageBox() override; + void ShowMissingLocaleMessageBox() override; private: scoped_ptr<base::MessageLoop> main_message_loop_;
diff --git a/chrome/browser/chrome_site_per_process_browsertest.cc b/chrome/browser/chrome_site_per_process_browsertest.cc index 2f212aa7..1ed8186 100644 --- a/chrome/browser/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/chrome_site_per_process_browsertest.cc
@@ -41,6 +41,15 @@ DISALLOW_COPY_AND_ASSIGN(ChromeSitePerProcessTest); }; +// Verify that browser shutdown path works correctly when there's a +// RenderFrameProxyHost for a child frame. +IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, RenderFrameProxyHostShutdown) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", + "/frame_tree/page_with_two_frames_remote_and_local.html")); + ui_test_utils::NavigateToURL(browser(), main_url); +} + // Verify that origin replication allows JS access to localStorage, database, // and FileSystem APIs. These features involve a check on the // WebSecurityOrigin of the topmost WebFrame in ContentSettingsObserver, and
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 13f5305..8fa28a3 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -110,6 +110,7 @@ "//ui/chromeos:ui_chromeos", "//ui/compositor", "//ui/display", + "//ui/events/devices", "//ui/events/platform", "//ui/events:dom4_keycode_converter", "//ui/file_manager",
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc index 5c2e583..8407bda 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -575,7 +575,8 @@ DISALLOW_COPY_AND_ASSIGN(OobeSpokenFeedbackTest); }; -IN_PROC_BROWSER_TEST_F(OobeSpokenFeedbackTest, SpokenFeedbackInOobe) { +// Test is flaky: http://crbug.com/346797 +IN_PROC_BROWSER_TEST_F(OobeSpokenFeedbackTest, DISABLED_SpokenFeedbackInOobe) { ui_controls::EnableUIControls(); ASSERT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc index e9b34015..93b45f37 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
@@ -146,12 +146,10 @@ } scoped_refptr<extensions::SandboxedUnpacker> unpacker( - new extensions::SandboxedUnpacker(crx_file_, - extensions::Manifest::INTERNAL, - extensions::Extension::NO_FLAGS, - temp_dir_.path(), - task_runner_.get(), - this)); + new extensions::SandboxedUnpacker( + extensions::CRXFileInfo(crx_file_), extensions::Manifest::INTERNAL, + extensions::Extension::NO_FLAGS, temp_dir_.path(), + task_runner_.get(), this)); unpacker->Start(); }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc index ed2754e..e1ed18c 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc
@@ -14,13 +14,11 @@ KioskExternalUpdateValidator::KioskExternalUpdateValidator( const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner, - const std::string& app_id, - const base::FilePath& crx_dir, + const extensions::CRXFileInfo& file, const base::FilePath& crx_unpack_dir, const base::WeakPtr<KioskExternalUpdateValidatorDelegate>& delegate) : backend_task_runner_(backend_task_runner), - app_id_(app_id), - crx_dir_(crx_dir), + crx_file_(file), crx_unpack_dir_(crx_unpack_dir), delegate_(delegate) { } @@ -30,12 +28,10 @@ void KioskExternalUpdateValidator::Start() { scoped_refptr<extensions::SandboxedUnpacker> unpacker( - new extensions::SandboxedUnpacker(crx_dir_, - extensions::Manifest::EXTERNAL_PREF, - extensions::Extension::NO_FLAGS, - crx_unpack_dir_, - backend_task_runner_.get(), - this)); + new extensions::SandboxedUnpacker( + crx_file_, extensions::Manifest::EXTERNAL_PREF, + extensions::Extension::NO_FLAGS, crx_unpack_dir_, + backend_task_runner_.get(), this)); if (!backend_task_runner_->PostTask( FROM_HERE, base::Bind(&extensions::SandboxedUnpacker::Start, unpacker.get()))) { @@ -45,15 +41,13 @@ void KioskExternalUpdateValidator::OnUnpackFailure( const base::string16& error_message) { - LOG(ERROR) << "Failed to unpack external kiosk crx file: " << app_id_ << " " - << error_message; + LOG(ERROR) << "Failed to unpack external kiosk crx file: " + << crx_file_.extension_id << " " << error_message; content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, + content::BrowserThread::UI, FROM_HERE, base::Bind( &KioskExternalUpdateValidatorDelegate::OnExternalUpdateUnpackFailure, - delegate_, - app_id_)); + delegate_, crx_file_.extension_id)); } void KioskExternalUpdateValidator::OnUnpackSuccess( @@ -62,26 +56,23 @@ const base::DictionaryValue* original_manifest, const extensions::Extension* extension, const SkBitmap& install_icon) { - DCHECK(app_id_ == extension->id()); + DCHECK(crx_file_.extension_id == extension->id()); std::string minimum_browser_version; if (!extension->manifest()->GetString( extensions::manifest_keys::kMinimumChromeVersion, &minimum_browser_version)) { - LOG(ERROR) << "Can't find minimum browser version for app " << app_id_; + LOG(ERROR) << "Can't find minimum browser version for app " + << crx_file_.extension_id; minimum_browser_version.clear(); } content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, + content::BrowserThread::UI, FROM_HERE, base::Bind( &KioskExternalUpdateValidatorDelegate::OnExtenalUpdateUnpackSuccess, - delegate_, - app_id_, - extension->VersionString(), - minimum_browser_version, - temp_dir)); + delegate_, crx_file_.extension_id, extension->VersionString(), + minimum_browser_version, temp_dir)); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h index dd02095..4d85f605 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h
@@ -39,8 +39,7 @@ public: KioskExternalUpdateValidator( const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner, - const std::string& app_id, - const base::FilePath& crx_path, + const extensions::CRXFileInfo& file, const base::FilePath& crx_unpack_dir, const base::WeakPtr<KioskExternalUpdateValidatorDelegate>& delegate); @@ -60,10 +59,10 @@ // Task runner for executing file I/O tasks. const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; - std::string app_id_; - // The directory where the external crx file resides. - base::FilePath crx_dir_; + // Information about the external crx file. + extensions::CRXFileInfo crx_file_; + // The temporary directory used by SandBoxedUnpacker for unpacking extensions. const base::FilePath crx_unpack_dir_;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc index bcef462..1617cc8a 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -93,6 +93,9 @@ KioskExternalUpdater::ExternalUpdate::ExternalUpdate() { } +KioskExternalUpdater::ExternalUpdate::~ExternalUpdate() { +} + KioskExternalUpdater::KioskExternalUpdater( const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner, const base::FilePath& crx_cache_dir, @@ -196,7 +199,8 @@ if (CheckExternalUpdateInterrupted()) return; - base::FilePath external_crx_path = external_updates_[app_id].external_crx; + base::FilePath external_crx_path = + external_updates_[app_id].external_crx.path; base::FilePath temp_crx_path = crx_unpack_dir_.Append(external_crx_path.BaseName()); bool* success = new bool; @@ -291,7 +295,8 @@ } else { NOTREACHED(); } - update.external_crx = external_update_path_.AppendASCII(external_crx_str); + update.external_crx = extensions::CRXFileInfo( + app_id, external_update_path_.AppendASCII(external_crx_str)); update.update_status = PENDING; external_updates_[app_id] = update; } @@ -326,7 +331,6 @@ if (it->second.update_status == PENDING) { scoped_refptr<KioskExternalUpdateValidator> crx_validator = new KioskExternalUpdateValidator(backend_task_runner_, - it->first, it->second.external_crx, crx_unpack_dir_, weak_factory_.GetWeakPtr()); @@ -429,7 +433,7 @@ external_updates_[app_id].update_status = FAILED; external_updates_[app_id].error = l10n_util::GetStringFUTF16( IDS_KIOSK_EXTERNAL_UPDATE_CANNOT_INSTALL_IN_LOCAL_CACHE, - base::UTF8ToUTF16(external_updates_[app_id].external_crx.value())); + base::UTF8ToUTF16(external_updates_[app_id].external_crx.path.value())); } else { external_updates_[app_id].update_status = SUCCESS; }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h index 02c40dc3..f56b0f72 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
@@ -45,9 +45,10 @@ }; struct ExternalUpdate { ExternalUpdate(); + ~ExternalUpdate(); std::string app_name; - base::FilePath external_crx; + extensions::CRXFileInfo external_crx; ExternalUpdateStatus update_status; base::string16 error; };
diff --git a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc index 4bdd7dd6c..a7652a3 100644 --- a/chrome/browser/chromeos/app_mode/startup_app_launcher.cc +++ b/chrome/browser/chromeos/app_mode/startup_app_launcher.cc
@@ -272,8 +272,13 @@ void StartupAppLauncher::OnFinishCrxInstall(const std::string& extension_id, bool success) { - if (extension_id != app_id_) + // Wait for pending updates or dependent extensions to download. + if (extensions::ExtensionSystem::Get(profile_) + ->extension_service() + ->pending_extension_manager() + ->HasPendingExtensions()) { return; + } extensions::InstallTracker* tracker = extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc index 6fb6233..6255d15 100644 --- a/chrome/browser/chromeos/display/display_preferences_unittest.cc +++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -674,20 +674,18 @@ gfx::Display::ROTATE_0); // Open up 270 degrees to trigger maximize mode - ui::AccelerometerUpdate update; - update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, - 0.0f, 0.0f, kMeanGravity); - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, - 0.0f, -kMeanGravity, 0.0f); + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 0.0f, 0.0f, + kMeanGravity); + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, 0.0f, -kMeanGravity, 0.0f); ash::MaximizeModeController* controller = shell->maximize_mode_controller(); controller->OnAccelerometerUpdated(update); EXPECT_TRUE(controller->IsMaximizeModeWindowManagerEnabled()); // Trigger 90 degree rotation - update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, - -kMeanGravity, 0.0f, 0.0f); - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, - -kMeanGravity, 0.0f, 0.0f); + update.Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, -kMeanGravity, + 0.0f, 0.0f); + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, -kMeanGravity, 0.0f, 0.0f); controller->OnAccelerometerUpdated(update); shell->screen_orientation_controller()->OnAccelerometerUpdated(update); EXPECT_EQ(gfx::Display::ROTATE_90, display_manager-> @@ -814,11 +812,10 @@ EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation); // Open up 270 degrees to trigger maximize mode - ui::AccelerometerUpdate update; - update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, - 0.0f, 0.0f, kMeanGravity); - update.Set(ui::ACCELEROMETER_SOURCE_SCREEN, - 0.0f, -kMeanGravity, 0.0f); + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 0.0f, 0.0f, + kMeanGravity); + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, 0.0f, -kMeanGravity, 0.0f); ash::MaximizeModeController* maximize_mode_controller = shell->maximize_mode_controller(); maximize_mode_controller->OnAccelerometerUpdated(update);
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc index 7eaa7b0..aed81d1 100644 --- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc +++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -17,12 +17,12 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/chromeos/input_method/input_method_configuration.h" #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/preferences.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_pref_service_syncable.h" #include "chromeos/chromeos_switches.h" +#include "components/user_manager/fake_user_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -222,7 +222,7 @@ class EventRewriterTest : public ash::test::AshTestBase { public: EventRewriterTest() - : fake_user_manager_(new chromeos::FakeUserManager), + : fake_user_manager_(new user_manager::FakeUserManager), user_manager_enabler_(fake_user_manager_), input_method_manager_mock_(NULL) {} ~EventRewriterTest() override {} @@ -255,7 +255,7 @@ : &event; } - chromeos::FakeUserManager* fake_user_manager_; // Not owned. + user_manager::FakeUserManager* fake_user_manager_; // Not owned. chromeos::ScopedUserManagerEnabler user_manager_enabler_; chromeos::input_method::MockInputMethodManager* input_method_manager_mock_; }; @@ -1821,7 +1821,7 @@ public: EventRewriterAshTest() : source_(&buffer_), - fake_user_manager_(new chromeos::FakeUserManager), + fake_user_manager_(new user_manager::FakeUserManager), user_manager_enabler_(fake_user_manager_) {} ~EventRewriterAshTest() override {} @@ -1880,7 +1880,7 @@ EventBuffer buffer_; TestEventSource source_; - chromeos::FakeUserManager* fake_user_manager_; // Not owned. + user_manager::FakeUserManager* fake_user_manager_; // Not owned. chromeos::ScopedUserManagerEnabler user_manager_enabler_; TestingPrefServiceSyncable prefs_;
diff --git a/chrome/browser/chromeos/extensions/external_cache.cc b/chrome/browser/chromeos/extensions/external_cache.cc index dd2a00f..c3f7b47b 100644 --- a/chrome/browser/chromeos/extensions/external_cache.cc +++ b/chrome/browser/chromeos/extensions/external_cache.cc
@@ -179,18 +179,17 @@ } void ExternalCache::OnExtensionDownloadFinished( - const std::string& id, - const base::FilePath& path, + const extensions::CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version, const extensions::ExtensionDownloaderDelegate::PingResult& ping_result, const std::set<int>& request_ids) { DCHECK(file_ownership_passed); - local_cache_.PutExtension(id, path, version, - base::Bind(&ExternalCache::OnPutExtension, - weak_ptr_factory_.GetWeakPtr(), - id)); + local_cache_.PutExtension( + file.extension_id, file.path, version, + base::Bind(&ExternalCache::OnPutExtension, weak_ptr_factory_.GetWeakPtr(), + file.extension_id)); } bool ExternalCache::IsExtensionPending(const std::string& id) {
diff --git a/chrome/browser/chromeos/extensions/external_cache.h b/chrome/browser/chromeos/extensions/external_cache.h index 6b4590a..f85e00a 100644 --- a/chrome/browser/chromeos/extensions/external_cache.h +++ b/chrome/browser/chromeos/extensions/external_cache.h
@@ -91,8 +91,7 @@ const PingResult& ping_result, const std::set<int>& request_ids) override; - void OnExtensionDownloadFinished(const std::string& id, - const base::FilePath& path, + void OnExtensionDownloadFinished(const extensions::CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version,
diff --git a/chrome/browser/chromeos/extensions/external_cache_unittest.cc b/chrome/browser/chromeos/extensions/external_cache_unittest.cc index e0c63155..df6baeb1 100644 --- a/chrome/browser/chromeos/extensions/external_cache_unittest.cc +++ b/chrome/browser/chromeos/extensions/external_cache_unittest.cc
@@ -205,13 +205,9 @@ base::FilePath temp_dir(CreateTempDir()); base::FilePath temp_file2 = temp_dir.Append("b.crx"); CreateFile(temp_file2); - external_cache.OnExtensionDownloadFinished(kTestExtensionId2, - temp_file2, - true, - GURL(), - "2", - extensions::ExtensionDownloaderDelegate::PingResult(), - std::set<int>()); + external_cache.OnExtensionDownloadFinished( + extensions::CRXFileInfo(kTestExtensionId2, temp_file2), true, GURL(), "2", + extensions::ExtensionDownloaderDelegate::PingResult(), std::set<int>()); WaitForCompletion(); EXPECT_EQ(provided_prefs()->size(), 3ul); @@ -234,13 +230,9 @@ // Update not from Webstore. base::FilePath temp_file4 = temp_dir.Append("d.crx"); CreateFile(temp_file4); - external_cache.OnExtensionDownloadFinished(kTestExtensionId4, - temp_file4, - true, - GURL(), - "4", - extensions::ExtensionDownloaderDelegate::PingResult(), - std::set<int>()); + external_cache.OnExtensionDownloadFinished( + extensions::CRXFileInfo(kTestExtensionId4, temp_file4), true, GURL(), "4", + extensions::ExtensionDownloaderDelegate::PingResult(), std::set<int>()); WaitForCompletion(); EXPECT_EQ(provided_prefs()->size(), 4ul);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc index b7b52fa..df7ec57 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -34,6 +34,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/common/url_constants.h" #include "net/base/escape.h" +#include "storage/browser/blob/file_stream_reader.h" #include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_file_util.h" #include "storage/browser/fileapi/file_system_operation_context.h" @@ -212,6 +213,16 @@ callback.Run(result == base::File::FILE_OK); } +// Calls a response callback (on the UI thread) with a file content hash +// computed on the IO thread. +void ComputeChecksumRespondOnUIThread( + const base::Callback<void(const std::string&)>& callback, + const std::string& hash) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(callback, hash)); +} + } // namespace void FileManagerPrivateRequestFileSystemFunction::DidFail( @@ -713,13 +724,23 @@ SendResponse(true); } +FileManagerPrivateComputeChecksumFunction:: + FileManagerPrivateComputeChecksumFunction() + : digester_(new drive::util::FileStreamMd5Digester()) { +} + +FileManagerPrivateComputeChecksumFunction:: + ~FileManagerPrivateComputeChecksumFunction() { +} + bool FileManagerPrivateComputeChecksumFunction::RunAsync() { using extensions::api::file_manager_private::ComputeChecksum::Params; + using drive::util::FileStreamMd5Digester; const scoped_ptr<Params> params(Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params); if (params->file_url.empty()) { - // TODO(kenobi): call SetError() + SetError("File URL must be provided"); return false; } @@ -727,23 +748,30 @@ file_manager::util::GetFileSystemContextForRenderViewHost( GetProfile(), render_view_host()); - storage::FileSystemURL file_url( - file_system_context->CrackURL(GURL(params->file_url))); + FileSystemURL file_url(file_system_context->CrackURL(GURL(params->file_url))); if (!file_url.is_valid()) { - // TODO(kenobi): Call SetError() + SetError("File URL was invalid"); return false; } - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::FILE, FROM_HERE, - base::Bind(&drive::util::GetMd5Digest, file_url.path()), + scoped_ptr<storage::FileStreamReader> reader = + file_system_context->CreateFileStreamReader( + file_url, 0, storage::kMaximumLength, base::Time()); + + FileStreamMd5Digester::ResultCallback result_callback = base::Bind( + &ComputeChecksumRespondOnUIThread, base::Bind(&FileManagerPrivateComputeChecksumFunction::Respond, this)); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&FileStreamMd5Digester::GetMd5Digest, + base::Unretained(digester_.get()), + base::Passed(&reader), result_callback)); return true; } void FileManagerPrivateComputeChecksumFunction::Respond( const std::string& hash) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); SetResult(new base::StringValue(hash)); SendResponse(true); }
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h index 5e3838ed..467873e 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
@@ -31,6 +31,9 @@ } // namespace file_manager namespace drive { +namespace util { +class FileStreamMd5Digester; +} // namespace util struct HashAndFilePath; } // namespace drive @@ -236,16 +239,20 @@ class FileManagerPrivateComputeChecksumFunction : public LoggedAsyncExtensionFunction { public: + FileManagerPrivateComputeChecksumFunction(); + DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.computeChecksum", FILEMANAGERPRIVATE_COMPUTECHECKSUM) protected: - ~FileManagerPrivateComputeChecksumFunction() override {} + ~FileManagerPrivateComputeChecksumFunction() override; // AsyncExtensionFunction overrides. bool RunAsync() override; private: + scoped_ptr<drive::util::FileStreamMd5Digester> digester_; + void Respond(const std::string& hash); };
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc index 52e2d13d..13eb977f 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -10,7 +10,7 @@ #include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/extensions/wallpaper_private_api.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.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" @@ -27,17 +27,14 @@ class WallpaperPrivateApiUnittest : public ash::test::AshTestBase { public: WallpaperPrivateApiUnittest() - : fake_user_manager_(new FakeUserManager()), - scoped_user_manager_(fake_user_manager_) { - } + : fake_user_manager_(new FakeChromeUserManager()), + scoped_user_manager_(fake_user_manager_) {} protected: - FakeUserManager* fake_user_manager() { - return fake_user_manager_; - } + FakeChromeUserManager* fake_user_manager() { return fake_user_manager_; } private: - FakeUserManager* fake_user_manager_; + FakeChromeUserManager* fake_user_manager_; ScopedUserManagerEnabler scoped_user_manager_; DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiUnittest);
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 07062b0..8c7ae1b 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -1039,11 +1039,13 @@ TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive"))); // Slow tests are disabled on debug build. http://crbug.com/327719 -// In addition, this test in particular has become very flaky as of this CL: -// https://codereview.chromium.org/838193002/ -// Disable completely until further investigation. See: http://crbug.com/444574. +#if !defined(NDEBUG) +#define MAYBE_DefaultActionDialog DISABLED_DefaultActionDialog +#else +#define MAYBE_DefaultActionDialog DefaultActionDialog +#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - DISABLED_DefaultActionDialog, + MAYBE_DefaultActionDialog, FileManagerBrowserTest, ::testing::Values( TestParameter(NOT_IN_GUEST_MODE, "defaultActionDialogOnDownloads"),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index 86bd587..addd0ef 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -149,3 +149,13 @@ RunTest(base::FilePath(FILE_PATH_LITERAL( "foreground/js/metadata/file_system_metadata_provider_unittest.html"))); } + +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExternalMetadataProvider) { + RunTest(base::FilePath(FILE_PATH_LITERAL( + "foreground/js/metadata/external_metadata_provider_unittest.html"))); +} + +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ContentMetadataProvider) { + RunTest(base::FilePath(FILE_PATH_LITERAL( + "foreground/js/metadata/content_metadata_provider_unittest.html"))); +}
diff --git a/chrome/browser/chromeos/file_manager/open_with_browser.cc b/chrome/browser/chromeos/file_manager/open_with_browser.cc index 974b34a..7384caf3 100644 --- a/chrome/browser/chromeos/file_manager/open_with_browser.cc +++ b/chrome/browser/chromeos/file_manager/open_with_browser.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" +#include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "content/public/browser/browser_thread.h" @@ -86,8 +87,8 @@ bool IsPdfPluginEnabled(Profile* profile) { DCHECK(profile); - base::FilePath plugin_path; - PathService::Get(chrome::FILE_PDF_PLUGIN, &plugin_path); + base::FilePath plugin_path = base::FilePath::FromUTF8Unsafe( + ChromeContentClient::kPDFPluginPath); return IsPepperPluginEnabled(profile, plugin_path); }
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc index ba0a05c..d8efb006 100644 --- a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
@@ -12,7 +12,7 @@ #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h" #include "chrome/browser/chromeos/file_system_provider/service.h" #include "chrome/browser/chromeos/file_system_provider/service_factory.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/test/base/testing_browser_process.h" @@ -74,7 +74,7 @@ new TestingProfileManager(TestingBrowserProcess::GetGlobal())); ASSERT_TRUE(profile_manager_->SetUp()); profile_ = profile_manager_->CreateTestingProfile("testing-profile"); - user_manager_ = new FakeUserManager(); + user_manager_ = new FakeChromeUserManager(); user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_)); user_manager_->AddUser(profile_->GetProfileName()); ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService); @@ -93,7 +93,7 @@ scoped_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; // Owned by TestingProfileManager. scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_; - FakeUserManager* user_manager_; + FakeChromeUserManager* user_manager_; Service* file_system_provider_service_; // Owned by its factory. };
diff --git a/chrome/browser/chromeos/file_system_provider/service_unittest.cc b/chrome/browser/chromeos/file_system_provider/service_unittest.cc index d8d23fb..29d4e98 100644 --- a/chrome/browser/chromeos/file_system_provider/service_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/service_unittest.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/chromeos/file_system_provider/observer.h" #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" #include "chrome/browser/chromeos/file_system_provider/registry_interface.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_pref_service_syncable.h" @@ -179,7 +179,7 @@ new TestingProfileManager(TestingBrowserProcess::GetGlobal())); ASSERT_TRUE(profile_manager_->SetUp()); profile_ = profile_manager_->CreateTestingProfile("test-user@example.com"); - user_manager_ = new FakeUserManager(); + user_manager_ = new FakeChromeUserManager(); user_manager_->AddUser(profile_->GetProfileName()); user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_)); extension_registry_.reset(new extensions::ExtensionRegistry(profile_)); @@ -201,7 +201,7 @@ content::TestBrowserThreadBundle thread_bundle_; scoped_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; - FakeUserManager* user_manager_; + FakeChromeUserManager* user_manager_; scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_; scoped_ptr<extensions::ExtensionRegistry> extension_registry_; scoped_ptr<Service> service_;
diff --git a/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc b/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc index 35f36c3e8..2d071bf 100644 --- a/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_persistence_unittest.cc
@@ -8,7 +8,7 @@ #include "base/prefs/pref_service.h" #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" #include "chrome/browser/chromeos/language_preferences.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" @@ -35,7 +35,7 @@ protected: InputMethodPersistenceTest() : mock_profile_manager_(TestingBrowserProcess::GetGlobal()), - fake_user_manager_(new chromeos::FakeUserManager()), + fake_user_manager_(new chromeos::FakeChromeUserManager()), user_manager_enabler_(fake_user_manager_) {} void SetUp() override { @@ -71,7 +71,7 @@ TestingPrefServiceSyncable* mock_user_prefs_; MockInputMethodManager mock_manager_; TestingProfileManager mock_profile_manager_; - chromeos::FakeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler user_manager_enabler_; };
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc index 62d9ccc1..c3dcd6e 100644 --- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc +++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -16,7 +16,6 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" @@ -44,6 +43,7 @@ #include "chromeos/login/auth/user_context.h" #include "chromeos/login/login_state.h" #include "components/ownership/mock_owner_key_util.h" +#include "components/user_manager/fake_user_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "crypto/nss_util_internal.h" #include "crypto/scoped_test_nss_chromeos_user.h" @@ -131,7 +131,7 @@ public: CryptohomeAuthenticatorTest() : user_context_("me@nowhere.org"), - user_manager_(new FakeUserManager()), + user_manager_(new user_manager::FakeUserManager()), user_manager_enabler_(user_manager_), mock_caller_(NULL), mock_homedir_methods_(NULL), @@ -325,7 +325,7 @@ TestingProfile profile_; scoped_ptr<TestingProfileManager> profile_manager_; - FakeUserManager* user_manager_; + user_manager::FakeUserManager* user_manager_; ScopedUserManagerEnabler user_manager_enabler_; cryptohome::MockAsyncMethodCaller* mock_caller_;
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index c7fe45b7..85d7be0f 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -90,6 +90,7 @@ ::switches::kDisableSeccompFilterSandbox, ::switches::kDisableSetuidSandbox, ::switches::kDisableTextBlobs, + ::switches::kDisableThreadedGpuRasterization, ::switches::kDisableThreadedScrolling, ::switches::kDisableTouchDragDrop, ::switches::kDisableTouchEditing, @@ -110,6 +111,7 @@ ::switches::kEnablePinch, ::switches::kEnablePluginPlaceholderShadowDom, ::switches::kEnableSlimmingPaint, + ::switches::kEnableThreadedGpuRasterization, ::switches::kEnableTouchDragDrop, ::switches::kEnableTouchEditing, ::switches::kEnableViewport,
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc index 2f75006b..286a85e 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
@@ -13,7 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/common/chrome_constants.h" @@ -193,10 +193,9 @@ public: EasyUnlockTpmKeyManagerTest() : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD), - user_manager_(new chromeos::FakeUserManager), + user_manager_(new chromeos::FakeChromeUserManager()), user_manager_enabler_(user_manager_), - profile_manager_(TestingBrowserProcess::GetGlobal()) { - } + profile_manager_(TestingBrowserProcess::GetGlobal()) {} ~EasyUnlockTpmKeyManagerTest() override {} void SetUp() override { @@ -286,7 +285,7 @@ scoped_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_; // Needed to properly set up signin and user profiles for test. - chromeos::FakeUserManager* user_manager_; + user_manager::FakeUserManager* user_manager_; chromeos::ScopedUserManagerEnabler user_manager_enabler_; TestingProfileManager profile_manager_;
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 079e937..340dff9 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -9,12 +9,16 @@ #include "base/bind_helpers.h" #include "base/files/file_util.h" #include "base/location.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/prefs/pref_service.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/synchronization/lock.h" +#include "base/thread_task_runner_handle.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/fake_cws.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" @@ -25,13 +29,16 @@ #include "chrome/browser/chromeos/login/test/app_window_waiter.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/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -47,6 +54,7 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/cryptohome_client.h" #include "chromeos/disks/disk_mount_manager.h" +#include "chromeos/settings/cros_settings_provider.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/signin_pref_names.h" #include "content/public/browser/browser_thread.h" @@ -395,6 +403,68 @@ DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter); }; +class CrosSettingsPermanentlyUntrustedMaker : + public DeviceSettingsService::Observer { + public: + CrosSettingsPermanentlyUntrustedMaker(); + + // DeviceSettingsService::Observer: + void OwnershipStatusChanged() override; + void DeviceSettingsUpdated() override; + void OnDeviceSettingsServiceShutdown() override; + + private: + bool untrusted_check_running_; + base::RunLoop run_loop_; + + void CheckIfUntrusted(); + + DISALLOW_COPY_AND_ASSIGN(CrosSettingsPermanentlyUntrustedMaker); +}; + +CrosSettingsPermanentlyUntrustedMaker::CrosSettingsPermanentlyUntrustedMaker() + : untrusted_check_running_(false) { + DeviceSettingsService::Get()->AddObserver(this); + + policy::DevicePolicyCrosTestHelper().InstallOwnerKey(); + DeviceSettingsService::Get()->OwnerKeySet(true); + + run_loop_.Run(); +} + +void CrosSettingsPermanentlyUntrustedMaker::OwnershipStatusChanged() { + if (untrusted_check_running_) + return; + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted, + base::Unretained(this))); +} + +void CrosSettingsPermanentlyUntrustedMaker::DeviceSettingsUpdated() { +} + +void CrosSettingsPermanentlyUntrustedMaker::OnDeviceSettingsServiceShutdown() { +} + +void CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted() { + untrusted_check_running_ = true; + const CrosSettingsProvider::TrustedStatus trusted_status = + CrosSettings::Get()->PrepareTrustedValues( + base::Bind(&CrosSettingsPermanentlyUntrustedMaker::CheckIfUntrusted, + base::Unretained(this))); + if (trusted_status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED) + return; + untrusted_check_running_ = false; + + if (trusted_status == CrosSettingsProvider::TRUSTED) + return; + + DeviceSettingsService::Get()->RemoveObserver(this); + run_loop_.Quit(); +} + } // namespace class KioskTest : public OobeBaseTest { @@ -703,11 +773,6 @@ return auto_lock.Pass(); } - void MakeCrosSettingsPermanentlyUntrusted() { - policy::DevicePolicyCrosTestHelper().InstallOwnerKey(); - DeviceSettingsService::Get()->OwnerKeySet(true); - } - MockUserManager* mock_user_manager() { return mock_user_manager_.get(); } void set_test_app_id(const std::string& test_app_id) { @@ -1135,7 +1200,7 @@ SimulateNetworkOnline(); // Make cros settings untrusted. - MakeCrosSettingsPermanentlyUntrusted(); + CrosSettingsPermanentlyUntrustedMaker(); // Check that the attempt to start a kiosk app fails with an error. LaunchApp(test_app_id(), false); @@ -1153,7 +1218,9 @@ &ignored)); } -IN_PROC_BROWSER_TEST_F(KioskTest, NoAutoLaunchWhenUntrusted) { +// Verifies that a consumer device does not auto-launch kiosk mode when cros +// settings are untrusted. +IN_PROC_BROWSER_TEST_F(KioskTest, NoConsumerAutoLaunchWhenUntrusted) { EnableConsumerKioskMode(); // Wait for and confirm the auto-launch warning. @@ -1172,12 +1239,32 @@ base::FundamentalValue(true)); // Make cros settings untrusted. - MakeCrosSettingsPermanentlyUntrusted(); + CrosSettingsPermanentlyUntrustedMaker(); // Check that the attempt to auto-launch a kiosk app fails with an error. OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait(); } +// Verifies that an enterprise device does not auto-launch kiosk mode when cros +// settings are untrusted. +IN_PROC_BROWSER_TEST_F(KioskTest, NoEnterpriseAutoLaunchWhenUntrusted) { + PrepareAppLaunch(); + SimulateNetworkOnline(); + + // Make cros settings untrusted. + CrosSettingsPermanentlyUntrustedMaker(); + + // Trigger the code that handles auto-launch on enterprise devices. This would + // normally be called from ShowLoginWizard(), which runs so early that it is + // not to inject an auto-launch policy before it runs. + LoginDisplayHost* login_display_host = LoginDisplayHostImpl::default_host(); + ASSERT_TRUE(login_display_host); + login_display_host->StartAppLaunch(test_app_id(), false); + + // Check that no launch has started. + EXPECT_FALSE(login_display_host->GetAppLaunchController()); +} + class KioskUpdateTest : public KioskTest { public: KioskUpdateTest() {} @@ -1865,15 +1952,14 @@ IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) { // Add a device owner. - FakeUserManager* user_manager = new FakeUserManager(); + FakeChromeUserManager* user_manager = new FakeChromeUserManager(); user_manager->AddUser(kTestOwnerEmail); ScopedUserManagerEnabler enabler(user_manager); // Set kiosk app to autolaunch. EnableConsumerKioskMode(); - chromeos::WizardController::SkipPostLoginScreensForTesting(); - chromeos::WizardController* wizard_controller = - chromeos::WizardController::default_controller(); + WizardController::SkipPostLoginScreensForTesting(); + WizardController* wizard_controller = WizardController::default_controller(); CHECK(wizard_controller); // Start login screen after configuring auto launch app since the warning
diff --git a/chrome/browser/chromeos/login/screens/mock_update_screen.cc b/chrome/browser/chromeos/login/screens/mock_update_screen.cc index cf914ce..02da115 100644 --- a/chrome/browser/chromeos/login/screens/mock_update_screen.cc +++ b/chrome/browser/chromeos/login/screens/mock_update_screen.cc
@@ -4,32 +4,36 @@ #include "chrome/browser/chromeos/login/screens/mock_update_screen.h" +using ::testing::AtLeast; +using ::testing::_; + namespace chromeos { -using ::testing::AtLeast; -using ::testing::NotNull; - MockUpdateScreen::MockUpdateScreen(BaseScreenDelegate* base_screen_delegate, - UpdateScreenActor* actor) - : UpdateScreen(base_screen_delegate, actor, NULL) { + UpdateView* view) + : UpdateScreen(base_screen_delegate, view, NULL) { } MockUpdateScreen::~MockUpdateScreen() { } -MockUpdateScreenActor::MockUpdateScreenActor() - : screen_(NULL) { - EXPECT_CALL(*this, MockSetDelegate(NotNull())).Times(AtLeast(1)); +MockUpdateView::MockUpdateView() : model_(nullptr) { + EXPECT_CALL(*this, MockBind(_)).Times(AtLeast(1)); } -MockUpdateScreenActor::~MockUpdateScreenActor() { - if (screen_) - screen_->OnActorDestroyed(this); +MockUpdateView::~MockUpdateView() { + if (model_) + model_->OnViewDestroyed(this); } -void MockUpdateScreenActor::SetDelegate(UpdateScreenActor::Delegate* screen) { - screen_ = screen; - MockSetDelegate(screen); +void MockUpdateView::Bind(UpdateModel& model) { + model_ = &model; + MockBind(model); +} + +void MockUpdateView::Unbind() { + model_ = nullptr; + MockUnbind(); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/mock_update_screen.h b/chrome/browser/chromeos/login/screens/mock_update_screen.h index 583347d5..e6b0334 100644 --- a/chrome/browser/chromeos/login/screens/mock_update_screen.h +++ b/chrome/browser/chromeos/login/screens/mock_update_screen.h
@@ -6,43 +6,37 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_UPDATE_SCREEN_H_ #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" +#include "chrome/browser/chromeos/login/screens/update_model.h" #include "chrome/browser/chromeos/login/screens/update_screen.h" -#include "chrome/browser/chromeos/login/screens/update_screen_actor.h" +#include "chrome/browser/chromeos/login/screens/update_view.h" #include "testing/gmock/include/gmock/gmock.h" namespace chromeos { class MockUpdateScreen : public UpdateScreen { public: - MockUpdateScreen(BaseScreenDelegate* base_screen_delegate, - UpdateScreenActor* actor); + MockUpdateScreen(BaseScreenDelegate* base_screen_delegate, UpdateView* view); virtual ~MockUpdateScreen(); MOCK_METHOD0(StartNetworkCheck, void()); }; -class MockUpdateScreenActor : public UpdateScreenActor { +class MockUpdateView : public UpdateView { public: - MockUpdateScreenActor(); - virtual ~MockUpdateScreenActor(); + MockUpdateView(); + virtual ~MockUpdateView(); - virtual void SetDelegate(UpdateScreenActor::Delegate* screen) override; + void Bind(UpdateModel& model) override; + void Unbind() override; - MOCK_METHOD1(MockSetDelegate, void(UpdateScreenActor::Delegate* screen)); + MOCK_METHOD0(PrepareToShow, void()); MOCK_METHOD0(Show, void()); MOCK_METHOD0(Hide, void()); - MOCK_METHOD0(PrepareToShow, void()); - MOCK_METHOD0(ShowManualRebootInfo, void()); - MOCK_METHOD1(SetProgress, void(int progress)); - MOCK_METHOD1(ShowEstimatedTimeLeft, void(bool enable)); - MOCK_METHOD1(SetEstimatedTimeLeft, void(const base::TimeDelta& time)); - MOCK_METHOD1(ShowProgressMessage, void(bool enable)); - MOCK_METHOD1(SetProgressMessage, void(ProgressMessage message)); - MOCK_METHOD1(ShowCurtain, void(bool enable)); - MOCK_METHOD1(ShowPreparingUpdatesInfo, void(bool enable)); + MOCK_METHOD1(MockBind, void(UpdateModel& model)); + MOCK_METHOD0(MockUnbind, void()); private: - UpdateScreenActor::Delegate* screen_; + UpdateModel* model_; }; } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/network_screen.h b/chrome/browser/chromeos/login/screens/network_screen.h index 00fc13a..8350d06 100644 --- a/chrome/browser/chromeos/login/screens/network_screen.h +++ b/chrome/browser/chromeos/login/screens/network_screen.h
@@ -13,7 +13,6 @@ #include "base/observer_list.h" #include "base/strings/string16.h" #include "base/timer/timer.h" -#include "chrome/browser/chromeos/login/screens/base_screen.h" #include "chrome/browser/chromeos/login/screens/network_model.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/network/network_state_handler_observer.h"
diff --git a/chrome/browser/chromeos/login/screens/update_model.cc b/chrome/browser/chromeos/login/screens/update_model.cc new file mode 100644 index 0000000..d8f2be49 --- /dev/null +++ b/chrome/browser/chromeos/login/screens/update_model.cc
@@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/screens/update_model.h" + +#include "chrome/browser/chromeos/login/wizard_controller.h" + +namespace chromeos { + +const char UpdateModel::kUserActionCancelUpdateShortcut[] = "cancel-update"; +const char UpdateModel::kContextKeyEstimatedTimeLeftSec[] = "time-left-sec"; +const char UpdateModel::kContextKeyShowEstimatedTimeLeft[] = "show-time-left"; +const char UpdateModel::kContextKeyUpdateMessage[] = "update-msg"; +const char UpdateModel::kContextKeyShowCurtain[] = "show-curtain"; +const char UpdateModel::kContextKeyShowProgressMessage[] = "show-progress-msg"; +const char UpdateModel::kContextKeyProgress[] = "progress"; +const char UpdateModel::kContextKeyProgressMessage[] = "progress-msg"; +const char UpdateModel::kContextKeyCancelUpdateShortcutEnabled[] = + "cancel-update-enabled"; + +UpdateModel::UpdateModel(BaseScreenDelegate* base_screen_delegate) + : BaseScreen(base_screen_delegate) { +} + +UpdateModel::~UpdateModel() { +} + +std::string UpdateModel::GetName() const { + return WizardController::kUpdateScreenName; +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/update_model.h b/chrome/browser/chromeos/login/screens/update_model.h new file mode 100644 index 0000000..1d1d7c5 --- /dev/null +++ b/chrome/browser/chromeos/login/screens/update_model.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 CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_MODEL_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_MODEL_H_ + +#include "chrome/browser/chromeos/login/screens/base_screen.h" + +namespace base { +class ListValue; +} + +namespace chromeos { + +class BaseScreenDelegate; +class UpdateView; + +class UpdateModel : public BaseScreen { + public: + static const char kUserActionCancelUpdateShortcut[]; + static const char kContextKeyEstimatedTimeLeftSec[]; + static const char kContextKeyShowEstimatedTimeLeft[]; + static const char kContextKeyUpdateMessage[]; + static const char kContextKeyShowCurtain[]; + static const char kContextKeyShowProgressMessage[]; + static const char kContextKeyProgress[]; + static const char kContextKeyProgressMessage[]; + static const char kContextKeyCancelUpdateShortcutEnabled[]; + + explicit UpdateModel(BaseScreenDelegate* base_screen_delegate); + ~UpdateModel() override; + + // BaseScreen implementation: + std::string GetName() const override; + + // This method is called, when view is being destroyed. Note, if model + // is destroyed earlier then it has to call Unbind(). + virtual void OnViewDestroyed(UpdateView* view) = 0; + + // Called any time a new network connect request occurs. + virtual void OnConnectToNetworkRequested() = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_MODEL_H_
diff --git a/chrome/browser/chromeos/login/screens/update_screen.cc b/chrome/browser/chromeos/login/screens/update_screen.cc index e6872c0..0457421 100644 --- a/chrome/browser/chromeos/login/screens/update_screen.cc +++ b/chrome/browser/chromeos/login/screens/update_screen.cc
@@ -15,12 +15,15 @@ #include "chrome/browser/chromeos/login/screen_manager.h" #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h" #include "chrome/browser/chromeos/login/screens/error_screen.h" -#include "chrome/browser/chromeos/login/screens/update_screen_actor.h" +#include "chrome/browser/chromeos/login/screens/update_view.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/grit/chromium_strings.h" +#include "chrome/grit/generated_resources.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/network/network_state.h" #include "content/public/browser/browser_thread.h" +#include "ui/base/l10n/l10n_util.h" using content::BrowserThread; using pairing_chromeos::HostPairingController; @@ -29,6 +32,9 @@ namespace { +// If reboot didn't happen, ask user to reboot device manually. +const int kWaitForRebootTimeSec = 3; + // Progress bar stages. Each represents progress bar value // at the beginning of each stage. // TODO(nkostylev): Base stage progress values on approximate time. @@ -94,41 +100,39 @@ } UpdateScreen::UpdateScreen(BaseScreenDelegate* base_screen_delegate, - UpdateScreenActor* actor, + UpdateView* view, HostPairingController* remora_controller) - : BaseScreen(base_screen_delegate), + : UpdateModel(base_screen_delegate), state_(STATE_IDLE), - reboot_check_delay_(0), + reboot_check_delay_(kWaitForRebootTimeSec), is_checking_for_update_(true), is_downloading_update_(false), - is_ignore_update_deadlines_(false), + is_ignore_update_deadlines_(true), is_shown_(false), ignore_idle_status_(true), - actor_(actor), + view_(view), remora_controller_(remora_controller), is_first_detection_notification_(true), is_first_portal_notification_(true), histogram_helper_(new ErrorScreensHistogramHelper("Update")), weak_factory_(this) { - DCHECK(actor_); - if (actor_) - actor_->SetDelegate(this); + if (view_) + view_->Bind(*this); + GetInstanceSet().insert(this); } UpdateScreen::~UpdateScreen() { + if (view_) + view_->Unbind(); + DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this); NetworkPortalDetector::Get()->RemoveObserver(this); GetInstanceSet().erase(this); - if (actor_) - actor_->SetDelegate(NULL); } void UpdateScreen::UpdateStatusChanged( const UpdateEngineClient::Status& status) { - if (!actor_) - return; - if (is_checking_for_update_ && status.status > UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE) { is_checking_for_update_ = false; @@ -147,17 +151,19 @@ break; case UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE: MakeSureScreenIsShown(); - actor_->SetProgress(kBeforeDownloadProgress); - actor_->ShowEstimatedTimeLeft(false); + GetContextEditor() + .SetInteger(kContextKeyProgress, kBeforeDownloadProgress) + .SetBoolean(kContextKeyShowEstimatedTimeLeft, false); if (!HasCriticalUpdate()) { VLOG(1) << "Noncritical update available: " << status.new_version; ExitUpdate(REASON_UPDATE_NON_CRITICAL); } else { VLOG(1) << "Critical update available: " << status.new_version; - actor_->SetProgressMessage( - UpdateScreenActor::PROGRESS_MESSAGE_UPDATE_AVAILABLE); - actor_->ShowProgressMessage(true); - actor_->ShowCurtain(false); + GetContextEditor() + .SetString(kContextKeyProgressMessage, + l10n_util::GetStringUTF16(IDS_UPDATE_AVAILABLE)) + .SetBoolean(kContextKeyShowProgressMessage, true) + .SetBoolean(kContextKeyShowCurtain, false); } break; case UpdateEngineClient::UPDATE_STATUS_DOWNLOADING: @@ -177,10 +183,11 @@ ExitUpdate(REASON_UPDATE_NON_CRITICAL); } else { VLOG(1) << "Critical update available: " << status.new_version; - actor_->SetProgressMessage( - UpdateScreenActor::PROGRESS_MESSAGE_INSTALLING_UPDATE); - actor_->ShowProgressMessage(true); - actor_->ShowCurtain(false); + GetContextEditor() + .SetString(kContextKeyProgressMessage, + l10n_util::GetStringUTF16(IDS_INSTALLING_UPDATE)) + .SetBoolean(kContextKeyShowProgressMessage, true) + .SetBoolean(kContextKeyShowCurtain, false); } } UpdateDownloadingStats(status); @@ -188,23 +195,27 @@ break; case UpdateEngineClient::UPDATE_STATUS_VERIFYING: MakeSureScreenIsShown(); - actor_->SetProgress(kBeforeVerifyingProgress); - actor_->SetProgressMessage(UpdateScreenActor::PROGRESS_MESSAGE_VERIFYING); - actor_->ShowProgressMessage(true); + GetContextEditor() + .SetInteger(kContextKeyProgress, kBeforeVerifyingProgress) + .SetString(kContextKeyProgressMessage, + l10n_util::GetStringUTF16(IDS_UPDATE_VERIFYING)) + .SetBoolean(kContextKeyShowProgressMessage, true); break; case UpdateEngineClient::UPDATE_STATUS_FINALIZING: MakeSureScreenIsShown(); - actor_->SetProgress(kBeforeFinalizingProgress); - actor_->SetProgressMessage( - UpdateScreenActor::PROGRESS_MESSAGE_FINALIZING); - actor_->ShowProgressMessage(true); + GetContextEditor() + .SetInteger(kContextKeyProgress, kBeforeFinalizingProgress) + .SetString(kContextKeyProgressMessage, + l10n_util::GetStringUTF16(IDS_UPDATE_FINALIZING)) + .SetBoolean(kContextKeyShowProgressMessage, true); break; case UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT: MakeSureScreenIsShown(); - actor_->SetProgress(kProgressComplete); - actor_->ShowEstimatedTimeLeft(false); + GetContextEditor() + .SetInteger(kContextKeyProgress, kProgressComplete) + .SetBoolean(kContextKeyShowEstimatedTimeLeft, false); if (HasCriticalUpdate()) { - actor_->ShowCurtain(false); + GetContextEditor().SetBoolean(kContextKeyShowCurtain, false); VLOG(1) << "Initiate reboot after update"; SetHostPairingControllerStatus( HostPairingController::UPDATE_STATUS_REBOOTING); @@ -298,33 +309,59 @@ NetworkPortalDetector::Get()->AddAndFireObserver(this); } -void UpdateScreen::CancelUpdate() { - VLOG(1) << "Forced update cancel"; - ExitUpdate(REASON_UPDATE_CANCELED); +void UpdateScreen::PrepareToShow() { + if (!view_) + return; + + view_->PrepareToShow(); } void UpdateScreen::Show() { is_shown_ = true; histogram_helper_->OnScreenShow(); - if (actor_) { - actor_->Show(); - actor_->SetProgress(kBeforeUpdateCheckProgress); - } + +#if !defined(OFFICIAL_BUILD) + GetContextEditor().SetBoolean(kContextKeyCancelUpdateShortcutEnabled, true); +#endif + GetContextEditor().SetInteger(kContextKeyProgress, + kBeforeUpdateCheckProgress); + + if (view_) + view_->Show(); } void UpdateScreen::Hide() { - if (actor_) - actor_->Hide(); + if (view_) + view_->Hide(); is_shown_ = false; } -std::string UpdateScreen::GetName() const { - return WizardController::kUpdateScreenName; +void UpdateScreen::Initialize(::login::ScreenContext* context) { + UpdateModel::Initialize(context); } -void UpdateScreen::PrepareToShow() { - if (actor_) - actor_->PrepareToShow(); +void UpdateScreen::OnViewDestroyed(UpdateView* view) { + if (view_ == view) + view_ = nullptr; +} + +void UpdateScreen::OnUserAction(const std::string& action_id) { +#if !defined(OFFICIAL_BUILD) + if (action_id == kUserActionCancelUpdateShortcut) + CancelUpdate(); +#endif +} + +void UpdateScreen::OnContextKeyUpdated( + const ::login::ScreenContext::KeyType& key) { + UpdateModel::OnContextKeyUpdated(key); +} + +void UpdateScreen::OnConnectToNetworkRequested() { + if (state_ == STATE_ERROR) { + LOG(WARNING) << "Hiding error message since AP was reselected"; + StartUpdateCheck(); + } } void UpdateScreen::ExitUpdate(UpdateScreen::ExitReason reason) { @@ -378,8 +415,8 @@ void UpdateScreen::OnWaitForRebootTimeElapsed() { LOG(ERROR) << "Unable to reboot - asking user for a manual reboot."; MakeSureScreenIsShown(); - if (actor_) - actor_->ShowManualRebootInfo(); + GetContextEditor().SetString(kContextKeyUpdateMessage, + l10n_util::GetStringUTF16(IDS_UPDATE_COMPLETED)); } void UpdateScreen::MakeSureScreenIsShown() { @@ -387,21 +424,17 @@ get_base_screen_delegate()->ShowCurrentScreen(); } -void UpdateScreen::SetRebootCheckDelay(int seconds) { - if (seconds <= 0) - reboot_timer_.Stop(); - DCHECK(!reboot_timer_.IsRunning()); - reboot_check_delay_ = seconds; -} - void UpdateScreen::SetIgnoreIdleStatus(bool ignore_idle_status) { ignore_idle_status_ = ignore_idle_status; } +void UpdateScreen::CancelUpdate() { + VLOG(1) << "Forced update cancel"; + ExitUpdate(REASON_UPDATE_CANCELED); +} + void UpdateScreen::UpdateDownloadingStats( const UpdateEngineClient::Status& status) { - if (!actor_) - return; base::Time download_current_time = base::Time::Now(); if (download_current_time >= download_last_time_ + kMinTimeStep) { // Estimate downloading rate. @@ -437,14 +470,16 @@ // |bound possible estimations. time_left = std::min(time_left, kMaxTimeLeft); - actor_->ShowEstimatedTimeLeft(true); - actor_->SetEstimatedTimeLeft( - base::TimeDelta::FromSeconds(static_cast<int64>(time_left))); + GetContextEditor() + .SetBoolean(kContextKeyShowEstimatedTimeLeft, true) + .SetInteger(kContextKeyEstimatedTimeLeftSec, + static_cast<int>(time_left)); } int download_progress = static_cast<int>( status.download_progress * kDownloadProgressIncrement); - actor_->SetProgress(kBeforeDownloadProgress + download_progress); + GetContextEditor().SetInteger(kContextKeyProgress, + kBeforeDownloadProgress + download_progress); } bool UpdateScreen::HasCriticalUpdate() { @@ -466,18 +501,6 @@ return true; } -void UpdateScreen::OnActorDestroyed(UpdateScreenActor* actor) { - if (actor_ == actor) - actor_ = NULL; -} - -void UpdateScreen::OnConnectToNetworkRequested() { - if (state_ == STATE_ERROR) { - LOG(WARNING) << "Hiding error message since AP was reselected"; - StartUpdateCheck(); - } -} - ErrorScreen* UpdateScreen::GetErrorScreen() { return get_base_screen_delegate()->GetErrorScreen(); }
diff --git a/chrome/browser/chromeos/login/screens/update_screen.h b/chrome/browser/chromeos/login/screens/update_screen.h index 6b39389..e9b291e 100644 --- a/chrome/browser/chromeos/login/screens/update_screen.h +++ b/chrome/browser/chromeos/login/screens/update_screen.h
@@ -13,8 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "chrome/browser/chromeos/login/screens/base_screen.h" -#include "chrome/browser/chromeos/login/screens/update_screen_actor.h" +#include "chrome/browser/chromeos/login/screens/update_model.h" #include "chromeos/dbus/update_engine_client.h" #include "chromeos/network/portal_detector/network_portal_detector.h" #include "components/pairing/host_pairing_controller.h" @@ -26,40 +25,33 @@ class ErrorScreensHistogramHelper; class NetworkState; class ScreenManager; +class UpdateView; -// Controller for the update screen. It does not depend on the specific -// implementation of the screen showing (Views of WebUI based), the dependency -// is moved to the UpdateScreenActor instead. -class UpdateScreen : public UpdateEngineClient::Observer, - public UpdateScreenActor::Delegate, - public BaseScreen, +// Controller for the update screen. +class UpdateScreen : public UpdateModel, + public UpdateEngineClient::Observer, public NetworkPortalDetector::Observer { public: UpdateScreen(BaseScreenDelegate* base_screen_delegate, - UpdateScreenActor* actor, + UpdateView* view, pairing_chromeos::HostPairingController* remora_controller); ~UpdateScreen() override; static UpdateScreen* Get(ScreenManager* manager); - // Overridden from BaseScreen. + // UpdateModel: void PrepareToShow() override; void Show() override; void Hide() override; - std::string GetName() const override; - - // UpdateScreenActor::Delegate implementation: - void CancelUpdate() override; - void OnActorDestroyed(UpdateScreenActor* actor) override; + void Initialize(::login::ScreenContext* context) override; + void OnViewDestroyed(UpdateView* view) override; + void OnUserAction(const std::string& action_id) override; + void OnContextKeyUpdated(const ::login::ScreenContext::KeyType& key) override; void OnConnectToNetworkRequested() override; // Starts network check. Made virtual to simplify mocking. virtual void StartNetworkCheck(); - // Reboot check delay get/set, in seconds. - int reboot_check_delay() const { return reboot_check_delay_; } - void SetRebootCheckDelay(int seconds); - // Returns true if this instance is still active (i.e. has not been deleted). static bool HasInstance(UpdateScreen* inst); @@ -82,6 +74,9 @@ const NetworkState* network, const NetworkPortalDetector::CaptivePortalState& state) override; + // Skip update UI, usually used only in debug builds/tests. + void CancelUpdate(); + private: FRIEND_TEST_ALL_PREFIXES(UpdateScreenTest, TestBasic); FRIEND_TEST_ALL_PREFIXES(UpdateScreenTest, TestUpdateAvailable); @@ -149,8 +144,7 @@ // Ignore fist IDLE status that is sent before update screen initiated check. bool ignore_idle_status_; - // Keeps actor which is delegated with all showing operations. - UpdateScreenActor* actor_; + UpdateView* view_; // Used to track updates over Bluetooth. pairing_chromeos::HostPairingController* remora_controller_;
diff --git a/chrome/browser/chromeos/login/screens/update_screen_actor.h b/chrome/browser/chromeos/login/screens/update_screen_actor.h deleted file mode 100644 index 064e2ce3..0000000 --- a/chrome/browser/chromeos/login/screens/update_screen_actor.h +++ /dev/null
@@ -1,73 +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_CHROMEOS_LOGIN_SCREENS_UPDATE_SCREEN_ACTOR_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_SCREEN_ACTOR_H_ - -#include "base/time/time.h" - -namespace chromeos { - -class UpdateScreenActor { - public: - // Indices for corresponding info messages during update stage. - enum ProgressMessage { - PROGRESS_MESSAGE_UPDATE_AVAILABLE = 0, - PROGRESS_MESSAGE_INSTALLING_UPDATE, - PROGRESS_MESSAGE_VERIFYING, - PROGRESS_MESSAGE_FINALIZING - }; - - class Delegate { - public: - virtual ~Delegate() {} - - // Force cancel update. - virtual void CancelUpdate() = 0; - - // Called prior to destroying |actor|. - virtual void OnActorDestroyed(UpdateScreenActor* actor) = 0; - - // Called any time a new network connect request occurs. - virtual void OnConnectToNetworkRequested() = 0; - }; - - virtual ~UpdateScreenActor() {} - - // Sets screen this actor belongs to. - virtual void SetDelegate(Delegate* screen) = 0; - - // Shows the screen. - virtual void Show() = 0; - - // Hides the screen. - virtual void Hide() = 0; - - virtual void PrepareToShow() = 0; - - // Shows manual reboot info message. - virtual void ShowManualRebootInfo() = 0; - - // Sets current progress in percents. - virtual void SetProgress(int progress) = 0; - - // Shows estimated time left message. - virtual void ShowEstimatedTimeLeft(bool visible) = 0; - - // Sets current estimation for time left in the downloading stage. - virtual void SetEstimatedTimeLeft(const base::TimeDelta& time) = 0; - - // Shows message under progress bar. - virtual void ShowProgressMessage(bool visible) = 0; - - // Sets message under progress bar. - virtual void SetProgressMessage(ProgressMessage message) = 0; - - // Shows screen curtains. - virtual void ShowCurtain(bool visible) = 0; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_SCREEN_ACTOR_H_
diff --git a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc index 489232f3..d517ee66 100644 --- a/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/screens/update_screen_browsertest.cc
@@ -126,7 +126,7 @@ }; IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) { - ASSERT_TRUE(update_screen_->actor_ != NULL); + ASSERT_TRUE(update_screen_->view_ != NULL); } IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) {
diff --git a/chrome/browser/chromeos/login/screens/update_view.h b/chrome/browser/chromeos/login/screens/update_view.h new file mode 100644 index 0000000..b188aff --- /dev/null +++ b/chrome/browser/chromeos/login/screens/update_view.h
@@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_VIEW_H_ + +#include "base/strings/string16.h" + +namespace chromeos { + +class UpdateModel; + +// Interface for dependency injection between NetworkScreen and its actual +// representation. Owned by UpdateScreen. +class UpdateView { + public: + virtual ~UpdateView() {} + + // Prepare the contents to showing. + virtual void PrepareToShow() = 0; + + // Shows the contents of the screen. + virtual void Show() = 0; + + // Hides the contents of the screen. + virtual void Hide() = 0; + + // Binds |model| to the view. + virtual void Bind(UpdateModel& model) = 0; + + // Unbinds model from the view. + virtual void Unbind() = 0; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_VIEW_H_
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc index 095359ec..20064c8 100644 --- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc +++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -37,6 +37,7 @@ const char kKeyPublicAccount[] = "publicAccount"; const char kKeySupervisedUser[] = "supervisedUser"; const char kKeyChildUser[] = "childUser"; +const char kKeyDesktopUser[] = "isDesktopUser"; const char kKeySignedIn[] = "signedIn"; const char kKeyCanRemove[] = "canRemove"; const char kKeyIsOwner[] = "isOwner"; @@ -150,6 +151,7 @@ user_dict->SetBoolean(kKeyPublicAccount, is_public_session); user_dict->SetBoolean(kKeySupervisedUser, is_supervised_user); user_dict->SetBoolean(kKeyChildUser, is_child_user); + user_dict->SetBoolean(kKeyDesktopUser, false); user_dict->SetInteger(kKeyInitialAuthType, auth_type); user_dict->SetBoolean(kKeySignedIn, user->is_logged_in()); user_dict->SetBoolean(kKeyIsOwner, is_owner);
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index 544f74e..ea0d3f0d 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -9,13 +9,13 @@ #include "base/path_service.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/fake_shill_manager_client.h" +#include "components/user_manager/fake_user_manager.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h index 6530ff4e..0337845 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.h +++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -19,11 +19,10 @@ namespace content { class WebUI; -} // namespace content +} namespace chromeos { -class FakeUserManager; class NetworkPortalDetectorTestImpl; // Base class for OOBE and Kiosk tests.
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc index 0f64d5f..b1634642 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -49,6 +49,8 @@ #include "chrome/browser/chromeos/net/delay_network_call.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/enrollment_config.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/chromeos/system/device_disabling_manager.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/chromeos/system/timezone_util.h" #include "chrome/browser/chromeos/ui/focus_ring_controller.h" @@ -65,6 +67,8 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" #include "chromeos/login/login_state.h" +#include "chromeos/settings/cros_settings_names.h" +#include "chromeos/settings/cros_settings_provider.h" #include "chromeos/settings/timezone_settings.h" #include "chromeos/timezone/timezone_resolver.h" #include "components/session_manager/core/session_manager.h" @@ -667,6 +671,35 @@ bool diagnostic_mode) { VLOG(1) << "Login WebUI >> start app launch."; SetStatusAreaVisible(false); + + // Wait for the |CrosSettings| to become either trusted or permanently + // untrusted. + const CrosSettingsProvider::TrustedStatus status = + CrosSettings::Get()->PrepareTrustedValues(base::Bind( + &LoginDisplayHostImpl::StartAppLaunch, + pointer_factory_.GetWeakPtr(), + app_id, + diagnostic_mode)); + if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED) + return; + + if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { + // If the |CrosSettings| are permanently untrusted, refuse to launch a + // single-app kiosk mode session. + LOG(ERROR) << "Login WebUI >> Refusing to launch single-app kiosk mode."; + SetStatusAreaVisible(true); + return; + } + + bool device_disabled = false; + CrosSettings::Get()->GetBoolean(kDeviceDisabled, &device_disabled); + if (device_disabled && system::DeviceDisablingManager:: + HonorDeviceDisablingDuringNormalOperation()) { + // If the device is disabled, bail out. A device disabled screen will be + // shown by the DeviceDisablingManager. + return; + } + finalize_animation_type_ = ANIMATION_FADE_OUT; if (!login_window_) LoadURL(GURL(kAppLaunchSplashURL)); @@ -1090,8 +1123,8 @@ } void LoginDisplayHostImpl::StartTimeZoneResolve() { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableTimeZoneTrackingOption)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kDisableTimeZoneTrackingOption)) { return; }
diff --git a/chrome/browser/chromeos/login/ui/oobe_display.h b/chrome/browser/chromeos/login/ui/oobe_display.h index d6a8cad..ca699b7 100644 --- a/chrome/browser/chromeos/login/ui/oobe_display.h +++ b/chrome/browser/chromeos/login/ui/oobe_display.h
@@ -30,7 +30,7 @@ class ResetScreenActor; class SupervisedUserCreationScreenHandler; class TermsOfServiceScreenActor; -class UpdateScreenActor; +class UpdateView; class UserImageView; class UserBoardView; class WrongHWIDScreenActor; @@ -74,9 +74,9 @@ // Pointers to actors which should be used by the specific screens. Actors // must be owned by the OobeDisplay implementation. virtual CoreOobeActor* GetCoreOobeActor() = 0; - virtual UpdateScreenActor* GetUpdateScreenActor() = 0; virtual NetworkView* GetNetworkView() = 0; virtual EulaView* GetEulaView() = 0; + virtual UpdateView* GetUpdateView() = 0; virtual EnableDebuggingScreenActor* GetEnableDebuggingScreenActor() = 0; virtual EnrollmentScreenActor* GetEnrollmentScreenActor() = 0; virtual ResetScreenActor* GetResetScreenActor() = 0;
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager.cc b/chrome/browser/chromeos/login/users/chrome_user_manager.cc index eccc602..d2c6a7d 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" +#include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" namespace chromeos { @@ -28,9 +29,8 @@ const user_manager::UserList& user_list) { user_manager::UserList result; for (user_manager::User* user : user_list) { - if (user->GetType() == user_manager::USER_TYPE_REGULAR) { + if (user->GetType() == user_manager::USER_TYPE_REGULAR) result.push_back(user); - } } return result; }
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager.h b/chrome/browser/chromeos/login/users/chrome_user_manager.h index 5ec3b8f..d97d2d75 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager.h +++ b/chrome/browser/chromeos/login/users/chrome_user_manager.h
@@ -6,22 +6,16 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_CHROME_USER_MANAGER_H_ #include "base/basictypes.h" -#include "components/user_manager/user.h" +#include "base/memory/ref_counted.h" +#include "base/task_runner.h" +#include "chrome/browser/chromeos/login/users/user_manager_interface.h" #include "components/user_manager/user_manager_base.h" -namespace base { -class TaskRunner; -} - namespace chromeos { -class MultiProfileUserController; -class SupervisedUserManager; -class UserFlow; -class UserImageManager; - // Chrome specific interface of the UserManager. -class ChromeUserManager : public user_manager::UserManagerBase { +class ChromeUserManager : public user_manager::UserManagerBase, + public UserManagerInterface { public: ChromeUserManager(scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::TaskRunner> blocking_task_runner); @@ -36,29 +30,6 @@ static user_manager::UserList GetUsersAllowedAsSupervisedUserManagers( const user_manager::UserList& user_list); - virtual MultiProfileUserController* GetMultiProfileUserController() = 0; - virtual UserImageManager* GetUserImageManager(const std::string& user_id) = 0; - virtual SupervisedUserManager* GetSupervisedUserManager() = 0; - - // Method that allows to set |flow| for user identified by |user_id|. - // Flow should be set before login attempt. - // Takes ownership of the |flow|, |flow| will be deleted in case of login - // failure. - virtual void SetUserFlow(const std::string& user_id, UserFlow* flow) = 0; - - // Return user flow for current user. Returns instance of DefaultUserFlow if - // no flow was defined for current user, or user is not logged in. - // Returned value should not be cached. - virtual UserFlow* GetCurrentUserFlow() const = 0; - - // Return user flow for user identified by |user_id|. Returns instance of - // DefaultUserFlow if no flow was defined for user. - // Returned value should not be cached. - virtual UserFlow* GetUserFlow(const std::string& user_id) const = 0; - - // Resets user flow for user identified by |user_id|. - virtual void ResetUserFlow(const std::string& user_id) = 0; - DISALLOW_COPY_AND_ASSIGN(ChromeUserManager); };
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index 61530d8..738015f 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -1048,8 +1048,8 @@ } void ChromeUserManagerImpl::UpdateUserTimeZoneRefresher(Profile* profile) { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableTimeZoneTrackingOption)) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kDisableTimeZoneTrackingOption)) { return; }
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h index 5d4a2a1..3e1ec1b 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.h
@@ -63,7 +63,7 @@ // Registers user manager preferences. static void RegisterPrefs(PrefRegistrySimple* registry); - // ChromeUserManager implementation: + // UserManagerInterface implementation: MultiProfileUserController* GetMultiProfileUserController() override; UserImageManager* GetUserImageManager(const std::string& user_id) override; SupervisedUserManager* GetSupervisedUserManager() override;
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc new file mode 100644 index 0000000..48309e4 --- /dev/null +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -0,0 +1,153 @@ +// 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/chromeos/login/users/fake_chrome_user_manager.h" + +#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_supervised_user_manager.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/grit/theme_resources.h" +#include "components/user_manager/user_image/user_image.h" +#include "components/user_manager/user_type.h" +#include "ui/base/resource/resource_bundle.h" + +namespace chromeos { + +class FakeSupervisedUserManager; + +FakeChromeUserManager::FakeChromeUserManager() + : supervised_user_manager_(new FakeSupervisedUserManager), + multi_profile_user_controller_(NULL) { +} + +FakeChromeUserManager::~FakeChromeUserManager() { +} + +const user_manager::User* FakeChromeUserManager::AddUser( + const std::string& email) { + user_manager::User* user = user_manager::User::CreateRegularUser(email); + user->set_username_hash( + ProfileHelper::GetUserIdHashByUserIdForTesting(email)); + user->SetStubImage(user_manager::UserImage( + *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_PROFILE_PICTURE_LOADING)), + user_manager::User::USER_IMAGE_PROFILE, false); + users_.push_back(user); + return user; +} + +const user_manager::User* FakeChromeUserManager::AddPublicAccountUser( + const std::string& email) { + user_manager::User* user = user_manager::User::CreatePublicAccountUser(email); + user->set_username_hash( + ProfileHelper::GetUserIdHashByUserIdForTesting(email)); + user->SetStubImage(user_manager::UserImage( + *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_PROFILE_PICTURE_LOADING)), + user_manager::User::USER_IMAGE_PROFILE, false); + users_.push_back(user); + return user; +} + +void FakeChromeUserManager::AddKioskAppUser( + const std::string& kiosk_app_username) { + user_manager::User* user = + user_manager::User::CreateKioskAppUser(kiosk_app_username); + user->set_username_hash( + ProfileHelper::GetUserIdHashByUserIdForTesting(kiosk_app_username)); + users_.push_back(user); +} + +void FakeChromeUserManager::LoginUser(const std::string& email) { + UserLoggedIn(email, ProfileHelper::GetUserIdHashByUserIdForTesting(email), + false /* browser_restart */); +} + +MultiProfileUserController* +FakeChromeUserManager::GetMultiProfileUserController() { + return multi_profile_user_controller_; +} + +SupervisedUserManager* FakeChromeUserManager::GetSupervisedUserManager() { + return supervised_user_manager_.get(); +} + +UserImageManager* FakeChromeUserManager::GetUserImageManager( + const std::string& /* user_id */) { + return nullptr; +} + +void FakeChromeUserManager::SetUserFlow(const std::string& email, + UserFlow* flow) { +} + +UserFlow* FakeChromeUserManager::GetCurrentUserFlow() const { + return nullptr; +} + +UserFlow* FakeChromeUserManager::GetUserFlow(const std::string& email) const { + return nullptr; +} + +void FakeChromeUserManager::ResetUserFlow(const std::string& email) { +} + +void FakeChromeUserManager::SwitchActiveUser(const std::string& email) { + active_user_id_ = email; + ProfileHelper::Get()->ActiveUserHashChanged( + ProfileHelper::GetUserIdHashByUserIdForTesting(email)); + if (!users_.empty() && !active_user_id_.empty()) { + for (user_manager::User* user : users_) + user->set_is_active(user->email() == active_user_id_); + } +} + +const std::string& FakeChromeUserManager::GetOwnerEmail() const { + return owner_email_; +} + +void FakeChromeUserManager::SessionStarted() { +} + +void FakeChromeUserManager::RemoveUser( + const std::string& email, + user_manager::RemoveUserDelegate* delegate) { +} + +user_manager::UserList +FakeChromeUserManager::GetUsersAllowedForSupervisedUsersCreation() const { + CrosSettings* cros_settings = CrosSettings::Get(); + bool allow_new_user = true; + cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); + bool supervised_users_allowed = AreSupervisedUsersAllowed(); + + // Restricted either by policy or by owner. + if (!allow_new_user || !supervised_users_allowed) + return user_manager::UserList(); + + return ChromeUserManager::GetUsersAllowedAsSupervisedUserManagers(GetUsers()); +} + +user_manager::UserList FakeChromeUserManager::GetUsersAllowedForMultiProfile() + const { + // Supervised users are not allowed to use multi-profiles. + if (GetLoggedInUsers().size() == 1 && + GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) { + return user_manager::UserList(); + } + + user_manager::UserList result; + const user_manager::UserList& users = GetUsers(); + for (user_manager::User* user : users) { + if (user->GetType() == user_manager::USER_TYPE_REGULAR && + !user->is_logged_in()) { + result.push_back(user); + } + } + + return result; +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h new file mode 100644 index 0000000..3a51cf4 --- /dev/null +++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -0,0 +1,82 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_USERS_FAKE_CHROME_USER_MANAGER_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_FAKE_CHROME_USER_MANAGER_H_ + +#include <map> +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/login/user_flow.h" +#include "chrome/browser/chromeos/login/users/user_manager_interface.h" +#include "components/user_manager/fake_user_manager.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_image/user_image.h" +#include "components/user_manager/user_manager_base.h" + +namespace chromeos { + +class FakeSupervisedUserManager; + +// Fake chrome user manager with a barebones implementation. Users can be added +// and set as logged in, and those users can be returned. +class FakeChromeUserManager : public user_manager::FakeUserManager, + public UserManagerInterface { + public: + FakeChromeUserManager(); + ~FakeChromeUserManager() override; + + // Create and add a kiosk app user. + void AddKioskAppUser(const std::string& kiosk_app_username); + + // Create and add a public account user. + const user_manager::User* AddPublicAccountUser(const std::string& email); + + // Calculates the user name hash and calls UserLoggedIn to login a user. + void LoginUser(const std::string& email); + + // UserManager overrides. + user_manager::UserList GetUsersAllowedForMultiProfile() const override; + + // user_manager::FakeUserManager override. + const user_manager::User* AddUser(const std::string& email) override; + + // UserManagerInterface implementation. + MultiProfileUserController* GetMultiProfileUserController() override; + UserImageManager* GetUserImageManager(const std::string& user_id) override; + SupervisedUserManager* GetSupervisedUserManager() override; + void SetUserFlow(const std::string& email, UserFlow* flow) override; + UserFlow* GetCurrentUserFlow() const override; + UserFlow* GetUserFlow(const std::string& email) const override; + void ResetUserFlow(const std::string& email) override; + user_manager::UserList GetUsersAllowedForSupervisedUsersCreation() + const override; + void SwitchActiveUser(const std::string& email) override; + const std::string& GetOwnerEmail() const override; + void SessionStarted() override; + void RemoveUser(const std::string& email, + user_manager::RemoveUserDelegate* delegate) override; + + void set_owner_email(const std::string& owner_email) { + owner_email_ = owner_email; + } + + void set_multi_profile_user_controller( + MultiProfileUserController* controller) { + multi_profile_user_controller_ = controller; + } + + private: + scoped_ptr<FakeSupervisedUserManager> supervised_user_manager_; + std::string owner_email_; + + MultiProfileUserController* multi_profile_user_controller_; + + DISALLOW_COPY_AND_ASSIGN(FakeChromeUserManager); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_FAKE_CHROME_USER_MANAGER_H_
diff --git a/chrome/browser/chromeos/login/users/fake_user_manager.cc b/chrome/browser/chromeos/login/users/fake_user_manager.cc deleted file mode 100644 index fac64ea..0000000 --- a/chrome/browser/chromeos/login/users/fake_user_manager.cc +++ /dev/null
@@ -1,357 +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 "chrome/browser/chromeos/login/users/fake_user_manager.h" - -#include "base/task_runner.h" -#include "chrome/browser/chromeos/login/users/fake_supervised_user_manager.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/grit/theme_resources.h" -#include "components/user_manager/user_image/user_image.h" -#include "components/user_manager/user_type.h" -#include "ui/base/resource/resource_bundle.h" - -namespace { - -class FakeTaskRunner : public base::TaskRunner { - public: - bool PostDelayedTask(const tracked_objects::Location& from_here, - const base::Closure& task, - base::TimeDelta delay) override { - task.Run(); - return true; - } - bool RunsTasksOnCurrentThread() const override { return true; } - - protected: - ~FakeTaskRunner() override {} -}; - -} // namespace - -namespace chromeos { - -FakeUserManager::FakeUserManager() - : ChromeUserManager(new FakeTaskRunner(), new FakeTaskRunner()), - supervised_user_manager_(new FakeSupervisedUserManager), - primary_user_(NULL), - multi_profile_user_controller_(NULL) { -} - -FakeUserManager::~FakeUserManager() { - // Can't use STLDeleteElements because of the private destructor of User. - for (user_manager::UserList::iterator it = user_list_.begin(); - it != user_list_.end(); - it = user_list_.erase(it)) { - delete *it; - } -} - -const user_manager::User* FakeUserManager::AddUser(const std::string& email) { - user_manager::User* user = user_manager::User::CreateRegularUser(email); - user->set_username_hash( - ProfileHelper::GetUserIdHashByUserIdForTesting(email)); - user->SetStubImage(user_manager::UserImage( - *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_PROFILE_PICTURE_LOADING)), - user_manager::User::USER_IMAGE_PROFILE, - false); - user_list_.push_back(user); - return user; -} - -const user_manager::User* FakeUserManager::AddPublicAccountUser( - const std::string& email) { - user_manager::User* user = user_manager::User::CreatePublicAccountUser(email); - user->set_username_hash( - ProfileHelper::GetUserIdHashByUserIdForTesting(email)); - user->SetStubImage(user_manager::UserImage( - *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_PROFILE_PICTURE_LOADING)), - user_manager::User::USER_IMAGE_PROFILE, - false); - user_list_.push_back(user); - return user; -} - -void FakeUserManager::AddKioskAppUser(const std::string& kiosk_app_username) { - user_manager::User* user = - user_manager::User::CreateKioskAppUser(kiosk_app_username); - user->set_username_hash( - ProfileHelper::GetUserIdHashByUserIdForTesting(kiosk_app_username)); - user_list_.push_back(user); -} - -void FakeUserManager::RemoveUserFromList(const std::string& email) { - user_manager::UserList::iterator it = user_list_.begin(); - while (it != user_list_.end() && (*it)->email() != email) ++it; - if (it != user_list_.end()) { - delete *it; - user_list_.erase(it); - } -} - -void FakeUserManager::LoginUser(const std::string& email) { - UserLoggedIn( - email, ProfileHelper::GetUserIdHashByUserIdForTesting(email), false); -} - -const user_manager::UserList& FakeUserManager::GetUsers() const { - return user_list_; -} - -user_manager::UserList FakeUserManager::GetUsersAllowedForMultiProfile() const { - user_manager::UserList result; - for (user_manager::UserList::const_iterator it = user_list_.begin(); - it != user_list_.end(); - ++it) { - if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR && - !(*it)->is_logged_in()) - result.push_back(*it); - } - return result; -} - -user_manager::UserList -FakeUserManager::GetUsersAllowedForSupervisedUsersCreation() const { - return ChromeUserManager::GetUsersAllowedAsSupervisedUserManagers(user_list_); -} - -const user_manager::UserList& FakeUserManager::GetLoggedInUsers() const { - return logged_in_users_; -} - -void FakeUserManager::UserLoggedIn(const std::string& email, - const std::string& username_hash, - bool browser_restart) { - for (user_manager::UserList::const_iterator it = user_list_.begin(); - it != user_list_.end(); - ++it) { - if ((*it)->username_hash() == username_hash) { - (*it)->set_is_logged_in(true); - (*it)->set_profile_is_created(); - logged_in_users_.push_back(*it); - - if (!primary_user_) - primary_user_ = *it; - break; - } - } -} - -user_manager::User* FakeUserManager::GetActiveUserInternal() const { - if (user_list_.size()) { - if (!active_user_id_.empty()) { - for (user_manager::UserList::const_iterator it = user_list_.begin(); - it != user_list_.end(); - ++it) { - if ((*it)->email() == active_user_id_) - return *it; - } - } - return user_list_[0]; - } - return NULL; -} - -const user_manager::User* FakeUserManager::GetActiveUser() const { - return GetActiveUserInternal(); -} - -user_manager::User* FakeUserManager::GetActiveUser() { - return GetActiveUserInternal(); -} - -void FakeUserManager::SwitchActiveUser(const std::string& email) { - active_user_id_ = email; - ProfileHelper::Get()->ActiveUserHashChanged( - ProfileHelper::GetUserIdHashByUserIdForTesting(email)); - if (user_list_.size() && !active_user_id_.empty()) { - for (user_manager::UserList::const_iterator it = user_list_.begin(); - it != user_list_.end(); ++it) { - (*it)->set_is_active((*it)->email() == active_user_id_); - } - } -} - -void FakeUserManager::SaveUserDisplayName( - const std::string& username, - const base::string16& display_name) { - for (user_manager::UserList::iterator it = user_list_.begin(); - it != user_list_.end(); - ++it) { - if ((*it)->email() == username) { - (*it)->set_display_name(display_name); - return; - } - } -} - -MultiProfileUserController* FakeUserManager::GetMultiProfileUserController() { - return multi_profile_user_controller_; -} - -SupervisedUserManager* FakeUserManager::GetSupervisedUserManager() { - return supervised_user_manager_.get(); -} - -UserImageManager* FakeUserManager::GetUserImageManager( - const std::string& /* user_id */) { - return NULL; -} - -const user_manager::UserList& FakeUserManager::GetLRULoggedInUsers() const { - return user_list_; -} - -user_manager::UserList FakeUserManager::GetUnlockUsers() const { - return user_list_; -} - -const std::string& FakeUserManager::GetOwnerEmail() const { - return owner_email_; -} - -bool FakeUserManager::IsKnownUser(const std::string& email) const { - return true; -} - -const user_manager::User* FakeUserManager::FindUser( - const std::string& email) const { - const user_manager::UserList& users = GetUsers(); - for (user_manager::UserList::const_iterator it = users.begin(); - it != users.end(); - ++it) { - if ((*it)->email() == email) - return *it; - } - return NULL; -} - -user_manager::User* FakeUserManager::FindUserAndModify( - const std::string& email) { - return NULL; -} - -const user_manager::User* FakeUserManager::GetLoggedInUser() const { - return NULL; -} - -user_manager::User* FakeUserManager::GetLoggedInUser() { - return NULL; -} - -const user_manager::User* FakeUserManager::GetPrimaryUser() const { - return primary_user_; -} - -base::string16 FakeUserManager::GetUserDisplayName( - const std::string& username) const { - return base::string16(); -} - -std::string FakeUserManager::GetUserDisplayEmail( - const std::string& username) const { - return std::string(); -} - -bool FakeUserManager::IsCurrentUserOwner() const { - return false; -} - -bool FakeUserManager::IsCurrentUserNew() const { - return false; -} - -bool FakeUserManager::IsCurrentUserNonCryptohomeDataEphemeral() const { - return false; -} - -bool FakeUserManager::CanCurrentUserLock() const { - return false; -} - -bool FakeUserManager::IsUserLoggedIn() const { - return logged_in_users_.size() > 0; -} - -bool FakeUserManager::IsLoggedInAsUserWithGaiaAccount() const { - return true; -} - -bool FakeUserManager::IsLoggedInAsPublicAccount() const { - return false; -} - -bool FakeUserManager::IsLoggedInAsGuest() const { - return false; -} - -bool FakeUserManager::IsLoggedInAsSupervisedUser() const { - return false; -} - -bool FakeUserManager::IsLoggedInAsKioskApp() const { - const user_manager::User* active_user = GetActiveUser(); - return active_user - ? active_user->GetType() == user_manager::USER_TYPE_KIOSK_APP - : false; -} - -bool FakeUserManager::IsLoggedInAsStub() const { - return false; -} - -bool FakeUserManager::IsSessionStarted() const { - return false; -} - -bool FakeUserManager::IsUserNonCryptohomeDataEphemeral( - const std::string& email) const { - return false; -} - -UserFlow* FakeUserManager::GetCurrentUserFlow() const { - return NULL; -} - -UserFlow* FakeUserManager::GetUserFlow(const std::string& email) const { - return NULL; -} - -bool FakeUserManager::AreSupervisedUsersAllowed() const { - return true; -} - -bool FakeUserManager::AreEphemeralUsersEnabled() const { - return false; -} - -const std::string& FakeUserManager::GetApplicationLocale() const { - static const std::string default_locale("en-US"); - return default_locale; -} - -PrefService* FakeUserManager::GetLocalState() const { - return NULL; -} - -bool FakeUserManager::IsEnterpriseManaged() const { - return false; -} - -bool FakeUserManager::IsDemoApp(const std::string& user_id) const { - return false; -} - -bool FakeUserManager::IsKioskApp(const std::string& user_id) const { - return false; -} - -bool FakeUserManager::IsPublicAccountMarkedForRemoval( - const std::string& user_id) const { - return false; -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc index bd822ac..126d6f1 100644 --- a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc +++ b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
@@ -7,7 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/multi_profile_user_controller_delegate.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/policy_cert_service.h" @@ -114,7 +114,7 @@ public MultiProfileUserControllerDelegate { public: MultiProfileUserControllerTest() - : fake_user_manager_(new FakeUserManager), + : fake_user_manager_(new FakeChromeUserManager), user_manager_enabler_(fake_user_manager_), user_not_allowed_count_(0) {} ~MultiProfileUserControllerTest() override {} @@ -203,7 +203,7 @@ content::TestBrowserThreadBundle threads_; scoped_ptr<policy::PolicyCertVerifier> cert_verifier_; scoped_ptr<TestingProfileManager> profile_manager_; - FakeUserManager* fake_user_manager_; // Not owned + FakeChromeUserManager* fake_user_manager_; // Not owned ScopedUserManagerEnabler user_manager_enabler_; scoped_ptr<MultiProfileUserController> controller_;
diff --git a/chrome/browser/chromeos/login/users/user_manager_interface.h b/chrome/browser/chromeos/login/users/user_manager_interface.h new file mode 100644 index 0000000..b17c543 --- /dev/null +++ b/chrome/browser/chromeos/login/users/user_manager_interface.h
@@ -0,0 +1,59 @@ +// 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_CHROMEOS_LOGIN_USERS_USER_MANAGER_INTERFACE_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_USER_MANAGER_INTERFACE_H_ + +#include "base/basictypes.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_type.h" + +namespace chromeos { + +class MultiProfileUserController; +class SupervisedUserManager; +class UserFlow; +class UserImageManager; + +// Chrome specific add-ons interface for the UserManager. +class UserManagerInterface { + public: + UserManagerInterface() {} + virtual ~UserManagerInterface() {} + + virtual MultiProfileUserController* GetMultiProfileUserController() = 0; + virtual UserImageManager* GetUserImageManager(const std::string& user_id) = 0; + virtual SupervisedUserManager* GetSupervisedUserManager() = 0; + + // Method that allows to set |flow| for user identified by |user_id|. + // Flow should be set before login attempt. + // Takes ownership of the |flow|, |flow| will be deleted in case of login + // failure. + virtual void SetUserFlow(const std::string& user_id, UserFlow* flow) = 0; + + // Return user flow for current user. Returns instance of DefaultUserFlow if + // no flow was defined for current user, or user is not logged in. + // Returned value should not be cached. + virtual UserFlow* GetCurrentUserFlow() const = 0; + + // Return user flow for user identified by |user_id|. Returns instance of + // DefaultUserFlow if no flow was defined for user. + // Returned value should not be cached. + virtual UserFlow* GetUserFlow(const std::string& user_id) const = 0; + + // Resets user flow for user identified by |user_id|. + virtual void ResetUserFlow(const std::string& user_id) = 0; + + // Returns list of users allowed for supervised user creation. + // Returns an empty list in cases when supervised user creation or adding new + // users is restricted. + virtual user_manager::UserList GetUsersAllowedForSupervisedUsersCreation() + const = 0; + + DISALLOW_COPY_AND_ASSIGN(UserManagerInterface); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_USER_MANAGER_INTERFACE_H_
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc index b8f2b564..12ab229d 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_unittest.cc
@@ -19,7 +19,7 @@ #include "base/prefs/pref_service.h" #include "base/prefs/testing_pref_service.h" #include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -39,14 +39,13 @@ class WallpaperManagerCacheTest : public test::AshTestBase { public: WallpaperManagerCacheTest() - : fake_user_manager_(new FakeUserManager()), - scoped_user_manager_(fake_user_manager_) { - } + : fake_user_manager_(new FakeChromeUserManager()), + scoped_user_manager_(fake_user_manager_) {} protected: ~WallpaperManagerCacheTest() override {} - FakeUserManager* fake_user_manager() { return fake_user_manager_; } + FakeChromeUserManager* fake_user_manager() { return fake_user_manager_; } void SetUp() override { test::AshTestBase::SetUp(); } @@ -59,7 +58,7 @@ } private: - FakeUserManager* fake_user_manager_; + FakeChromeUserManager* fake_user_manager_; ScopedUserManagerEnabler scoped_user_manager_; };
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index a9c66d1..b48c7d80 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -85,9 +85,6 @@ using content::BrowserThread; namespace { -// If reboot didn't happen, ask user to reboot device manually. -const int kWaitForRebootTimeSec = 3; - // Interval in ms which is used for smooth screen showing. static int kShowDelayMs = 400; @@ -194,8 +191,8 @@ PrefService* WizardController::local_state_for_testing_ = NULL; -WizardController::WizardController(chromeos::LoginDisplayHost* host, - chromeos::OobeDisplay* oobe_display) +WizardController::WizardController(LoginDisplayHost* host, + OobeDisplay* oobe_display) : current_screen_(NULL), previous_screen_(NULL), #if defined(GOOGLE_CHROME_BUILD) @@ -280,61 +277,54 @@ ShowWrongHWIDScreen(); } -chromeos::ErrorScreen* WizardController::GetErrorScreen() { - return static_cast<chromeos::ErrorScreen*>(GetScreen(kErrorScreenName)); +ErrorScreen* WizardController::GetErrorScreen() { + return static_cast<ErrorScreen*>(GetScreen(kErrorScreenName)); } BaseScreen* WizardController::CreateScreen(const std::string& screen_name) { if (screen_name == kNetworkScreenName) { - scoped_ptr<NetworkScreen> screen(new chromeos::NetworkScreen( - this, this, oobe_display_->GetNetworkView())); + scoped_ptr<NetworkScreen> screen( + new NetworkScreen(this, this, oobe_display_->GetNetworkView())); screen->Initialize(nullptr /* context */); return screen.release(); } else if (screen_name == kErrorScreenName) { - return new chromeos::ErrorScreen(this, - oobe_display_->GetErrorScreenActor()); + return new ErrorScreen(this, oobe_display_->GetErrorScreenActor()); } else if (screen_name == kUpdateScreenName) { - chromeos::UpdateScreen* result = - new chromeos::UpdateScreen(this, - oobe_display_->GetUpdateScreenActor(), - remora_controller_.get()); - result->SetRebootCheckDelay(kWaitForRebootTimeSec); - return result; + scoped_ptr<UpdateScreen> screen(new UpdateScreen( + this, oobe_display_->GetUpdateView(), remora_controller_.get())); + screen->Initialize(nullptr /* context */); + return screen.release(); } else if (screen_name == kUserImageScreenName) { - return new chromeos::UserImageScreen(this, - oobe_display_->GetUserImageView()); + return new UserImageScreen(this, oobe_display_->GetUserImageView()); } else if (screen_name == kEulaScreenName) { - return new chromeos::EulaScreen(this, this, oobe_display_->GetEulaView()); + return new EulaScreen(this, this, oobe_display_->GetEulaView()); } else if (screen_name == kEnrollmentScreenName) { - return new chromeos::EnrollmentScreen( - this, oobe_display_->GetEnrollmentScreenActor()); + return new EnrollmentScreen(this, + oobe_display_->GetEnrollmentScreenActor()); } else if (screen_name == kResetScreenName) { - return new chromeos::ResetScreen(this, - oobe_display_->GetResetScreenActor()); + return new ResetScreen(this, oobe_display_->GetResetScreenActor()); } else if (screen_name == kEnableDebuggingScreenName) { - return new chromeos::EnableDebuggingScreen( - this, - oobe_display_->GetEnableDebuggingScreenActor()); + return new EnableDebuggingScreen( + this, oobe_display_->GetEnableDebuggingScreenActor()); } else if (screen_name == kKioskEnableScreenName) { - return new chromeos::KioskEnableScreen( - this, oobe_display_->GetKioskEnableScreenActor()); + return new KioskEnableScreen(this, + oobe_display_->GetKioskEnableScreenActor()); } else if (screen_name == kKioskAutolaunchScreenName) { - return new chromeos::KioskAutolaunchScreen( + return new KioskAutolaunchScreen( this, oobe_display_->GetKioskAutolaunchScreenActor()); } else if (screen_name == kTermsOfServiceScreenName) { - return new chromeos::TermsOfServiceScreen( + return new TermsOfServiceScreen( this, oobe_display_->GetTermsOfServiceScreenActor()); } else if (screen_name == kWrongHWIDScreenName) { - return new chromeos::WrongHWIDScreen( - this, oobe_display_->GetWrongHWIDScreenActor()); + return new WrongHWIDScreen(this, oobe_display_->GetWrongHWIDScreenActor()); } else if (screen_name == kSupervisedUserCreationScreenName) { - return new chromeos::SupervisedUserCreationScreen( + return new SupervisedUserCreationScreen( this, oobe_display_->GetSupervisedUserCreationScreenActor()); } else if (screen_name == kHIDDetectionScreenName) { - return new chromeos::HIDDetectionScreen( - this, oobe_display_->GetHIDDetectionScreenActor()); + return new HIDDetectionScreen(this, + oobe_display_->GetHIDDetectionScreenActor()); } else if (screen_name == kAutoEnrollmentCheckScreenName) { - return new chromeos::AutoEnrollmentCheckScreen( + return new AutoEnrollmentCheckScreen( this, oobe_display_->GetAutoEnrollmentCheckScreenActor()); } else if (screen_name == kControllerPairingScreenName) { if (!shark_controller_) { @@ -357,7 +347,7 @@ oobe_display_->GetHostPairingScreenActor(), remora_controller_.get()); } else if (screen_name == kDeviceDisabledScreenName) { - return new chromeos::DeviceDisabledScreen( + return new DeviceDisabledScreen( this, oobe_display_->GetDeviceDisabledScreenActor()); } @@ -656,10 +646,9 @@ // Launch browser and delete login host controller. BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&chromeos::LoginUtils::DoBrowserLaunch, - base::Unretained(chromeos::LoginUtils::Get()), + BrowserThread::UI, FROM_HERE, + base::Bind(&LoginUtils::DoBrowserLaunch, + base::Unretained(LoginUtils::Get()), ProfileManager::GetActiveUserProfile(), host_)); host_ = NULL; } @@ -932,7 +921,7 @@ } /////////////////////////////////////////////////////////////////////////////// -// WizardController, chromeos::BaseScreenDelegate overrides: +// WizardController, BaseScreenDelegate overrides: void WizardController::OnExit(BaseScreen& /* screen */, ExitCodes exit_code, const ::login::ScreenContext* /* context */) { @@ -1193,8 +1182,8 @@ g_browser_process->platform_part()->browser_policy_connector_chromeos(); if (connector->IsEnterpriseManaged()) { std::string policy_timezone; - if (chromeos::CrosSettings::Get()->GetString( - chromeos::kSystemTimezonePolicy, &policy_timezone) && + if (CrosSettings::Get()->GetString(kSystemTimezonePolicy, + &policy_timezone) && !policy_timezone.empty()) { VLOG(1) << "Resolve TimeZone: TimeZone settings are overridden" << " by DevicePolicy."; @@ -1206,7 +1195,7 @@ VLOG(1) << "Resolve TimeZone: setting timezone to '" << timezone->timeZoneId << "'"; - chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID( + system::TimezoneSettings::GetInstance()->SetTimezoneFromID( base::UTF8ToUTF16(timezone->timeZoneId)); } }
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 0fe3ced..a075f8d 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -436,10 +436,8 @@ EXPECT_CALL(*mock_network_screen_, Show()).Times(0); EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); - MOCK(mock_update_screen_, - kUpdateScreenName, - MockUpdateScreen, - MockUpdateScreenActor); + MOCK(mock_update_screen_, kUpdateScreenName, MockUpdateScreen, + MockUpdateView); MOCK_WITH_DELEGATE(mock_eula_screen_, kEulaScreenName, MockEulaScreen, MockEulaView); MOCK(mock_enrollment_screen_, @@ -533,7 +531,7 @@ } linked_ptr<MockNetworkScreen> mock_network_screen_; - MockOutShowHide<MockUpdateScreen, MockUpdateScreenActor>* mock_update_screen_; + MockOutShowHide<MockUpdateScreen, MockUpdateView>* mock_update_screen_; MockOutShowHide<MockEulaScreen, MockEulaView>* mock_eula_screen_; MockOutShowHide<MockEnrollmentScreen, MockEnrollmentScreenActor>* mock_enrollment_screen_;
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc index 7ba138c..b4bdd1c 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -17,7 +17,6 @@ namespace { -const char kErrorInternal[] = "Internal Error."; const char kErrorKeyNotAllowedForSigning[] = "This key is not allowed for signing. Either it was used for signing " "before or it was not correctly generated."; @@ -30,16 +29,10 @@ return make_scoped_ptr(new base::StringValue(public_key_spki_der_b64)); } -// Wraps |callback| into a void(bool) callback which forwards -// |public_key_spki_der| if |true| is passed to it. -void WrapGenerateKeyCallback( +void RunGenerateKeyCallback( const PlatformKeysService::GenerateKeyCallback& callback, - const std::string& public_key_spki_der, - bool success) { - if (success) - callback.Run(public_key_spki_der, std::string() /* no error */); - else - callback.Run(std::string() /* no public key */, kErrorInternal); + const std::string& public_key_spki_der) { + callback.Run(public_key_spki_der, std::string() /* no error */); } // Callback used by |PlatformKeysService::Sign|. @@ -118,7 +111,7 @@ void PlatformKeysService::RegisterPublicKey( const std::string& extension_id, const std::string& public_key_spki_der, - const base::Callback<void(bool)>& callback) { + const base::Closure& callback) { GetPlatformKeysOfExtension( extension_id, base::Bind(&PlatformKeysService::RegisterPublicKeyGotPlatformKeys, @@ -144,12 +137,16 @@ const std::string& extension_id, const GetPlatformKeysCallback& callback) { state_store_->GetExtensionValue( - extension_id, - kStateStorePlatformKeys, + extension_id, kStateStorePlatformKeys, base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, - weak_factory_.GetWeakPtr(), - extension_id, - callback)); + weak_factory_.GetWeakPtr(), extension_id, callback)); +} + +void PlatformKeysService::SetPlatformKeysOfExtension( + const std::string& extension_id, + scoped_ptr<base::ListValue> platform_keys) { + state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, + platform_keys.Pass()); } void PlatformKeysService::GenerateRSAKeyCallback( @@ -161,22 +158,16 @@ callback.Run(std::string() /* no public key */, error_message); return; } - base::Callback<void(bool)> wrapped_callback( - base::Bind(&WrapGenerateKeyCallback, callback, public_key_spki_der)); + base::Closure wrapped_callback( + base::Bind(&RunGenerateKeyCallback, callback, public_key_spki_der)); RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback); } void PlatformKeysService::RegisterPublicKeyGotPlatformKeys( const std::string& extension_id, const std::string& public_key_spki_der, - const base::Callback<void(bool)>& callback, + const base::Closure& callback, scoped_ptr<base::ListValue> platform_keys) { - if (!platform_keys) { - LOG(ERROR) << "Error while reading the platform keys."; - callback.Run(false); - return; - } - scoped_ptr<base::StringValue> key_value( GetPublicKeyValue(public_key_spki_der)); @@ -184,10 +175,8 @@ << "Keys are assumed to be generated and not to be registered multiple " "times."; platform_keys->Append(key_value.release()); - - state_store_->SetExtensionValue( - extension_id, kStateStorePlatformKeys, platform_keys.Pass()); - callback.Run(true); + SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); + callback.Run(); } void PlatformKeysService::InvalidateKey( @@ -205,8 +194,7 @@ return; } - state_store_->SetExtensionValue( - extension_id, kStateStorePlatformKeys, platform_keys.Pass()); + SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); callback.Run(true); } @@ -220,8 +208,11 @@ base::ListValue* keys = NULL; if (!value->GetAsList(&keys)) { LOG(ERROR) << "Found a value of wrong type."; - value.reset(); + + keys = new base::ListValue; + value.reset(keys); } + ignore_result(value.release()); callback.Run(make_scoped_ptr(keys)); }
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.h b/chrome/browser/chromeos/platform_keys/platform_keys_service.h index f903d4d..79342d7 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.h
@@ -85,8 +85,8 @@ const SignCallback& callback); private: - typedef base::Callback<void(scoped_ptr<base::ListValue> platform_keys)> - GetPlatformKeysCallback; + using GetPlatformKeysCallback = + base::Callback<void(scoped_ptr<base::ListValue> platform_keys)>; // Registers the given public key as newly generated key, which is allowed to // be used for signing for a single time. Afterwards, calls |callback|. If @@ -94,7 +94,7 @@ // callback. void RegisterPublicKey(const std::string& extension_id, const std::string& public_key_spki_der, - const base::Callback<void(bool)>& callback); + const base::Closure& callback); // Gets the current validity of the given public key by reading StateStore. // Invalidates the key if it was found to be valid. Finally, calls |callback| @@ -109,6 +109,11 @@ void GetPlatformKeysOfExtension(const std::string& extension_id, const GetPlatformKeysCallback& callback); + // Writes |platform_keys| to the state store of the extension with id + // |extension_id|. + void SetPlatformKeysOfExtension(const std::string& extension_id, + scoped_ptr<base::ListValue> platform_keys); + // Callback used by |GenerateRSAKey|. // If the key generation was successful, registers the generated public key // for the given extension. If any error occurs during key generation or @@ -125,7 +130,7 @@ void RegisterPublicKeyGotPlatformKeys( const std::string& extension_id, const std::string& public_key_spki_der, - const base::Callback<void(bool)>& callback, + const base::Closure& callback, scoped_ptr<base::ListValue> platform_keys); // Callback used by |ReadValidityAndInvalidateKey|.
diff --git a/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.cc b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.cc new file mode 100644 index 0000000..952cab4c --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.cc
@@ -0,0 +1,65 @@ +// 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 "chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h" + +#include "base/logging.h" +#include "base/thread_task_runner_handle.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" + +namespace policy { + +AffiliatedCloudPolicyInvalidator::AffiliatedCloudPolicyInvalidator( + enterprise_management::DeviceRegisterRequest::Type type, + CloudPolicyCore* core, + AffiliatedInvalidationServiceProvider* invalidation_service_provider) + : type_(type), + core_(core), + invalidation_service_provider_(invalidation_service_provider), + highest_handled_invalidation_version_(0) { + invalidation_service_provider_->RegisterConsumer(this); +} + +AffiliatedCloudPolicyInvalidator::~AffiliatedCloudPolicyInvalidator() { + DestroyInvalidator(); + invalidation_service_provider_->UnregisterConsumer(this); +} + +void AffiliatedCloudPolicyInvalidator::OnInvalidationServiceSet( + invalidation::InvalidationService* invalidation_service) { + DestroyInvalidator(); + if (invalidation_service) + CreateInvalidator(invalidation_service); +} + +CloudPolicyInvalidator* +AffiliatedCloudPolicyInvalidator::GetInvalidatorForTest() const { + return invalidator_.get(); +} + +void AffiliatedCloudPolicyInvalidator::CreateInvalidator( + invalidation::InvalidationService* invalidation_service) { + DCHECK(!invalidator_); + invalidator_.reset(new CloudPolicyInvalidator( + type_, + core_, + base::ThreadTaskRunnerHandle::Get(), + scoped_ptr<base::Clock>(new base::DefaultClock()), + highest_handled_invalidation_version_)); + invalidator_->Initialize(invalidation_service); +} + +void AffiliatedCloudPolicyInvalidator::DestroyInvalidator() { + if (!invalidator_) + return; + + highest_handled_invalidation_version_ = + invalidator_->highest_handled_invalidation_version(); + invalidator_->Shutdown(); + invalidator_.reset(); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h new file mode 100644 index 0000000..162f39b1 --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h
@@ -0,0 +1,71 @@ +// 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 CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_CLOUD_POLICY_INVALIDATOR_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_CLOUD_POLICY_INVALIDATOR_H_ + +#include "base/basictypes.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" +#include "policy/proto/device_management_backend.pb.h" + +namespace invalidation { +class InvalidationService; +} + +namespace policy { + +class CloudPolicyCore; +class CloudPolicyInvalidator; + +// This class provides policy invalidations for a |CloudPolicyCore| that wishes +// to use a shared |InvalidationService| affiliated with the device's enrollment +// domain. This is the case e.g. for device policy and device-local account +// policy. +// It relies on an |AffiliatedInvalidationServiceProvider| to provide it with +// access to a shared |InvalidationService| to back the +// |CloudPolicyInvalidator|. Whenever the shared |InvalidationService| changes, +// the |CloudPolicyInvalidator| is destroyed and re-created. +class AffiliatedCloudPolicyInvalidator + : public AffiliatedInvalidationServiceProvider::Consumer { + public: + AffiliatedCloudPolicyInvalidator( + enterprise_management::DeviceRegisterRequest::Type type, + CloudPolicyCore* core, + AffiliatedInvalidationServiceProvider* invalidation_service_provider); + ~AffiliatedCloudPolicyInvalidator() override; + + // AffiliatedInvalidationServiceProvider::Consumer: + void OnInvalidationServiceSet( + invalidation::InvalidationService* invalidation_service) override; + + CloudPolicyInvalidator* GetInvalidatorForTest() const; + + private: + // Create a |CloudPolicyInvalidator| backed by the |invalidation_service|. + void CreateInvalidator( + invalidation::InvalidationService* invalidation_service); + + // Destroy the current |CloudPolicyInvalidator|, if any. + void DestroyInvalidator(); + + const enterprise_management::DeviceRegisterRequest::Type type_; + CloudPolicyCore* const core_; + + AffiliatedInvalidationServiceProvider* const invalidation_service_provider_; + + // The highest invalidation version that was handled already. + int64 highest_handled_invalidation_version_; + + // The current |CloudPolicyInvalidator|. nullptr if no connected invalidation + // service is available. + scoped_ptr<CloudPolicyInvalidator> invalidator_; + + DISALLOW_COPY_AND_ASSIGN(AffiliatedCloudPolicyInvalidator); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_CLOUD_POLICY_INVALIDATOR_H_
diff --git a/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator_unittest.cc b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator_unittest.cc new file mode 100644 index 0000000..f277324a --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator_unittest.cc
@@ -0,0 +1,194 @@ +// 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 "chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h" + +#include <string> + +#include "base/run_loop.h" +#include "base/thread_task_runner_handle.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" +#include "chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h" +#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/invalidation/fake_invalidation_service.h" +#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" +#include "components/invalidation/invalidation.h" +#include "components/invalidation/object_id_invalidation_map.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/policy/core/common/cloud/cloud_policy_core.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "google/cacheinvalidation/include/types.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace em = enterprise_management; + +using testing::Invoke; +using testing::Mock; +using testing::WithArgs; + +namespace policy { + +namespace { + +const int kInvalidationSource = 123; +const char kInvalidationName[] = "invalidation"; + +class FakeCloudPolicyStore : public CloudPolicyStore { + public: + FakeCloudPolicyStore(); + + // CloudPolicyStore: + void Store(const em::PolicyFetchResponse& policy) override; + void Load() override; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeCloudPolicyStore); +}; + +FakeCloudPolicyStore::FakeCloudPolicyStore() { +} + +void FakeCloudPolicyStore::Store(const em::PolicyFetchResponse& policy) { + policy_.reset(new em::PolicyData); + policy_->ParseFromString(policy.policy_data()); + Load(); +} + +void FakeCloudPolicyStore::Load() { + NotifyStoreLoaded(); +} + +} // namespace + +// Verifies that an invalidator is created/destroyed as an invalidation service +// becomes available/unavailable. Also verifies that invalidations are handled +// correctly and the highest handled invalidation version is preserved when +// switching invalidation services. +TEST(AffiliatedCloudPolicyInvalidatorTest, CreateUseDestroy) { + content::TestBrowserThreadBundle thread_bundle; + + // Set up a CloudPolicyCore backed by a simple CloudPolicyStore that does no + // signature verification and stores policy in memory. + FakeCloudPolicyStore store; + CloudPolicyCore core(dm_protocol::kChromeDevicePolicyType, + std::string(), + &store, + base::ThreadTaskRunnerHandle::Get()); + + // Connect |core|. Expect it to send a registration request. Let the + // registration succeed. + scoped_ptr<MockCloudPolicyClient> policy_client_owner( + new MockCloudPolicyClient); + MockCloudPolicyClient* policy_client = policy_client_owner.get(); + EXPECT_CALL(*policy_client, SetupRegistration("token", "device-id")) + .WillOnce(WithArgs<1>(Invoke(policy_client, + &MockCloudPolicyClient::SetDMToken))); + core.Connect(policy_client_owner.Pass()); + Mock::VerifyAndClearExpectations(&policy_client); + core.StartRefreshScheduler(); + + DevicePolicyBuilder policy; + policy.policy_data().set_invalidation_source(kInvalidationSource); + policy.policy_data().set_invalidation_name(kInvalidationName); + policy.Build(); + store.Store(policy.policy()); + + FakeAffiliatedInvalidationServiceProvider provider; + AffiliatedCloudPolicyInvalidator affiliated_invalidator( + em::DeviceRegisterRequest::DEVICE, + &core, + &provider); + + // Verify that no invalidator exists initially. + EXPECT_FALSE(affiliated_invalidator.GetInvalidatorForTest()); + + // Make a first invalidation service available. + invalidation::FakeInvalidationService invalidation_service_1; + affiliated_invalidator.OnInvalidationServiceSet(&invalidation_service_1); + + // Verify that an invalidator backed by the first invalidation service has + // been created and its highest handled invalidation version starts out as + // zero. + CloudPolicyInvalidator* invalidator = + affiliated_invalidator.GetInvalidatorForTest(); + ASSERT_TRUE(invalidator); + EXPECT_EQ(0, invalidator->highest_handled_invalidation_version()); + EXPECT_EQ(&invalidation_service_1, + invalidator->invalidation_service_for_test()); + + // Trigger an invalidation. The invalidation version is interpreted as a + // timestamp in microseconds. The policy blob contains a timestamp in + // milliseconds. Convert from one to the other by multiplying by 1000. + const int64 invalidation_version = policy.policy_data().timestamp() * 1000; + syncer::Invalidation invalidation = syncer::Invalidation::Init( + invalidation::ObjectId(kInvalidationSource, kInvalidationName), + invalidation_version, + "dummy payload"); + syncer::ObjectIdInvalidationMap invalidation_map; + invalidation_map.Insert(invalidation); + invalidator->OnIncomingInvalidation(invalidation_map); + + // Allow the invalidation to be handled. + policy_client->SetFetchedInvalidationVersion(invalidation_version); + policy.payload().mutable_reboot_on_shutdown()->set_reboot_on_shutdown(true); + policy.Build(); + policy_client->SetPolicy(dm_protocol::kChromeDevicePolicyType, + std::string(), + policy.policy()); + EXPECT_CALL(*policy_client, FetchPolicy()) + .WillOnce(Invoke(policy_client, + &MockCloudPolicyClient::NotifyPolicyFetched)); + base::RunLoop().RunUntilIdle(); + + // Verify that the invalidator's highest handled invalidation version was + // updated and the new policy was stored. + EXPECT_EQ(invalidation_version, + invalidator->highest_handled_invalidation_version()); + ASSERT_TRUE(store.policy()); + em::ChromeDeviceSettingsProto device_policy; + device_policy.ParseFromString(store.policy()->policy_value()); + EXPECT_EQ(true, device_policy.reboot_on_shutdown().reboot_on_shutdown()); + + // Make the first invalidation service unavailable. Verify that the + // invalidator is destroyed. + affiliated_invalidator.OnInvalidationServiceSet(nullptr); + EXPECT_FALSE(affiliated_invalidator.GetInvalidatorForTest()); + + // Make a second invalidation service available. + invalidation::FakeInvalidationService invalidation_service_2; + affiliated_invalidator.OnInvalidationServiceSet(&invalidation_service_2); + + // Verify that an invalidator backed by the second invalidation service has + // been created and its highest handled invalidation version does not start + // out as zero. + invalidator = affiliated_invalidator.GetInvalidatorForTest(); + ASSERT_TRUE(invalidator); + EXPECT_EQ(invalidation_version, + invalidator->highest_handled_invalidation_version()); + EXPECT_EQ(&invalidation_service_2, + invalidator->invalidation_service_for_test()); + + // Make the first invalidation service available again. This implies that the + // second invalidation service is no longer available. + affiliated_invalidator.OnInvalidationServiceSet(&invalidation_service_1); + + // Verify that the invalidator backed by the second invalidation service was + // destroyed and an invalidation backed by the first invalidation service has + // been created instead. Also verify that its highest handled invalidation + // version does not start out as zero. + invalidator = affiliated_invalidator.GetInvalidatorForTest(); + ASSERT_TRUE(invalidator); + EXPECT_EQ(invalidation_version, + invalidator->highest_handled_invalidation_version()); + EXPECT_EQ(&invalidation_service_1, + invalidator->invalidation_service_for_test()); + + provider.Shutdown(); + affiliated_invalidator.OnInvalidationServiceSet(nullptr); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.cc index 7fbbdf3..6cc2a87 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.cc
@@ -4,340 +4,19 @@ #include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" -#include <vector> - -#include "base/logging.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/ticl_device_settings_provider.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/device_identity_provider.h" -#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" -#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/common/chrome_content_client.h" -#include "components/invalidation/invalidation_handler.h" -#include "components/invalidation/invalidation_service.h" -#include "components/invalidation/invalidation_state_tracker.h" -#include "components/invalidation/invalidator_state.h" -#include "components/invalidation/invalidator_storage.h" -#include "components/invalidation/profile_invalidation_provider.h" -#include "components/invalidation/ticl_invalidation_service.h" -#include "components/invalidation/ticl_settings_provider.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/user_manager/user.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_service.h" -#include "google_apis/gaia/identity_provider.h" - namespace policy { +AffiliatedInvalidationServiceProvider::Consumer::Consumer() { +} + AffiliatedInvalidationServiceProvider::Consumer::~Consumer() { } -class AffiliatedInvalidationServiceProvider::InvalidationServiceObserver - : public syncer::InvalidationHandler { - public: - explicit InvalidationServiceObserver( - AffiliatedInvalidationServiceProvider* parent, - invalidation::InvalidationService* invalidation_service); - ~InvalidationServiceObserver() override; - - invalidation::InvalidationService* GetInvalidationService(); - bool IsServiceConnected() const; - - // public syncer::InvalidationHandler: - void OnInvalidatorStateChange(syncer::InvalidatorState state) override; - void OnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map) override; - std::string GetOwnerName() const override; - - private: - AffiliatedInvalidationServiceProvider* parent_; - invalidation::InvalidationService* invalidation_service_; - bool is_service_connected_; - bool is_observer_ready_; - - DISALLOW_COPY_AND_ASSIGN(InvalidationServiceObserver); -}; - -AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - InvalidationServiceObserver( - AffiliatedInvalidationServiceProvider* parent, - invalidation::InvalidationService* invalidation_service) - : parent_(parent), - invalidation_service_(invalidation_service), - is_service_connected_(false), - is_observer_ready_(false) { - invalidation_service_->RegisterInvalidationHandler(this); - is_service_connected_ = invalidation_service->GetInvalidatorState() == - syncer::INVALIDATIONS_ENABLED; - is_observer_ready_ = true; -} - -AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - ~InvalidationServiceObserver() { - is_observer_ready_ = false; - invalidation_service_->UnregisterInvalidationHandler(this); -} - -invalidation::InvalidationService* -AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - GetInvalidationService() { - return invalidation_service_; -} - -bool AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - IsServiceConnected() const { - return is_service_connected_; -} - -void AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - OnInvalidatorStateChange(syncer::InvalidatorState state) { - if (!is_observer_ready_) - return; - - const bool is_service_connected = (state == syncer::INVALIDATIONS_ENABLED); - if (is_service_connected == is_service_connected_) - return; - - is_service_connected_ = is_service_connected; - if (is_service_connected_) - parent_->OnInvalidationServiceConnected(invalidation_service_); - else - parent_->OnInvalidationServiceDisconnected(invalidation_service_); -} - -void AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - OnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map) { -} - -std::string AffiliatedInvalidationServiceProvider::InvalidationServiceObserver:: - GetOwnerName() const { - return "AffiliatedInvalidationService"; -} - -AffiliatedInvalidationServiceProvider::AffiliatedInvalidationServiceProvider() - : invalidation_service_(nullptr), - consumer_count_(0), - is_shut_down_(false) { - // The AffiliatedInvalidationServiceProvider should be created before any user - // Profiles. - DCHECK(g_browser_process->profile_manager()->GetLoadedProfiles().empty()); - - // Subscribe to notification about new user profiles becoming available. - registrar_.Add(this, - chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, - content::NotificationService::AllSources()); +AffiliatedInvalidationServiceProvider::AffiliatedInvalidationServiceProvider() { } AffiliatedInvalidationServiceProvider:: ~AffiliatedInvalidationServiceProvider() { - // Verify that the provider was shut down first. - DCHECK(is_shut_down_); -} - -void AffiliatedInvalidationServiceProvider::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, type); - DCHECK(!is_shut_down_); - Profile* profile = content::Details<Profile>(details).ptr(); - invalidation::ProfileInvalidationProvider* invalidation_provider = - invalidation::ProfileInvalidationProviderFactory::GetForProfile(profile); - if (!invalidation_provider) { - // If the Profile does not support invalidation (e.g. guest, incognito), - // ignore it. - return; - } - user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - if (!user || - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetUserAffiliation(user->email()) != USER_AFFILIATION_MANAGED) { - // If the Profile belongs to a user who is not affiliated with the device's - // enrollment domain, ignore it. - return; - } - - // Create a state observer for the user's invalidation service. - invalidation::InvalidationService* invalidation_service = - invalidation_provider->GetInvalidationService(); - profile_invalidation_service_observers_.push_back( - new InvalidationServiceObserver(this, invalidation_service)); - - if (profile_invalidation_service_observers_.back()->IsServiceConnected()) { - // If the invalidation service is connected, check whether to switch to it. - OnInvalidationServiceConnected(invalidation_service); - } -} - -void AffiliatedInvalidationServiceProvider::RegisterConsumer( - Consumer* consumer) { - if (consumers_.HasObserver(consumer) || is_shut_down_) - return; - - consumers_.AddObserver(consumer); - ++consumer_count_; - - if (invalidation_service_) - consumer->OnInvalidationServiceSet(invalidation_service_); - else if (consumer_count_ == 1) - FindConnectedInvalidationService(); -} - -void AffiliatedInvalidationServiceProvider::UnregisterConsumer( - Consumer* consumer) { - if (!consumers_.HasObserver(consumer)) - return; - - consumers_.RemoveObserver(consumer); - --consumer_count_; - - if (invalidation_service_ && consumer_count_ == 0) { - invalidation_service_ = nullptr; - DestroyDeviceInvalidationService(); - } -} - -void AffiliatedInvalidationServiceProvider::Shutdown() { - is_shut_down_ = true; - - registrar_.RemoveAll(); - profile_invalidation_service_observers_.clear(); - DestroyDeviceInvalidationService(); - - if (invalidation_service_) { - invalidation_service_ = nullptr; - // Explicitly notify consumers that the invalidation service they were using - // is no longer available. - SetInvalidationService(nullptr); - } -} - -invalidation::TiclInvalidationService* -AffiliatedInvalidationServiceProvider:: - GetDeviceInvalidationServiceForTest() const { - return device_invalidation_service_.get(); -} - -void AffiliatedInvalidationServiceProvider::OnInvalidationServiceConnected( - invalidation::InvalidationService* invalidation_service) { - DCHECK(!is_shut_down_); - - if (consumer_count_ == 0) { - // If there are no consumers, no invalidation service is required. - return; - } - - if (!device_invalidation_service_) { - // The lack of a device-global invalidation service implies that another - // connected invalidation service is being made available to consumers - // already. There is no need to switch from that to the service which just - // connected. - return; - } - - if (invalidation_service != device_invalidation_service_.get()) { - // If an invalidation service other than the device-global one connected, - // destroy the device-global service. - invalidation_service_ = nullptr; - DestroyDeviceInvalidationService(); - } - - // Make the invalidation service that just connected available to consumers. - SetInvalidationService(invalidation_service); -} - -void AffiliatedInvalidationServiceProvider::OnInvalidationServiceDisconnected( - invalidation::InvalidationService* invalidation_service) { - DCHECK(!is_shut_down_); - - if (invalidation_service != invalidation_service_) { - // If the invalidation service which disconnected was not being made - // available to consumers, return. - return; - } - - // The invalidation service which disconnected was being made available to - // consumers. Stop making it available. - DCHECK(consumer_count_); - invalidation_service_ = nullptr; - - // Try to make another invalidation service available to consumers. - FindConnectedInvalidationService(); - - // If no other connected invalidation service was found, explicitly notify - // consumers that the invalidation service they were using is no longer - // available. - if (!invalidation_service_) - SetInvalidationService(nullptr); -} - -void AffiliatedInvalidationServiceProvider::FindConnectedInvalidationService() { - DCHECK(!invalidation_service_); - DCHECK(consumer_count_); - DCHECK(!is_shut_down_); - - for (ScopedVector<InvalidationServiceObserver>::const_iterator it = - profile_invalidation_service_observers_.begin(); - it != profile_invalidation_service_observers_.end(); ++it) { - if ((*it)->IsServiceConnected()) { - // If a connected invalidation service belonging to an affiliated - // logged-in user is found, make it available to consumers. - DestroyDeviceInvalidationService(); - SetInvalidationService((*it)->GetInvalidationService()); - return; - } - } - - if (!device_invalidation_service_) { - // If no other connected invalidation service was found and no device-global - // invalidation service exists, create one. - device_invalidation_service_.reset( - new invalidation::TiclInvalidationService( - GetUserAgent(), - scoped_ptr<IdentityProvider>(new chromeos::DeviceIdentityProvider( - chromeos::DeviceOAuth2TokenServiceFactory::Get())), - scoped_ptr<invalidation::TiclSettingsProvider>( - new TiclDeviceSettingsProvider), - g_browser_process->gcm_driver(), - g_browser_process->system_request_context())); - device_invalidation_service_->Init( - scoped_ptr<syncer::InvalidationStateTracker>( - new invalidation::InvalidatorStorage( - g_browser_process->local_state()))); - device_invalidation_service_observer_.reset( - new InvalidationServiceObserver( - this, - device_invalidation_service_.get())); - } - - if (device_invalidation_service_observer_->IsServiceConnected()) { - // If the device-global invalidation service is connected already, make it - // available to consumers immediately. Otherwise, the invalidation service - // will be made available to clients when it successfully connects. - OnInvalidationServiceConnected(device_invalidation_service_.get()); - } -} - -void AffiliatedInvalidationServiceProvider::SetInvalidationService( - invalidation::InvalidationService* invalidation_service) { - DCHECK(!invalidation_service_); - invalidation_service_ = invalidation_service; - FOR_EACH_OBSERVER(Consumer, - consumers_, - OnInvalidationServiceSet(invalidation_service_)); -} - -void AffiliatedInvalidationServiceProvider::DestroyDeviceInvalidationService() { - device_invalidation_service_observer_.reset(); - device_invalidation_service_.reset(); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h index 548435507..c1b3b36 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h
@@ -6,15 +6,9 @@ #define CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_H_ #include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/observer_list.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" namespace invalidation { class InvalidationService; -class TiclInvalidationService; } namespace policy { @@ -34,11 +28,12 @@ // between them whenever the service currently in use disconnects or the // device-global invalidation service can be replaced with another service that // just connected. -class AffiliatedInvalidationServiceProvider - : public content::NotificationObserver { +class AffiliatedInvalidationServiceProvider { public: class Consumer { public: + Consumer(); + // This method is called when the invalidation service that the consumer // should use changes: // * If |invalidation_service| is a nullptr, no invalidation service is @@ -51,15 +46,12 @@ protected: virtual ~Consumer(); + + DISALLOW_ASSIGN(Consumer); }; AffiliatedInvalidationServiceProvider(); - ~AffiliatedInvalidationServiceProvider() override; - - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + virtual ~AffiliatedInvalidationServiceProvider(); // Indicates that |consumer| is interested in using the shared // |InvalidationService|. The consumer's OnInvalidationServiceSet() method @@ -67,72 +59,20 @@ // available. If an invalidation service is available already, the callback // will occur synchronously. The |consumer| must be unregistered before |this| // is destroyed. - void RegisterConsumer(Consumer* consumer); + virtual void RegisterConsumer(Consumer* consumer) = 0; // Indicates that |consumer| is no longer interested in using the // shared |InvalidationService|. - void UnregisterConsumer(Consumer* consumer); + virtual void UnregisterConsumer(Consumer* consumer) = 0; // Shuts down the provider. Once the provider is shut down, it no longer makes // any invalidation service available to consumers, no longer observes any // per-profile invalidation services and no longer maintains a device-global // invalidation service. - void Shutdown(); - - invalidation::TiclInvalidationService* - GetDeviceInvalidationServiceForTest() const; + virtual void Shutdown() = 0; private: - // Helper that monitors the status of a single |InvalidationService|. - class InvalidationServiceObserver; - - // Status updates received from |InvalidationServiceObserver|s. - void OnInvalidationServiceConnected( - invalidation::InvalidationService* invalidation_service); - void OnInvalidationServiceDisconnected( - invalidation::InvalidationService* invalidation_service); - - // Checks whether a connected |InvalidationService| affiliated with the - // device's enrollment domain is available. If so, notifies the consumers. - // Otherwise, consumers will be notified once such an invalidation service - // becomes available. - // Further ensures that a device-global invalidation service is running iff - // there is no other connected service available for use and there is at least - // one registered consumer. - void FindConnectedInvalidationService(); - - // Choose |invalidation_service| as the shared invalidation service and notify - // consumers. - void SetInvalidationService( - invalidation::InvalidationService* invalidation_service); - - // Destroy the device-global invalidation service, if any. - void DestroyDeviceInvalidationService(); - - content::NotificationRegistrar registrar_; - - // Device-global invalidation service. - scoped_ptr<invalidation::TiclInvalidationService> - device_invalidation_service_; - - // State observer for the device-global invalidation service. - scoped_ptr<InvalidationServiceObserver> device_invalidation_service_observer_; - - // State observers for logged-in users' invalidation services. - ScopedVector<InvalidationServiceObserver> - profile_invalidation_service_observers_; - - // The invalidation service currently used by consumers. nullptr if there are - // no registered consumers or no connected invalidation service is available - // for use. - invalidation::InvalidationService* invalidation_service_; - - ObserverList<Consumer, true> consumers_; - int consumer_count_; - - bool is_shut_down_; - - DISALLOW_COPY_AND_ASSIGN(AffiliatedInvalidationServiceProvider); + DISALLOW_ASSIGN(AffiliatedInvalidationServiceProvider); }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc new file mode 100644 index 0000000..353662c --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
@@ -0,0 +1,345 @@ +// 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/chromeos/policy/affiliated_invalidation_service_provider_impl.h" + +#include <vector> + +#include "base/logging.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/policy/ticl_device_settings_provider.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/device_identity_provider.h" +#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" +#include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_content_client.h" +#include "components/invalidation/invalidation_handler.h" +#include "components/invalidation/invalidation_service.h" +#include "components/invalidation/invalidation_state_tracker.h" +#include "components/invalidation/invalidator_state.h" +#include "components/invalidation/invalidator_storage.h" +#include "components/invalidation/profile_invalidation_provider.h" +#include "components/invalidation/ticl_invalidation_service.h" +#include "components/invalidation/ticl_settings_provider.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/user_manager/user.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_service.h" +#include "google_apis/gaia/identity_provider.h" + +namespace policy { + +class AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver + : public syncer::InvalidationHandler { + public: + explicit InvalidationServiceObserver( + AffiliatedInvalidationServiceProviderImpl* parent, + invalidation::InvalidationService* invalidation_service); + ~InvalidationServiceObserver() override; + + invalidation::InvalidationService* GetInvalidationService(); + bool IsServiceConnected() const; + + // public syncer::InvalidationHandler: + void OnInvalidatorStateChange(syncer::InvalidatorState state) override; + void OnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map) override; + std::string GetOwnerName() const override; + + private: + AffiliatedInvalidationServiceProviderImpl* parent_; + invalidation::InvalidationService* invalidation_service_; + bool is_service_connected_; + bool is_observer_ready_; + + DISALLOW_COPY_AND_ASSIGN(InvalidationServiceObserver); +}; + +AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + InvalidationServiceObserver( + AffiliatedInvalidationServiceProviderImpl* parent, + invalidation::InvalidationService* invalidation_service) + : parent_(parent), + invalidation_service_(invalidation_service), + is_service_connected_(false), + is_observer_ready_(false) { + invalidation_service_->RegisterInvalidationHandler(this); + is_service_connected_ = invalidation_service->GetInvalidatorState() == + syncer::INVALIDATIONS_ENABLED; + is_observer_ready_ = true; +} + +AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + ~InvalidationServiceObserver() { + is_observer_ready_ = false; + invalidation_service_->UnregisterInvalidationHandler(this); +} + +invalidation::InvalidationService* +AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + GetInvalidationService() { + return invalidation_service_; +} + +bool AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + IsServiceConnected() const { + return is_service_connected_; +} + +void AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + OnInvalidatorStateChange(syncer::InvalidatorState state) { + if (!is_observer_ready_) + return; + + const bool is_service_connected = (state == syncer::INVALIDATIONS_ENABLED); + if (is_service_connected == is_service_connected_) + return; + + is_service_connected_ = is_service_connected; + if (is_service_connected_) + parent_->OnInvalidationServiceConnected(invalidation_service_); + else + parent_->OnInvalidationServiceDisconnected(invalidation_service_); +} + +void AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + OnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map) { +} + +std::string +AffiliatedInvalidationServiceProviderImpl::InvalidationServiceObserver:: + GetOwnerName() const { + return "AffiliatedInvalidationService"; +} + +AffiliatedInvalidationServiceProviderImpl:: +AffiliatedInvalidationServiceProviderImpl() + : invalidation_service_(nullptr), + consumer_count_(0), + is_shut_down_(false) { + // The AffiliatedInvalidationServiceProviderImpl should be created before any + // user Profiles. + DCHECK(g_browser_process->profile_manager()->GetLoadedProfiles().empty()); + + // Subscribe to notification about new user profiles becoming available. + registrar_.Add(this, + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, + content::NotificationService::AllSources()); +} + +AffiliatedInvalidationServiceProviderImpl:: +~AffiliatedInvalidationServiceProviderImpl() { + // Verify that the provider was shut down first. + DCHECK(is_shut_down_); +} + +void AffiliatedInvalidationServiceProviderImpl::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK_EQ(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, type); + DCHECK(!is_shut_down_); + Profile* profile = content::Details<Profile>(details).ptr(); + invalidation::ProfileInvalidationProvider* invalidation_provider = + invalidation::ProfileInvalidationProviderFactory::GetForProfile(profile); + if (!invalidation_provider) { + // If the Profile does not support invalidation (e.g. guest, incognito), + // ignore it. + return; + } + user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile(profile); + if (!user || + g_browser_process->platform_part()->browser_policy_connector_chromeos()-> + GetUserAffiliation(user->email()) != USER_AFFILIATION_MANAGED) { + // If the Profile belongs to a user who is not affiliated with the device's + // enrollment domain, ignore it. + return; + } + + // Create a state observer for the user's invalidation service. + invalidation::InvalidationService* invalidation_service = + invalidation_provider->GetInvalidationService(); + profile_invalidation_service_observers_.push_back( + new InvalidationServiceObserver(this, invalidation_service)); + + if (profile_invalidation_service_observers_.back()->IsServiceConnected()) { + // If the invalidation service is connected, check whether to switch to it. + OnInvalidationServiceConnected(invalidation_service); + } +} + +void AffiliatedInvalidationServiceProviderImpl::RegisterConsumer( + Consumer* consumer) { + if (consumers_.HasObserver(consumer) || is_shut_down_) + return; + + consumers_.AddObserver(consumer); + ++consumer_count_; + + if (invalidation_service_) + consumer->OnInvalidationServiceSet(invalidation_service_); + else if (consumer_count_ == 1) + FindConnectedInvalidationService(); +} + +void AffiliatedInvalidationServiceProviderImpl::UnregisterConsumer( + Consumer* consumer) { + if (!consumers_.HasObserver(consumer)) + return; + + consumers_.RemoveObserver(consumer); + --consumer_count_; + + if (invalidation_service_ && consumer_count_ == 0) { + invalidation_service_ = nullptr; + DestroyDeviceInvalidationService(); + } +} + +void AffiliatedInvalidationServiceProviderImpl::Shutdown() { + is_shut_down_ = true; + + registrar_.RemoveAll(); + profile_invalidation_service_observers_.clear(); + DestroyDeviceInvalidationService(); + + if (invalidation_service_) { + invalidation_service_ = nullptr; + // Explicitly notify consumers that the invalidation service they were using + // is no longer available. + SetInvalidationService(nullptr); + } +} + +invalidation::TiclInvalidationService* +AffiliatedInvalidationServiceProviderImpl:: + GetDeviceInvalidationServiceForTest() const { + return device_invalidation_service_.get(); +} + +void AffiliatedInvalidationServiceProviderImpl::OnInvalidationServiceConnected( + invalidation::InvalidationService* invalidation_service) { + DCHECK(!is_shut_down_); + + if (consumer_count_ == 0) { + // If there are no consumers, no invalidation service is required. + return; + } + + if (!device_invalidation_service_) { + // The lack of a device-global invalidation service implies that another + // connected invalidation service is being made available to consumers + // already. There is no need to switch from that to the service which just + // connected. + return; + } + + if (invalidation_service != device_invalidation_service_.get()) { + // If an invalidation service other than the device-global one connected, + // destroy the device-global service. + invalidation_service_ = nullptr; + DestroyDeviceInvalidationService(); + } + + // Make the invalidation service that just connected available to consumers. + SetInvalidationService(invalidation_service); +} + +void +AffiliatedInvalidationServiceProviderImpl::OnInvalidationServiceDisconnected( + invalidation::InvalidationService* invalidation_service) { + DCHECK(!is_shut_down_); + + if (invalidation_service != invalidation_service_) { + // If the invalidation service which disconnected was not being made + // available to consumers, return. + return; + } + + // The invalidation service which disconnected was being made available to + // consumers. Stop making it available. + DCHECK(consumer_count_); + invalidation_service_ = nullptr; + + // Try to make another invalidation service available to consumers. + FindConnectedInvalidationService(); + + // If no other connected invalidation service was found, explicitly notify + // consumers that the invalidation service they were using is no longer + // available. + if (!invalidation_service_) + SetInvalidationService(nullptr); +} + +void +AffiliatedInvalidationServiceProviderImpl::FindConnectedInvalidationService() { + DCHECK(!invalidation_service_); + DCHECK(consumer_count_); + DCHECK(!is_shut_down_); + + for (ScopedVector<InvalidationServiceObserver>::const_iterator it = + profile_invalidation_service_observers_.begin(); + it != profile_invalidation_service_observers_.end(); ++it) { + if ((*it)->IsServiceConnected()) { + // If a connected invalidation service belonging to an affiliated + // logged-in user is found, make it available to consumers. + DestroyDeviceInvalidationService(); + SetInvalidationService((*it)->GetInvalidationService()); + return; + } + } + + if (!device_invalidation_service_) { + // If no other connected invalidation service was found and no device-global + // invalidation service exists, create one. + device_invalidation_service_.reset( + new invalidation::TiclInvalidationService( + GetUserAgent(), + scoped_ptr<IdentityProvider>(new chromeos::DeviceIdentityProvider( + chromeos::DeviceOAuth2TokenServiceFactory::Get())), + scoped_ptr<invalidation::TiclSettingsProvider>( + new TiclDeviceSettingsProvider), + g_browser_process->gcm_driver(), + g_browser_process->system_request_context())); + device_invalidation_service_->Init( + scoped_ptr<syncer::InvalidationStateTracker>( + new invalidation::InvalidatorStorage( + g_browser_process->local_state()))); + device_invalidation_service_observer_.reset( + new InvalidationServiceObserver( + this, + device_invalidation_service_.get())); + } + + if (device_invalidation_service_observer_->IsServiceConnected()) { + // If the device-global invalidation service is connected already, make it + // available to consumers immediately. Otherwise, the invalidation service + // will be made available to clients when it successfully connects. + OnInvalidationServiceConnected(device_invalidation_service_.get()); + } +} + +void AffiliatedInvalidationServiceProviderImpl::SetInvalidationService( + invalidation::InvalidationService* invalidation_service) { + DCHECK(!invalidation_service_); + invalidation_service_ = invalidation_service; + FOR_EACH_OBSERVER(Consumer, + consumers_, + OnInvalidationServiceSet(invalidation_service_)); +} + +void +AffiliatedInvalidationServiceProviderImpl::DestroyDeviceInvalidationService() { + device_invalidation_service_observer_.reset(); + device_invalidation_service_.reset(); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h new file mode 100644 index 0000000..1ab8216b --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h
@@ -0,0 +1,98 @@ +// 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_CHROMEOS_POLICY_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_IMPL_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_IMPL_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "base/observer_list.h" +#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +namespace invalidation { +class InvalidationService; +class TiclInvalidationService; +} + +namespace policy { + +class AffiliatedInvalidationServiceProviderImpl + : public AffiliatedInvalidationServiceProvider, + public content::NotificationObserver { + public: + AffiliatedInvalidationServiceProviderImpl(); + ~AffiliatedInvalidationServiceProviderImpl() override; + + // content::NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + + // AffiliatedInvalidationServiceProvider: + void RegisterConsumer(Consumer* consumer) override; + void UnregisterConsumer(Consumer* consumer) override; + void Shutdown() override; + + invalidation::TiclInvalidationService* + GetDeviceInvalidationServiceForTest() const; + + private: + // Helper that monitors the status of a single |InvalidationService|. + class InvalidationServiceObserver; + + // Status updates received from |InvalidationServiceObserver|s. + void OnInvalidationServiceConnected( + invalidation::InvalidationService* invalidation_service); + void OnInvalidationServiceDisconnected( + invalidation::InvalidationService* invalidation_service); + + // Checks whether a connected |InvalidationService| affiliated with the + // device's enrollment domain is available. If so, notifies the consumers. + // Otherwise, consumers will be notified once such an invalidation service + // becomes available. + // Further ensures that a device-global invalidation service is running iff + // there is no other connected service available for use and there is at least + // one registered consumer. + void FindConnectedInvalidationService(); + + // Choose |invalidation_service| as the shared invalidation service and notify + // consumers. + void SetInvalidationService( + invalidation::InvalidationService* invalidation_service); + + // Destroy the device-global invalidation service, if any. + void DestroyDeviceInvalidationService(); + + content::NotificationRegistrar registrar_; + + // Device-global invalidation service. + scoped_ptr<invalidation::TiclInvalidationService> + device_invalidation_service_; + + // State observer for the device-global invalidation service. + scoped_ptr<InvalidationServiceObserver> device_invalidation_service_observer_; + + // State observers for logged-in users' invalidation services. + ScopedVector<InvalidationServiceObserver> + profile_invalidation_service_observers_; + + // The invalidation service currently used by consumers. nullptr if there are + // no registered consumers or no connected invalidation service is available + // for use. + invalidation::InvalidationService* invalidation_service_; + + ObserverList<Consumer, true> consumers_; + int consumer_count_; + + bool is_shut_down_; + + DISALLOW_COPY_AND_ASSIGN(AffiliatedInvalidationServiceProviderImpl); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_IMPL_H_
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc similarity index 87% rename from chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_unittest.cc rename to chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc index c0798064..370d4a7 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_unittest.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" +#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h" #include <string> #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -68,9 +68,9 @@ DISALLOW_COPY_AND_ASSIGN(MockConsumer); }; -class AffiliatedInvalidationServiceProviderTest : public testing::Test { +class AffiliatedInvalidationServiceProviderImplTest : public testing::Test { public: - AffiliatedInvalidationServiceProviderTest(); + AffiliatedInvalidationServiceProviderImplTest(); // testing::Test: virtual void SetUp() override; @@ -105,14 +105,14 @@ bool create); protected: - scoped_ptr<AffiliatedInvalidationServiceProvider> provider_; + scoped_ptr<AffiliatedInvalidationServiceProviderImpl> provider_; StrictMock<MockConsumer> consumer_; invalidation::TiclInvalidationService* device_invalidation_service_; invalidation::FakeInvalidationService* profile_invalidation_service_; private: content::TestBrowserThreadBundle thread_bundle_; - chromeos::FakeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler user_manager_enabler_; ScopedStubEnterpriseInstallAttributes install_attributes_; scoped_ptr<chromeos::ScopedTestDeviceSettingsService> @@ -127,11 +127,11 @@ MockConsumer::~MockConsumer() { } -AffiliatedInvalidationServiceProviderTest:: -AffiliatedInvalidationServiceProviderTest() +AffiliatedInvalidationServiceProviderImplTest:: +AffiliatedInvalidationServiceProviderImplTest() : device_invalidation_service_(nullptr), profile_invalidation_service_(nullptr), - fake_user_manager_(new chromeos::FakeUserManager), + fake_user_manager_(new chromeos::FakeChromeUserManager), user_manager_enabler_(fake_user_manager_), install_attributes_("example.com", "user@example.com", @@ -140,7 +140,7 @@ profile_manager_(TestingBrowserProcess::GetGlobal()) { } -void AffiliatedInvalidationServiceProviderTest::SetUp() { +void AffiliatedInvalidationServiceProviderImplTest::SetUp() { chromeos::SystemSaltGetter::Initialize(); chromeos::DBusThreadManager::Initialize(); ASSERT_TRUE(profile_manager_.SetUp()); @@ -153,10 +153,10 @@ invalidation::ProfileInvalidationProviderFactory::GetInstance()-> RegisterTestingFactory(BuildProfileInvalidationProvider); - provider_.reset(new AffiliatedInvalidationServiceProvider); + provider_.reset(new AffiliatedInvalidationServiceProviderImpl); } -void AffiliatedInvalidationServiceProviderTest::TearDown() { +void AffiliatedInvalidationServiceProviderImplTest::TearDown() { provider_->Shutdown(); provider_.reset(); @@ -167,7 +167,7 @@ chromeos::SystemSaltGetter::Shutdown(); } -Profile* AffiliatedInvalidationServiceProviderTest::LogInAndReturnProfile( +Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile( const std::string& user_id) { fake_user_manager_->AddUser(user_id); Profile* profile = profile_manager_.CreateTestingProfile(user_id); @@ -178,7 +178,7 @@ return profile; } -void AffiliatedInvalidationServiceProviderTest:: +void AffiliatedInvalidationServiceProviderImplTest:: LogInAsAffiliatedUserAndConnectInvalidationService() { Mock::VerifyAndClearExpectations(&consumer_); @@ -209,7 +209,7 @@ Mock::VerifyAndClearExpectations(&consumer_); } -void AffiliatedInvalidationServiceProviderTest:: +void AffiliatedInvalidationServiceProviderImplTest:: LogInAsUnaffiliatedUserAndConnectInvalidationService() { Mock::VerifyAndClearExpectations(&consumer_); @@ -236,7 +236,7 @@ Mock::VerifyAndClearExpectations(&consumer_); } -void AffiliatedInvalidationServiceProviderTest:: +void AffiliatedInvalidationServiceProviderImplTest:: ConnectDeviceGlobalInvalidationService() { Mock::VerifyAndClearExpectations(&consumer_); @@ -255,7 +255,7 @@ Mock::VerifyAndClearExpectations(&consumer_); } -void AffiliatedInvalidationServiceProviderTest:: +void AffiliatedInvalidationServiceProviderImplTest:: DisconnectPerProfileInvalidationService() { Mock::VerifyAndClearExpectations(&consumer_); @@ -274,7 +274,7 @@ } invalidation::FakeInvalidationService* -AffiliatedInvalidationServiceProviderTest::GetProfileInvalidationService( +AffiliatedInvalidationServiceProviderImplTest::GetProfileInvalidationService( Profile* profile, bool create) { invalidation::ProfileInvalidationProvider* invalidation_provider = static_cast<invalidation::ProfileInvalidationProvider*>( @@ -286,10 +286,11 @@ invalidation_provider->GetInvalidationService()); } -// No consumers are registered with the AffiliatedInvalidationServiceProvider. -// Verifies that no device-global invalidation service is created, whether an -// affiliated user is logged in or not. -TEST_F(AffiliatedInvalidationServiceProviderTest, NoConsumers) { +// No consumers are registered with the +// AffiliatedInvalidationServiceProviderImpl. Verifies that no device-global +// invalidation service is created, whether an affiliated user is logged in or +// not. +TEST_F(AffiliatedInvalidationServiceProviderImplTest, NoConsumers) { // Verify that no device-global invalidation service has been created. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); @@ -300,12 +301,12 @@ EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. // Verifies that when no per-profile invalidation service belonging to an // affiliated user is available, a device-global invalidation service is // created. Further verifies that when the device-global invalidation service // connects, it is made available to the consumer. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, UseDeviceInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -330,10 +331,10 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. // Verifies that when a per-profile invalidation service belonging to an // affiliated user connects, it is made available to the consumer. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, UseAffiliatedProfileInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -358,10 +359,10 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. // Verifies that when a per-profile invalidation service belonging to an // unaffiliated user connects, it is ignored. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, DoNotUseUnaffiliatedProfileInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -381,12 +382,12 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// device-global invalidation service exists, is connected and is made available -// to the consumer. Verifies that when a per-profile invalidation service -// belonging to an affiliated user connects, it is made available to the +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A device-global invalidation service exists, is connected and is made +// available to the consumer. Verifies that when a per-profile invalidation +// service belonging to an affiliated user connects, it is made available to the // consumer instead and the device-global invalidation service is destroyed. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchToAffiliatedProfileInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -407,13 +408,13 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// device-global invalidation service exists, is connected and is made available -// to the consumer. Verifies that when a per-profile invalidation service -// belonging to an unaffiliated user connects, it is ignored and the +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A device-global invalidation service exists, is connected and is made +// available to the consumer. Verifies that when a per-profile invalidation +// service belonging to an unaffiliated user connects, it is ignored and the // device-global invalidation service continues to be made available to the // consumer. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, DoNotSwitchToUnaffiliatedProfileInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -434,13 +435,13 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// per-profile invalidation service belonging to an affiliated user exists, is +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A per-profile invalidation service belonging to an affiliated user exists, is // connected and is made available to the consumer. Verifies that when the // per-profile invalidation service disconnects, a device-global invalidation // service is created. Further verifies that when the device-global invalidation // service connects, it is made available to the consumer. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchToDeviceInvalidationService) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -469,14 +470,14 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// per-profile invalidation service belonging to a first affiliated user exists, -// is connected and is made available to the consumer. A per-profile +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A per-profile invalidation service belonging to a first affiliated user +// exists, is connected and is made available to the consumer. A per-profile // invalidation service belonging to a second affiliated user also exists and is // connected. Verifies that when the per-profile invalidation service belonging // to the first user disconnects, the per-profile invalidation service belonging // to the second user is made available to the consumer instead. -TEST_F(AffiliatedInvalidationServiceProviderTest, +TEST_F(AffiliatedInvalidationServiceProviderImplTest, SwitchBetweenAffiliatedProfileInvalidationServices) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. @@ -529,15 +530,15 @@ Mock::VerifyAndClearExpectations(&consumer_); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// device-global invalidation service exists, is connected and is made available -// to the consumer. Verifies that when a second consumer registers, the -// device-global invalidation service is made available to it as well. Further -// verifies that when the first consumer unregisters, the device-global +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A device-global invalidation service exists, is connected and is made +// available to the consumer. Verifies that when a second consumer registers, +// the device-global invalidation service is made available to it as well. +// Further verifies that when the first consumer unregisters, the device-global // invalidation service is not destroyed and remains available to the second // consumer. Further verifies that when the second consumer also unregisters, // the device-global invalidation service is destroyed. -TEST_F(AffiliatedInvalidationServiceProviderTest, MultipleConsumers) { +TEST_F(AffiliatedInvalidationServiceProviderImplTest, MultipleConsumers) { // Register a first consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. provider_->RegisterConsumer(&consumer_); @@ -569,14 +570,15 @@ Mock::VerifyAndClearExpectations(&second_consumer); } -// A consumer is registered with the AffiliatedInvalidationServiceProvider. A -// per-profile invalidation service belonging to a first affiliated user exists, -// is connected and is made available to the consumer. Verifies that when the -// provider is shut down, the consumer is informed that no invalidation service -// is available for use anymore. Also verifies that no device-global -// invalidation service is created and a per-profile invalidation service -// belonging to a second affiliated user that subsequently connects is ignored. -TEST_F(AffiliatedInvalidationServiceProviderTest, NoServiceAfterShutdown) { +// A consumer is registered with the AffiliatedInvalidationServiceProviderImpl. +// A per-profile invalidation service belonging to a first affiliated user +// exists, is connected and is made available to the consumer. Verifies that +// when the provider is shut down, the consumer is informed that no +// invalidation service is available for use anymore. Also verifies that no +// device-global invalidation service is created and a per-profile invalidation +// service belonging to a second affiliated user that subsequently connects is +// ignored. +TEST_F(AffiliatedInvalidationServiceProviderImplTest, NoServiceAfterShutdown) { // Register a consumer. Verify that the consumer is not called back // immediately as no connected invalidation service exists yet. provider_->RegisterConsumer(&consumer_);
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index e1e1c656..07883e40 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -17,10 +17,11 @@ #include "base/sequenced_task_runner.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_worker_pool.h" +#include "chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h" #include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" +#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h" #include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" @@ -49,6 +50,7 @@ #include "content/public/browser/browser_thread.h" #include "google_apis/gaia/gaia_auth_util.h" #include "net/url_request/url_request_context_getter.h" +#include "policy/proto/device_management_backend.pb.h" using content::BrowserThread; @@ -155,7 +157,7 @@ ChromeBrowserPolicyConnector::Init(local_state, request_context); affiliated_invalidation_service_provider_.reset( - new AffiliatedInvalidationServiceProvider); + new AffiliatedInvalidationServiceProviderImpl); const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -185,6 +187,7 @@ chromeos::DBusThreadManager::Get()->GetSessionManagerClient(), chromeos::DeviceSettingsService::Get(), chromeos::CrosSettings::Get(), + affiliated_invalidation_service_provider_.get(), GetBackgroundTaskRunner(), GetBackgroundTaskRunner(), GetBackgroundTaskRunner(), @@ -192,8 +195,12 @@ content::BrowserThread::IO), request_context)); device_local_account_policy_service_->Connect(device_management_service()); - device_cloud_policy_invalidator_.reset(new DeviceCloudPolicyInvalidator( - affiliated_invalidation_service_provider_.get())); + if (device_cloud_policy_manager_) { + device_cloud_policy_invalidator_.reset(new AffiliatedCloudPolicyInvalidator( + enterprise_management::DeviceRegisterRequest::DEVICE, + device_cloud_policy_manager_->core(), + affiliated_invalidation_service_provider_.get())); + } SetTimezoneIfPolicyAvailable();
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h index cb3ec6f..878eda22 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -27,7 +27,7 @@ class AffiliatedInvalidationServiceProvider; class ConsumerManagementService; class DeviceCloudPolicyInitializer; -class DeviceCloudPolicyInvalidator; +class AffiliatedCloudPolicyInvalidator; class DeviceLocalAccountPolicyService; class DeviceManagementService; struct EnrollmentConfig; @@ -160,7 +160,7 @@ scoped_ptr<DeviceCloudPolicyInitializer> device_cloud_policy_initializer_; scoped_ptr<DeviceLocalAccountPolicyService> device_local_account_policy_service_; - scoped_ptr<DeviceCloudPolicyInvalidator> device_cloud_policy_invalidator_; + scoped_ptr<AffiliatedCloudPolicyInvalidator> device_cloud_policy_invalidator_; // This policy provider is used on Chrome OS to feed user policy into the // global PolicyService instance. This works by installing the cloud policy
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc index d076ae9b..29f5ede 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc +++ b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" +#include "chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -140,6 +141,8 @@ chromeos::CrosSettings cros_settings_; scoped_ptr<DeviceLocalAccountPolicyService> device_local_account_policy_service_; + FakeAffiliatedInvalidationServiceProvider + affiliated_invalidation_service_provider_; net::TestURLFetcherFactory url_fetcher_factory_; scoped_ptr<DeviceLocalAccountPolicyProvider> @@ -177,16 +180,20 @@ void CloudExternalDataPolicyObserverTest::SetUp() { chromeos::DeviceSettingsTestBase::SetUp(); + ASSERT_TRUE(profile_manager_.SetUp()); + device_local_account_policy_service_.reset( - new DeviceLocalAccountPolicyService(&device_settings_test_helper_, - &device_settings_service_, - &cros_settings_, - base::MessageLoopProxy::current(), - base::MessageLoopProxy::current(), - base::MessageLoopProxy::current(), - base::MessageLoopProxy::current(), - NULL)); + new DeviceLocalAccountPolicyService( + &device_settings_test_helper_, + &device_settings_service_, + &cros_settings_, + &affiliated_invalidation_service_provider_, + base::MessageLoopProxy::current(), + base::MessageLoopProxy::current(), + base::MessageLoopProxy::current(), + base::MessageLoopProxy::current(), + nullptr)); url_fetcher_factory_.set_remove_fetcher_on_delete(true); EXPECT_CALL(user_policy_provider_, IsInitializationComplete(_))
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc index 5f8b595c..8e56c19 100644 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc +++ b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/consumer_management_service.h" @@ -27,10 +27,10 @@ public: ConsumerEnrollmentHandlerFactoryTest() : fake_service_(new FakeConsumerManagementService()), - fake_user_manager_(new chromeos::FakeUserManager()), + fake_user_manager_(new chromeos::FakeChromeUserManager()), scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_(new TestingProfileManager( - TestingBrowserProcess::GetGlobal())) { + testing_profile_manager_( + new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { // Set up FakeConsumerManagementService. fake_service_->SetStatusAndStage( ConsumerManagementService::STATUS_ENROLLING, @@ -42,7 +42,7 @@ connector->SetConsumerManagementServiceForTesting( make_scoped_ptr(fake_service_)); - // Set up FakeUserManager. + // Set up FakeChromeUserManager. fake_user_manager_->AddUser(kTestOwner); fake_user_manager_->AddUser(kTestUser); fake_user_manager_->set_owner_email(kTestOwner); @@ -53,7 +53,7 @@ } FakeConsumerManagementService* fake_service_; - chromeos::FakeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; scoped_ptr<TestingProfileManager> testing_profile_manager_; };
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc index 4c518c0..15ecd7e3 100644 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc +++ b/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc
@@ -8,7 +8,7 @@ #include "base/run_loop.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/consumer_management_service.h" @@ -40,10 +40,10 @@ ConsumerEnrollmentHandlerTest() : fake_service_(new FakeConsumerManagementService()), fake_initializer_(new FakeDeviceCloudPolicyInitializer()), - fake_user_manager_(new chromeos::FakeUserManager()), + fake_user_manager_(new chromeos::FakeChromeUserManager()), scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_(new TestingProfileManager( - TestingBrowserProcess::GetGlobal())) { + testing_profile_manager_( + new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { // Set up FakeConsumerManagementService. fake_service_->SetStatusAndStage( ConsumerManagementService::STATUS_ENROLLING, @@ -57,7 +57,7 @@ connector->SetDeviceCloudPolicyInitializerForTesting( make_scoped_ptr(fake_initializer_)); - // Set up FakeUserManager. + // Set up FakeChromeUserManager. fake_user_manager_->AddUser(kTestOwner); fake_user_manager_->AddUser(kTestUser); fake_user_manager_->set_owner_email(kTestOwner); @@ -92,7 +92,7 @@ content::TestBrowserThreadBundle thread_bundle; FakeConsumerManagementService* fake_service_; FakeDeviceCloudPolicyInitializer* fake_initializer_; - chromeos::FakeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; scoped_ptr<TestingProfileManager> testing_profile_manager_; Profile* profile_;
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc index d29be20..ca78a43d 100644 --- a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc +++ b/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/consumer_management_service.h" @@ -27,10 +27,10 @@ public: ConsumerManagementNotifierFactoryTest() : fake_service_(new FakeConsumerManagementService()), - fake_user_manager_(new chromeos::FakeUserManager()), + fake_user_manager_(new chromeos::FakeChromeUserManager()), scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_(new TestingProfileManager( - TestingBrowserProcess::GetGlobal())) { + testing_profile_manager_( + new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { // Set up FakeConsumerManagementService. fake_service_->SetStatusAndStage( ConsumerManagementService::STATUS_UNENROLLED, @@ -42,7 +42,7 @@ connector->SetConsumerManagementServiceForTesting( make_scoped_ptr(fake_service_)); - // Set up FakeUserManager. + // Set up FakeChromeUserManager. fake_user_manager_->AddUser(kTestOwner); fake_user_manager_->AddUser(kTestUser); fake_user_manager_->set_owner_email(kTestOwner); @@ -53,7 +53,7 @@ } FakeConsumerManagementService* fake_service_; - chromeos::FakeUserManager* fake_user_manager_; + chromeos::FakeChromeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; scoped_ptr<TestingProfileManager> testing_profile_manager_; };
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.cc b/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.cc deleted file mode 100644 index e41442e0..0000000 --- a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.cc +++ /dev/null
@@ -1,67 +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 "chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h" - -#include "base/logging.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/time/clock.h" -#include "base/time/default_clock.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" -#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" -#include "policy/proto/device_management_backend.pb.h" - -namespace policy { - -DeviceCloudPolicyInvalidator::DeviceCloudPolicyInvalidator( - AffiliatedInvalidationServiceProvider* invalidation_service_provider) - : invalidation_service_provider_(invalidation_service_provider), - highest_handled_invalidation_version_(0) { - invalidation_service_provider_->RegisterConsumer(this); -} - -DeviceCloudPolicyInvalidator::~DeviceCloudPolicyInvalidator() { - DestroyInvalidator(); - invalidation_service_provider_->UnregisterConsumer(this); -} - -void DeviceCloudPolicyInvalidator::OnInvalidationServiceSet( - invalidation::InvalidationService* invalidation_service) { - DestroyInvalidator(); - if (invalidation_service) - CreateInvalidator(invalidation_service); -} - -CloudPolicyInvalidator* -DeviceCloudPolicyInvalidator::GetInvalidatorForTest() const { - return invalidator_.get(); -} - -void DeviceCloudPolicyInvalidator::CreateInvalidator( - invalidation::InvalidationService* invalidation_service) { - DCHECK(!invalidator_); - invalidator_.reset(new CloudPolicyInvalidator( - enterprise_management::DeviceRegisterRequest::DEVICE, - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetDeviceCloudPolicyManager()->core(), - base::MessageLoopProxy::current(), - scoped_ptr<base::Clock>(new base::DefaultClock()), - highest_handled_invalidation_version_)); - invalidator_->Initialize(invalidation_service); -} - -void DeviceCloudPolicyInvalidator::DestroyInvalidator() { - if (!invalidator_) - return; - - highest_handled_invalidation_version_ = - invalidator_->highest_handled_invalidation_version(); - invalidator_->Shutdown(); - invalidator_.reset(); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h b/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h deleted file mode 100644 index e767514..0000000 --- a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h +++ /dev/null
@@ -1,62 +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 CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_CLOUD_POLICY_INVALIDATOR_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_CLOUD_POLICY_INVALIDATOR_H_ - -#include "base/basictypes.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" - -namespace invalidation { -class InvalidationService; -} - -namespace policy { - -class CloudPolicyInvalidator; - -// This class manages the lifetime of a device-global |CloudPolicyInvalidator| -// that handles device policy invalidations. It relies on an -// |AffiliatedInvalidationServiceProvider| to provide it with access to a shared -// |InvalidationService| to back the |CloudPolicyInvalidator|. Whenever the -// shared |InvalidationService| changes, the |CloudPolicyInvalidator| destroyed -// and re-created. -class DeviceCloudPolicyInvalidator - : public AffiliatedInvalidationServiceProvider::Consumer { - public: - explicit DeviceCloudPolicyInvalidator( - AffiliatedInvalidationServiceProvider* invalidation_service_provider); - ~DeviceCloudPolicyInvalidator() override; - - // AffiliatedInvalidationServiceProvider::Consumer: - void OnInvalidationServiceSet( - invalidation::InvalidationService* invalidation_service) override; - - CloudPolicyInvalidator* GetInvalidatorForTest() const; - - private: - // Create a |CloudPolicyInvalidator| backed by the |invalidation_service|. - void CreateInvalidator( - invalidation::InvalidationService* invalidation_service); - - // Destroy the current |CloudPolicyInvalidator|, if any. - void DestroyInvalidator(); - - AffiliatedInvalidationServiceProvider* invalidation_service_provider_; - - // The highest invalidation version that was handled already. - int64 highest_handled_invalidation_version_; - - // The current |CloudPolicyInvalidator|. nullptr if no connected invalidation - // service is available. - scoped_ptr<CloudPolicyInvalidator> invalidator_; - - DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyInvalidator); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_DEVICE_CLOUD_POLICY_INVALIDATOR_H_
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc deleted file mode 100644 index 3c80871..0000000 --- a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc +++ /dev/null
@@ -1,189 +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 "chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h" - -#include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop_proxy.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" -#include "chrome/browser/chromeos/policy/device_policy_builder.h" -#include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" -#include "chrome/browser/chromeos/settings/device_settings_service.h" -#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" -#include "chrome/browser/invalidation/fake_invalidation_service.h" -#include "chrome/browser/policy/cloud/cloud_policy_invalidator.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "chromeos/cryptohome/system_salt_getter.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "components/ownership/mock_owner_key_util.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/policy/core/common/cloud/cloud_policy_core.h" -#include "components/policy/core/common/cloud/cloud_policy_store.h" -#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_test_util.h" -#include "policy/proto/device_management_backend.pb.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace policy { - -class DeviceCloudPolicyInvalidatorTest : public testing::Test { - public: - DeviceCloudPolicyInvalidatorTest(); - ~DeviceCloudPolicyInvalidatorTest() override; - - // testing::Test: - void SetUp() override; - void TearDown() override; - - protected: - DevicePolicyBuilder device_policy_; - - private: - content::TestBrowserThreadBundle thread_bundle_; - scoped_refptr<net::URLRequestContextGetter> system_request_context_; - ScopedStubEnterpriseInstallAttributes install_attributes_; - scoped_ptr<chromeos::ScopedTestDeviceSettingsService> - test_device_settings_service_; - scoped_ptr<chromeos::ScopedTestCrosSettings> test_cros_settings_; - chromeos::DeviceSettingsTestHelper device_settings_test_helper_; - TestingProfileManager profile_manager_; -}; - -DeviceCloudPolicyInvalidatorTest::DeviceCloudPolicyInvalidatorTest() - : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), - system_request_context_(new net::TestURLRequestContextGetter( - base::MessageLoopProxy::current())), - install_attributes_("example.com", - "user@example.com", - "device_id", - DEVICE_MODE_ENTERPRISE), - profile_manager_(TestingBrowserProcess::GetGlobal()) { -} - -DeviceCloudPolicyInvalidatorTest::~DeviceCloudPolicyInvalidatorTest() { -} - -void DeviceCloudPolicyInvalidatorTest::SetUp() { - chromeos::SystemSaltGetter::Initialize(); - chromeos::DBusThreadManager::Initialize(); - TestingBrowserProcess::GetGlobal()->SetSystemRequestContext( - system_request_context_.get()); - ASSERT_TRUE(profile_manager_.SetUp()); - - test_device_settings_service_.reset(new - chromeos::ScopedTestDeviceSettingsService); - test_cros_settings_.reset(new chromeos::ScopedTestCrosSettings); - chromeos::DeviceOAuth2TokenServiceFactory::Initialize(); - - scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util( - new ownership::MockOwnerKeyUtil); - owner_key_util->SetPublicKeyFromPrivateKey( - *device_policy_.GetSigningKey()); - chromeos::DeviceSettingsService::Get()->SetSessionManager( - &device_settings_test_helper_, - owner_key_util); - - device_policy_.policy_data().set_invalidation_source(123); - device_policy_.policy_data().set_invalidation_name("invalidation"); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - device_settings_test_helper_.Flush(); - - scoped_ptr<MockCloudPolicyClient> policy_client(new MockCloudPolicyClient); - EXPECT_CALL(*policy_client, SetupRegistration("token", "device-id")); - CloudPolicyCore* core = TestingBrowserProcess::GetGlobal()->platform_part()-> - browser_policy_connector_chromeos()->GetDeviceCloudPolicyManager()-> - core(); - core->Connect(policy_client.Pass()); - core->StartRefreshScheduler(); -} - -void DeviceCloudPolicyInvalidatorTest::TearDown() { - chromeos::DeviceSettingsService::Get()->UnsetSessionManager(); - TestingBrowserProcess::GetGlobal()->SetBrowserPolicyConnector(nullptr); - chromeos::DeviceOAuth2TokenServiceFactory::Shutdown(); - chromeos::DBusThreadManager::Shutdown(); - chromeos::SystemSaltGetter::Shutdown(); -} - -// Verifies that an invalidator is created/destroyed as an invalidation service -// becomes available/unavailable. Also verifies that the highest handled -// invalidation version is preserved when switching invalidation services. -TEST_F(DeviceCloudPolicyInvalidatorTest, CreateUseDestroy) { - CloudPolicyStore* store = static_cast<CloudPolicyStore*>( - TestingBrowserProcess::GetGlobal()->platform_part()-> - browser_policy_connector_chromeos()->GetDeviceCloudPolicyManager()-> - device_store()); - ASSERT_TRUE(store); - - AffiliatedInvalidationServiceProvider provider; - DeviceCloudPolicyInvalidator device_policy_invalidator(&provider); - - // Verify that no invalidator exists initially. - EXPECT_FALSE(device_policy_invalidator.GetInvalidatorForTest()); - - // Make a first invalidation service available. - invalidation::FakeInvalidationService invalidation_service_1; - device_policy_invalidator.OnInvalidationServiceSet(&invalidation_service_1); - - // Verify that an invalidator backed by the first invalidation service has - // been created and its highest handled invalidation version starts out as 0. - CloudPolicyInvalidator* invalidator = - device_policy_invalidator.GetInvalidatorForTest(); - ASSERT_TRUE(invalidator); - EXPECT_EQ(0, invalidator->highest_handled_invalidation_version()); - EXPECT_EQ(&invalidation_service_1, - invalidator->invalidation_service_for_test()); - - // Handle an invalidation with version 1. Verify that the invalidator's - // highest handled invalidation version is updated accordingly. - store->Store(device_policy_.policy(), 1); - invalidator->OnStoreLoaded(store); - EXPECT_EQ(1, invalidator->highest_handled_invalidation_version()); - - // Make the first invalidation service unavailable. Verify that the - // invalidator is destroyed. - device_policy_invalidator.OnInvalidationServiceSet(nullptr); - EXPECT_FALSE(device_policy_invalidator.GetInvalidatorForTest()); - - // Make a second invalidation service available. - invalidation::FakeInvalidationService invalidation_service_2; - device_policy_invalidator.OnInvalidationServiceSet(&invalidation_service_2); - - // Verify that an invalidator backed by the second invalidation service has - // been created and its highest handled invalidation version starts out as 1. - invalidator = device_policy_invalidator.GetInvalidatorForTest(); - ASSERT_TRUE(invalidator); - EXPECT_EQ(1, invalidator->highest_handled_invalidation_version()); - EXPECT_EQ(&invalidation_service_2, - invalidator->invalidation_service_for_test()); - - // Make the first invalidation service available again. This implies that the - // second invalidation service is no longer available. - device_policy_invalidator.OnInvalidationServiceSet(&invalidation_service_1); - - // Verify that the invalidator backed by the second invalidation service was - // destroyed and an invalidation backed by the first invalidation service has - // been created instead. Also verify that its highest handled invalidation - // version starts out as 1. - invalidator = device_policy_invalidator.GetInvalidatorForTest(); - ASSERT_TRUE(invalidator); - EXPECT_EQ(1, invalidator->highest_handled_invalidation_version()); - EXPECT_EQ(&invalidation_service_1, - invalidator->invalidation_service_for_test()); - - provider.Shutdown(); - device_policy_invalidator.OnInvalidationServiceSet(nullptr); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc index 150095c..f93d637 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
@@ -18,7 +18,9 @@ #include "base/sequenced_task_runner.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" +#include "base/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/policy/affiliated_cloud_policy_invalidator.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/device_local_account_external_data_service.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" @@ -120,8 +122,10 @@ scoped_ptr<DeviceLocalAccountPolicyStore> store, scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager, const base::Closure& policy_update_callback, - const scoped_refptr<base::SequencedTaskRunner>& task_runner) - : account_id_(account.account_id), + const scoped_refptr<base::SequencedTaskRunner>& task_runner, + AffiliatedInvalidationServiceProvider* invalidation_service_provider) + : invalidation_service_provider_(invalidation_service_provider), + account_id_(account.account_id), user_id_(account.user_id), component_policy_cache_path_(component_policy_cache_path), store_(store.Pass()), @@ -160,6 +164,10 @@ store_->Load(); } +bool DeviceLocalAccountPolicyBroker::HasInvalidatorForTest() const { + return invalidator_; +} + void DeviceLocalAccountPolicyBroker::ConnectIfPossible( chromeos::DeviceSettingsService* device_settings_service, DeviceManagementService* device_management_service, @@ -178,6 +186,10 @@ external_data_manager_->Connect(request_context); core_.StartRefreshScheduler(); UpdateRefreshDelay(); + invalidator_.reset(new AffiliatedCloudPolicyInvalidator( + em::DeviceRegisterRequest::DEVICE, + &core_, + invalidation_service_provider_)); } void DeviceLocalAccountPolicyBroker::UpdateRefreshDelay() { @@ -243,6 +255,7 @@ chromeos::SessionManagerClient* session_manager_client, chromeos::DeviceSettingsService* device_settings_service, chromeos::CrosSettings* cros_settings, + AffiliatedInvalidationServiceProvider* invalidation_service_provider, scoped_refptr<base::SequencedTaskRunner> store_background_task_runner, scoped_refptr<base::SequencedTaskRunner> extension_cache_task_runner, scoped_refptr<base::SequencedTaskRunner> @@ -252,6 +265,7 @@ : session_manager_client_(session_manager_client), device_settings_service_(device_settings_service), cros_settings_(cros_settings), + invalidation_service_provider_(invalidation_service_provider), device_management_service_(nullptr), waiting_for_cros_settings_(false), orphan_extension_cache_deletion_state_(NOT_STARTED), @@ -462,7 +476,8 @@ base::Bind(&DeviceLocalAccountPolicyService::NotifyPolicyUpdated, base::Unretained(this), it->user_id), - base::MessageLoopProxy::current())); + base::ThreadTaskRunnerHandle::Get(), + invalidation_service_provider_)); } // Fire up the cloud connection for fetching policy for the account from
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.h b/chrome/browser/chromeos/policy/device_local_account_policy_service.h index 3230a64e..de76639 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service.h +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.h
@@ -41,6 +41,8 @@ namespace policy { +class AffiliatedCloudPolicyInvalidator; +class AffiliatedInvalidationServiceProvider; struct DeviceLocalAccount; class DeviceLocalAccountExternalDataService; class DeviceLocalAccountPolicyStore; @@ -52,6 +54,7 @@ : public CloudPolicyStore::Observer, public ComponentCloudPolicyService::Delegate { public: + // |invalidation_service_provider| must outlive |this|. // |policy_update_callback| will be invoked to notify observers that the // policy for |account| has been updated. // |task_runner| is the runner for policy refresh tasks. @@ -62,7 +65,8 @@ scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager, const base::Closure& policy_updated_callback, - const scoped_refptr<base::SequencedTaskRunner>& task_runner); + const scoped_refptr<base::SequencedTaskRunner>& task_runner, + AffiliatedInvalidationServiceProvider* invalidation_service_provider); ~DeviceLocalAccountPolicyBroker() override; // Initialize the broker, loading its |store_|. @@ -89,6 +93,8 @@ SchemaRegistry* schema_registry() { return &schema_registry_; } + bool HasInvalidatorForTest() const; + // Fire up the cloud connection for fetching policy for the account from the // cloud if this is an enterprise-managed device. void ConnectIfPossible( @@ -115,6 +121,7 @@ const scoped_refptr<net::URLRequestContextGetter>& request_context, CloudPolicyClient* client); + AffiliatedInvalidationServiceProvider* const invalidation_service_provider_; const std::string account_id_; const std::string user_id_; const base::FilePath component_policy_cache_path_; @@ -127,6 +134,7 @@ CloudPolicyCore core_; scoped_ptr<ComponentCloudPolicyService> component_policy_service_; base::Closure policy_update_callback_; + scoped_ptr<AffiliatedCloudPolicyInvalidator> invalidator_; DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountPolicyBroker); }; @@ -153,6 +161,7 @@ chromeos::SessionManagerClient* session_manager_client, chromeos::DeviceSettingsService* device_settings_service, chromeos::CrosSettings* cros_settings, + AffiliatedInvalidationServiceProvider* invalidation_service_provider, scoped_refptr<base::SequencedTaskRunner> store_background_task_runner, scoped_refptr<base::SequencedTaskRunner> extension_cache_task_runner, scoped_refptr<base::SequencedTaskRunner> @@ -227,6 +236,7 @@ chromeos::SessionManagerClient* session_manager_client_; chromeos::DeviceSettingsService* device_settings_service_; chromeos::CrosSettings* cros_settings_; + AffiliatedInvalidationServiceProvider* invalidation_service_provider_; DeviceManagementService* device_management_service_;
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc index 155e2e3..1355846 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
@@ -22,6 +22,7 @@ #include "base/test/test_simple_task_runner.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_provider.h" +#include "chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -98,6 +99,8 @@ chromeos::CrosSettings cros_settings_; scoped_refptr<base::TestSimpleTaskRunner> extension_cache_task_runner_; MockDeviceManagementService mock_device_management_service_; + FakeAffiliatedInvalidationServiceProvider + affiliated_invalidation_service_provider_; scoped_ptr<DeviceLocalAccountPolicyService> service_; private: @@ -162,6 +165,7 @@ &device_settings_test_helper_, &device_settings_service_, &cros_settings_, + &affiliated_invalidation_service_provider_, base::MessageLoopProxy::current(), extension_cache_task_runner_, base::MessageLoopProxy::current(), @@ -231,6 +235,7 @@ EXPECT_EQ(CloudPolicyStore::STATUS_OK, broker->core()->store()->status()); EXPECT_FALSE(broker->core()->client()); EXPECT_FALSE(broker->core()->store()->policy_map().empty()); + EXPECT_FALSE(broker->HasInvalidatorForTest()); } TEST_F(DeviceLocalAccountPolicyServiceTest, LoadNoPolicy) { @@ -246,6 +251,7 @@ EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, broker->core()->store()->status()); EXPECT_TRUE(broker->core()->store()->policy_map().empty()); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_FALSE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -265,6 +271,7 @@ EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, broker->core()->store()->status()); EXPECT_TRUE(broker->core()->store()->policy_map().empty()); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_FALSE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -285,6 +292,7 @@ broker->core()->store()->policy()->SerializeAsString()); EXPECT_TRUE(expected_policy_map_.Equals( broker->core()->store()->policy_map())); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_TRUE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -311,6 +319,7 @@ broker->core()->store()->status()); EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_WRONG_POLICY_TYPE, broker->core()->store()->validation_status()); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_FALSE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -339,6 +348,7 @@ broker->core()->store()->policy()->SerializeAsString()); EXPECT_TRUE(expected_policy_map_.Equals( broker->core()->store()->policy_map())); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_TRUE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -377,6 +387,7 @@ broker->core()->store()->policy()->SerializeAsString()); EXPECT_TRUE(expected_policy_map_.Equals( broker->core()->store()->policy_map())); + EXPECT_FALSE(broker->HasInvalidatorForTest()); EXPECT_TRUE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -411,7 +422,6 @@ // This will be called twice, because the ComponentCloudPolicyService will // also become ready after flushing all the pending tasks. EXPECT_CALL(service_observer_, OnPolicyUpdated(account_1_user_id_)).Times(2); - broker->core()->client()->FetchPolicy(); FlushDeviceSettings(); Mock::VerifyAndClearExpectations(&service_observer_); Mock::VerifyAndClearExpectations(&mock_device_management_service_); @@ -446,6 +456,7 @@ broker->core()->store()->policy()->SerializeAsString()); EXPECT_TRUE(expected_policy_map_.Equals( broker->core()->store()->policy_map())); + EXPECT_TRUE(broker->HasInvalidatorForTest()); EXPECT_TRUE(service_->IsPolicyAvailableForUser(account_1_user_id_)); } @@ -485,6 +496,7 @@ broker->core()->store()->status()); EXPECT_TRUE(expected_policy_map_.Equals( broker->core()->store()->policy_map())); + EXPECT_TRUE(broker->HasInvalidatorForTest()); EXPECT_TRUE(service_->IsPolicyAvailableForUser(account_1_user_id_)); }
diff --git a/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.cc b/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.cc new file mode 100644 index 0000000..0fe5740 --- /dev/null +++ b/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.cc
@@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h" + +namespace policy { + +FakeAffiliatedInvalidationServiceProvider:: +FakeAffiliatedInvalidationServiceProvider() { +} + +void FakeAffiliatedInvalidationServiceProvider::RegisterConsumer( + Consumer* consumer) { +} + +void FakeAffiliatedInvalidationServiceProvider::UnregisterConsumer( + Consumer* consumer) { +} + +void FakeAffiliatedInvalidationServiceProvider::Shutdown() { +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h b/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h new file mode 100644 index 0000000..e184c3f --- /dev/null +++ b/chrome/browser/chromeos/policy/fake_affiliated_invalidation_service_provider.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 CHROME_BROWSER_CHROMEOS_POLICY_FAKE_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_FAKE_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_H_ + +#include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" +#include "base/macros.h" + +namespace policy { + +class FakeAffiliatedInvalidationServiceProvider + : public AffiliatedInvalidationServiceProvider { + public: + FakeAffiliatedInvalidationServiceProvider(); + + // AffiliatedInvalidationServiceProvider: + void RegisterConsumer(Consumer* consumer) override; + void UnregisterConsumer(Consumer* consumer) override; + void Shutdown() override; + + private: + DISALLOW_COPY_AND_ASSIGN(FakeAffiliatedInvalidationServiceProvider); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_FAKE_AFFILIATED_INVALIDATION_SERVICE_PROVIDER_H_
diff --git a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto index 5d75fb87..0b496e7 100644 --- a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto +++ b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
@@ -98,6 +98,10 @@ optional bool report_network_interfaces = 5; optional bool report_users = 6; optional bool report_hardware_status = 7; + optional bool report_session_status = 8 [default = true]; + + // Frequency to report device status, default to 3 hours. + optional int64 device_status_frequency = 9 [default = 10800000]; } message EphemeralUsersEnabledProto { @@ -594,6 +598,17 @@ optional bool reboot_on_shutdown = 1 [default = false]; } +// Settings that control whether a device would send heartbeat messages to GCM, +// and how frequently to send these. +message DeviceHeartbeatSettingsProto { + // Whether the device should send heartbeat messages. The default is false. + optional bool heartbeat_enabled = 1 [default = false]; + + // How frequently devices send heartbeats back to server. The unit is in + // milliseconds. The default is 2 minutes. + optional int64 heartbeat_frequency = 2 [default = 120000]; +} + message ChromeDeviceSettingsProto { optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1; optional UserWhitelistProto user_whitelist = 2; @@ -631,4 +646,5 @@ optional SystemSettingsProto system_settings = 32; optional SAMLSettingsProto saml_settings = 33; optional RebootOnShutdownProto reboot_on_shutdown = 34; + optional DeviceHeartbeatSettingsProto device_heartbeat_settings = 35; }
diff --git a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc index acc30b7..d35a7401 100644 --- a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc +++ b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
@@ -10,7 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -36,7 +36,7 @@ public: ExtensionEventObserverTest() : power_manager_client_(new FakePowerManagerClient()), - fake_user_manager_(new FakeUserManager()), + fake_user_manager_(new FakeChromeUserManager()), scoped_user_manager_enabler_(fake_user_manager_) { DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient( make_scoped_ptr(power_manager_client_)); @@ -132,7 +132,7 @@ ScopedTestCrosSettings test_cros_settings_; // Owned by |scoped_user_manager_enabler_|. - FakeUserManager* fake_user_manager_; + FakeChromeUserManager* fake_user_manager_; ScopedUserManagerEnabler scoped_user_manager_enabler_; std::vector<scoped_refptr<extensions::Extension>> created_apps_;
diff --git a/chrome/browser/chromeos/power/power_prefs_unittest.cc b/chrome/browser/chromeos/power/power_prefs_unittest.cc index cd881fa..9bf1e9c57 100644 --- a/chrome/browser/chromeos/power/power_prefs_unittest.cc +++ b/chrome/browser/chromeos/power/power_prefs_unittest.cc
@@ -11,7 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/prefs/pref_service.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/extension_special_storage_policy.h" @@ -234,7 +234,7 @@ } TEST_F(PowerPrefsTest, UserSession) { - FakeUserManager* user_manager = new FakeUserManager(); + FakeChromeUserManager* user_manager = new FakeChromeUserManager(); ScopedUserManagerEnabler user_manager_enabler(user_manager); // Set up user profile.
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc index b4f6c95..b58fb5d2 100644 --- a/chrome/browser/chromeos/preferences_unittest.cc +++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/chromeos/input_method/input_method_configuration.h" #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/system/fake_input_device_settings.h" #include "chrome/common/chrome_constants.h" @@ -149,7 +149,8 @@ new TestingProfileManager(TestingBrowserProcess::GetGlobal())); ASSERT_TRUE(profile_manager_->SetUp()); - chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); + chromeos::FakeChromeUserManager* user_manager = + new chromeos::FakeChromeUserManager(); user_manager_enabler_.reset( new chromeos::ScopedUserManagerEnabler(user_manager));
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h index 654a98b3..cac7855 100644 --- a/chrome/browser/chromeos/profiles/profile_helper.h +++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -126,7 +126,7 @@ friend class CryptohomeAuthenticatorTest; friend class DeviceSettingsTestBase; friend class extensions::ExtensionGarbageCollectorChromeOSUnitTest; - friend class FakeUserManager; + friend class FakeChromeUserManager; friend class KioskTest; friend class MockUserManager; friend class MultiProfileUserControllerTest;
diff --git a/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc b/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc index c5fefff..09f7c18 100644 --- a/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc +++ b/chrome/browser/chromeos/profiles/profile_list_chromeos_unittest.cc
@@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/prefs/pref_service_syncable.h" @@ -58,22 +58,24 @@ // AvatarMenu and multiple profiles works after user logged in. manager_.SetLoggedIn(true); - // Initialize the UserManager singleton to a fresh FakeUserManager instance. + // Initialize the UserManager singleton to a fresh FakeChromeUserManager + // instance. user_manager_enabler_.reset( - new ScopedUserManagerEnabler(new FakeUserManager)); + new ScopedUserManagerEnabler(new FakeChromeUserManager)); } - FakeUserManager* GetFakeUserManager() { - return static_cast<FakeUserManager*>(user_manager::UserManager::Get()); + FakeChromeUserManager* GetFakeChromeUserManager() { + return static_cast<FakeChromeUserManager*>( + user_manager::UserManager::Get()); } void AddProfile(base::string16 name, bool log_in) { std::string email_string = base::UTF16ToASCII(name) + "@example.com"; // Add a user to the fake user manager. - GetFakeUserManager()->AddUser(email_string); + GetFakeChromeUserManager()->AddUser(email_string); if (log_in) - GetFakeUserManager()->LoginUser(email_string); + GetFakeChromeUserManager()->LoginUser(email_string); // Create a profile for the user. manager()->CreateTestingProfile(email_string); @@ -96,7 +98,7 @@ void ActiveUserChanged(const base::string16& name) { std::string email_string = base::UTF16ToASCII(name) + "@example.com"; - GetFakeUserManager()->SwitchActiveUser(email_string); + GetFakeChromeUserManager()->SwitchActiveUser(email_string); } TestingProfileManager* manager() { return &manager_; } @@ -163,7 +165,7 @@ cache->GetUserDataDir().AppendASCII("p2"), supervised_name, base::string16(), 0, "TEST_ID"); - GetFakeUserManager()->AddUser(base::UTF16ToASCII(supervised_name)); + GetFakeChromeUserManager()->AddUser(base::UTF16ToASCII(supervised_name)); AvatarMenu* menu = GetAvatarMenu(); ASSERT_EQ(1U, menu->GetNumberOfItems()); @@ -238,7 +240,7 @@ // Change name of the first profile, to trigger resorting of the profiles: // now the first menu item should be named "beta", and the second be "gamma". - GetFakeUserManager()->SaveUserDisplayName( + GetFakeChromeUserManager()->SaveUserDisplayName( base::UTF16ToASCII(name1) + "@example.com", newname1); manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc index 56366f8..d6e9b6c 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -12,7 +12,6 @@ #include "base/path_service.h" #include "base/test/scoped_path_override.h" #include "base/values.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" @@ -21,6 +20,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/settings/cros_settings_names.h" +#include "components/user_manager/fake_user_manager.h" #include "components/user_manager/user.h" #include "policy/proto/device_management_backend.pb.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc index 712b356..abc8caf 100644 --- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc +++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -200,7 +200,8 @@ } DeviceSettingsTestBase::DeviceSettingsTestBase() - : user_manager_(new FakeUserManager()), + : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), + user_manager_(new FakeChromeUserManager()), user_manager_enabler_(user_manager_), owner_key_util_(new ownership::MockOwnerKeyUtil()) { OwnerSettingsServiceChromeOSFactory::SetDeviceSettingsServiceForTesting(
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h index 05c6be2..0e5742e 100644 --- a/chrome/browser/chromeos/settings/device_settings_test_helper.h +++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -15,7 +15,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/strings/string_util.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" @@ -180,7 +180,7 @@ DeviceSettingsTestHelper device_settings_test_helper_; // Note that FakeUserManager is used by ProfileHelper, which some of the // tested classes depend on implicitly. - FakeUserManager* user_manager_; + FakeChromeUserManager* user_manager_; ScopedUserManagerEnabler user_manager_enabler_; scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_; // Local DeviceSettingsService instance for tests. Avoid using in combination
diff --git a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc index e3186fb..9eda36b 100644 --- a/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc +++ b/chrome/browser/chromeos/settings/session_manager_operation_unittest.cc
@@ -14,7 +14,6 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" @@ -25,6 +24,7 @@ #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/cloud_policy_validator.h" #include "components/policy/core/common/cloud/policy_builder.h" +#include "components/user_manager/fake_user_manager.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_utils.h" #include "crypto/rsa_private_key.h" @@ -45,7 +45,7 @@ : ui_thread_(content::BrowserThread::UI, &message_loop_), file_thread_(content::BrowserThread::FILE, &message_loop_), owner_key_util_(new ownership::MockOwnerKeyUtil()), - user_manager_(new FakeUserManager()), + user_manager_(new user_manager::FakeUserManager()), user_manager_enabler_(user_manager_), validated_(false) { OwnerSettingsServiceChromeOSFactory::GetInstance() @@ -91,7 +91,7 @@ DeviceSettingsTestHelper device_settings_test_helper_; scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_; - FakeUserManager* user_manager_; + user_manager::FakeUserManager* user_manager_; ScopedUserManagerEnabler user_manager_enabler_; scoped_ptr<TestingProfile> profile_;
diff --git a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc index 5453267..771b719 100644 --- a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc +++ b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc
@@ -12,7 +12,6 @@ #include "base/prefs/testing_pref_service.h" #include "base/run_loop.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" @@ -25,6 +24,7 @@ #include "chromeos/chromeos_switches.h" #include "components/ownership/mock_owner_key_util.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/user_manager/fake_user_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "policy/proto/device_management_backend.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -73,7 +73,7 @@ policy::ScopedStubEnterpriseInstallAttributes install_attributes_; chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; chromeos::ScopedTestCrosSettings test_cros_settings_; - FakeUserManager fake_user_manager_; + user_manager::FakeUserManager fake_user_manager_; scoped_ptr<DeviceDisablingManager> device_disabling_manager_; DISALLOW_COPY_AND_ASSIGN(DeviceDisablingManagerTestBase);
diff --git a/chrome/browser/chromeos/system/pointer_device_observer.cc b/chrome/browser/chromeos/system/pointer_device_observer.cc index 29bbd67..2de1305 100644 --- a/chrome/browser/chromeos/system/pointer_device_observer.cc +++ b/chrome/browser/chromeos/system/pointer_device_observer.cc
@@ -9,6 +9,7 @@ #include "base/bind_helpers.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "content/public/browser/browser_thread.h" +#include "ui/events/devices/device_data_manager.h" #if defined(USE_X11) #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h" @@ -27,6 +28,8 @@ #if defined(USE_X11) XInputHierarchyChangedEventListener::GetInstance() ->RemoveObserver(this); +#elif defined(USE_OZONE) + ui::DeviceDataManager::GetInstance()->RemoveObserver(this); #endif } @@ -34,6 +37,8 @@ #if defined(USE_X11) XInputHierarchyChangedEventListener::GetInstance() ->AddObserver(this); +#elif defined(USE_OZONE) + ui::DeviceDataManager::GetInstance()->AddObserver(this); #endif } @@ -54,6 +59,14 @@ CheckDevices(); } +void PointerDeviceObserver::OnMouseDeviceConfigurationChanged() { + CheckDevices(); +} + +void PointerDeviceObserver::OnTouchpadDeviceConfigurationChanged() { + CheckDevices(); +} + void PointerDeviceObserver::CheckTouchpadExists() { InputDeviceSettings::Get()->TouchpadExists( base::Bind(&PointerDeviceObserver::OnTouchpadExists,
diff --git a/chrome/browser/chromeos/system/pointer_device_observer.h b/chrome/browser/chromeos/system/pointer_device_observer.h index 51ce2a8..b5911cb 100644 --- a/chrome/browser/chromeos/system/pointer_device_observer.h +++ b/chrome/browser/chromeos/system/pointer_device_observer.h
@@ -8,11 +8,13 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "chrome/browser/chromeos/device_hierarchy_observer.h" +#include "ui/events/devices/input_device_event_observer.h" namespace chromeos { namespace system { -class PointerDeviceObserver : public DeviceHierarchyObserver { +class PointerDeviceObserver : public DeviceHierarchyObserver, + public ui::InputDeviceEventObserver { public: PointerDeviceObserver(); ~PointerDeviceObserver() override; @@ -36,11 +38,17 @@ void RemoveObserver(Observer* observer); private: - // DeviceHierarchyObserver implementation. + // DeviceHierarchyObserver: void DeviceHierarchyChanged() override; void DeviceAdded(int device_id) override {} void DeviceRemoved(int device_id) override {} + // InputDeviceEventObserver: + void OnTouchscreenDeviceConfigurationChanged() override {} + void OnKeyboardDeviceConfigurationChanged() override {} + void OnMouseDeviceConfigurationChanged() override; + void OnTouchpadDeviceConfigurationChanged() override; + // Check for pointer devices. void CheckTouchpadExists(); void CheckMouseExists();
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 3a8eafe..cf0f241 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -958,6 +958,18 @@ extension, http_host, CONTENT_SETTINGS_TYPE_COOKIES)); } +TEST_F(HostContentSettingsMapTest, IsSettingAllowedForType) { + TestingProfile profile; + PrefService* prefs = profile.GetPrefs(); + + EXPECT_TRUE(HostContentSettingsMap::IsSettingAllowedForType( + prefs, CONTENT_SETTING_ASK, + CONTENT_SETTINGS_TYPE_FULLSCREEN)); + + // TODO(msramek): Add more checks for setting type - setting pairs where + // it is not obvious whether or not they are allowed. +} + TEST_F(HostContentSettingsMapTest, AddContentSettingsObserver) { TestingProfile profile; HostContentSettingsMap* host_content_settings_map =
diff --git a/chrome/browser/content_settings/permission_context_base.cc b/chrome/browser/content_settings/permission_context_base.cc index c188377..045ac48 100644 --- a/chrome/browser/content_settings/permission_context_base.cc +++ b/chrome/browser/content_settings/permission_context_base.cc
@@ -18,6 +18,12 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/attestation/platform_verification_dialog.h" +using chromeos::attestation::PlatformVerificationDialog; +using chromeos::attestation::PlatformVerificationFlow; +#endif + PermissionContextBase::PermissionContextBase( Profile* profile, const ContentSettingsType permission_type) @@ -126,6 +132,19 @@ PermissionContextUmaUtil::PermissionRequested( permission_type_, requesting_origin); +#if defined(OS_CHROMEOS) + // TODO(xhwang): This is to use the existing platform verification UI. Remove + // it when the infobar/bubble UI can satisfy our requirements. + if (permission_type_ == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { + PlatformVerificationDialog::ShowDialog( + web_contents, + base::Bind(&PermissionContextBase::OnPlatformVerificationResult, + weak_factory_.GetWeakPtr(), id, requesting_origin, + embedding_origin, callback)); + return; + } +#endif + if (PermissionBubbleManager::Enabled()) { if (pending_bubbles_.get(id.ToString()) != NULL) return; @@ -229,3 +248,25 @@ ContentSettingsPattern::FromURLNoWildcard(embedding_origin), permission_type_, std::string(), content_setting); } + +#if defined(OS_CHROMEOS) +void PermissionContextBase::OnPlatformVerificationResult( + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + const BrowserPermissionCallback& callback, + chromeos::attestation::PlatformVerificationFlow::ConsentResponse response) { + if (response == PlatformVerificationFlow::CONSENT_RESPONSE_NONE) { + // Deny request and do not save to content settings. + PermissionDecided(id, requesting_origin, embedding_origin, callback, + false, // Do not save to content settings. + false); // Do not allow the permission. + return; + } + + PermissionDecided( + id, requesting_origin, embedding_origin, callback, + true, // Save to content settings. + response == PlatformVerificationFlow::CONSENT_RESPONSE_ALLOW); +} +#endif
diff --git a/chrome/browser/content_settings/permission_context_base.h b/chrome/browser/content_settings/permission_context_base.h index 740aa8f..fe711ecc 100644 --- a/chrome/browser/content_settings/permission_context_base.h +++ b/chrome/browser/content_settings/permission_context_base.h
@@ -15,6 +15,10 @@ #include "components/keyed_service/core/keyed_service.h" #include "url/gurl.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/attestation/platform_verification_flow.h" +#endif + class PermissionQueueController; class PermissionRequestID; class Profile; @@ -127,6 +131,16 @@ // Called when a bubble is no longer used so it can be cleaned up. void CleanUpBubble(const PermissionRequestID& id); +#if defined(OS_CHROMEOS) + void OnPlatformVerificationResult( + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + const BrowserPermissionCallback& callback, + chromeos::attestation::PlatformVerificationFlow::ConsentResponse + response); +#endif + Profile* profile_; const ContentSettingsType permission_type_; scoped_ptr<PermissionQueueController> permission_queue_controller_;
diff --git a/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc b/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc index 635fcedb..4a34f9a 100644 --- a/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc +++ b/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc
@@ -176,35 +176,52 @@ DISALLOW_COPY_AND_ASSIGN(ChromeWhispernetClientTest); }; -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Initialize) { +// These tests are irrelevant if NACL is disabled. See crbug.com/449198 +#if defined(DISABLE_NACL) +#define MAYBE_Initialize DISABLED_Initialize +#define MAYBE_EncodeToken DISABLED_EncodeToken +#define MAYBE_DecodeSamples DISABLED_DecodeSamples +#define MAYBE_DetectBroadcast DISABLED_DetectBroadcast +#define MAYBE_Audible DISABLED_Audible +#define MAYBE_TokenLengths DISABLED_TokenLengths +#else +#define MAYBE_Initialize Initialize +#define MAYBE_EncodeToken EncodeToken +#define MAYBE_DecodeSamples DecodeSamples +#define MAYBE_DetectBroadcast DetectBroadcast +#define MAYBE_Audible Audible +#define MAYBE_TokenLengths TokenLengths +#endif + +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_Initialize) { InitializeWhispernet(); } -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, EncodeToken) { +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_EncodeToken) { InitializeWhispernet(); EncodeTokenAndSaveSamples(false, kSixZeros); } -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DecodeSamples) { +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_DecodeSamples) { InitializeWhispernet(); EncodeTokenAndSaveSamples(false, kSixZeros); DecodeSamplesAndVerifyToken(false, kSixZeros, kTokenLengths); } -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, DetectBroadcast) { +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_DetectBroadcast) { InitializeWhispernet(); EncodeTokenAndSaveSamples(false, kSixZeros); DecodeSamplesAndVerifyToken(false, kSixZeros, kTokenLengths); DetectBroadcast(); } -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, Audible) { +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_Audible) { InitializeWhispernet(); EncodeTokenAndSaveSamples(true, kSixZeros); DecodeSamplesAndVerifyToken(true, kSixZeros, kTokenLengths); } -IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, TokenLengths) { +IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest, MAYBE_TokenLengths) { InitializeWhispernet(); size_t kLongTokenLengths[2] = {8, 9};
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 75f824a..da7853c0 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -828,7 +828,7 @@ void DevToolsWindow::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { if (new_contents == toolbox_web_contents_) { @@ -848,7 +848,7 @@ WebContents* inspected_web_contents = GetInspectedWebContents(); if (inspected_web_contents) { inspected_web_contents->GetDelegate()->AddNewContents( - source, new_contents, disposition, initial_pos, user_gesture, + source, new_contents, disposition, initial_rect, user_gesture, was_blocked); } }
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h index dd605b4..f1471e1 100644 --- a/chrome/browser/devtools/devtools_window.h +++ b/chrome/browser/devtools/devtools_window.h
@@ -233,7 +233,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void WebContentsCreated(content::WebContents* source_contents,
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc index 6f8b219..5c249cd 100644 --- a/chrome/browser/download/download_ui_controller.cc +++ b/chrome/browser/download/download_ui_controller.cc
@@ -29,11 +29,11 @@ : public DownloadUIController::Delegate { public: DefaultUIControllerDelegateAndroid() {} - virtual ~DefaultUIControllerDelegateAndroid() {} + ~DefaultUIControllerDelegateAndroid() override {} private: // DownloadUIController::Delegate - virtual void OnNewDownloadReady(content::DownloadItem* item) override; + void OnNewDownloadReady(content::DownloadItem* item) override; }; void DefaultUIControllerDelegateAndroid::OnNewDownloadReady(
diff --git a/chrome/browser/drive/drive_api_util.cc b/chrome/browser/drive/drive_api_util.cc index 064f4a2..d23a782 100644 --- a/chrome/browser/drive/drive_api_util.cc +++ b/chrome/browser/drive/drive_api_util.cc
@@ -16,6 +16,9 @@ #include "base/values.h" #include "google_apis/drive/drive_api_parser.h" #include "net/base/escape.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "storage/browser/blob/file_stream_reader.h" #include "third_party/re2/re2/re2.h" #include "url/gurl.h" @@ -40,6 +43,8 @@ const char kUnknownHostedDocumentExtension[] = ".glink"; +const int kMd5DigestBufferSize = 512 * 1024; // 512 kB. + } // namespace std::string EscapeQueryStringValue(const std::string& str) { @@ -131,8 +136,6 @@ } std::string GetMd5Digest(const base::FilePath& file_path) { - const int kBufferSize = 512 * 1024; // 512kB. - base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); if (!file.IsValid()) return std::string(); @@ -141,9 +144,9 @@ base::MD5Init(&context); int64 offset = 0; - scoped_ptr<char[]> buffer(new char[kBufferSize]); + scoped_ptr<char[]> buffer(new char[kMd5DigestBufferSize]); while (true) { - int result = file.Read(offset, buffer.get(), kBufferSize); + int result = file.Read(offset, buffer.get(), kMd5DigestBufferSize); if (result < 0) { // Found an error. return std::string(); @@ -163,6 +166,53 @@ return MD5DigestToBase16(digest); } +FileStreamMd5Digester::FileStreamMd5Digester() + : buffer_(new net::IOBuffer(kMd5DigestBufferSize)) { +} + +FileStreamMd5Digester::~FileStreamMd5Digester() { +} + +void FileStreamMd5Digester::GetMd5Digest( + scoped_ptr<storage::FileStreamReader> stream_reader, + const ResultCallback& callback) { + reader_ = stream_reader.Pass(); + callback_ = callback; + base::MD5Init(&md5_context_); + + // Start the read/hash. + ReadNextChunk(); +} + +void FileStreamMd5Digester::ReadNextChunk() { + const int result = reader_->Read( + buffer_.get(), kMd5DigestBufferSize, + base::Bind(&FileStreamMd5Digester::OnChunkRead, base::Unretained(this))); + if (result != net::ERR_IO_PENDING) + OnChunkRead(result); +} + +void FileStreamMd5Digester::OnChunkRead(int result) { + if (result < 0) { + // Error - just return empty string. + callback_.Run(""); + return; + } else if (result == 0) { + // EOF. + base::MD5Digest digest; + base::MD5Final(&digest, &md5_context_); + std::string result = MD5DigestToBase16(digest); + callback_.Run(result); + return; + } + + // Read data and digest it. + base::MD5Update(&md5_context_, base::StringPiece(buffer_->data(), result)); + + // Kick off the next read. + ReadNextChunk(); +} + std::string GetHostedDocumentExtension(const std::string& mime_type) { for (size_t i = 0; i < arraysize(kHostedDocumentKinds); ++i) { if (mime_type == kHostedDocumentKinds[i].mime_type)
diff --git a/chrome/browser/drive/drive_api_util.h b/chrome/browser/drive/drive_api_util.h index 95771ca2..def1199 100644 --- a/chrome/browser/drive/drive_api_util.h +++ b/chrome/browser/drive/drive_api_util.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/md5.h" #include "base/memory/scoped_ptr.h" #include "google_apis/drive/drive_api_error_codes.h" #include "google_apis/drive/drive_common_callbacks.h" @@ -26,6 +27,14 @@ class ResourceEntry; } // namespace google_apis +namespace net { +class IOBuffer; +} // namespace net + +namespace storage { +class FileStreamReader; +} // namespace storage + namespace drive { namespace util { @@ -64,6 +73,38 @@ // or an empty string if an error is found. std::string GetMd5Digest(const base::FilePath& file_path); +// Computes the (base-16 encoded) MD5 digest of data extracted from a file +// stream. +class FileStreamMd5Digester { + public: + typedef base::Callback<void(const std::string&)> ResultCallback; + + FileStreamMd5Digester(); + ~FileStreamMd5Digester(); + + // Computes an MD5 digest of data read from the given |streamReader|. The + // work occurs asynchronously, and the resulting hash is returned via the + // |callback|. If an error occurs, |callback| is called with an empty string. + // Only one stream can be processed at a time by each digester. Do not call + // GetMd5Digest before the results of a previous call have been returned. + void GetMd5Digest(scoped_ptr<storage::FileStreamReader> stream_reader, + const ResultCallback& callback); + + private: + // Kicks off a read of the next chunk from the stream. + void ReadNextChunk(); + // Handles the incoming chunk of data from a stream read. + void OnChunkRead(int result); + + // Maximum chunk size for read operations. + scoped_ptr<storage::FileStreamReader> reader_; + ResultCallback callback_; + scoped_refptr<net::IOBuffer> buffer_; + base::MD5Context md5_context_; + + DISALLOW_COPY_AND_ASSIGN(FileStreamMd5Digester); +}; + // Returns preferred file extension for hosted documents which have given mime // type. std::string GetHostedDocumentExtension(const std::string& mime_type);
diff --git a/chrome/browser/errorpage_browsertest.cc b/chrome/browser/errorpage_browsertest.cc index 289898ba..6c4708a 100644 --- a/chrome/browser/errorpage_browsertest.cc +++ b/chrome/browser/errorpage_browsertest.cc
@@ -15,9 +15,9 @@ #include "base/synchronization/lock.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" #include "chrome/browser/browsing_data/browsing_data_remover.h" -#include "chrome/browser/google/google_profile_helper.h" #include "chrome/browser/net/url_request_mock_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -279,10 +279,11 @@ // Add a mock for the search engine the error page will use. base::FilePath root_http; PathService::Get(chrome::DIR_TEST_DATA, &root_http); - net::URLRequestMockHTTPJob::AddHostnameToFileHandler( - search_url.host(), - root_http.AppendASCII("title3.html"), - BrowserThread::GetBlockingPool()); + net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( + search_url.scheme(), search_url.host(), + net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile( + root_http.AppendASCII("title3.html"), + BrowserThread::GetBlockingPool())); } class ErrorPageTest : public InProcessBrowserTest { @@ -412,12 +413,11 @@ // Ownership of the |interceptor_| is passed to an object the IO thread, but // a pointer is kept in the test fixture. As soon as anything calls // URLRequestFilter::ClearHandlers(), |interceptor_| can become invalid. + UIThreadSearchTermsData search_terms_data(browser()->profile()); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&InstallMockInterceptors, - google_util::GetGoogleSearchURL( - google_profile_helper::GetGoogleHomePageURL( - browser()->profile())), + GURL(search_terms_data.GoogleBaseURLValue()), base::Passed(&owned_interceptor))); }
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc index 747b84a..2643257 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
@@ -109,6 +109,11 @@ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(example_url, example_url, + CONTENT_SETTINGS_TYPE_FULLSCREEN, + std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting(example_url, + example_url, CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string())); EXPECT_EQ(CONTENT_SETTING_ASK, @@ -121,6 +126,16 @@ example_url, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting(example_url, + example_url, + CONTENT_SETTINGS_TYPE_PPAPI_BROKER, + std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting(example_url, + example_url, + CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, + std::string())); // Check content settings for www.google.com GURL url("http://www.google.com"); @@ -144,6 +159,9 @@ CONTENT_SETTING_BLOCK, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string())); EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string())); @@ -153,6 +171,13 @@ EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string())); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_PPAPI_BROKER, std::string())); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, + std::string())); } void CheckContentSettingsDefault() { @@ -187,6 +212,9 @@ url, url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string())); EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_FULLSCREEN, std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_MOUSELOCK, std::string())); EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting( @@ -194,6 +222,13 @@ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_PPAPI_BROKER, std::string())); + EXPECT_EQ(CONTENT_SETTING_ASK, + map->GetContentSetting( + url, url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, + std::string())); } private:
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc b/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc index 8ae4730..a262d23 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc
@@ -31,7 +31,10 @@ "mixed-script", "media-stream", "media-stream-mic", - "media-stream-camera" + "media-stream-camera", + "register-protocol-handler", + "ppapi-broker", + "multiple-automatic-downloads" }; // TODO(msramek): Assert that |kContentSettingsTypeNames| is synced with
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc index 92a387f..d2aa388f 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -306,20 +306,6 @@ strings->SetString( "setupErrorFindingPhone", l10n_util::GetStringUTF16(IDS_EASY_UNLOCK_SETUP_ERROR_FINDING_PHONE)); - // TODO(isherman): Remove the setupErrorBluetoothConnectionFailed string; it - // is unused. - strings->SetString( - "setupErrorBluetoothConnectionFailed", - l10n_util::GetStringFUTF16( - IDS_EASY_UNLOCK_SETUP_ERROR_BLUETOOTH_CONNECTION_FAILED, - device_type)); - // TODO(isherman): Remove the setupErrorConnectionToPhoneTimeout string; it is - // identical to the setupErrorConnectingToPhone string, and hence obsolete. - strings->SetString( - "setupErrorConnectionToPhoneTimeout", - l10n_util::GetStringFUTF16( - IDS_EASY_UNLOCK_SETUP_ERROR_CONNECT_TO_PHONE_TIMEOUT, - device_type)); strings->SetString( "setupErrorSyncPhoneState", l10n_util::GetStringUTF16( @@ -329,9 +315,6 @@ l10n_util::GetStringFUTF16( IDS_EASY_UNLOCK_SETUP_ERROR_CONNECTING_TO_PHONE, device_type)); - // TODO(isherman): Remove this string once the app has been updated. - strings->SetString("setupIntroHeaderFootnote", base::string16()); - SetResult(strings.release()); return true; }
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc index 6afb8850..05d5c8a 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -476,9 +476,9 @@ const std::string extension_id(extension_->id()); std::string notification_id; - if (!params_->notification_id.empty()) { + if (params_->notification_id.get() && !params_->notification_id->empty()) { // If the caller provided a notificationId, use that. - notification_id = params_->notification_id; + notification_id = *params_->notification_id; } else { // Otherwise, use a randomly created GUID. In case that GenerateGUID returns // the empty string, simply generate a random string.
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc index b9a2e1e..bafa06b 100644 --- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc +++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc
@@ -101,6 +101,7 @@ base::ThreadTaskRunnerHandle::Get(), // ui_task_runner MakeSequencedTaskRunner(), MakeSequencedTaskRunner(), + content::BrowserThread::GetBlockingPool(), base_dir_.path(), NULL, // task_logger NULL, // notification_manager
diff --git a/chrome/browser/extensions/chrome_extension_host_delegate.cc b/chrome/browser/extensions/chrome_extension_host_delegate.cc index c8d2b58..8cb4ec6 100644 --- a/chrome/browser/extensions/chrome_extension_host_delegate.cc +++ b/chrome/browser/extensions/chrome_extension_host_delegate.cc
@@ -41,10 +41,10 @@ void ChromeExtensionHostDelegate::CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { ExtensionTabUtil::CreateTab( - web_contents, extension_id, disposition, initial_pos, user_gesture); + web_contents, extension_id, disposition, initial_rect, user_gesture); } void ChromeExtensionHostDelegate::ProcessMediaAccessRequest(
diff --git a/chrome/browser/extensions/chrome_extension_host_delegate.h b/chrome/browser/extensions/chrome_extension_host_delegate.h index c4a481a..0ba69555 100644 --- a/chrome/browser/extensions/chrome_extension_host_delegate.h +++ b/chrome/browser/extensions/chrome_extension_host_delegate.h
@@ -22,7 +22,7 @@ void CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; void ProcessMediaAccessRequest(content::WebContents* web_contents, const content::MediaStreamRequest& request,
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc index 3841dba..2ee48167 100644 --- a/chrome/browser/extensions/component_loader.cc +++ b/chrome/browser/extensions/component_loader.cc
@@ -626,12 +626,7 @@ #endif // defined(GOOGLE_CHROME_BUILD) #if defined(ENABLE_PLUGINS) - base::FilePath pdf_path; - content::PluginService* plugin_service = - content::PluginService::GetInstance(); - if (switches::OutOfProcessPdfEnabled() && - PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path) && - plugin_service->GetRegisteredPpapiPluginInfo(pdf_path)) { + if (switches::OutOfProcessPdfEnabled()) { if (switches::PdfMaterialUIEnabled()) Add(IDR_PDF_MANIFEST_MATERIAL, base::FilePath(FILE_PATH_LITERAL("pdf"))); else
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index a4207e7..17cc1a95 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -170,13 +170,17 @@ } void CrxInstaller::InstallCrx(const base::FilePath& source_file) { + InstallCrxFile(CRXFileInfo(source_file)); +} + +void CrxInstaller::InstallCrxFile(const CRXFileInfo& source_file) { ExtensionService* service = service_weak_.get(); if (!service || service->browser_terminating()) return; NotifyCrxInstallBegin(); - source_file_ = source_file; + source_file_ = source_file.path; scoped_refptr<SandboxedUnpacker> unpacker( new SandboxedUnpacker(source_file,
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 769ca30..9d014bf 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -98,6 +98,7 @@ // Install the crx in |source_file|. void InstallCrx(const base::FilePath& source_file); + void InstallCrxFile(const CRXFileInfo& source_file); // Convert the specified user script into an extension and install it. void InstallUserScript(const base::FilePath& source_file,
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index ffbf01e..13d8da7 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -46,7 +46,7 @@ #include "ui/base/l10n/l10n_util.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/extensions/extension_assets_manager_chromeos.h" #include "chromeos/chromeos_switches.h" @@ -533,8 +533,8 @@ #if defined(OS_CHROMEOS) // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over // lifetime of |user_manager|. - chromeos::FakeUserManager* fake_user_manager = - new chromeos::FakeUserManager(); + chromeos::FakeChromeUserManager* fake_user_manager = + new chromeos::FakeChromeUserManager(); fake_user_manager->AddKioskAppUser("example@example.com"); fake_user_manager->LoginUser("example@example.com"); chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
diff --git a/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc b/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc index 61724981..622f324a 100644 --- a/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc +++ b/chrome/browser/extensions/extension_garbage_collector_chromeos_unittest.cc
@@ -13,7 +13,7 @@ #include "base/strings/string_util.h" #include "base/threading/sequenced_worker_pool.h" #include "base/values.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/extension_assets_manager_chromeos.h" @@ -66,9 +66,10 @@ ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(cache_dir()); ExtensionGarbageCollectorChromeOS::ClearGarbageCollectedForTesting(); - // Initialize the UserManager singleton to a fresh FakeUserManager instance. - user_manager_enabler_.reset( - new chromeos::ScopedUserManagerEnabler(new chromeos::FakeUserManager)); + // Initialize the UserManager singleton to a fresh FakeChromeUserManager + // instance. + user_manager_enabler_.reset(new chromeos::ScopedUserManagerEnabler( + new chromeos::FakeChromeUserManager)); GetFakeUserManager()->AddUser(chromeos::login::kStubUser); GetFakeUserManager()->LoginUser(chromeos::login::kStubUser); @@ -144,8 +145,8 @@ return ExtensionPrefs::Get(profile_.get()); } - chromeos::FakeUserManager* GetFakeUserManager() { - return static_cast<chromeos::FakeUserManager*>( + chromeos::FakeChromeUserManager* GetFakeUserManager() { + return static_cast<chromeos::FakeChromeUserManager*>( user_manager::UserManager::Get()); }
diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc index ecf8310..4cf7f77 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc +++ b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
@@ -306,7 +306,7 @@ extensions::NOTIFICATION_CRX_INSTALLER_DONE, base::Bind(&IsCrxInstallerDone, &installer)); extension_service_->UpdateExtension( - extension->id(), path, true, &installer); + extensions::CRXFileInfo(extension->id(), path), true, &installer); if (installer) observer.Wait();
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 53d907bd..94e4b52 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -474,8 +474,7 @@ } } -bool ExtensionService::UpdateExtension(const std::string& id, - const base::FilePath& extension_path, +bool ExtensionService::UpdateExtension(const extensions::CRXFileInfo& file, bool file_ownership_passed, CrxInstaller** out_crx_installer) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -487,6 +486,8 @@ return false; } + const std::string& id = file.extension_id; + const extensions::PendingExtensionInfo* pending_extension_info = pending_extension_manager()->GetById(id); @@ -498,8 +499,7 @@ // that would do it for us. if (!GetFileTaskRunner()->PostTask( FROM_HERE, - base::Bind( - &extensions::file_util::DeleteFile, extension_path, false))) + base::Bind(&extensions::file_util::DeleteFile, file.path, false))) NOTREACHED(); return false; @@ -557,7 +557,7 @@ installer->set_delete_source(file_ownership_passed); installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE); - installer->InstallCrx(extension_path); + installer->InstallCrxFile(file); if (out_crx_installer) *out_crx_installer = installer.get();
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index b65a45f..4b6005d 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h
@@ -21,6 +21,7 @@ #include "chrome/browser/extensions/pending_extension_manager.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "extensions/browser/crx_file_info.h" #include "extensions/browser/external_provider_interface.h" #include "extensions/browser/install_flag.h" #include "extensions/browser/management_policy.h" @@ -83,8 +84,7 @@ // TODO(aa): This method can be removed. ExtensionUpdater could use // CrxInstaller directly instead. virtual bool UpdateExtension( - const std::string& id, - const base::FilePath& path, + const extensions::CRXFileInfo& file, bool file_ownership_passed, extensions::CrxInstaller** out_crx_installer) = 0; @@ -207,8 +207,7 @@ bool include_disabled) const override; const extensions::Extension* GetInstalledExtension( const std::string& id) const override; - bool UpdateExtension(const std::string& id, - const base::FilePath& extension_path, + bool UpdateExtension(const extensions::CRXFileInfo& file, bool file_ownership_passed, extensions::CrxInstaller** out_crx_installer) override; bool IsExtensionEnabled(const std::string& extension_id) const override;
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 947c600..679c7eb 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -826,7 +826,8 @@ content::WindowedNotificationObserver observer( extensions::NOTIFICATION_CRX_INSTALLER_DONE, base::Bind(&IsCrxInstallerDone, &installer)); - service()->UpdateExtension(id, path, true, &installer); + service()->UpdateExtension(extensions::CRXFileInfo(id, path), true, + &installer); if (installer) observer.Wait(); @@ -2717,7 +2718,8 @@ // Update should fail and extension should not be updated. path = data_dir().AppendASCII("good2.crx"); - bool updated = service()->UpdateExtension(good_crx, path, true, NULL); + bool updated = service()->UpdateExtension( + extensions::CRXFileInfo(good_crx, path), true, NULL); ASSERT_FALSE(updated); ASSERT_EQ( "1.0.0.0", @@ -6763,7 +6765,7 @@ // We don't want the extension to be installed. A path that doesn't // point to a valid CRX ensures this. - const base::FilePath kInvalidPathToCrx = base::FilePath(); + const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path")); const int kCreationFlags = 0; const bool kDontMarkAcknowledged = false; @@ -6967,7 +6969,7 @@ Version kVersion123("1.2.3"); Version kVersion124("1.2.4"); Version kVersion125("1.2.5"); - const base::FilePath kInvalidPathToCrx = base::FilePath(); + const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path")); const int kCreationFlags = 0; const bool kDontMarkAcknowledged = false;
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 9551132..4009221 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -171,7 +171,7 @@ GURL url; if (params.url.get()) { - std::string url_string= *params.url; + std::string url_string = *params.url; url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, function->extension()); if (!url.is_valid()) { @@ -528,7 +528,7 @@ void ExtensionTabUtil::CreateTab(WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); @@ -548,7 +548,7 @@ params.extension_app_id = extension_id; params.disposition = disposition; - params.window_bounds = initial_pos; + params.window_bounds = initial_rect; params.window_action = chrome::NavigateParams::SHOW_WINDOW; params.user_gesture = user_gesture; chrome::Navigate(¶ms);
diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h index 0f185d2..5a45abf 100644 --- a/chrome/browser/extensions/extension_tab_util.h +++ b/chrome/browser/extensions/extension_tab_util.h
@@ -161,7 +161,7 @@ static void CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture); // Executes the specified callback for all tabs in all browser windows.
diff --git a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc index 5793068d..edf428d2 100644 --- a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc +++ b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/customization/customization_document.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" @@ -21,6 +20,7 @@ #include "chrome/test/base/testing_profile.h" #include "chromeos/system/fake_statistics_provider.h" #include "chromeos/system/statistics_provider.h" +#include "components/user_manager/fake_user_manager.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" @@ -33,9 +33,8 @@ class ExternalProviderImplChromeOSTest : public ExtensionServiceTestBase { public: ExternalProviderImplChromeOSTest() - : fake_user_manager_(new chromeos::FakeUserManager()), - scoped_user_manager_(fake_user_manager_) { - } + : fake_user_manager_(new user_manager::FakeUserManager()), + scoped_user_manager_(fake_user_manager_) {} ~ExternalProviderImplChromeOSTest() override {} @@ -75,7 +74,7 @@ TestingPrefServiceSimple local_state_; scoped_ptr<base::ScopedPathOverride> external_externsions_overrides_; chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_; - chromeos::FakeUserManager* fake_user_manager_; + user_manager::FakeUserManager* fake_user_manager_; chromeos::ScopedUserManagerEnabler scoped_user_manager_; DISALLOW_COPY_AND_ASSIGN(ExternalProviderImplChromeOSTest);
diff --git a/chrome/browser/extensions/external_provider_impl_unittest.cc b/chrome/browser/extensions/external_provider_impl_unittest.cc index 011d032b..486eac6 100644 --- a/chrome/browser/extensions/external_provider_impl_unittest.cc +++ b/chrome/browser/extensions/external_provider_impl_unittest.cc
@@ -33,10 +33,10 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/customization/customization_document.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chromeos/system/fake_statistics_provider.h" #include "chromeos/system/statistics_provider.h" +#include "components/user_manager/fake_user_manager.h" #endif using ::testing::NotNull; @@ -60,7 +60,7 @@ void InitServiceWithExternalProviders() { #if defined(OS_CHROMEOS) chromeos::ScopedUserManagerEnabler scoped_user_manager( - new chromeos::FakeUserManager); + new user_manager::FakeUserManager); #endif InitializeExtensionServiceWithUpdaterAndPrefs();
diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc index a69f73d..b00df110 100644 --- a/chrome/browser/extensions/startup_helper.cc +++ b/chrome/browser/extensions/startup_helper.cc
@@ -120,11 +120,14 @@ class ValidateCrxHelper : public SandboxedUnpackerClient { public: - ValidateCrxHelper(const base::FilePath& crx_file, + ValidateCrxHelper(const CRXFileInfo& file, const base::FilePath& temp_dir, base::RunLoop* run_loop) - : crx_file_(crx_file), temp_dir_(temp_dir), run_loop_(run_loop), - finished_(false), success_(false) {} + : crx_file_(file), + temp_dir_(temp_dir), + run_loop_(run_loop), + finished_(false), + success_(false) {} bool finished() { return finished_; } bool success() { return success_; } @@ -185,7 +188,7 @@ } // The file being validated. - const base::FilePath& crx_file_; + const CRXFileInfo& crx_file_; // The temporary directory where the sandboxed unpacker will do work. const base::FilePath& temp_dir_; @@ -222,8 +225,9 @@ } base::RunLoop run_loop; + CRXFileInfo file(path); scoped_refptr<ValidateCrxHelper> helper( - new ValidateCrxHelper(path, temp_dir.path(), &run_loop)); + new ValidateCrxHelper(file, temp_dir.path(), &run_loop)); helper->Start(); if (!helper->finished()) run_loop.Run();
diff --git a/chrome/browser/extensions/test_extension_service.cc b/chrome/browser/extensions/test_extension_service.cc index c5ae36a..ae2c2b8 100644 --- a/chrome/browser/extensions/test_extension_service.cc +++ b/chrome/browser/extensions/test_extension_service.cc
@@ -17,8 +17,7 @@ } bool TestExtensionService::UpdateExtension( - const std::string& id, - const base::FilePath& path, + const extensions::CRXFileInfo& file, bool file_ownership_passed, extensions::CrxInstaller** out_crx_installer) { ADD_FAILURE();
diff --git a/chrome/browser/extensions/test_extension_service.h b/chrome/browser/extensions/test_extension_service.h index e4409e35..64d0ab38 100644 --- a/chrome/browser/extensions/test_extension_service.h +++ b/chrome/browser/extensions/test_extension_service.h
@@ -25,8 +25,7 @@ // ExtensionServiceInterface implementation. extensions::PendingExtensionManager* pending_extension_manager() override; - bool UpdateExtension(const std::string& id, - const base::FilePath& path, + bool UpdateExtension(const extensions::CRXFileInfo& file, bool file_ownership_passed, extensions::CrxInstaller** out_crx_installer) override; const extensions::Extension* GetExtensionById(
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index 0a373a9..ee47c897 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -189,17 +189,17 @@ ExtensionUpdater::CheckParams::~CheckParams() {} ExtensionUpdater::FetchedCRXFile::FetchedCRXFile( - const std::string& i, - const base::FilePath& p, + const CRXFileInfo& file, bool file_ownership_passed, const std::set<int>& request_ids) - : extension_id(i), - path(p), + : info(file), file_ownership_passed(file_ownership_passed), - request_ids(request_ids) {} + request_ids(request_ids) { +} ExtensionUpdater::FetchedCRXFile::FetchedCRXFile() - : path(), file_ownership_passed(true) {} + : file_ownership_passed(true) { +} ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() {} @@ -591,19 +591,18 @@ } void ExtensionUpdater::OnExtensionDownloadFinished( - const std::string& id, - const base::FilePath& path, + const CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version, const PingResult& ping, const std::set<int>& request_ids) { DCHECK(alive_); - UpdatePingData(id, ping); + UpdatePingData(file.extension_id, ping); - VLOG(2) << download_url << " written to " << path.value(); + VLOG(2) << download_url << " written to " << file.path.value(); - FetchedCRXFile fetched(id, path, file_ownership_passed, request_ids); + FetchedCRXFile fetched(file, file_ownership_passed, request_ids); fetched_crx_files_.push(fetched); // MaybeInstallCRXFile() removes extensions from |in_progress_ids_| after @@ -682,14 +681,13 @@ while (!fetched_crx_files_.empty() && !crx_install_is_running_) { const FetchedCRXFile& crx_file = fetched_crx_files_.top(); - VLOG(2) << "updating " << crx_file.extension_id - << " with " << crx_file.path.value(); + VLOG(2) << "updating " << crx_file.info.extension_id + << " with " << crx_file.info.path.value(); // The ExtensionService is now responsible for cleaning up the temp file - // at |crx_file.path|. + // at |crx_file.info.path|. CrxInstaller* installer = NULL; - if (service_->UpdateExtension(crx_file.extension_id, - crx_file.path, + if (service_->UpdateExtension(crx_file.info, crx_file.file_ownership_passed, &installer)) { crx_install_is_running_ = true; @@ -713,7 +711,7 @@ for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); it != crx_file.request_ids.end(); ++it) { InProgressCheck& request = requests_in_progress_[*it]; - request.in_progress_ids_.remove(crx_file.extension_id); + request.in_progress_ids_.remove(crx_file.info.extension_id); } request_ids.insert(crx_file.request_ids.begin(), crx_file.request_ids.end()); @@ -739,7 +737,7 @@ for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); it != crx_file.request_ids.end(); ++it) { InProgressCheck& request = requests_in_progress_[*it]; - request.in_progress_ids_.remove(crx_file.extension_id); + request.in_progress_ids_.remove(crx_file.info.extension_id); NotifyIfFinished(*it); }
diff --git a/chrome/browser/extensions/updater/extension_updater.h b/chrome/browser/extensions/updater/extension_updater.h index 7e09908cf..169534fc 100644 --- a/chrome/browser/extensions/updater/extension_updater.h +++ b/chrome/browser/extensions/updater/extension_updater.h
@@ -139,14 +139,12 @@ // but have not yet installed. struct FetchedCRXFile { FetchedCRXFile(); - FetchedCRXFile(const std::string& id, - const base::FilePath& path, + FetchedCRXFile(const CRXFileInfo& file, bool file_ownership_passed, const std::set<int>& request_ids); ~FetchedCRXFile(); - std::string extension_id; - base::FilePath path; + CRXFileInfo info; bool file_ownership_passed; std::set<int> request_ids; }; @@ -198,8 +196,7 @@ Error error, const PingResult& ping, const std::set<int>& request_ids) override; - void OnExtensionDownloadFinished(const std::string& id, - const base::FilePath& path, + void OnExtensionDownloadFinished(const CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version,
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index b1e2f51..6afb075 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -145,13 +145,13 @@ Error, const PingResult&, const std::set<int>&)); - MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&, - const base::FilePath&, - bool, - const GURL&, - const std::string&, - const PingResult&, - const std::set<int>&)); + MOCK_METHOD6(OnExtensionDownloadFinished, + void(const extensions::CRXFileInfo&, + bool, + const GURL&, + const std::string&, + const PingResult&, + const std::set<int>&)); MOCK_METHOD2(GetPingDataForExtension, bool(const std::string&, ManifestFetchData::PingData*)); MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&)); @@ -175,9 +175,10 @@ ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _)) .WillByDefault(Invoke(delegate, &ExtensionDownloaderDelegate::OnExtensionDownloadFailed)); - ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _)) - .WillByDefault(Invoke(delegate, - &ExtensionDownloaderDelegate::OnExtensionDownloadFinished)); + ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _)) + .WillByDefault( + Invoke(delegate, + &ExtensionDownloaderDelegate::OnExtensionDownloadFinished)); ON_CALL(*this, GetPingDataForExtension(_, _)) .WillByDefault(Invoke(delegate, &ExtensionDownloaderDelegate::GetPingDataForExtension)); @@ -499,15 +500,14 @@ fake_crx_installers_[id] = crx_installer; } - bool UpdateExtension(const std::string& id, - const base::FilePath& extension_path, + bool UpdateExtension(const CRXFileInfo& file, bool file_ownership_passed, CrxInstaller** out_crx_installer) override { - extension_id_ = id; - install_path_ = extension_path; + extension_id_ = file.extension_id; + install_path_ = file.path; - if (ContainsKey(fake_crx_installers_, id)) { - *out_crx_installer = fake_crx_installers_[id]; + if (ContainsKey(fake_crx_installers_, extension_id_)) { + *out_crx_installer = fake_crx_installers_[extension_id_]; return true; } @@ -1221,7 +1221,8 @@ fetcher->set_response_code(200); fetcher->SetResponseFilePath(extension_file_path); EXPECT_CALL(delegate, OnExtensionDownloadFinished( - id, _, _, _, version.GetString(), _, requests)); + CRXFileInfo(id, extension_file_path, hash), _, + _, version.GetString(), _, requests)); } fetcher->delegate()->OnURLFetchComplete(fetcher);
diff --git a/chrome/browser/google/google_profile_helper.cc b/chrome/browser/google/google_profile_helper.cc deleted file mode 100644 index d216622..0000000 --- a/chrome/browser/google/google_profile_helper.cc +++ /dev/null
@@ -1,21 +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 "chrome/browser/google/google_profile_helper.h" - -#include "chrome/browser/google/google_url_tracker_factory.h" -#include "components/google/core/browser/google_url_tracker.h" -#include "components/google/core/browser/google_util.h" -#include "url/gurl.h" - -namespace google_profile_helper { - -GURL GetGoogleHomePageURL(Profile* profile) { - const GoogleURLTracker* tracker = - GoogleURLTrackerFactory::GetForProfile(profile); - return tracker ? - tracker->google_url() : GURL(GoogleURLTracker::kDefaultGoogleHomepage); -} - -} // namespace google_profile_helper
diff --git a/chrome/browser/google/google_profile_helper.h b/chrome/browser/google/google_profile_helper.h deleted file mode 100644 index ea58960..0000000 --- a/chrome/browser/google/google_profile_helper.h +++ /dev/null
@@ -1,26 +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. -// -// Provides Google-related information for a given Profile. - -#ifndef CHROME_BROWSER_GOOGLE_GOOGLE_PROFILE_HELPER_H__ -#define CHROME_BROWSER_GOOGLE_GOOGLE_PROFILE_HELPER_H__ - -#include <string> - -#include "base/basictypes.h" - -class GURL; -class Profile; - -namespace google_profile_helper { - -// Returns the current Google homepage URL. Guaranteed to synchronously return -// a value at all times (even during startup, in unittest mode or if |profile| -// is NULL). -GURL GetGoogleHomePageURL(Profile* profile); - -} // namespace google_profile_helper - -#endif // CHROME_BROWSER_GOOGLE_GOOGLE_PROFILE_HELPER_H__
diff --git a/chrome/browser/google/google_search_counter_android.h b/chrome/browser/google/google_search_counter_android.h index b13013f4..89830c3 100644 --- a/chrome/browser/google/google_search_counter_android.h +++ b/chrome/browser/google/google_search_counter_android.h
@@ -17,7 +17,7 @@ class GoogleSearchCounterAndroid : content::NotificationObserver { public: explicit GoogleSearchCounterAndroid(Profile* profile); - virtual ~GoogleSearchCounterAndroid(); + ~GoogleSearchCounterAndroid() override; private: friend class GoogleSearchCounterAndroidTest; @@ -26,9 +26,9 @@ const content::NotificationDetails& details); // content::NotificationObserver: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; Profile* profile_; content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/google/google_search_counter_android_unittest.cc b/chrome/browser/google/google_search_counter_android_unittest.cc index 3b8bf6e..0bd7d12 100644 --- a/chrome/browser/google/google_search_counter_android_unittest.cc +++ b/chrome/browser/google/google_search_counter_android_unittest.cc
@@ -31,11 +31,11 @@ class GoogleSearchCounterAndroidTest : public testing::Test { protected: GoogleSearchCounterAndroidTest(); - virtual ~GoogleSearchCounterAndroidTest(); + ~GoogleSearchCounterAndroidTest() override; // testing::Test - virtual void SetUp(); - virtual void TearDown(); + void SetUp() override; + void TearDown() override; // Test if |url| is a Google search for specific types. When |is_omnibox| is // true, this method will append Omnibox identifiers to the simulated URL
diff --git a/chrome/browser/history/android/android_cache_database_unittest.cc b/chrome/browser/history/android/android_cache_database_unittest.cc index d67c997..8d51ffa 100644 --- a/chrome/browser/history/android/android_cache_database_unittest.cc +++ b/chrome/browser/history/android/android_cache_database_unittest.cc
@@ -21,10 +21,10 @@ class AndroidCacheDatabaseTest : public testing::Test { public: AndroidCacheDatabaseTest() {} - virtual ~AndroidCacheDatabaseTest() {} + ~AndroidCacheDatabaseTest() override {} protected: - virtual void SetUp() { + void SetUp() override { // Get a temporary directory for the test DB files. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); base::FilePath history_db_name_ =
diff --git a/chrome/browser/history/android/android_history_provider_service_unittest.cc b/chrome/browser/history/android/android_history_provider_service_unittest.cc index ca59252..2fadfdc 100644 --- a/chrome/browser/history/android/android_history_provider_service_unittest.cc +++ b/chrome/browser/history/android/android_history_provider_service_unittest.cc
@@ -40,11 +40,10 @@ ui_thread_(BrowserThread::UI, &message_loop_), file_thread_(BrowserThread::FILE, &message_loop_) { } - virtual ~AndroidHistoryProviderServiceTest() { - } + ~AndroidHistoryProviderServiceTest() override {} protected: - virtual void SetUp() override { + void SetUp() override { // Setup the testing profile, so the bookmark_model_sql_handler could // get the bookmark model from it. ASSERT_TRUE(profile_manager_.SetUp()); @@ -60,7 +59,7 @@ service_.reset(new AndroidHistoryProviderService(testing_profile_)); } - virtual void TearDown() override { + void TearDown() override { testing_profile_->DestroyHistoryService(); profile_manager_.DeleteTestingProfile(chrome::kInitialProfile); testing_profile_=NULL;
diff --git a/chrome/browser/history/android/android_provider_backend.cc b/chrome/browser/history/android/android_provider_backend.cc index beecfe39..bf8d5b2 100644 --- a/chrome/browser/history/android/android_provider_backend.cc +++ b/chrome/browser/history/android/android_provider_backend.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/history/android/android_provider_backend.h" #include "base/i18n/case_conversion.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/history/android/bookmark_model_sql_handler.h" #include "chrome/browser/history/history_backend.h" #include "components/history/core/browser/android/android_time.h"
diff --git a/chrome/browser/history/android/android_urls_database_unittest.cc b/chrome/browser/history/android/android_urls_database_unittest.cc index cbc2755..dc1b65a 100644 --- a/chrome/browser/history/android/android_urls_database_unittest.cc +++ b/chrome/browser/history/android/android_urls_database_unittest.cc
@@ -20,10 +20,10 @@ class AndroidURLsMigrationTest : public HistoryUnitTestBase { public: AndroidURLsMigrationTest() {} - virtual ~AndroidURLsMigrationTest() {} + ~AndroidURLsMigrationTest() override {} protected: - virtual void SetUp() { + void SetUp() override { profile_.reset(new TestingProfile); base::FilePath data_path;
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler.cc b/chrome/browser/history/android/bookmark_model_sql_handler.cc index 4625f37..cd57bcba 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler.cc +++ b/chrome/browser/history/android/bookmark_model_sql_handler.cc
@@ -6,7 +6,6 @@ #include "base/logging.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h"
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler.h b/chrome/browser/history/android/bookmark_model_sql_handler.h index 58b14dc4..7f15600b 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler.h +++ b/chrome/browser/history/android/bookmark_model_sql_handler.h
@@ -22,13 +22,13 @@ public: explicit BookmarkModelSQLHandler(URLDatabase* url_database); - virtual ~BookmarkModelSQLHandler(); + ~BookmarkModelSQLHandler() override; // SQLHandler overrides: - virtual bool Update(const HistoryAndBookmarkRow& row, - const TableIDRows& ids_set) override; - virtual bool Delete(const TableIDRows& ids_set) override; - virtual bool Insert(HistoryAndBookmarkRow* row) override; + bool Update(const HistoryAndBookmarkRow& row, + const TableIDRows& ids_set) override; + bool Delete(const TableIDRows& ids_set) override; + bool Insert(HistoryAndBookmarkRow* row) override; private: // This class helps to modify the bookmark model in UI thread.
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc index 5f7f1be33..508c7e2 100644 --- a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc +++ b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
@@ -34,10 +34,10 @@ bookmark_model_(NULL), ui_thread_(BrowserThread::UI, &message_loop_), file_thread_(BrowserThread::FILE, &message_loop_) {} - virtual ~BookmarkModelSQLHandlerTest() {} + ~BookmarkModelSQLHandlerTest() override {} protected: - virtual void SetUp() override { + void SetUp() override { // Setup the testing profile, so the bookmark_model_sql_handler could // get the bookmark model from it. ASSERT_TRUE(profile_manager_.SetUp());
diff --git a/chrome/browser/history/android/sqlite_cursor_unittest.cc b/chrome/browser/history/android/sqlite_cursor_unittest.cc index 076eb449..c7aa0c2 100644 --- a/chrome/browser/history/android/sqlite_cursor_unittest.cc +++ b/chrome/browser/history/android/sqlite_cursor_unittest.cc
@@ -48,11 +48,10 @@ ui_thread_(BrowserThread::UI, &message_loop_), file_thread_(BrowserThread::FILE, &message_loop_) { } - virtual ~SQLiteCursorTest() { - } + ~SQLiteCursorTest() override {} protected: - virtual void SetUp() override { + void SetUp() override { // Setup the testing profile, so the bookmark_model_sql_handler could // get the bookmark model from it. ASSERT_TRUE(profile_manager_.SetUp()); @@ -72,28 +71,20 @@ testing_profile_, ServiceAccessType::EXPLICIT_ACCESS); } - virtual void TearDown() override { + void TearDown() override { testing_profile_->DestroyHistoryService(); profile_manager_.DeleteTestingProfile(chrome::kInitialProfile); testing_profile_ = NULL; } // Override SQLiteCursor::TestObserver. - virtual void OnPostMoveToTask() override { - base::MessageLoop::current()->Run(); - } + void OnPostMoveToTask() override { base::MessageLoop::current()->Run(); } - virtual void OnGetMoveToResult() override { - base::MessageLoop::current()->Quit(); - } + void OnGetMoveToResult() override { base::MessageLoop::current()->Quit(); } - virtual void OnPostGetFaviconTask() override { - base::MessageLoop::current()->Run(); - } + void OnPostGetFaviconTask() override { base::MessageLoop::current()->Run(); } - virtual void OnGetFaviconResult() override { - base::MessageLoop::current()->Quit(); - } + void OnGetFaviconResult() override { base::MessageLoop::current()->Quit(); } protected: TestingProfileManager profile_manager_;
diff --git a/chrome/browser/history/android/urls_sql_handler_unittest.cc b/chrome/browser/history/android/urls_sql_handler_unittest.cc index 2c92eca3..623110b5 100644 --- a/chrome/browser/history/android/urls_sql_handler_unittest.cc +++ b/chrome/browser/history/android/urls_sql_handler_unittest.cc
@@ -26,10 +26,10 @@ UrlsSQLHandlerTest() : urls_sql_handler_(&history_db_), visit_sql_handler_(&history_db_, &history_db_) {} - virtual ~UrlsSQLHandlerTest() {} + ~UrlsSQLHandlerTest() override {} protected: - virtual void SetUp() { + void SetUp() override { // Get a temporary directory for the test DB files. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); base::FilePath history_db_name = @@ -37,8 +37,7 @@ ASSERT_EQ(sql::INIT_OK, history_db_.Init(history_db_name)); } - virtual void TearDown() { - } + void TearDown() override {} TestHistoryDatabase history_db_; base::ScopedTempDir temp_dir_;
diff --git a/chrome/browser/history/android/visit_sql_handler_unittest.cc b/chrome/browser/history/android/visit_sql_handler_unittest.cc index 3229d7ae..723b0fe 100644 --- a/chrome/browser/history/android/visit_sql_handler_unittest.cc +++ b/chrome/browser/history/android/visit_sql_handler_unittest.cc
@@ -26,10 +26,10 @@ VisitSQLHandlerTest() : urls_sql_handler_(&history_db_), visit_sql_handler_(&history_db_, &history_db_) {} - virtual ~VisitSQLHandlerTest() {} + ~VisitSQLHandlerTest() override {} protected: - virtual void SetUp() { + void SetUp() override { // Get a temporary directory for the test DB files. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); base::FilePath history_db_name = @@ -37,8 +37,7 @@ ASSERT_EQ(sql::INIT_OK, history_db_.Init(history_db_name)); } - virtual void TearDown() { - } + void TearDown() override {} TestHistoryDatabase history_db_; base::ScopedTempDir temp_dir_;
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc index e46633d..6adc6755b 100644 --- a/chrome/browser/history/history_service.cc +++ b/chrome/browser/history/history_service.cc
@@ -741,8 +741,7 @@ callback); } -void HistoryService::GetNextDownloadId( - const content::DownloadIdCallback& callback) { +void HistoryService::GetNextDownloadId(const DownloadIdCallback& callback) { DCHECK(thread_) << "History service being called after cleanup"; DCHECK(thread_checker_.CalledOnValidThread()); PostTaskAndReplyWithResult(
diff --git a/chrome/browser/history/history_service.h b/chrome/browser/history/history_service.h index c14dafc4..b167f43 100644 --- a/chrome/browser/history/history_service.h +++ b/chrome/browser/history/history_service.h
@@ -24,13 +24,11 @@ #include "base/time/time.h" #include "chrome/browser/history/delete_directive_handler.h" #include "chrome/browser/history/typed_url_syncable_service.h" -#include "chrome/common/ref_counted_util.h" #include "components/favicon_base/favicon_callback.h" #include "components/history/core/browser/history_client.h" #include "components/history/core/browser/keyword_id.h" #include "components/keyed_service/core/keyed_service.h" #include "components/visitedlink/browser/visitedlink_delegate.h" -#include "content/public/browser/download_manager_delegate.h" #include "sql/init_status.h" #include "sync/api/syncable_service.h" #include "ui/base/page_transition_types.h" @@ -379,9 +377,13 @@ const history::DownloadRow& info, const DownloadCreateCallback& callback); + // Implemented by the caller of 'GetNextDownloadId' below, and is called with + // the maximum id of all downloads records in the database plus 1. + typedef base::Callback<void(uint32)> DownloadIdCallback; + // Responds on the calling thread with the maximum id of all downloads records // in the database plus 1. - void GetNextDownloadId(const content::DownloadIdCallback& callback); + void GetNextDownloadId(const DownloadIdCallback& callback); // Implemented by the caller of 'QueryDownloads' below, and is called when the // history service has retrieved a list of all download state. The call
diff --git a/chrome/browser/interstitials/security_interstitial_uma_helper.cc b/chrome/browser/interstitials/security_interstitial_metrics_helper.cc similarity index 64% rename from chrome/browser/interstitials/security_interstitial_uma_helper.cc rename to chrome/browser/interstitials/security_interstitial_metrics_helper.cc index aade7ff..322220e 100644 --- a/chrome/browser/interstitials/security_interstitial_uma_helper.cc +++ b/chrome/browser/interstitials/security_interstitial_metrics_helper.cc
@@ -2,56 +2,88 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/interstitials/security_interstitial_uma_helper.h" +#include "chrome/browser/interstitials/security_interstitial_metrics_helper.h" + +#include <string> #include "base/metrics/histogram.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_service.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/webdata/web_data_service_factory.h" +#include "components/rappor/rappor_service.h" #include "content/public/browser/web_contents.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #if defined(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h" #endif -SecurityInterstitialUmaHelper::SecurityInterstitialUmaHelper( +SecurityInterstitialMetricsHelper::SecurityInterstitialMetricsHelper( content::WebContents* web_contents, const GURL& request_url, - const std::string& histogram_prefix, + const std::string& uma_prefix, + const std::string& rappor_prefix, + RapporReporting rappor_reporting, const std::string& sampling_event_name) : web_contents_(web_contents), request_url_(request_url), - histogram_prefix_(histogram_prefix), + uma_prefix_(uma_prefix), + rappor_prefix_(rappor_prefix), + rappor_reporting_(rappor_reporting), sampling_event_name_(sampling_event_name), num_visits_(-1) { + DCHECK(!uma_prefix_.empty()); + DCHECK(!rappor_prefix_.empty()); + DCHECK(!sampling_event_name_.empty()); HistoryService* history_service = HistoryServiceFactory::GetForProfile( Profile::FromBrowserContext(web_contents->GetBrowserContext()), ServiceAccessType::EXPLICIT_ACCESS); if (history_service) { history_service->GetVisibleVisitCountToHost( request_url_, - base::Bind(&SecurityInterstitialUmaHelper::OnGotHistoryCount, + base::Bind(&SecurityInterstitialMetricsHelper::OnGotHistoryCount, base::Unretained(this)), &request_tracker_); } } -SecurityInterstitialUmaHelper::~SecurityInterstitialUmaHelper() { +SecurityInterstitialMetricsHelper::~SecurityInterstitialMetricsHelper() { } -// Directly adds to the histograms, using the same properties as +// Directly adds to the UMA histograms, using the same properties as // UMA_HISTOGRAM_ENUMERATION, because the macro doesn't allow non-constant -// histogram names. -void SecurityInterstitialUmaHelper::RecordUserDecision( +// histogram names. Reports to Rappor for certain decisions. +void SecurityInterstitialMetricsHelper::RecordUserDecision( SecurityInterstitialDecision decision) { + // UMA std::string decision_histogram_name( - "interstitial." + histogram_prefix_ + ".decision"); + "interstitial." + uma_prefix_ + ".decision"); base::HistogramBase* decision_histogram = base::LinearHistogram::FactoryGet( decision_histogram_name, 1, MAX_DECISION, MAX_DECISION + 1, base::HistogramBase::kUmaTargetedHistogramFlag); decision_histogram->Add(decision); + // Rappor + rappor::RapporService* rappor_service = g_browser_process->rappor_service(); + if (rappor_service && rappor_reporting_ == REPORT_RAPPOR && + (decision == PROCEED || decision == DONT_PROCEED)) { + // |domain| will be empty for hosts w/o TLDs (localhost, ip addrs) + const std::string domain = + net::registry_controlled_domains::GetDomainAndRegistry( + request_url_, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + + // e.g. "interstitial.malware.domain" or "interstitial.ssl.domain" + const std::string metric_name = + "interstitial." + rappor_prefix_ + ".domain"; + rappor_service->RecordSample(metric_name, rappor::COARSE_RAPPOR_TYPE, + domain); + // TODO(nparker): Add reporting of (num_visits > 0) and decision + // once http://crbug.com/451647 is fixed. + } + #if defined(ENABLE_EXTENSIONS) if (!sampling_event_.get()) { sampling_event_.reset(new extensions::ExperienceSamplingEvent( @@ -81,7 +113,7 @@ if (num_visits_ < 1 || (decision != PROCEED && decision != DONT_PROCEED)) return; std::string history_histogram_name( - "interstitial." + histogram_prefix_ + ".decision.repeat_visit"); + "interstitial." + uma_prefix_ + ".decision.repeat_visit"); base::HistogramBase* history_histogram = base::LinearHistogram::FactoryGet( history_histogram_name, 1, MAX_DECISION, MAX_DECISION + 1, base::HistogramBase::kUmaTargetedHistogramFlag); @@ -89,10 +121,10 @@ history_histogram->Add(decision); } -void SecurityInterstitialUmaHelper::RecordUserInteraction( +void SecurityInterstitialMetricsHelper::RecordUserInteraction( SecurityInterstitialInteraction interaction) { std::string interaction_histogram_name( - "interstitial." + histogram_prefix_ + ".interaction"); + "interstitial." + uma_prefix_ + ".interaction"); base::HistogramBase* interaction_histogram = base::LinearHistogram::FactoryGet( interaction_histogram_name, 1, MAX_INTERACTION, MAX_INTERACTION + 1, @@ -125,7 +157,7 @@ #endif } -void SecurityInterstitialUmaHelper::OnGotHistoryCount( +void SecurityInterstitialMetricsHelper::OnGotHistoryCount( bool success, int num_visits, base::Time first_visit) {
diff --git a/chrome/browser/interstitials/security_interstitial_metrics_helper.h b/chrome/browser/interstitials/security_interstitial_metrics_helper.h new file mode 100644 index 0000000..1808852 --- /dev/null +++ b/chrome/browser/interstitials/security_interstitial_metrics_helper.h
@@ -0,0 +1,94 @@ +// Copyright (c) 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 CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_METRICS_HELPER_H_ +#define CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_METRICS_HELPER_H_ + +#include <string> + +#include "base/task/cancelable_task_tracker.h" +#include "base/time/time.h" +#include "url/gurl.h" + +namespace content { +class WebContents; +} + +namespace extensions { +class ExperienceSamplingEvent; +} + +// Most of the security interstitials share a common layout and set of +// choices. SecurityInterstitialMetricsHelper is intended to help the security +// interstitials record user choices in a common way via METRICS histograms +// and RAPPOR metrics. +class SecurityInterstitialMetricsHelper { + public: + // These enums are used for histograms. Don't reorder, delete, or insert + // elements. New elements should be added at the end (right before the max). + enum SecurityInterstitialDecision { + SHOW, + PROCEED, + DONT_PROCEED, + PROCEEDING_DISABLED, + MAX_DECISION + }; + enum SecurityInterstitialInteraction { + TOTAL_VISITS, + SHOW_ADVANCED, + SHOW_PRIVACY_POLICY, + SHOW_DIAGNOSTIC, + SHOW_LEARN_MORE, + RELOAD, + OPEN_TIME_SETTINGS, + MAX_INTERACTION + }; + + enum RapporReporting { + REPORT_RAPPOR, + SKIP_RAPPOR, + }; + + // Args: + // url: URL of page that triggered the interstitial. Only origin is used. + // uma_prefix: Histogram prefix for UMA. + // examples: "phishing", "ssl_overridable" + // rappor_prefix: Metric prefix for Rappor. + // examples: "phishing", "ssl" + // rappor_reporting: Used to skip rappor rapporting if desired. + // sampling_event_name: Event name for Experience Sampling. + // e.g. "phishing_interstitial_" + SecurityInterstitialMetricsHelper(content::WebContents* web_contents, + const GURL& url, + const std::string& uma_prefix, + const std::string& rappor_prefix, + RapporReporting rappor_reporting, + const std::string& sampling_event_name); + ~SecurityInterstitialMetricsHelper(); + + // Record a user decision or interaction to the appropriate UMA histogram + // and potentially in a RAPPOR metric. + void RecordUserDecision(SecurityInterstitialDecision decision); + void RecordUserInteraction(SecurityInterstitialInteraction interaction); + + private: + // Used to query the HistoryService to see if the URL is in history. + void OnGotHistoryCount(bool success, int num_visits, base::Time first_visit); + + content::WebContents* web_contents_; + const GURL request_url_; + const std::string uma_prefix_; + const std::string rappor_prefix_; + const RapporReporting rappor_reporting_; + const std::string sampling_event_name_; + int num_visits_; + base::CancelableTaskTracker request_tracker_; +#if defined(ENABLE_EXTENSIONS) + scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_; +#endif + + DISALLOW_COPY_AND_ASSIGN(SecurityInterstitialMetricsHelper); +}; + +#endif // CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_METRICS_HELPER_H_
diff --git a/chrome/browser/interstitials/security_interstitial_uma_helper.h b/chrome/browser/interstitials/security_interstitial_uma_helper.h deleted file mode 100644 index ffb465d4..0000000 --- a/chrome/browser/interstitials/security_interstitial_uma_helper.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright (c) 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 CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_UMA_HELPER_H_ -#define CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_UMA_HELPER_H_ - -#include "base/task/cancelable_task_tracker.h" -#include "base/time/time.h" -#include "url/gurl.h" - -namespace content { -class WebContents; -} - -namespace extensions { -class ExperienceSamplingEvent; -} - -// Most of the security interstitials share a common layout and set of -// choices. SecurityInterstitialUmaHelper is intended to help the security -// interstitials record user choices in a common way via UMA histograms. -class SecurityInterstitialUmaHelper { - public: - // These enums are used for histograms. Don't reorder, delete, or insert - // elements. New elements should be added at the end (right before the max). - enum SecurityInterstitialDecision { - SHOW, - PROCEED, - DONT_PROCEED, - PROCEEDING_DISABLED, - MAX_DECISION - }; - enum SecurityInterstitialInteraction { - TOTAL_VISITS, - SHOW_ADVANCED, - SHOW_PRIVACY_POLICY, - SHOW_DIAGNOSTIC, - SHOW_LEARN_MORE, - RELOAD, - OPEN_TIME_SETTINGS, - MAX_INTERACTION - }; - - SecurityInterstitialUmaHelper(content::WebContents* web_contents, - const GURL& url, - const std::string& histogram_prefix, - const std::string& sampling_event_name); - ~SecurityInterstitialUmaHelper(); - - // Record a user decision or interaction to the appropriate UMA histogram. - void RecordUserDecision(SecurityInterstitialDecision decision); - void RecordUserInteraction(SecurityInterstitialInteraction interaction); - - private: - // Used to query the HistoryService to see if the URL is in history. - void OnGotHistoryCount(bool success, int num_visits, base::Time first_visit); - - content::WebContents* web_contents_; - const GURL request_url_; - const std::string histogram_prefix_; - const std::string sampling_event_name_; - int num_visits_; - base::CancelableTaskTracker request_tracker_; -#if defined(ENABLE_EXTENSIONS) - scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_; -#endif - - DISALLOW_COPY_AND_ASSIGN(SecurityInterstitialUmaHelper); -}; - -#endif // CHROME_BROWSER_INTERSTITIALS_SECURITY_INTERSTITIAL_UMA_HELPER_H_
diff --git a/chrome/browser/invalidation/profile_invalidation_provider_factory.h b/chrome/browser/invalidation/profile_invalidation_provider_factory.h index 2e45328..5d475cd 100644 --- a/chrome/browser/invalidation/profile_invalidation_provider_factory.h +++ b/chrome/browser/invalidation/profile_invalidation_provider_factory.h
@@ -10,8 +10,7 @@ #include "components/keyed_service/content/browser_context_keyed_service_factory.h" namespace policy { -class AffiliatedInvalidationServiceProviderTest; -class DeviceCloudPolicyInvalidatorTest; +class AffiliatedInvalidationServiceProviderImplTest; } namespace user_prefs { @@ -49,8 +48,7 @@ private: friend class ProfileInvalidationProviderFactoryTestBase; - friend class policy::AffiliatedInvalidationServiceProviderTest; - friend class policy::DeviceCloudPolicyInvalidatorTest; + friend class policy::AffiliatedInvalidationServiceProviderImplTest; friend struct DefaultSingletonTraits<ProfileInvalidationProviderFactory>; ProfileInvalidationProviderFactory();
diff --git a/chrome/browser/media/OWNERS b/chrome/browser/media/OWNERS index 28093d9..6bd9a3c 100644 --- a/chrome/browser/media/OWNERS +++ b/chrome/browser/media/OWNERS
@@ -3,7 +3,6 @@ scherkus@chromium.org sergeyu@chromium.org tommi@chromium.org -vrk@chromium.org xhwang@chromium.org per-file cast_*=hclam@chromium.org
diff --git a/chrome/browser/metrics/android_metrics_provider.h b/chrome/browser/metrics/android_metrics_provider.h index 23ff210..6582682 100644 --- a/chrome/browser/metrics/android_metrics_provider.h +++ b/chrome/browser/metrics/android_metrics_provider.h
@@ -21,12 +21,12 @@ public: // Creates the AndroidMetricsProvider with the given |local_state|. explicit AndroidMetricsProvider(PrefService* local_state); - virtual ~AndroidMetricsProvider(); + ~AndroidMetricsProvider() override; // metrics::MetricsProvider: - virtual void ProvideStabilityMetrics( + void ProvideStabilityMetrics( metrics::SystemProfileProto* system_profile_proto) override; - virtual void ProvideGeneralMetrics( + void ProvideGeneralMetrics( metrics::ChromeUserMetricsExtension* uma_proto) override; // Called when the Activity that the user interacts with is swapped out.
diff --git a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc index 2bd9218..89707577 100644 --- a/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc +++ b/chrome/browser/metrics/chromeos_metrics_provider_unittest.cc
@@ -7,7 +7,7 @@ #include <string> #include "base/basictypes.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/metrics/chromeos_metrics_provider.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -120,7 +120,8 @@ std::string user3("user3@example.com"); // |scoped_enabler| takes over the lifetime of |user_manager|. - chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); + chromeos::FakeChromeUserManager* user_manager = + new chromeos::FakeChromeUserManager(); chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager); user_manager->AddKioskAppUser(user1); user_manager->AddKioskAppUser(user2); @@ -142,7 +143,8 @@ std::string user3("user3@example.com"); // |scoped_enabler| takes over the lifetime of |user_manager|. - chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); + chromeos::FakeChromeUserManager* user_manager = + new chromeos::FakeChromeUserManager(); chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager); user_manager->AddKioskAppUser(user1); user_manager->AddKioskAppUser(user2);
diff --git a/chrome/browser/net/spdyproxy/OWNERS b/chrome/browser/net/spdyproxy/OWNERS index a46d1ea..952891ee 100644 --- a/chrome/browser/net/spdyproxy/OWNERS +++ b/chrome/browser/net/spdyproxy/OWNERS
@@ -1,2 +1,3 @@ bengr@chromium.org marq@chromium.org +sclittle@chromium.org
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc index ce1f7c96..1297c62 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc
@@ -30,8 +30,17 @@ // hierarchy. This method removes the Data Reduction Proxy configuration from // prefs, if present. |proxy_pref_name| is the name of the proxy pref. void MigrateDataReductionProxyOffProxyPrefs(PrefService* prefs) { - DictionaryPrefUpdate update(prefs, prefs::kProxy); - base::DictionaryValue* dict = update.Get(); + base::DictionaryValue* dict = + (base::DictionaryValue*) prefs->GetUserPrefValue(prefs::kProxy); + if (!dict) + return; + + // Clear empty "proxy" dictionary created by a bug. See http://crbug/448172 + if (dict->empty()) { + prefs->ClearPref(prefs::kProxy); + return; + } + std::string mode; if (!dict->GetString("mode", &mode)) return; @@ -46,9 +55,7 @@ ContainsDataReductionProxy(proxy_rules)) { return; } - dict->SetString("mode", ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); - dict->SetString("server", ""); - dict->SetString("bypass_list", ""); + prefs->ClearPref(prefs::kProxy); } DataReductionProxyChromeSettings::DataReductionProxyChromeSettings(
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc index d60ba1d4..4248c272 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
@@ -39,9 +39,7 @@ settings_(settings) {} // Returns the provided setting object. Used by wrapping methods. - virtual DataReductionProxySettings* Settings() override { - return settings_; - } + DataReductionProxySettings* Settings() override { return settings_; } // The wrapped settings object. DataReductionProxySettings* settings_; @@ -126,7 +124,7 @@ DataReductionProxyChromeSettings> { public: // DataReductionProxySettingsTest implementation: - virtual void SetUp() override { + void SetUp() override { env_ = base::android::AttachCurrentThread(); DataReductionProxySettingsAndroid::Register(env_); DataReductionProxySettingsTestBase::SetUp();
diff --git a/chrome/browser/notifications/message_center_settings_controller_unittest.cc b/chrome/browser/notifications/message_center_settings_controller_unittest.cc index 4b44208..cd8e18b 100644 --- a/chrome/browser/notifications/message_center_settings_controller_unittest.cc +++ b/chrome/browser/notifications/message_center_settings_controller_unittest.cc
@@ -21,7 +21,7 @@ #if defined(OS_CHROMEOS) #include "ash/system/system_notifier.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #endif @@ -74,8 +74,8 @@ MessageCenterSettingsControllerBaseTest::SetUp(); // Initialize the UserManager singleton to a fresh FakeUserManager instance. - user_manager_enabler_.reset( - new chromeos::ScopedUserManagerEnabler(new chromeos::FakeUserManager)); + user_manager_enabler_.reset(new chromeos::ScopedUserManagerEnabler( + new chromeos::FakeChromeUserManager)); } void TearDown() override { @@ -98,8 +98,8 @@ } private: - chromeos::FakeUserManager* GetFakeUserManager() { - return static_cast<chromeos::FakeUserManager*>( + chromeos::FakeChromeUserManager* GetFakeUserManager() { + return static_cast<chromeos::FakeChromeUserManager*>( user_manager::UserManager::Get()); }
diff --git a/chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h b/chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h index be155f8..1122cf4 100644 --- a/chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h +++ b/chrome/browser/password_manager/generated_password_saved_infobar_delegate_android.h
@@ -39,8 +39,8 @@ GeneratedPasswordSavedInfoBarDelegateAndroid(); // InfoBarDelegate implementation: - virtual int GetIconID() const override; - virtual Type GetInfoBarType() const override; + int GetIconID() const override; + Type GetInfoBarType() const override; // The translated text of the message to display. base::string16 message_text_;
diff --git a/chrome/browser/password_manager/native_backend_gnome_x.cc b/chrome/browser/password_manager/native_backend_gnome_x.cc index b3571d6..bf98cd1 100644 --- a/chrome/browser/password_manager/native_backend_gnome_x.cc +++ b/chrome/browser/password_manager/native_backend_gnome_x.cc
@@ -31,6 +31,10 @@ using base::UTF16ToUTF8; using content::BrowserThread; +namespace { +const int kMaxPossibleTimeTValue = std::numeric_limits<int>::max(); +} + #define GNOME_KEYRING_DEFINE_POINTER(name) \ typeof(&::gnome_keyring_##name) GnomeKeyringLoader::gnome_keyring_##name; GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DEFINE_POINTER) @@ -131,7 +135,15 @@ bool date_ok = base::StringToInt64(string_attr_map["date_created"], &date_created); DCHECK(date_ok); - form->date_created = base::Time::FromTimeT(date_created); + // In the past |date_created| was stored as time_t. Currently is stored as + // base::Time's internal value. We need to distinguish, which format the + // number in |date_created| was stored in. We use the fact that + // kMaxPossibleTimeTValue interpreted as the internal value corresponds to an + // unlikely date back in 17th century, and anything above + // kMaxPossibleTimeTValue clearly must be in the internal value format. + form->date_created = date_created < kMaxPossibleTimeTValue + ? base::Time::FromTimeT(date_created) + : base::Time::FromInternalValue(date_created); form->blacklisted_by_user = uint_attr_map["blacklisted_by_user"]; form->type = static_cast<PasswordForm::Type>(uint_attr_map["type"]); form->times_used = uint_attr_map["times_used"]; @@ -142,7 +154,7 @@ form->display_name = UTF8ToUTF16(string_attr_map["display_name"]); form->avatar_url = GURL(string_attr_map["avatar_url"]); form->federation_url = GURL(string_attr_map["federation_url"]); - form->is_zero_click = uint_attr_map["is_zero_click"]; + form->skip_zero_click = uint_attr_map["skip_zero_click"]; return form.Pass(); } @@ -230,7 +242,7 @@ { "display_name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { "avatar_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { "federation_url", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, - { "is_zero_click", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, + { "skip_zero_click", GNOME_KEYRING_ATTRIBUTE_TYPE_UINT32 }, // This field is always "chrome" so that we can search for it. { "application", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { NULL } @@ -317,11 +329,11 @@ void GKRMethod::AddLogin(const PasswordForm& form, const char* app_string) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - time_t date_created = form.date_created.ToTimeT(); + int64 date_created = form.date_created.ToInternalValue(); // If we are asked to save a password with 0 date, use the current time. - // We don't want to actually save passwords as though on January 1, 1970. + // We don't want to actually save passwords as though on January 1, 1601. if (!date_created) - date_created = time(NULL); + date_created = base::Time::Now().ToInternalValue(); int64 date_synced = form.date_synced.ToInternalValue(); gnome_keyring_store_password( &kGnomeSchema, @@ -349,7 +361,7 @@ "display_name", UTF16ToUTF8(form.display_name).c_str(), "avatar_url", form.avatar_url.spec().c_str(), "federation_url", form.federation_url.spec().c_str(), - "is_zero_click", form.is_zero_click, + "skip_zero_click", form.skip_zero_click, "application", app_string, NULL); }
diff --git a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc index 0f144b9e..8a1c29624 100644 --- a/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc +++ b/chrome/browser/password_manager/native_backend_gnome_x_unittest.cc
@@ -298,8 +298,7 @@ EXPECT_EQ(expected.signon_realm, actual.signon_realm); EXPECT_EQ(expected.ssl_valid, actual.ssl_valid); EXPECT_EQ(expected.preferred, actual.preferred); - // We don't check the date created. It varies due to bug in the - // serialization. Integer seconds are saved instead of microseconds. + EXPECT_EQ(expected.date_created, actual.date_created); EXPECT_EQ(expected.blacklisted_by_user, actual.blacklisted_by_user); EXPECT_EQ(expected.type, actual.type); EXPECT_EQ(expected.times_used, actual.times_used); @@ -308,7 +307,7 @@ EXPECT_EQ(expected.display_name, actual.display_name); EXPECT_EQ(expected.avatar_url, actual.avatar_url); EXPECT_EQ(expected.federation_url, actual.federation_url); - EXPECT_EQ(expected.is_zero_click, actual.is_zero_click); + EXPECT_EQ(expected.skip_zero_click, actual.skip_zero_click); } } @@ -356,7 +355,7 @@ form_google_.display_name = UTF8ToUTF16("Joe Schmoe"); form_google_.avatar_url = GURL("http://www.google.com/avatar"); form_google_.federation_url = GURL("http://www.google.com/federation_url"); - form_google_.is_zero_click = true; + form_google_.skip_zero_click = true; form_facebook_.origin = GURL("http://www.facebook.com/"); form_facebook_.action = GURL("http://www.facebook.com/login"); @@ -371,7 +370,7 @@ form_facebook_.display_name = UTF8ToUTF16("Joe Schmoe"); form_facebook_.avatar_url = GURL("http://www.facebook.com/avatar"); form_facebook_.federation_url = GURL("http://www.facebook.com/federation"); - form_facebook_.is_zero_click = true; + form_facebook_.skip_zero_click = true; form_isc_.origin = GURL("http://www.isc.org/"); form_isc_.action = GURL("http://www.isc.org/auth"); @@ -469,7 +468,7 @@ CheckStringAttribute(item, "display_name", UTF16ToUTF8(form.display_name)); CheckStringAttribute(item, "avatar_url", form.avatar_url.spec()); CheckStringAttribute(item, "federation_url", form.federation_url.spec()); - CheckUint32Attribute(item, "is_zero_click", form.is_zero_click); + CheckUint32Attribute(item, "skip_zero_click", form.skip_zero_click); CheckStringAttribute(item, "application", app_string); } @@ -663,15 +662,13 @@ NativeBackendGnome backend(42); backend.Init(); - form_google_.date_synced = base::Time(); - form_isc_.date_synced = base::Time(); - form_google_.date_created = base::Time(); - form_isc_.date_created = base::Time(); base::Time now = base::Time::Now(); base::Time next_day = now + base::TimeDelta::FromDays(1); + form_google_.date_synced = base::Time(); + form_isc_.date_synced = base::Time(); + form_google_.date_created = now; + form_isc_.date_created = now; if (date_to_test == CREATED) { - // crbug/374132. Remove the next line once it's fixed. - next_day = base::Time::FromTimeT(next_day.ToTimeT()); form_google_.date_created = now; form_isc_.date_created = next_day; } else {
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.cc b/chrome/browser/password_manager/native_backend_kwallet_x.cc index 55958b1..f31310b 100644 --- a/chrome/browser/password_manager/native_backend_kwallet_x.cc +++ b/chrome/browser/password_manager/native_backend_kwallet_x.cc
@@ -722,7 +722,7 @@ pickle->WriteBool(form->ssl_valid); pickle->WriteBool(form->preferred); pickle->WriteBool(form->blacklisted_by_user); - pickle->WriteInt64(form->date_created.ToTimeT()); + pickle->WriteInt64(form->date_created.ToInternalValue()); pickle->WriteInt(form->type); pickle->WriteInt(form->times_used); autofill::SerializeFormData(form->form_data, pickle); @@ -730,7 +730,7 @@ pickle->WriteString16(form->display_name); pickle->WriteString(form->avatar_url.spec()); pickle->WriteString(form->federation_url.spec()); - pickle->WriteBool(form->is_zero_click); + pickle->WriteBool(form->skip_zero_click); } } @@ -801,7 +801,6 @@ return false; } form->scheme = static_cast<PasswordForm::Scheme>(scheme); - form->date_created = base::Time::FromTimeT(date_created); if (version > 1) { if (!iter.ReadInt(&type) || @@ -826,12 +825,18 @@ if (!iter.ReadString16(&form->display_name) || !ReadGURL(&iter, warn_only, &form->avatar_url) || !ReadGURL(&iter, warn_only, &form->federation_url) || - !iter.ReadBool(&form->is_zero_click)) { + !iter.ReadBool(&form->skip_zero_click)) { LogDeserializationWarning(version, signon_realm, false); return false; } } + if (version > 4) { + form->date_created = base::Time::FromInternalValue(date_created); + } else { + form->date_created = base::Time::FromTimeT(date_created); + } + forms->push_back(form.release()); }
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x.h b/chrome/browser/password_manager/native_backend_kwallet_x.h index 2ed7aab..116cf6fa 100644 --- a/chrome/browser/password_manager/native_backend_kwallet_x.h +++ b/chrome/browser/password_manager/native_backend_kwallet_x.h
@@ -142,7 +142,7 @@ // In case the fields in the pickle ever change, version them so we can try to // read old pickles. (Note: do not eat old pickles past the expiration date.) - static const int kPickleVersion = 4; + static const int kPickleVersion = 5; // Generates a profile-specific folder name based on profile_id_. std::string GetProfileSpecificFolderName() const;
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc index 53de5ba..edfbdc05 100644 --- a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc +++ b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
@@ -157,6 +157,7 @@ old_form_google_.password_value = UTF8ToUTF16("seekrit"); old_form_google_.submit_element = UTF8ToUTF16("submit"); old_form_google_.signon_realm = "Google"; + old_form_google_.date_created = base::Time::Now(); form_google_ = old_form_google_; form_google_.times_used = 3; @@ -164,10 +165,11 @@ form_google_.form_data.name = UTF8ToUTF16("form_name"); form_google_.form_data.user_submitted = true; form_google_.date_synced = base::Time::Now(); + form_google_.date_created = old_form_google_.date_created; form_google_.display_name = UTF8ToUTF16("Joe Schmoe"); form_google_.avatar_url = GURL("http://www.google.com/avatar"); form_google_.federation_url = GURL("http://www.google.com/federation_url"); - form_google_.is_zero_click = true; + form_google_.skip_zero_click = true; form_isc_.origin = GURL("http://www.isc.org/"); form_isc_.action = GURL("http://www.isc.org/auth"); @@ -178,10 +180,12 @@ form_isc_.submit_element = UTF8ToUTF16("login"); form_isc_.signon_realm = "ISC"; form_isc_.date_synced = base::Time::Now(); + form_isc_.date_created = base::Time::Now(); } static void CheckPasswordForm(const PasswordForm& expected, - const PasswordForm& actual); + const PasswordForm& actual, + bool check_date_created); static void CheckPasswordChanges(const PasswordStoreChangeList& expected, const PasswordStoreChangeList& actual); static void CheckPasswordChangesWithResult( @@ -196,7 +200,9 @@ // static void NativeBackendKWalletTestBase::CheckPasswordForm( - const PasswordForm& expected, const PasswordForm& actual) { + const PasswordForm& expected, + const PasswordForm& actual, + bool check_date_created) { EXPECT_EQ(expected.origin, actual.origin); EXPECT_EQ(expected.password_value, actual.password_value); EXPECT_EQ(expected.action, actual.action); @@ -207,7 +213,9 @@ EXPECT_EQ(expected.signon_realm, actual.signon_realm); EXPECT_EQ(expected.ssl_valid, actual.ssl_valid); EXPECT_EQ(expected.preferred, actual.preferred); - // We don't check the date created. It varies. + if (check_date_created) { + EXPECT_EQ(expected.date_created, actual.date_created); + } EXPECT_EQ(expected.blacklisted_by_user, actual.blacklisted_by_user); EXPECT_EQ(expected.type, actual.type); EXPECT_EQ(expected.times_used, actual.times_used); @@ -216,7 +224,7 @@ EXPECT_EQ(expected.display_name, actual.display_name); EXPECT_EQ(expected.avatar_url, actual.avatar_url); EXPECT_EQ(expected.federation_url, actual.federation_url); - EXPECT_EQ(expected.is_zero_click, actual.is_zero_click); + EXPECT_EQ(expected.skip_zero_click, actual.skip_zero_click); } // static @@ -226,7 +234,7 @@ ASSERT_EQ(expected.size(), actual.size()); for (size_t i = 0; i < expected.size(); ++i) { EXPECT_EQ(expected[i].type(), actual[i].type()); - CheckPasswordForm(expected[i].form(), actual[i].form()); + CheckPasswordForm(expected[i].form(), actual[i].form(), true); } } @@ -365,8 +373,6 @@ base::Time now = base::Time::Now(); base::Time next_day = now + base::TimeDelta::FromDays(1); if (date_to_test == CREATED) { - // crbug/374132. Remove the next line once it's fixed. - next_day = base::Time::FromTimeT(next_day.ToTimeT()); form_google_.date_created = now; form_isc_.date_created = next_day; } else { @@ -604,7 +610,7 @@ const std::vector<const PasswordForm*>& expect = sorted_expected[i].second; EXPECT_EQ(expect.size(), forms.size()); for (size_t j = 0; j < forms.size() && j < expect.size(); ++j) - CheckPasswordForm(*expect[j], *forms[j]); + CheckPasswordForm(*expect[j], *forms[j], true); } } @@ -923,25 +929,49 @@ class NativeBackendKWalletPickleTest : public NativeBackendKWalletTestBase { protected: + void CreateVersion5Pickle(const PasswordForm& form, Pickle* pickle); void CreateVersion3Pickle(const PasswordForm& form, Pickle* pickle); void CreateVersion2Pickle(const PasswordForm& form, Pickle* pickle); void CreateVersion1Pickle(const PasswordForm& form, Pickle* pickle); void CreateVersion0Pickle(bool size_32, const PasswordForm& form, Pickle* pickle); + void CheckVersion5Pickle(); void CheckVersion3Pickle(); void CheckVersion2Pickle(); void CheckVersion1Pickle(); void CheckVersion0Pickle(bool size_32, PasswordForm::Scheme scheme); private: - void CreatePickle(bool size_32, const PasswordForm& form, Pickle* pickle); + // Creates a Pickle from |form|. If |size_32| is true, stores the number of + // forms in the pickle as a 32bit uint, otherwise as 64 bit size_t. The latter + // should be the case for versions > 0. If |date_created_internal| is true, + // stores |date_created| as base::Time's internal value, otherwise as time_t. + void CreatePickle(bool size_32, + bool date_created_internal, + const PasswordForm& form, + Pickle* pickle); }; +void NativeBackendKWalletPickleTest::CreateVersion5Pickle( + const PasswordForm& form, + Pickle* pickle) { + pickle->WriteInt(5); + CreatePickle(false, true, form, pickle); + pickle->WriteInt(form.type); + pickle->WriteInt(form.times_used); + autofill::SerializeFormData(form.form_data, pickle); + pickle->WriteInt64(form.date_synced.ToInternalValue()); + pickle->WriteString16(form.display_name); + pickle->WriteString(form.avatar_url.spec()); + pickle->WriteString(form.federation_url.spec()); + pickle->WriteBool(form.skip_zero_click); +} + void NativeBackendKWalletPickleTest::CreateVersion3Pickle( const PasswordForm& form, Pickle* pickle) { pickle->WriteInt(3); - CreatePickle(false, form, pickle); + CreatePickle(false, false, form, pickle); pickle->WriteInt(form.type); pickle->WriteInt(form.times_used); autofill::SerializeFormData(form.form_data, pickle); @@ -951,7 +981,7 @@ void NativeBackendKWalletPickleTest::CreateVersion2Pickle( const PasswordForm& form, Pickle* pickle) { pickle->WriteInt(2); - CreatePickle(false, form, pickle); + CreatePickle(false, false, form, pickle); pickle->WriteInt(form.type); pickle->WriteInt(form.times_used); autofill::SerializeFormData(form.form_data, pickle); @@ -960,17 +990,19 @@ void NativeBackendKWalletPickleTest::CreateVersion1Pickle( const PasswordForm& form, Pickle* pickle) { pickle->WriteInt(1); - CreatePickle(false, form, pickle); + CreatePickle(false, false, form, pickle); } void NativeBackendKWalletPickleTest::CreateVersion0Pickle( bool size_32, const PasswordForm& form, Pickle* pickle) { pickle->WriteInt(0); - CreatePickle(size_32, form, pickle); + CreatePickle(size_32, false, form, pickle); } -void NativeBackendKWalletPickleTest::CreatePickle( - bool size_32, const PasswordForm& form, Pickle* pickle) { +void NativeBackendKWalletPickleTest::CreatePickle(bool size_32, + bool date_created_internal, + const PasswordForm& form, + Pickle* pickle) { if (size_32) pickle->WriteUInt32(1); // Size of form list. 32 bits. else @@ -986,7 +1018,24 @@ pickle->WriteBool(form.ssl_valid); pickle->WriteBool(form.preferred); pickle->WriteBool(form.blacklisted_by_user); - pickle->WriteInt64(form.date_created.ToTimeT()); + if (date_created_internal) + pickle->WriteInt64(form.date_created.ToInternalValue()); + else + pickle->WriteInt64(form.date_created.ToTimeT()); +} + +void NativeBackendKWalletPickleTest::CheckVersion5Pickle() { + Pickle pickle; + PasswordForm form = form_google_; + CreateVersion5Pickle(form, &pickle); + + ScopedVector<PasswordForm> form_list; + NativeBackendKWalletStub::DeserializeValue(form.signon_realm, pickle, + &form_list); + + EXPECT_EQ(1u, form_list.size()); + if (form_list.size() > 0) + CheckPasswordForm(form, *form_list[0], true); } void NativeBackendKWalletPickleTest::CheckVersion3Pickle() { @@ -996,7 +1045,7 @@ form.display_name.clear(); form.avatar_url = GURL(); form.federation_url = GURL(); - form.is_zero_click = false; + form.skip_zero_click = false; CreateVersion3Pickle(form, &pickle); ScopedVector<PasswordForm> form_list; @@ -1005,7 +1054,7 @@ EXPECT_EQ(1u, form_list.size()); if (form_list.size() > 0) - CheckPasswordForm(form, *form_list[0]); + CheckPasswordForm(form, *form_list[0], false); } void NativeBackendKWalletPickleTest::CheckVersion2Pickle() { @@ -1022,7 +1071,7 @@ EXPECT_EQ(1u, form_list.size()); if (form_list.size() > 0) - CheckPasswordForm(form, *form_list[0]); + CheckPasswordForm(form, *form_list[0], false); } // Make sure that we can still read version 1 pickles. @@ -1039,7 +1088,7 @@ // |form_google_| will be deserialized. EXPECT_EQ(1u, form_list.size()); if (form_list.size() > 0) - CheckPasswordForm(old_form_google_, *form_list[0]); + CheckPasswordForm(old_form_google_, *form_list[0], false); } void NativeBackendKWalletPickleTest::CheckVersion0Pickle( @@ -1053,7 +1102,7 @@ pickle, &form_list); EXPECT_EQ(1u, form_list.size()); if (form_list.size() > 0) - CheckPasswordForm(form, *form_list[0]); + CheckPasswordForm(form, *form_list[0], false); } // Check that if KWallet fails to respond, the backend propagates the error. @@ -1113,3 +1162,7 @@ TEST_F(NativeBackendKWalletPickleTest, CheckVersion3Pickle) { CheckVersion3Pickle(); } + +TEST_F(NativeBackendKWalletPickleTest, CheckVersion5Pickle) { + CheckVersion5Pickle(); +}
diff --git a/chrome/browser/password_manager/native_backend_libsecret.cc b/chrome/browser/password_manager/native_backend_libsecret.cc index 7cc94af..d23ac45 100644 --- a/chrome/browser/password_manager/native_backend_libsecret.cc +++ b/chrome/browser/password_manager/native_backend_libsecret.cc
@@ -21,6 +21,7 @@ namespace { const char kEmptyString[] = ""; +const int kMaxPossibleTimeTValue = std::numeric_limits<int>::max(); } typeof(&::secret_password_store_sync) @@ -118,7 +119,7 @@ {"display_name", SECRET_SCHEMA_ATTRIBUTE_STRING}, {"avatar_url", SECRET_SCHEMA_ATTRIBUTE_STRING}, {"federation_url", SECRET_SCHEMA_ATTRIBUTE_STRING}, - {"is_zero_click", SECRET_SCHEMA_ATTRIBUTE_INTEGER}, + {"skip_zero_click", SECRET_SCHEMA_ATTRIBUTE_INTEGER}, // This field is always "chrome-profile_id" so that we can search for it. {"application", SECRET_SCHEMA_ATTRIBUTE_STRING}, {nullptr, SECRET_SCHEMA_ATTRIBUTE_STRING}}}; @@ -164,7 +165,15 @@ bool date_ok = base::StringToInt64( GetStringFromAttributes(attrs, "date_created"), &date_created); DCHECK(date_ok); - form->date_created = base::Time::FromTimeT(date_created); + // In the past |date_created| was stored as time_t. Currently is stored as + // base::Time's internal value. We need to distinguish, which format the + // number in |date_created| was stored in. We use the fact that + // kMaxPossibleTimeTValue interpreted as the internal value corresponds to an + // unlikely date back in 17th century, and anything above + // kMaxPossibleTimeTValue clearly must be in the internal value format. + form->date_created = date_created < kMaxPossibleTimeTValue + ? base::Time::FromTimeT(date_created) + : base::Time::FromInternalValue(date_created); form->blacklisted_by_user = GetUintFromAttributes(attrs, "blacklisted_by_user"); form->type = @@ -180,7 +189,7 @@ UTF8ToUTF16(GetStringFromAttributes(attrs, "display_name")); form->avatar_url = GURL(GetStringFromAttributes(attrs, "avatar_url")); form->federation_url = GURL(GetStringFromAttributes(attrs, "federation_url")); - form->is_zero_click = GetUintFromAttributes(attrs, "is_zero_click"); + form->skip_zero_click = GetUintFromAttributes(attrs, "skip_zero_click"); return form.Pass(); } @@ -397,11 +406,11 @@ } bool NativeBackendLibsecret::RawAddLogin(const PasswordForm& form) { - time_t date_created = form.date_created.ToTimeT(); + int64 date_created = form.date_created.ToInternalValue(); // If we are asked to save a password with 0 date, use the current time. - // We don't want to actually save passwords as though on January 1, 1970. + // We don't want to actually save passwords as though on January 1, 1601. if (!date_created) - date_created = time(nullptr); + date_created = base::Time::Now().ToInternalValue(); int64 date_synced = form.date_synced.ToInternalValue(); GError* error = nullptr; secret_password_store_sync( @@ -410,20 +419,26 @@ form.origin.spec().c_str(), // Display name. UTF16ToUTF8(form.password_value).c_str(), nullptr, // no cancellable ojbect - &error, "origin_url", form.origin.spec().c_str(), "action_url", - form.action.spec().c_str(), "username_element", - UTF16ToUTF8(form.username_element).c_str(), "username_value", - UTF16ToUTF8(form.username_value).c_str(), "password_element", - UTF16ToUTF8(form.password_element).c_str(), "submit_element", - UTF16ToUTF8(form.submit_element).c_str(), "signon_realm", - form.signon_realm.c_str(), "ssl_valid", form.ssl_valid, "preferred", - form.preferred, "date_created", base::Int64ToString(date_created).c_str(), - "blacklisted_by_user", form.blacklisted_by_user, "type", form.type, - "times_used", form.times_used, "scheme", form.scheme, "date_synced", - base::Int64ToString(date_synced).c_str(), "display_name", - UTF16ToUTF8(form.display_name).c_str(), "avatar_url", - form.avatar_url.spec().c_str(), "federation_url", - form.federation_url.spec().c_str(), "is_zero_click", form.is_zero_click, + &error, + "origin_url", form.origin.spec().c_str(), + "action_url", form.action.spec().c_str(), + "username_element", UTF16ToUTF8(form.username_element).c_str(), + "username_value", UTF16ToUTF8(form.username_value).c_str(), + "password_element", UTF16ToUTF8(form.password_element).c_str(), + "submit_element", UTF16ToUTF8(form.submit_element).c_str(), + "signon_realm", form.signon_realm.c_str(), + "ssl_valid", form.ssl_valid, + "preferred", form.preferred, + "date_created", base::Int64ToString(date_created).c_str(), + "blacklisted_by_user", form.blacklisted_by_user, + "type", form.type, + "times_used", form.times_used, + "scheme", form.scheme, + "date_synced", base::Int64ToString(date_synced).c_str(), + "display_name", UTF16ToUTF8(form.display_name).c_str(), + "avatar_url", form.avatar_url.spec().c_str(), + "federation_url", form.federation_url.spec().c_str(), + "skip_zero_click", form.skip_zero_click, "application", app_string_.c_str(), nullptr); if (error) {
diff --git a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc index b7ae4be0..2e531ce 100644 --- a/chrome/browser/password_manager/native_backend_libsecret_unittest.cc +++ b/chrome/browser/password_manager/native_backend_libsecret_unittest.cc
@@ -236,8 +236,7 @@ EXPECT_EQ(expected.signon_realm, actual.signon_realm); EXPECT_EQ(expected.ssl_valid, actual.ssl_valid); EXPECT_EQ(expected.preferred, actual.preferred); - // We don't check the date created. It varies due to bug in the - // serialization. Integer seconds are saved instead of microseconds. + EXPECT_EQ(expected.date_created, actual.date_created); EXPECT_EQ(expected.blacklisted_by_user, actual.blacklisted_by_user); EXPECT_EQ(expected.type, actual.type); EXPECT_EQ(expected.times_used, actual.times_used); @@ -246,7 +245,7 @@ EXPECT_EQ(expected.display_name, actual.display_name); EXPECT_EQ(expected.avatar_url, actual.avatar_url); EXPECT_EQ(expected.federation_url, actual.federation_url); - EXPECT_EQ(expected.is_zero_click, actual.is_zero_click); + EXPECT_EQ(expected.skip_zero_click, actual.skip_zero_click); } } @@ -289,7 +288,7 @@ form_google_.display_name = UTF8ToUTF16("Joe Schmoe"); form_google_.avatar_url = GURL("http://www.google.com/avatar"); form_google_.federation_url = GURL("http://www.google.com/federation_url"); - form_google_.is_zero_click = true; + form_google_.skip_zero_click = true; form_facebook_.origin = GURL("http://www.facebook.com/"); form_facebook_.action = GURL("http://www.facebook.com/login"); @@ -304,7 +303,7 @@ form_facebook_.display_name = UTF8ToUTF16("Joe Schmoe"); form_facebook_.avatar_url = GURL("http://www.facebook.com/avatar"); form_facebook_.federation_url = GURL("http://www.facebook.com/federation"); - form_facebook_.is_zero_click = true; + form_facebook_.skip_zero_click = true; form_isc_.origin = GURL("http://www.isc.org/"); form_isc_.action = GURL("http://www.isc.org/auth"); @@ -388,7 +387,7 @@ CheckStringAttribute(item, "display_name", UTF16ToUTF8(form.display_name)); CheckStringAttribute(item, "avatar_url", form.avatar_url.spec()); CheckStringAttribute(item, "federation_url", form.federation_url.spec()); - CheckUint32Attribute(item, "is_zero_click", form.is_zero_click); + CheckUint32Attribute(item, "skip_zero_click", form.skip_zero_click); CheckStringAttribute(item, "application", app_string); } @@ -528,15 +527,13 @@ void CheckRemoveLoginsBetween(RemoveBetweenMethod date_to_test) { NativeBackendLibsecret backend(42); - form_google_.date_synced = base::Time(); - form_isc_.date_synced = base::Time(); - form_google_.date_created = base::Time(); - form_isc_.date_created = base::Time(); base::Time now = base::Time::Now(); base::Time next_day = now + base::TimeDelta::FromDays(1); + form_google_.date_synced = base::Time(); + form_isc_.date_synced = base::Time(); + form_google_.date_created = now; + form_isc_.date_created = now; if (date_to_test == CREATED) { - // http://crbug.com/374132. Remove the next line once it's fixed. - next_day = base::Time::FromTimeT(next_day.ToTimeT()); form_google_.date_created = now; form_isc_.date_created = next_day; } else {
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc index 29a3f90..4576c28 100644 --- a/chrome/browser/password_manager/password_store_mac_unittest.cc +++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -255,7 +255,7 @@ if (form_data.username_value) { form->username_value = WideToUTF16(form_data.username_value); form->display_name = form->username_value; - form->is_zero_click = true; + form->skip_zero_click = true; if (form_data.password_value) form->password_value = WideToUTF16(form_data.password_value); } else { @@ -307,7 +307,7 @@ form->username_value) << test_label; EXPECT_EQ(WideToUTF16(expectation->username_value), form->display_name) << test_label; - EXPECT_TRUE(form->is_zero_click) << test_label; + EXPECT_TRUE(form->skip_zero_click) << test_label; EXPECT_EQ(WideToUTF16(expectation->password_value), form->password_value) << test_label; } else {
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc index 1075f61..ad996d3 100644 --- a/chrome/browser/printing/print_preview_dialog_controller.cc +++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -52,9 +52,8 @@ void EnableInternalPDFPluginForContents(WebContents* preview_dialog) { // Always enable the internal PDF plugin for the print preview page. - base::FilePath pdf_plugin_path; - if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_plugin_path)) - return; + base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe( + ChromeContentClient::kPDFPluginPath); content::WebPluginInfo pdf_plugin; if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
diff --git a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc index 367a92d3..f6a9321 100644 --- a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc +++ b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
@@ -22,7 +22,6 @@ #include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/scoped_native_library.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/printing/print_preview_dialog_controller.h" @@ -39,6 +38,7 @@ #include "content/public/test/browser_test_utils.h" #include "ipc/ipc_message_macros.h" #include "net/base/filename_util.h" +#include "pdf/pdf.h" #include "printing/pdf_render_settings.h" #include "printing/units.h" #include "ui/gfx/codec/png_codec.h" @@ -323,33 +323,6 @@ ASSERT_TRUE(pdf_file.IsValid()); } - // Initializes function pointers from the PDF library. Called once when the - // test starts. The library is closed when the browser test ends. - void InitPdfFunctions() { - base::FilePath pdf_module_path; - - ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path)); - ASSERT_TRUE(base::PathExists(pdf_module_path)); - pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); - - ASSERT_TRUE(pdf_lib_.is_valid()); - pdf_to_bitmap_func_ = - reinterpret_cast<PDFPageToBitmapProc>( - pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); - - pdf_doc_info_func_ = - reinterpret_cast<GetPDFDocInfoProc>( - pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); - - pdf_page_size_func_ = - reinterpret_cast<GetPDFPageSizeByIndexProc>( - pdf_lib_.GetFunctionPointer("GetPDFPageSizeByIndex")); - - ASSERT_TRUE(pdf_to_bitmap_func_); - ASSERT_TRUE(pdf_doc_info_func_); - ASSERT_TRUE(pdf_page_size_func_); - } - // Converts the PDF to a PNG file so that the layout test can do an image // diff on this image and a reference image. void PdfToPng() { @@ -360,10 +333,10 @@ std::string pdf_data; ASSERT_TRUE(base::ReadFileToString(pdf_file_save_path_, &pdf_data)); - ASSERT_TRUE(pdf_doc_info_func_(pdf_data.data(), - pdf_data.size(), - &num_pages, - &max_width_in_points)); + ASSERT_TRUE(chrome_pdf::GetPDFDocInfo(pdf_data.data(), + pdf_data.size(), + &num_pages, + &max_width_in_points)); ASSERT_GT(num_pages, 0); double max_width_in_pixels = @@ -371,11 +344,11 @@ for (int i = 0; i < num_pages; ++i) { double width_in_points, height_in_points; - ASSERT_TRUE(pdf_page_size_func_(pdf_data.data(), - pdf_data.size(), - i, - &width_in_points, - &height_in_points)); + ASSERT_TRUE(chrome_pdf::GetPDFPageSizeByIndex(pdf_data.data(), + pdf_data.size(), + i, + &width_in_points, + &height_in_points)); double width_in_pixels = ConvertUnitDouble( width_in_points, kPointsPerInch, kDpi); @@ -405,15 +378,15 @@ std::vector<uint8_t> page_bitmap_data( kColorChannels * settings.area().size().GetArea()); - ASSERT_TRUE(pdf_to_bitmap_func_(pdf_data.data(), - pdf_data.size(), - i, - page_bitmap_data.data(), - settings.area().size().width(), - settings.area().size().height(), - settings.dpi(), - settings.dpi(), - true)); + ASSERT_TRUE(chrome_pdf::RenderPDFPageToBitmap( + pdf_data.data(), + pdf_data.size(), + i, + page_bitmap_data.data(), + settings.area().size().width(), + settings.area().size().height(), + settings.dpi(), + true)); FillPng(&page_bitmap_data, width_in_pixels, max_width_in_pixels, @@ -572,41 +545,6 @@ scoped_ptr<PrintPreviewObserver> print_preview_observer_; base::FilePath pdf_file_save_path_; - // These typedefs are function pointers to pdflib functions that give - // information about the PDF as a whole and about specific pages. - - // Converts the PDF to a bitmap. - typedef bool (*PDFPageToBitmapProc)(const void* pdf_buffer, - int pdf_buffer_size, - int page_number, - void* bitmap_buffer, - int bitmap_width, - int bitmap_height, - int dpi_x, - int dpi_y, - bool autorotate); - - // Gets the page count and maximum page width of the PDF in points. - typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, - int buffer_size, - int* pages_count, - double* max_page_width); - - // Gets the dimensions of a specific page within a PDF. - typedef bool (*GetPDFPageSizeByIndexProc)(const void* pdf_buffer, - int buffer_size, - int index, - double* width, - double* height); - - // Instantiations of the function pointers described above. - PDFPageToBitmapProc pdf_to_bitmap_func_; - GetPDFDocInfoProc pdf_doc_info_func_; - GetPDFPageSizeByIndexProc pdf_page_size_func_; - - // Used to open up the pdf plugin, which contains the functions above. - base::ScopedNativeLibrary pdf_lib_; - // Vector for storing the PNG to be sent to the layout test framework. // TODO(ivandavid): Eventually change this to uint32_t and make everything // work with that. It might be a bit tricky to fix everything to work with @@ -641,8 +579,7 @@ // to send data to the browser test. Writing "EOF\n" to |std::cout| indicates // that whatever block of data that the test was expecting has been completely // sent. Sometimes EOF is printed to stderr because the test will expect it - // from stderr in addition to stdout for certain blocks of data. - InitPdfFunctions(); + // from stderr in addition to stdout for certain blocks of data.= SetupStdinAndSavePath(); while (true) {
diff --git a/chrome/browser/printing/print_view_manager_basic.h b/chrome/browser/printing/print_view_manager_basic.h index 553c555..afcdfb2 100644 --- a/chrome/browser/printing/print_view_manager_basic.h +++ b/chrome/browser/printing/print_view_manager_basic.h
@@ -19,7 +19,7 @@ : public PrintViewManagerBase, public content::WebContentsUserData<PrintViewManagerBasic> { public: - virtual ~PrintViewManagerBasic(); + ~PrintViewManagerBasic() override; #if defined(OS_ANDROID) // Sets the file descriptor into which the PDF will be written. @@ -32,10 +32,10 @@ // content::WebContentsObserver implementation. // Terminates or cancels the print job if one was pending. - virtual void RenderProcessGone(base::TerminationStatus status) override; + void RenderProcessGone(base::TerminationStatus status) override; // content::WebContentsObserver implementation. - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; #endif private: @@ -43,7 +43,7 @@ friend class content::WebContentsUserData<PrintViewManagerBasic>; #if defined(OS_ANDROID) - virtual void OnPrintingFailed(int cookie) override; + void OnPrintingFailed(int cookie) override; // The file descriptor into which the PDF of the page will be written. base::FileDescriptor file_descriptor_;
diff --git a/chrome/browser/profiles/profile_android.h b/chrome/browser/profiles/profile_android.h index 7a202811..b336342 100644 --- a/chrome/browser/profiles/profile_android.h +++ b/chrome/browser/profiles/profile_android.h
@@ -45,7 +45,7 @@ jboolean IsOffTheRecord(JNIEnv* env, jobject obj); explicit ProfileAndroid(Profile* profile); - virtual ~ProfileAndroid(); + ~ProfileAndroid() override; base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 89238a2b..48463fa 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -44,7 +44,7 @@ #include "ui/base/l10n/l10n_util.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -222,7 +222,8 @@ profile_manager->GetInitialProfileDir().value()); const char kTestUserName[] = "test-user@example.com"; - chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); + chromeos::FakeChromeUserManager* user_manager = + new chromeos::FakeChromeUserManager(); chromeos::ScopedUserManagerEnabler enabler(user_manager); const user_manager::User* active_user = user_manager->AddUser(kTestUserName);
diff --git a/chrome/browser/renderer_host/OWNERS b/chrome/browser/renderer_host/OWNERS new file mode 100644 index 0000000..db2d1f0 --- /dev/null +++ b/chrome/browser/renderer_host/OWNERS
@@ -0,0 +1,15 @@ +# Mac files +per-file *.mm=avi@chromium.org +per-file *.mm=ccameron@chromium.org +per-file *.mm=erikchen@chromium.org +per-file *.mm=mark@chromium.org +per-file *.mm=rsesek@chromium.org +per-file *.mm=thakis@chromium.org + +per-file *_mac.h=avi@chromium.org +per-file *_mac.h=ccameron@chromium.org +per-file *_mac.h=erikchen@chromium.org +per-file *_mac.h=mark@chromium.org +per-file *_mac.h=rsesek@chromium.org +per-file *_mac.h=thakis@chromium.org +
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm index 471b921..c064f72 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm
@@ -124,6 +124,26 @@ // Create mock events -------------------------------------------------------- + // Create a gesture event with no useful data. Used to create Begin and End + // events. + id MockGestureEvent(NSEventType type) { + id event = [OCMockObject mockForClass:[NSEvent class]]; + NSPoint locationInWindow = NSMakePoint(0, 0); + CGFloat deltaX = 0; + CGFloat deltaY = 0; + NSTimeInterval timestamp = 0; + NSUInteger modifierFlags = 0; + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type]; + [(NSEvent*)[[event stub] + andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow]; + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX]; + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY]; + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp]; + [(NSEvent*)[[event stub] + andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags]; + return event; + } + // Creates a mock scroll wheel event that is backed by a real CGEvent. id MockScrollWheelEvent(NSPoint delta, NSEventType type) { CGEventRef cg_event = @@ -189,18 +209,14 @@ // Queues a gesture begin event (e.g. [NSView gestureDidBegin:]) void QueueGestureBegin() { - id event = [OCMockObject mockForClass:[NSEvent class]]; - NSEventType type = NSEventTypeBeginGesture; - [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type]; - QueueEvent(event, DEPLOYMENT_GESTURE_BEGIN, NO); + QueueEvent(MockGestureEvent(NSEventTypeBeginGesture), + DEPLOYMENT_GESTURE_BEGIN, NO); } // Queues a gesture end event (e.g. [NSView gestureDidEnd:]) void QueueGestureEnd() { - id event = [OCMockObject mockForClass:[NSEvent class]]; - NSEventType type = NSEventTypeEndGesture; - [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type]; - QueueEvent(event, DEPLOYMENT_GESTURE_END, NO); + QueueEvent(MockGestureEvent(NSEventTypeEndGesture), + DEPLOYMENT_GESTURE_BEGIN, NO); } // Queues a touch event with absolute coordinates |x| and |y|.
diff --git a/chrome/browser/resources/app_list/start_page.css b/chrome/browser/resources/app_list/start_page.css index 2a6049f..a83d4408 100644 --- a/chrome/browser/resources/app_list/start_page.css +++ b/chrome/browser/resources/app_list/start_page.css
@@ -4,6 +4,7 @@ html, body { + -webkit-user-select: none; background-color: rgb(245, 245, 245); height: 100%; margin: 0; @@ -12,7 +13,12 @@ width: 100%; } -#logo { +#doodle { + display: none; + justify-content: center; +} + +#default_logo { background-image: -webkit-image-set( url(chrome://theme/IDR_LOCAL_NTP_IMAGES_LOGO_PNG) 1x, url(chrome://theme/IDR_LOCAL_NTP_IMAGES_LOGO_PNG@2x) 2x); @@ -20,3 +26,9 @@ margin: auto; width: 269px; } + +#logo_container { + bottom: 0; + position: absolute; + width: 100%; +}
diff --git a/chrome/browser/resources/app_list/start_page.html b/chrome/browser/resources/app_list/start_page.html index 4a51a183..e360a16 100644 --- a/chrome/browser/resources/app_list/start_page.html +++ b/chrome/browser/resources/app_list/start_page.html
@@ -11,10 +11,13 @@ <script src="chrome://resources/js/util.js"></script> <script src="chrome://app-list/strings.js"></script> <script src="chrome://app-list/start_page.js"></script> + <base id="base"> </head> <body> - <div id="logo"></div> + <div id="logo_container"> + <div id="default_logo"></div> + </div> <script src="chrome://resources/js/i18n_template2.js"></script> </body> </html>
diff --git a/chrome/browser/resources/app_list/start_page.js b/chrome/browser/resources/app_list/start_page.js index 21ccc4e..e205592 100644 --- a/chrome/browser/resources/app_list/start_page.js +++ b/chrome/browser/resources/app_list/start_page.js
@@ -13,6 +13,9 @@ var speechManager = null; + // The element containing the current Google Doodle. + var doodle = null; + /** * Initialize the page. */ @@ -48,6 +51,75 @@ } /** + * Sets the doodle's visibility, hiding or showing the default logo. + * + * @param {boolean} visible Whether the doodle should be made visible. + */ + function setDoodleVisible(visible) { + var doodle = $('doodle'); + var defaultLogo = $('default_logo'); + if (visible) { + doodle.style.display = 'flex'; + defaultLogo.style.display = 'none'; + } else { + if (doodle) + doodle.style.display = 'none'; + + defaultLogo.style.display = 'block'; + } + } + + /** + * Invoked when the app-list doodle is updated. + * + * @param {Object} data The data object representing the current doodle. + */ + function onAppListDoodleUpdated(data, base_url) { + if (this.doodle) { + this.doodle.parentNode.removeChild(this.doodle); + this.doodle = null; + } + + var doodleData = data.ddljson; + if (!doodleData || !doodleData.transparent_large_image) { + setDoodleVisible(false); + return; + } + + // Set the page's base URL so that links will resolve relative to the Google + // homepage. + $('base').href = base_url; + + this.doodle = document.createElement('div'); + this.doodle.id = 'doodle'; + this.doodle.style.display = 'none'; + + var doodleImage = document.createElement('img'); + doodleImage.id = 'doodle_image'; + if (doodleData.alt_text) { + doodleImage.alt = doodleData.alt_text; + doodleImage.title = doodleData.alt_text; + } + + doodleImage.onload = function() { + setDoodleVisible(true); + }; + doodleImage.src = doodleData.transparent_large_image.url; + + if (doodleData.target_url) { + var doodleLink = document.createElement('a'); + doodleLink.id = 'doodle_link'; + doodleLink.href = doodleData.target_url; + doodleLink.target = '_blank'; + doodleLink.appendChild(doodleImage); + this.doodle.appendChild(doodleLink); + } else { + this.doodle.appendChild(doodleImage); + } + $('logo_container').appendChild(this.doodle); + } + + /** * Invoked when the app-list bubble is hidden. */ function onAppListHidden() { @@ -66,10 +138,12 @@ initialize: initialize, setHotwordEnabled: setHotwordEnabled, setNaclArch: setNaclArch, + onAppListDoodleUpdated: onAppListDoodleUpdated, onAppListShown: onAppListShown, onAppListHidden: onAppListHidden, toggleSpeechRecognition: toggleSpeechRecognition }; }); +document.addEventListener('contextmenu', function(e) { e.preventDefault(); }); document.addEventListener('DOMContentLoaded', appList.startPage.initialize);
diff --git a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js index f3d312211..41edd0e21 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js +++ b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
@@ -1511,6 +1511,7 @@ unknown: 'unknown', tooltip: 'tooltip', webArea: 'webArea', + webView: 'webView', window: 'window' }; /**
diff --git a/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js index d7d7bd4..5731239 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js +++ b/chrome/browser/resources/chromeos/chromevox/common/editable_text_base.js
@@ -6,6 +6,7 @@ goog.provide('cvox.TextChangeEvent'); goog.provide('cvox.TypingEcho'); +goog.require('cvox.AbstractTts'); goog.require('cvox.ChromeVox'); goog.require('cvox.TtsInterface'); goog.require('goog.i18n.MessageFormat');
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js index d5d9956..16f7506 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
@@ -88,8 +88,12 @@ while (cur) { var next = dir == Dir.BACKWARD ? cur.previousSibling : cur.nextSibling; + if (!AutomationUtil.isInSameTree(cur, next)) + return null; if (next) return next; + if (!AutomationUtil.isInSameTree(cur, cur.parent)) + return null; cur = cur.parent; } }; @@ -164,6 +168,10 @@ var candidate = node; while (candidate) { ret.push(candidate); + + if (!AutomationUtil.isInSameTree(candidate, candidate.parent)) + break; + candidate = candidate.parent; } return ret.reverse(); @@ -226,4 +234,17 @@ return divA.indexInParent <= divB.indexInParent ? Dir.FORWARD : Dir.BACKWARD; }; +/** + * Determines whether the two given nodes come from the same tree source. + * @param {AutomationNode} a + * @param {AutomationNode} b + * @return {boolean} + */ +AutomationUtil.isInSameTree = function(a, b) { + if (!a || !b) + return true; + + return a.root === b.root; +}; + }); // goog.scope
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js index c330608..7659707e 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -16,7 +16,6 @@ goog.require('Output.EventType'); goog.require('cursors.Cursor'); goog.require('cvox.ChromeVoxEditableTextBase'); -goog.require('cvox.TabsApiHandler'); goog.scope(function() { var AutomationNode = chrome.automation.AutomationNode; @@ -37,14 +36,6 @@ this.whitelist_ = ['chromevox_next_test']; /** - * @type {cvox.TabsApiHandler} - * @private - */ - this.tabsHandler_ = new cvox.TabsApiHandler(cvox.ChromeVox.tts, - cvox.ChromeVox.braille, - cvox.ChromeVox.earcons); - - /** * @type {cursors.Range} * @private */ @@ -82,43 +73,29 @@ // Register listeners for ... // Desktop. - chrome.automation.getDesktop(this.onGotTree); - - // Tabs. - chrome.tabs.onUpdated.addListener(this.onTabUpdated); + chrome.automation.getDesktop(this.onGotDesktop); }; Background.prototype = { /** - * Handles chrome.tabs.onUpdated. - * @param {number} tabId - * @param {Object} changeInfo - */ - onTabUpdated: function(tabId, changeInfo) { - if (changeInfo.status != 'complete') - return; - chrome.tabs.get(tabId, function(tab) { - if (!tab.url) - return; - - var next = this.isWhitelisted_(tab.url); - - this.toggleChromeVoxVersion({next: next, classic: !next}); - }.bind(this)); - }, - - /** * Handles all setup once a new automation tree appears. - * @param {chrome.automation.AutomationNode} root + * @param {chrome.automation.AutomationNode} desktop */ - onGotTree: function(root) { + onGotDesktop: function(desktop) { // Register all automation event listeners. for (var eventType in this.listeners_) - root.addEventListener(eventType, this.listeners_[eventType], true); + desktop.addEventListener(eventType, this.listeners_[eventType], true); - if (root.attributes.docLoaded) { - this.onLoadComplete( - {target: root, type: chrome.automation.EventType.loadComplete}); + // The focused state gets set on the containing webView node. + var webView = desktop.find({role: chrome.automation.RoleType.webView, + state: {focused: true}}); + if (webView) { + var root = webView.find({role: chrome.automation.RoleType.rootWebArea}); + if (root) { + this.onLoadComplete( + {target: root, + type: chrome.automation.EventType.loadComplete}); + } } }, @@ -270,14 +247,28 @@ * @param {Object} evt */ onLoadComplete: function(evt) { + var next = this.isWhitelisted_(evt.target.attributes.url); + this.toggleChromeVoxVersion({next: next, classic: !next}); // Don't process nodes inside of web content if ChromeVox Next is inactive. if (evt.target.root.role != chrome.automation.RoleType.desktop && !this.active_) return; - var node = AutomationUtil.findNodePost(evt.target, + if (this.currentRange_) + return; + + var root = evt.target; + var webView = root; + while (webView && webView.role != chrome.automation.RoleType.webView) + webView = webView.parent; + + if (!webView || !webView.state.focused) + return; + + var node = AutomationUtil.findNodePost(root, Dir.FORWARD, AutomationPredicate.leaf); + if (node) this.currentRange_ = cursors.Range.fromNode(node); @@ -362,21 +353,11 @@ if (opt_options.next) { if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) - chrome.commands.onCommand.addListener(this.onGotCommand); - - if (!this.active_) - chrome.automation.getTree(this.onGotTree); - this.active_ = true; + chrome.commands.onCommand.addListener(this.onGotCommand); + this.active_ = true; } else { if (chrome.commands.onCommand.hasListener(this.onGotCommand)) chrome.commands.onCommand.removeListener(this.onGotCommand); - - if (this.active_) { - for (var eventType in this.listeners_) { - this.currentRange_.getStart().getNode().root.removeEventListener( - eventType, this.listeners_[eventType], true); - } - } this.active_ = false; }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index 7ed70f7c..d37e4d9 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -97,7 +97,7 @@ }, true); cvox.ChromeVox.tts.expectSpeech('end', testDone, true); - this.runWithDocument(function() {/*! + this.runWithAutomation(function() {/*! <p>start <p>end */}, @@ -107,7 +107,7 @@ /** Tests consistency of navigating forward and backward. */ TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithDocument(this.linksAndHeadingsDoc, function() { + this.runWithAutomation(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expectAfter = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts); @@ -138,7 +138,7 @@ TEST_F('BackgroundTest', 'CaretNavigation', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithDocument(this.linksAndHeadingsDoc, function() { + this.runWithAutomation(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expectAfter = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts); @@ -168,7 +168,7 @@ // Flaky: http://crbug.com/451362 TEST_F('BackgroundTest', 'DISABLED_SelectSingleBasic', function() { - this.runWithDocument(this.formsDoc, function(tabId) { + this.runWithAutomation(this.formsDoc, function(tabId) { var sendDownToSelect = this.sendKeyToElement.bind(this, tabId, 'Down', '#fruitSelect'); var expect = cvox.ChromeVox.tts.expectSpeech.bind(cvox.ChromeVox.tts); @@ -181,7 +181,7 @@ TEST_F('BackgroundTest', 'ContinuousRead', function() { cvox.ChromeVox.tts.expectSpeech('start', null, true); - this.runWithDocument(this.linksAndHeadingsDoc, function() { + this.runWithAutomation(this.linksAndHeadingsDoc, function() { var doCmd = this.doCmd.bind(this); var expect = cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs index 7cc281a4b..d5b9fd3 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
@@ -70,6 +70,7 @@ range = range.move(move[0], move[1]); var expectedStart = move[2]; var expectedEnd = move[3]; + this.makeCursorAssertion(expectedStart, range.getStart()); this.makeCursorAssertion(expectedEnd, range.getEnd()); } @@ -93,27 +94,25 @@ * @param {string=} opt_testType Either CURSOR or RANGE. */ runCursorMovesOnDocument: function(doc, moves, opt_testType) { - this.runWithDocument(doc, - function() { - chrome.automation.getTree(function(root) { - var start = null; + this.runWithAutomation(doc, + function(root) { + var start = null; - // This occurs as a result of a load complete. - var start = AutomationUtil.findNodePost(root, - FORWARD, - AutomationPredicate.leaf); + // This occurs as a result of a load complete. + var start = AutomationUtil.findNodePost(root, + FORWARD, + AutomationPredicate.leaf); + var cursor = new cursors.Cursor(start, 0); + if (!opt_testType || opt_testType == this.CURSOR) { var cursor = new cursors.Cursor(start, 0); - if (!opt_testType || opt_testType == this.CURSOR) { - var cursor = new cursors.Cursor(start, 0); - this.cursorMoveAndAssert(cursor, moves); - testDone(); - } else if (opt_testType == this.RANGE) { - var range = new cursors.Range(cursor, cursor); - this.rangeMoveAndAssert(range, moves); - testDone(); - } - }.bind(this)); + this.cursorMoveAndAssert(cursor, moves); + testDone(); + } else if (opt_testType == this.RANGE) { + var range = new cursors.Range(cursor, cursor); + this.rangeMoveAndAssert(range, moves); + testDone(); + } }.bind(this)); },
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 101e896d2..7fb786b7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -13,6 +13,8 @@ goog.require('cursors.Cursor'); goog.require('cursors.Range'); goog.require('cursors.Unit'); +goog.require('cvox.AbstractEarcons'); +goog.require('cvox.NavBraille'); goog.require('cvox.Spannable'); goog.require('cvox.ValueSelectionSpan'); goog.require('cvox.ValueSpan');
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js b/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js index e432a998..038155f 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/chromevox_next_e2e_test_base.js
@@ -32,7 +32,14 @@ runWithAutomation: function(doc, callback) { this.runWithDocument(doc, function() { chrome.automation.getTree(function(root) { - callback(root); + if (root.children.length == 0) { + root.addEventListener('loadComplete', + function() { + callback(root); + }.bind(this), true); + } else { + callback(root); + } }.bind(this)); }.bind(this)); }
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js b/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js index 0915e112..fb34e1a 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/mock_tts.js
@@ -113,7 +113,7 @@ // Process any idleUtterances. this.idleUtterances_.forEach(function(utterance) { this.process_(utterance, true); - }); + }.bind(this)); }, /**
diff --git a/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py b/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py new file mode 100755 index 0000000..4782c3d --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox/tools/print_js_deps.py
@@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +'''Print the dependency tree for a JavaScript module. + +Given one or more root directories, specified by -r options and one top-level +file, walk the dependency tree and print all modules encountered. +A module is only expanded once; on a second encounter, its dependencies +are represented by a line containing the characters '[...]' as a short-hand. +''' + +import optparse +import os +import sys + +from jsbundler import ReadSources + + +def Die(message): + '''Prints an error message and exit the program.''' + print >>sys.stderr, message + sys.exit(1) + + +def CreateOptionParser(): + parser = optparse.OptionParser(description=__doc__) + parser.usage = '%prog [options] <top_level_file>' + parser.add_option('-r', '--root', dest='roots', action='append', default=[], + metavar='ROOT', + help='Roots of directory trees to scan for sources. ' + 'If none specified, all of ChromeVox and closure sources ' + 'are scanned.') + return parser + + +def DefaultRoots(): + script_dir = os.path.dirname(os.path.abspath(__file__)) + source_root_dir = os.path.join(script_dir, *[os.path.pardir] * 6) + return [os.path.relpath(os.path.join(script_dir, os.path.pardir)), + os.path.relpath( + os.path.join(source_root_dir, 'chrome', 'third_party', + 'chromevox', 'third_party', + 'closure-library', 'closure'))] + + +def WalkDeps(sources, start_source): + def Walk(source, depth): + indent = ' ' * depth + if source.GetInPath() in expanded and len(source.requires) > 0: + print '%s[...]' % indent + return + expanded.add(source.GetInPath()) + for require in source.requires: + if not require in providers: + Die('%s not provided, required by %s' % (require, source.GetInPath())) + require_source = providers[require] + print '%s%s (%s)' % (indent, require, require_source.GetInPath()) + Walk(require_source, depth + 1) + + # Create a map from provided module names to source objects. + providers = {} + expanded = set() + for source in sources.values(): + for provide in source.provides: + if provide in providers: + Die('%s provided multiple times' % provide) + providers[provide] = source + + print '(%s)' % start_source.GetInPath() + Walk(start_source, 1) + + +def main(): + parser = CreateOptionParser() + options, args = parser.parse_args() + if len(args) != 1: + Die('Exactly one top-level source file must be specified.') + start_path = args[0] + roots = options.roots or DefaultRoots() + sources = ReadSources(roots=roots, source_files=[start_path]) + start_source = sources[start_path] + WalkDeps(sources, start_source) + + +if __name__ == '__main__': + main()
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_update.css b/chrome/browser/resources/chromeos/login/oobe_screen_update.css index bd650cf..f522347 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_update.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_update.css
@@ -33,7 +33,7 @@ #update #update-cancel-hint { -webkit-margin-start: 45px; color: rgb(170, 0, 0); - margin-top: 15px; + margin-top: 30px; position: absolute; }
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_update.js b/chrome/browser/resources/chromeos/login/oobe_screen_update.js index 34c9f03..1fa14c97 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_update.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_update.js
@@ -7,17 +7,56 @@ */ login.createScreen('UpdateScreen', 'update', function() { + var USER_ACTION_CANCEL_UPDATE_SHORTCUT = 'cancel-update'; + var CONTEXT_KEY_TIME_LEFT_SEC = 'time-left-sec'; + var CONTEXT_KEY_SHOW_TIME_LEFT = 'show-time-left'; + var CONTEXT_KEY_UPDATE_MESSAGE = 'update-msg'; + var CONTEXT_KEY_SHOW_CURTAIN = 'show-curtain'; + var CONTEXT_KEY_SHOW_PROGRESS_MESSAGE = 'show-progress-msg'; + var CONTEXT_KEY_PROGRESS = 'progress'; + var CONTEXT_KEY_PROGRESS_MESSAGE = 'progress-msg'; + var CONTEXT_KEY_CANCEL_UPDATE_SHORTCUT_ENABLED = 'cancel-update-enabled'; + return { - EXTERNAL_API: [ - 'enableUpdateCancel', - 'setUpdateProgress', - 'showEstimatedTimeLeft', - 'setEstimatedTimeLeft', - 'showProgressMessage', - 'setProgressMessage', - 'setUpdateMessage', - 'showUpdateCurtain' - ], + EXTERNAL_API: [], + + /** @override */ + decorate: function() { + var self = this; + + this.context.addObserver(CONTEXT_KEY_TIME_LEFT_SEC, + function(time_left_sec) { + self.setEstimatedTimeLeft(time_left_sec); + }); + this.context.addObserver(CONTEXT_KEY_SHOW_TIME_LEFT, + function(show_time_left) { + self.showEstimatedTimeLeft(show_time_left); + }); + this.context.addObserver(CONTEXT_KEY_UPDATE_MESSAGE, + function(update_msg) { + self.setUpdateMessage(update_msg); + }); + this.context.addObserver(CONTEXT_KEY_SHOW_CURTAIN, + function(show_curtain) { + self.showUpdateCurtain(show_curtain); + }); + this.context.addObserver(CONTEXT_KEY_SHOW_PROGRESS_MESSAGE, + function(show_progress_msg) { + self.showProgressMessage(show_progress_msg); + }); + this.context.addObserver(CONTEXT_KEY_PROGRESS, + function(progress) { + self.setUpdateProgress(progress); + }); + this.context.addObserver(CONTEXT_KEY_PROGRESS_MESSAGE, + function(progress_msg) { + self.setProgressMessage(progress_msg); + }); + this.context.addObserver(CONTEXT_KEY_CANCEL_UPDATE_SHORTCUT_ENABLED, + function(enabled) { + $('update-cancel-hint').hidden = !enabled; + }); + }, /** * Header text of the screen. @@ -32,18 +71,12 @@ */ cancel: function() { // It's safe to act on the accelerator even if it's disabled on official - // builds, since Chrome will just ignore the message in that case. + // builds, since Chrome will just ignore this user action in that case. var updateCancelHint = $('update-cancel-hint').firstElementChild; updateCancelHint.textContent = loadTimeData.getString('cancelledUpdateMessage'); - chrome.send('cancelUpdate'); - }, - - /** - * Makes 'press Escape to cancel update' hint visible. - */ - enableUpdateCancel: function() { - $('update-cancel-hint').hidden = false; + this.send(login.Screen.CALLBACK_USER_ACTED, + USER_ACTION_CANCEL_UPDATE_SHORTCUT); }, /**
diff --git a/chrome/browser/resources/downloads/downloads.css b/chrome/browser/resources/downloads/downloads.css index 2e632ec..f95268e 100644 --- a/chrome/browser/resources/downloads/downloads.css +++ b/chrome/browser/resources/downloads/downloads.css
@@ -29,6 +29,10 @@ position: relative; } +.focus-row-active { + background-color: rgba(0, 0, 0, .05); +} + .download, #no-downloads-or-results { margin-top: 6px;
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html index 7cae33b3..c87227e 100644 --- a/chrome/browser/resources/downloads/downloads.html +++ b/chrome/browser/resources/downloads/downloads.html
@@ -12,6 +12,10 @@ <script src="chrome://resources/js/cr/ui/command.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/util.js"></script> + <script src="chrome://resources/js/assert.js"></script> + <script src="chrome://resources/js/event_tracker.js"></script> + <script src="chrome://resources/js/cr/ui/focus_row.js"></script> + <script src="chrome://resources/js/cr/ui/focus_grid.js"></script> <script src="chrome://downloads/downloads.js"></script> </head> <body>
diff --git a/chrome/browser/resources/downloads/downloads.js b/chrome/browser/resources/downloads/downloads.js index fd7ccc9..5a3aeb40 100644 --- a/chrome/browser/resources/downloads/downloads.js +++ b/chrome/browser/resources/downloads/downloads.js
@@ -3,6 +3,7 @@ // found in the LICENSE file. // TODO(jhawkins): Use hidden instead of showInline* and display:none. +// TODO(hcarmona): This file is big: it may be good to split it up. /** * The type of the download object. The definition is based on @@ -77,6 +78,103 @@ } /////////////////////////////////////////////////////////////////////////////// +// DownloadFocusRow: + +/** + * Provides an implementation for a single column grid. + * @constructor + * @extends {cr.ui.FocusRow} + */ +function DownloadFocusRow() {} + +/** + * Decorates |focusRow| so that it can be treated as a DownloadFocusRow. + * @param {Element} focusRow The element that has all the columns represented + * by |download|. + * @param {Download} download The Download representing this row. + * @param {Node} boundary Focus events are ignored outside of this node. + */ +DownloadFocusRow.decorate = function(focusRow, download, boundary) { + focusRow.__proto__ = DownloadFocusRow.prototype; + focusRow.decorate(boundary); + + // Add all clickable elements as a row into the grid. + focusRow.addElementIfFocusable_(download.nodeFileLink_, 'name'); + focusRow.addElementIfFocusable_(download.nodeURL_, 'url'); + focusRow.addElementIfFocusable_(download.controlShow_, 'show'); + focusRow.addElementIfFocusable_(download.controlRetry_, 'retry'); + focusRow.addElementIfFocusable_(download.controlPause_, 'pause'); + focusRow.addElementIfFocusable_(download.controlResume_, 'resume'); + focusRow.addElementIfFocusable_(download.controlRemove_, 'remove'); + focusRow.addElementIfFocusable_(download.controlCancel_, 'cancel'); + focusRow.addElementIfFocusable_(download.malwareSave_, 'save'); + focusRow.addElementIfFocusable_(download.dangerSave_, 'save'); + focusRow.addElementIfFocusable_(download.malwareDiscard_, 'discard'); + focusRow.addElementIfFocusable_(download.dangerDiscard_, 'discard'); + focusRow.addElementIfFocusable_(download.controlByExtensionLink_, + 'extension'); +}; + +DownloadFocusRow.prototype = { + __proto__: cr.ui.FocusRow.prototype, + + /** @override */ + getEquivalentElement: function(element) { + if (this.contains(element)) + return element; + + // All elements default to another element with the same type. + var columnType = element.getAttribute('column-type'); + var equivalent = this.querySelector('[column-type=' + columnType + ']'); + + if (!equivalent) { + var equivalentTypes = + ['show', 'retry', 'pause', 'resume', 'remove', 'cancel']; + if (equivalentTypes.indexOf(columnType) != -1) { + var allTypes = equivalentTypes.map(function(type) { + return '[column-type=' + type + ']'; + }).join(', '); + equivalent = this.querySelector(allTypes); + } + } + + // Return the first focusable element if no equivalent type is found. + return equivalent || this.focusableElements[0]; + }, + + /** + * @param {Element} element The element that should be added. + * @param {string} type The column type to use for the element. + * @private + */ + addElementIfFocusable_: function(element, type) { + if (this.shouldFocus_(element)) { + this.addFocusableElement(element); + element.setAttribute('column-type', type); + } + }, + + /** + * Determines if element should be focusable. + * @param {!Element} element + * @return {boolean} + * @private + */ + shouldFocus_: function(element) { + if (!element) + return false; + + // Hidden elements are not focusable. + var style = window.getComputedStyle(element); + if (style.visibility == 'hidden' || style.display == 'none') + return false; + + // Verify all ancestors are focusable. + return !element.parentElement || this.shouldFocus_(element.parentElement); + }, +}; + +/////////////////////////////////////////////////////////////////////////////// // Downloads /** * Class to hold all the information about the visible downloads. @@ -91,6 +189,7 @@ this.node_ = $('downloads-display'); this.summary_ = $('downloads-summary-text'); this.searchText_ = ''; + this.focusGrid_ = new cr.ui.FocusGrid(); // Keep track of the dates of the newest and oldest downloads so that we // know where to insert them. @@ -176,6 +275,29 @@ if (loadTimeData.getBoolean('allow_deleting_history')) $('clear-all').hidden = !hasDownloads || this.searchText_.length > 0; + + this.rebuildFocusGrid_(); +}; + +/** + * Rebuild the focusGrid_ using the elements that each download will have. + * @private + */ +Downloads.prototype.rebuildFocusGrid_ = function() { + this.focusGrid_.destroy(); + + var keys = Object.keys(this.downloads_); + for (var i = 0; i < keys.length; ++i) { + var download = this.downloads_[keys[i]]; + DownloadFocusRow.decorate(download.node, download, this.node_); + } + + // The ordering of the keys is not guaranteed, and downloads should be added + // to the FocusGrid in the order they will be in the UI. + var downloads = document.querySelectorAll('.download'); + for (var i = 0; i < downloads.length; ++i) { + this.focusGrid_.addRow(downloads[i]); + } }; /**
diff --git a/chrome/browser/resources/gaia_auth/manifest_keyboard.json b/chrome/browser/resources/gaia_auth/manifest_keyboard.json index 63d07a19..7718c0b 100644 --- a/chrome/browser/resources/gaia_auth/manifest_keyboard.json +++ b/chrome/browser/resources/gaia_auth/manifest_keyboard.json
@@ -27,6 +27,7 @@ ], "content_security_policy": "default-src 'self'; script-src 'self'; frame-src *; style-src 'self' 'unsafe-inline'", "description": "GAIA Component Extension", + "incognito": "split", "web_accessible_resources": [ "main.css", "main.html",
diff --git a/chrome/browser/resources/hangout_services/OWNERS b/chrome/browser/resources/hangout_services/OWNERS index f85f435..b6caf7a 100644 --- a/chrome/browser/resources/hangout_services/OWNERS +++ b/chrome/browser/resources/hangout_services/OWNERS
@@ -1,2 +1 @@ bemasc@chromium.org -vrk@chromium.org
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js index 9d0cae3e..24a6736 100644 --- a/chrome/browser/resources/history/history.js +++ b/chrome/browser/resources/history/history.js
@@ -250,6 +250,10 @@ e.preventDefault(); }.bind(this)); } + + if (focusless) + bookmarkSection.tabIndex = -1; + entryBox.appendChild(bookmarkSection); var visitEntryWrapper = /** @type {HTMLElement} */( @@ -884,69 +888,87 @@ }; /////////////////////////////////////////////////////////////////////////////// -// HistoryFocusObserver: +// HistoryFocusRow: /** + * Provides an implementation for a single column grid. * @constructor - * @implements {cr.ui.FocusRow.Observer} + * @extends {cr.ui.FocusRow} */ -function HistoryFocusObserver() {} +function HistoryFocusRow() {} -HistoryFocusObserver.prototype = { +/** + * Decorates |rowElement| so that it can be treated as a HistoryFocusRow item. + * @param {Element} rowElement The element representing this row. + * @param {Node} boundary Focus events are ignored outside of this node. + */ +HistoryFocusRow.decorate = function(rowElement, boundary) { + rowElement.__proto__ = HistoryFocusRow.prototype; + rowElement.decorate(boundary); + + rowElement.addElementIfPresent_('.entry-box input', 'checkbox'); + rowElement.addElementIfPresent_('.domain-checkbox', 'checkbox'); + rowElement.addElementIfPresent_('.bookmark-section.starred', 'star'); + rowElement.addElementIfPresent_('[is="action-link"]', 'domain'); + rowElement.addElementIfPresent_('.title a', 'title'); + rowElement.addElementIfPresent_('.drop-down', 'menu'); +}; + +HistoryFocusRow.prototype = { + __proto__: cr.ui.FocusRow.prototype, + /** @override */ - onActivate: function(row) { - this.getActiveRowElement_(row).classList.add('active'); + onActiveStateChanged: function(state) { + this.classList.toggle('active', state); }, /** @override */ - onDeactivate: function(row) { - this.getActiveRowElement_(row).classList.remove('active'); + getEquivalentElement: function(element) { + if (this.contains(element)) + return element; + + // All elements default to another element with the same type. + var equivalent = this.getColumn_(element.getAttribute('column-type')); + + if (!equivalent) { + switch (element.getAttribute('column-type')) { + case 'star': + equivalent = this.getColumn_('title') || this.getColumn_('domain'); + break; + case 'domain': + equivalent = this.getColumn_('title'); + break; + case 'title': + equivalent = this.getColumn_('domain'); + break; + case 'menu': + return this.focusableElements[this.focusableElements.length - 1]; + } + } + + return equivalent || this.focusableElements[0]; }, /** - * @param {cr.ui.FocusRow} row The row to find an element for. - * @return {Element} |row|'s "active" element. + * @param {string} type The type of column to return. + * @return {?Element} The column matching the type. * @private */ - getActiveRowElement_: function(row) { - return findAncestorByClass(row.items[0], 'entry') || - findAncestorByClass(row.items[0], 'site-domain-wrapper'); + getColumn_: function(type) { + return this.querySelector('[column-type=' + type + ']'); }, -}; -/////////////////////////////////////////////////////////////////////////////// -// HistoryFocusGrid: - -/** - * @param {Node=} opt_boundary - * @param {cr.ui.FocusRow.Observer=} opt_observer - * @constructor - * @extends {cr.ui.FocusGrid} - */ -function HistoryFocusGrid(opt_boundary, opt_observer) { - cr.ui.FocusGrid.apply(this, arguments); -} - -HistoryFocusGrid.prototype = { - __proto__: cr.ui.FocusGrid.prototype, - - /** @override */ - onMousedown: function(row, e) { - // TODO(dbeam): Can cr.ui.FocusGrid know about cr.ui.MenuButton? If so, bake - // this logic into the base class directly. - var menuButton = findAncestorByClass(e.target, 'menu-button'); - if (menuButton) { - // Deactivate any other active row. - this.rows.some(function(r) { - if (r.activeIndex >= 0 && r != row) { - r.activeIndex = -1; - return true; - } - }); - // Activate only the row with a pressed menu button. - row.activeIndex = row.items.indexOf(menuButton); + /** + * @param {string} query A query to select the appropriate element. + * @param {string} type The type to use for the element. + * @private + */ + addElementIfPresent_: function(query, type) { + var element = this.querySelector(query); + if (element) { + this.addFocusableElement(element); + element.setAttribute('column-type', type); } - return !!menuButton; }, }; @@ -964,8 +986,7 @@ this.editButtonTd_ = $('edit-button'); this.editingControlsDiv_ = $('editing-controls'); this.resultDiv_ = $('results-display'); - this.focusGrid_ = new HistoryFocusGrid(this.resultDiv_, - new HistoryFocusObserver); + this.focusGrid_ = new cr.ui.FocusGrid(); this.pageDiv_ = $('results-pagination'); this.model_ = model; this.pageIndex_ = 0; @@ -1197,14 +1218,14 @@ HistoryView.prototype.onBeforeRemove = function(visit) { assert(this.currentVisits_.indexOf(visit) >= 0); - var pos = this.focusGrid_.getPositionForTarget(document.activeElement); - if (!pos) + var rowIndex = this.focusGrid_.getRowIndexForTarget(document.activeElement); + if (rowIndex == -1) return; - var row = this.focusGrid_.rows[pos.row + 1] || - this.focusGrid_.rows[pos.row - 1]; - if (row) - row.focusIndex(Math.min(pos.col, row.items.length - 1)); + var rowToFocus = this.focusGrid_.rows[rowIndex + 1] || + this.focusGrid_.rows[rowIndex - 1]; + if (rowToFocus) + rowToFocus.getEquivalentElement(document.activeElement).focus(); }; /** @param {Visit} visit The visit about to be unstarred. */ @@ -1212,9 +1233,12 @@ assert(this.currentVisits_.indexOf(visit) >= 0); assert(visit.bookmarkStar == document.activeElement); - var pos = this.focusGrid_.getPositionForTarget(document.activeElement); - var row = this.focusGrid_.rows[pos.row]; - row.focusIndex(Math.min(pos.col + 1, row.items.length - 1)); + var rowIndex = this.focusGrid_.getRowIndexForTarget(document.activeElement); + var row = this.focusGrid_.rows[rowIndex]; + + // Focus the title or domain when the bookmarked star is removed because the + // star will no longer be focusable. + row.querySelector('[column-type=title], [column-type=domain]').focus(); }; /** @param {Visit} visit The visit that was just unstarred. */ @@ -1312,7 +1336,7 @@ * @return {boolean} Whether |el| is in |this.focusGrid_|. */ HistoryView.prototype.isInFocusGrid = function(el) { - return !!this.focusGrid_.getPositionForTarget(el); + return this.focusGrid_.getRowIndexForTarget(el) != -1; }; // HistoryView, private: ------------------------------------------------------ @@ -1674,26 +1698,16 @@ '.site-domain-wrapper' ].join(', '); -var focusGridColumnSelector = [ - '.entry-box input', - '.bookmark-section.starred', - '.title a', - '.drop-down', - '.domain-checkbox', - '[is="action-link"]', -].join(', '); - /** @private */ HistoryView.prototype.updateFocusGrid_ = function() { var rows = this.resultDiv_.querySelectorAll(focusGridRowSelector); - var grid = []; + this.focusGrid_.destroy(); for (var i = 0; i < rows.length; ++i) { assert(rows[i].parentNode); - grid.push(rows[i].querySelectorAll(focusGridColumnSelector)); + HistoryFocusRow.decorate(rows[i], this.resultDiv_); + this.focusGrid_.addRow(rows[i]); } - - this.focusGrid_.setGrid(grid); }; /**
diff --git a/chrome/browser/resources/history/history_mobile.css b/chrome/browser/resources/history/history_mobile.css index fc73e7c..8cd9bcc6 100644 --- a/chrome/browser/resources/history/history_mobile.css +++ b/chrome/browser/resources/history/history_mobile.css
@@ -4,6 +4,10 @@ /* This file contains styles specific to Android and iOS. */ +html:not(.focus-outline-visible) :focus { + outline: none; +} + html { height: 100%; }
diff --git a/chrome/browser/resources/history/other_devices.js b/chrome/browser/resources/history/other_devices.js index 33e4bd4..f0ebe80 100644 --- a/chrome/browser/resources/history/other_devices.js +++ b/chrome/browser/resources/history/other_devices.js
@@ -427,6 +427,33 @@ // DevicesView, Private ------------------------------------------------------- /** + * Provides an implementation for a single column grid. + * @constructor + * @extends {cr.ui.FocusRow} + */ +function DevicesViewFocusRow() {} + +/** + * Decorates |rowElement| so that it can be treated as a DevicesViewFocusRow. + * @param {Element} rowElement The element representing this row. + * @param {Node} boundary Focus events are ignored outside of this node. + */ +DevicesViewFocusRow.decorate = function(rowElement, boundary) { + rowElement.__proto__ = DevicesViewFocusRow.prototype; + rowElement.decorate(boundary); + rowElement.addFocusableElement(rowElement); +}; + +DevicesViewFocusRow.prototype = { + __proto__: cr.ui.FocusRow.prototype, + + /** @override */ + getEquivalentElement: function(element) { + return this; + }, +}; + +/** * Update the page with results. * @private */ @@ -479,16 +506,17 @@ this.focusGrids_.forEach(function(grid) { grid.destroy(); }); this.focusGrids_.length = 0; - var singleColumn = function(e) { return [e]; }; - var devices = this.resultDiv_.querySelectorAll('.device-contents'); for (var i = 0; i < devices.length; ++i) { var rows = devices[i].querySelectorAll('.device-tab-entry, button'); if (!rows.length) continue; - var grid = new cr.ui.FocusGrid(devices[i]); - grid.setGrid(Array.prototype.map.call(rows, singleColumn)); + var grid = new cr.ui.FocusGrid(); + for (var i = 0; i < rows.length; ++i) { + DevicesViewFocusRow.decorate(rows[i], devices[i]); + grid.addRow(rows[i]); + } this.focusGrids_.push(grid); } };
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js index 8ce8fe00..96ad0ca6 100644 --- a/chrome/browser/resources/omnibox/omnibox.js +++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -17,13 +17,14 @@ * are available, the Javascript formats them and displays them. */ define('main', [ + 'mojo/public/js/bindings', + 'mojo/public/js/core', 'mojo/public/js/connection', 'chrome/browser/ui/webui/omnibox/omnibox.mojom', 'content/public/renderer/service_provider', -], function(connector, browser, serviceProvider) { +], function(bindings, core, connection, browser, serviceProvider) { 'use strict'; - var connection; var page; /** @@ -71,12 +72,17 @@ // - forth element: the value of prefer-keyword // - fifth element: the value of page-classification cursorPositionUsed = $('input-text').selectionEnd; + var pipe = core.createMessagePipe(); + var stub = connection.bindHandleToStub(pipe.handle0, browser.OmniboxPage); + bindings.StubBindings(stub).delegate = page; + page.stub_ = stub; page.browser_.startOmniboxQuery( $('input-text').value, cursorPositionUsed, $('prevent-inline-autocomplete').checked, $('prefer-keyword').checked, - parseInt($('page-classification').value)); + parseInt($('page-classification').value), + pipe.handle1); // Cancel the submit action. i.e., don't submit the form. (We handle // display the results solely with Javascript.) event.preventDefault(); @@ -421,7 +427,6 @@ function OmniboxPageImpl(browser) { this.browser_ = browser; - page = this; initialize(); } @@ -434,10 +439,10 @@ }; return function() { - connection = new connector.Connection( + var browserProxy = connection.bindHandleToProxy( serviceProvider.connectToService( browser.OmniboxUIHandlerMojo.name), - OmniboxPageImpl, - browser.OmniboxUIHandlerMojo.proxyClass); + browser.OmniboxUIHandlerMojo); + page = new OmniboxPageImpl(browserProxy); }; });
diff --git a/chrome/browser/resources/pdf/elements/viewer-pane/viewer-pane.css b/chrome/browser/resources/pdf/elements/viewer-pane/viewer-pane.css index a84a0b5f3..b9c35e50 100644 --- a/chrome/browser/resources/pdf/elements/viewer-pane/viewer-pane.css +++ b/chrome/browser/resources/pdf/elements/viewer-pane/viewer-pane.css
@@ -10,10 +10,10 @@ */ direction: rtl; font-family: Roboto, 'Helvetica Neue', Helvetica, Arial; - height: calc(100% - 64px); + height: calc(100% - 56px); margin: 0; right: 0; - top: 64px; + top: 56px; width: 22em; }
diff --git a/chrome/browser/resources/pdf/index-material.css b/chrome/browser/resources/pdf/index-material.css index e9b12c6..f38941a 100644 --- a/chrome/browser/resources/pdf/index-material.css +++ b/chrome/browser/resources/pdf/index-material.css
@@ -26,6 +26,10 @@ z-index: 3; } +core-toolbar /deep/ ::selection { + background: rgb(187, 222, 251); +} + #toolbar-shadow { position: fixed; width: 100%;
diff --git a/chrome/browser/resources/pdf/index-material.html b/chrome/browser/resources/pdf/index-material.html index af1870c..2f34e4b2 100644 --- a/chrome/browser/resources/pdf/index-material.html +++ b/chrome/browser/resources/pdf/index-material.html
@@ -9,6 +9,7 @@ <link rel="import" href="elements/viewer-password-screen/viewer-password-screen.html"> <link rel="import" href="elements/viewer-toolbar/viewer-toolbar.html"> + <link rel="import" href="chrome://resources/polymer/core-icons/image-icons.html"> <link rel="import" href="chrome://resources/polymer/core-toolbar/core-toolbar.html"> <link rel="import" href="chrome://resources/polymer/paper-icon-button/paper-icon-button.html"> <link rel="import" href="chrome://resources/polymer/paper-progress/paper-progress.html"> @@ -25,6 +26,7 @@ <viewer-page-selector id="page-indicator" flex></viewer-page-selector> + <paper-icon-button icon="image:rotate-right" id="rotate-right-button"></paper-icon-button> <paper-icon-button icon="bookmark-outline" id="bookmarks-button"></paper-icon-button> <paper-icon-button icon="file-download" id="save-button"></paper-icon-button> <paper-icon-button icon="print" id="print-button"></paper-icon-button>
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index ef62ca7..c1c9931 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js
@@ -162,6 +162,8 @@ $('bookmarks-button').addEventListener('click', function() { this.bookmarksPane.toggle(); }.bind(this)); + $('rotate-right-button').addEventListener('click', + this.rotateClockwise_.bind(this)); } // Setup the keyboard event listener. @@ -206,7 +208,7 @@ handleKeyEvent_: function(e) { var position = this.viewport_.position; // Certain scroll events may be sent from outside of the extension. - var fromScriptingAPI = e.type == 'scriptingKeypress'; + var fromScriptingAPI = e.fromScriptingAPI; var pageUpHandler = function() { // Go to the previous page if we are fit-to-page. @@ -306,20 +308,42 @@ } return; case 219: // left bracket. - if (e.ctrlKey) { - this.plugin_.postMessage({ - type: 'rotateCounterclockwise' - }); - } + if (e.ctrlKey) + this.rotateCounterClockwise_(); return; case 221: // right bracket. - if (e.ctrlKey) { - this.plugin_.postMessage({ - type: 'rotateClockwise' - }); - } + if (e.ctrlKey) + this.rotateClockwise_(); return; } + + // Give print preview a chance to handle the key event. + if (!fromScriptingAPI && this.isPrintPreview_) { + this.sendScriptingMessage_({ + type: 'sendKeyEvent', + keyEvent: SerializeKeyEvent(e) + }); + } + }, + + /** + * @private + * Rotate the plugin clockwise. + */ + rotateClockwise_: function() { + this.plugin_.postMessage({ + type: 'rotateClockwise' + }); + }, + + /** + * @private + * Rotate the plugin counter-clockwise. + */ + rotateCounterClockwise_: function() { + this.plugin_.postMessage({ + type: 'rotateCounterclockwise' + }); }, /** @@ -699,10 +723,7 @@ }); return true; case 'sendKeyEvent': - var e = document.createEvent('Event'); - e.initEvent('scriptingKeypress'); - e.keyCode = message.data.keyCode; - this.handleKeyEvent_(e); + this.handleKeyEvent_(DeserializeKeyEvent(message.data.keyEvent)); return true; }
diff --git a/chrome/browser/resources/pdf/pdf_extension_test.cc b/chrome/browser/resources/pdf/pdf_extension_test.cc index 6a56a91..d89c474 100644 --- a/chrome/browser/resources/pdf/pdf_extension_test.cc +++ b/chrome/browser/resources/pdf/pdf_extension_test.cc
@@ -41,11 +41,6 @@ } void RunTestsInFile(std::string filename, std::string pdf_filename) { - base::FilePath pdf_path; - ASSERT_TRUE(PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path)); - ASSERT_TRUE( - content::PluginService::GetInstance()->GetRegisteredPpapiPluginInfo( - pdf_path)); ExtensionService* service = extensions::ExtensionSystem::Get( profile())->extension_service(); service->component_loader()->Add(IDR_PDF_MANIFEST,
diff --git a/chrome/browser/resources/pdf/pdf_scripting_api.js b/chrome/browser/resources/pdf/pdf_scripting_api.js index 59c4d40..03f14de6 100644 --- a/chrome/browser/resources/pdf/pdf_scripting_api.js +++ b/chrome/browser/resources/pdf/pdf_scripting_api.js
@@ -3,6 +3,38 @@ // found in the LICENSE file. /** + * Turn a dictionary received from postMessage into a key event. + * @param {Object} dict A dictionary representing the key event. + * @return {Event} A key event. + */ +function DeserializeKeyEvent(dict) { + var e = document.createEvent('Event'); + e.initEvent('keydown'); + e.keyCode = dict.keyCode; + e.shiftKey = dict.shiftKey; + e.ctrlKey = dict.ctrlKey; + e.altKey = dict.altKey; + e.metaKey = dict.metaKey; + e.fromScriptingAPI = true; + return e; +} + +/** + * Turn a key event into a dictionary which can be sent over postMessage. + * @param {Event} event A key event. + * @return {Object} A dictionary representing the key event. + */ +function SerializeKeyEvent(event) { + return { + keyCode: event.keyCode, + shiftKey: event.shiftKey, + ctrlKey: event.ctrlKey, + altKey: event.altKey, + metaKey: event.metaKey + }; +} + +/** * Create a new PDFScriptingAPI. This provides a scripting interface to * the PDF viewer so that it can be customized by things like print preview. * @param {Window} window the window of the page containing the pdf viewer. @@ -45,6 +77,10 @@ this.selectedTextCallback_ = null; } break; + case 'sendKeyEvent': + if (this.keyEventCallback_) + this.keyEventCallback_(DeserializeKeyEvent(event.data.keyEvent)); + break; } }.bind(this), false); } @@ -104,6 +140,14 @@ }, /** + * Sets a callback that gets run when a key event is fired in the PDF viewer. + * @param {Function} callback the callback to be called with a key event. + */ + setKeyEventCallback: function(callback) { + this.keyEventCallback_ = callback; + }, + + /** * Resets the PDF viewer into print preview mode. * @param {string} url the url of the PDF to load. * @param {boolean} grayscale whether or not to display the PDF in grayscale. @@ -196,12 +240,12 @@ /** * Send a key event to the extension. - * @param {number} keyCode the key code to send to the extension. + * @param {Event} keyEvent the key event to send to the extension. */ - sendKeyEvent: function(keyCode) { + sendKeyEvent: function(keyEvent) { this.sendMessage_({ type: 'sendKeyEvent', - keyCode: keyCode + keyEvent: SerializeKeyEvent(keyEvent) }); }, }; @@ -227,6 +271,7 @@ iframe.setViewportChangedCallback = client.setViewportChangedCallback.bind(client); iframe.setLoadCallback = client.setLoadCallback.bind(client); + iframe.setKeyEventCallback = client.setKeyEventCallback.bind(client); iframe.resetPrintPreviewMode = client.resetPrintPreviewMode.bind(client); iframe.loadPreviewPage = client.loadPreviewPage.bind(client); iframe.sendKeyEvent = client.sendKeyEvent.bind(client);
diff --git a/chrome/browser/resources/plugin_metadata/OWNERS b/chrome/browser/resources/plugin_metadata/OWNERS index e7e17284..981dd0a 100644 --- a/chrome/browser/resources/plugin_metadata/OWNERS +++ b/chrome/browser/resources/plugin_metadata/OWNERS
@@ -1,2 +1,3 @@ bauerb@chromium.org jschuh@chromium.org +wfh@chromium.org
diff --git a/chrome/browser/resources/print_preview/data/app_state.js b/chrome/browser/resources/print_preview/data/app_state.js index a8ebb06..6d90373 100644 --- a/chrome/browser/resources/print_preview/data/app_state.js +++ b/chrome/browser/resources/print_preview/data/app_state.js
@@ -39,6 +39,7 @@ SELECTED_DESTINATION_ORIGIN: 'selectedDestinationOrigin', SELECTED_DESTINATION_CAPABILITIES: 'selectedDestinationCapabilities', SELECTED_DESTINATION_NAME: 'selectedDestinationName', + SELECTED_DESTINATION_EXTENSION_ID: 'selectedDestinationExtensionId', IS_GCP_PROMO_DISMISSED: 'isGcpPromoDismissed', DPI: 'dpi', MEDIA_SIZE: 'mediaSize', @@ -99,6 +100,13 @@ return this.state_[AppState.Field.SELECTED_DESTINATION_NAME]; }, + /** + * @return {?string} Extension ID associated with the selected destination. + */ + get selectedDestinationExtensionId() { + return this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_ID]; + }, + /** @return {boolean} Whether the GCP promotion has been dismissed. */ get isGcpPromoDismissed() { return this.state_[AppState.Field.IS_GCP_PROMO_DISMISSED]; @@ -193,6 +201,8 @@ this.state_[AppState.Field.SELECTED_DESTINATION_CAPABILITIES] = dest.capabilities; this.state_[AppState.Field.SELECTED_DESTINATION_NAME] = dest.displayName; + this.state_[AppState.Field.SELECTED_DESTINATION_EXTENSION_ID] = + dest.extensionId; this.persist_(); },
diff --git a/chrome/browser/resources/print_preview/data/destination.js b/chrome/browser/resources/print_preview/data/destination.js index 4bbaeb12..a644acb8b 100644 --- a/chrome/browser/resources/print_preview/data/destination.js +++ b/chrome/browser/resources/print_preview/data/destination.js
@@ -54,6 +54,7 @@ * lastAccessTime: (number|undefined), * isTosAccepted: (boolean|undefined), * cloudID: (string|undefined), + * extensionId: (string|undefined), * description: (string|undefined)}=} opt_params Optional parameters * for the destination. * @constructor @@ -153,6 +154,12 @@ * @private {string} */ this.cloudID_ = (opt_params && opt_params.cloudID) || ''; + + /** + * Extension ID for extension managed printers. + * @private {string} + */ + this.extensionId_ = (opt_params && opt_params.extensionId) || ''; }; /** @@ -195,7 +202,8 @@ COOKIES: 'cookies', PROFILE: 'profile', DEVICE: 'device', - PRIVET: 'privet' + PRIVET: 'privet', + EXTENSION: 'extension' }; /** @@ -280,6 +288,7 @@ /** @return {boolean} Whether the destination is local or cloud-based. */ get isLocal() { return this.origin_ == Destination.Origin.LOCAL || + this.origin_ == Destination.Origin.EXTENSION || (this.origin_ == Destination.Origin.PRIVET && this.connectionStatus_ != Destination.ConnectionStatus.UNREGISTERED); @@ -291,6 +300,14 @@ }, /** + * @return {boolean} Whether the destination is an extension managed + * printer. + */ + get isExtension() { + return this.origin_ == Destination.Origin.EXTENSION; + }, + + /** * @return {string} The location of the destination, or an empty string if * the location is unknown. */ @@ -339,6 +356,14 @@ return this.cloudID_; }, + /** + * @return {string} Extension ID associated with the destination. Non-empty + * only for extension managed printers. + */ + get extensionId() { + return this.extensionId_; + }, + /** @return {?print_preview.Cdd} Print capabilities of the destination. */ get capabilities() { return this.capabilities_; @@ -410,6 +435,10 @@ return Destination.IconUrl_.FEDEX; } else if (this.id_ == Destination.GooglePromotedId.SAVE_AS_PDF) { return Destination.IconUrl_.PDF; + } else if (this.isExtension) { + // TODO(tbarzic): Update the way extension printers are displayed in the + // destination list when the desired UX is defined. + return 'chrome://extension-icon/' + this.extensionId + '/48/1'; } else if (this.isLocal) { return Destination.IconUrl_.LOCAL; } else if (this.type_ == Destination.Type.MOBILE && this.isOwned_) {
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index b3249f2..267cb8b 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -154,6 +154,29 @@ this.privetSearchTimeout_ = null; /** + * Whether a search for extension destinations is in progress. + * @type {boolean} + * @private + */ + this.isExtensionDestinationSearchInProgress_ = false; + + /** + * Whether the destination store has already loaded all extension + * destinations. + * @type {boolean} + * @private + */ + this.hasLoadedAllExtensionDestinations_ = false; + + /** + * ID of a timeout set at the start of an extension destination search. The + * timeout ends the search. + * @type {?number} + * @private + */ + this.extensionSearchTimeout_ = null; + + /** * MDNS service name of destination that we are waiting to register. * @type {?string} * @private @@ -201,6 +224,15 @@ DestinationStore.PRIVET_SEARCH_DURATION_ = 2000; /** + * Maximum amount of time spent searching for extension destinations, in + * milliseconds. + * @type {number} + * @const + * @private + */ + DestinationStore.EXTENSION_SEARCH_DURATION_ = 5000; + + /** * Localizes printer capabilities. * @param {!Object} capabilities Printer capabilities to localize. * @return {!Object} Localized capabilities. @@ -267,7 +299,8 @@ */ get isLocalDestinationSearchInProgress() { return this.isLocalDestinationSearchInProgress_ || - this.isPrivetDestinationSearchInProgress_; + this.isPrivetDestinationSearchInProgress_ || + this.isExtensionDestinationSearchInProgress_; }, /** @@ -339,6 +372,28 @@ cr.dispatchSimpleEvent( this, DestinationStore.EventType.CACHED_SELECTED_DESTINATION_INFO_READY); + } else if (this.appState_.selectedDestinationOrigin == + print_preview.Destination.Origin.EXTENSION) { + // TODO(tbarzic): Add support for requesting a single extension's + // printer list. + this.startLoadExtensionDestinations(); + + this.selectedDestination_ = + print_preview.ExtensionDestinationParser.parse({ + extensionId: this.appState_.selectedDestinationExtensionId, + id: this.appState_.selectedDestinationId, + name: this.appState_.selectedDestinationName || '' + }); + + if (this.appState_.selectedDestinationCapabilities) { + this.selectedDestination_.capabilities = + this.appState_.selectedDestinationCapabilities; + + cr.dispatchSimpleEvent( + this, + DestinationStore.EventType + .CACHED_SELECTED_DESTINATION_INFO_READY); + } } else { this.selectDefaultDestination_(); } @@ -437,8 +492,10 @@ if (destination.isPrivet) { this.nativeLayer_.startGetPrivetDestinationCapabilities( destination.id); - } - else if (destination.isLocal) { + } else if (destination.isExtension) { + this.nativeLayer_.startGetExtensionDestinationCapabilities( + destination.id); + } else if (destination.isLocal) { this.nativeLayer_.startGetLocalDestinationCapabilities( destination.id); } else { @@ -481,18 +538,35 @@ /** Initiates loading of privet print destinations. */ startLoadPrivetDestinations: function() { if (!this.hasLoadedAllPrivetDestinations_) { + if (this.privetDestinationSearchInProgress_) + clearTimeout(this.privetSearchTimeout_); this.isPrivetDestinationSearchInProgress_ = true; this.nativeLayer_.startGetPrivetDestinations(); cr.dispatchSimpleEvent( this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); - if (this.privetDestinationSearchInProgress_) - clearTimeout(this.privetSearchTimeout_); this.privetSearchTimeout_ = setTimeout( this.endPrivetPrinterSearch_.bind(this), DestinationStore.PRIVET_SEARCH_DURATION_); } }, + /** Initializes loading of extension managed print destinations. */ + startLoadExtensionDestinations: function() { + if (this.hasLoadedAllExtensionDestinations_) + return; + + if (this.isExtensionDestinationSearchInProgress_) + clearTimeout(this.extensionSearchTimeout_); + + this.isExtensionDestinationSearchInProgress_ = true; + this.nativeLayer_.startGetExtensionDestinations(); + cr.dispatchSimpleEvent( + this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); + this.extensionSearchTimeout_ = setTimeout( + this.endExtensionPrinterSearch_.bind(this), + DestinationStore.EXTENSION_SEARCH_DURATION_); + }, + /** * Initiates loading of cloud destinations. * @param {print_preview.Destination.Origin=} opt_origin Search destinations @@ -528,6 +602,7 @@ this.startLoadCloudDestinations(); this.startLoadLocalDestinations(); this.startLoadPrivetDestinations(); + this.startLoadExtensionDestinations(); }, /** @@ -632,6 +707,21 @@ }, /** + * Called when loading of extension managed printers is done. + * @private + */ + endExtensionPrinterSearch_: function() { + this.isExtensionDestinationSearchInProgress_ = false; + this.hasLoadedAllExtensionDestinations_ = true; + cr.dispatchSimpleEvent( + this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); + // Clear initially selected (cached) extension destination if it hasn't + // been found among reported extension destinations. + if (this.isInAutoSelectMode_ && this.selectedDestination_.isExtension) + this.selectDefaultDestination_(); + }, + + /** * Inserts a destination into the store without dispatching any events. * @return {boolean} Whether the inserted destination was not already in the * store. @@ -684,6 +774,14 @@ this.nativeLayer_, print_preview.NativeLayer.EventType.PRIVET_CAPABILITIES_SET, this.onPrivetCapabilitiesSet_.bind(this)); + this.tracker_.add( + this.nativeLayer_, + print_preview.NativeLayer.EventType.EXTENSION_PRINTERS_ADDED, + this.onExtensionPrintersAdded_.bind(this)); + this.tracker_.add( + this.nativeLayer_, + print_preview.NativeLayer.EventType.EXTENSION_CAPABILITIES_SET, + this.onExtensionCapabilitiesSet_.bind(this)); }, /** @@ -716,6 +814,7 @@ this.loadedCloudOrigins_ = {}; this.hasLoadedAllLocalDestinations_ = false; this.hasLoadedAllPrivetDestinations_ = false; + this.hasLoadedAllExtensionDestinations_ = false; clearTimeout(this.autoSelectTimeout_); this.autoSelectTimeout_ = setTimeout( @@ -891,7 +990,6 @@ * @private */ onPrivetCapabilitiesSet_: function(event) { - var destinationId = event.printerId; var destinations = print_preview.PrivetDestinationParser.parse(event.printer); destinations.forEach(function(dest) { @@ -901,6 +999,43 @@ }, /** + * Called when an extension responds to a getExtensionDestinations + * request. + * @param {Object} event Contains information about list of printers + * reported by the extension. + * {@code done} parameter is set iff this is the final list of printers + * returned as part of getExtensionDestinations request. + * @private + */ + onExtensionPrintersAdded_: function(event) { + this.insertDestinations_(event.printers.map(function(printer) { + return print_preview.ExtensionDestinationParser.parse(printer); + })); + + if (event.done && this.isExtensionDestinationSearchInProgress_) { + clearTimeout(this.extensionSearchTimeout_); + this.endExtensionPrinterSearch_(); + } + }, + + /** + * Called when capabilities for an extension managed printer are set. + * @param {Object} event Contains the printer's capabilities and ID. + * @private + */ + onExtensionCapabilitiesSet_: function(event) { + var destinationKey = this.getDestinationKey_( + print_preview.Destination.Origin.EXTENSION, + event.printerId, + '' /* account */); + var destination = this.destinationMap_[destinationKey]; + if (!destination) + return; + destination.capabilities = event.capabilities; + this.updateDestination_(destination); + }, + + /** * Called from native layer after the user was requested to sign in, and did * so successfully. * @private
diff --git a/chrome/browser/resources/print_preview/data/local_parsers.js b/chrome/browser/resources/print_preview/data/local_parsers.js index c15fb59..c7c3e19 100644 --- a/chrome/browser/resources/print_preview/data/local_parsers.js +++ b/chrome/browser/resources/print_preview/data/local_parsers.js
@@ -66,9 +66,30 @@ return returnedPrinters; }; + function ExtensionDestinationParser() {} + + /** + * Parses an extension destination from an extension supplied printer + * description. + * @param {!Object} destinationInfo Object describing an extension printer. + * @return {!print_preview.Destination} Parsed destination. + */ + ExtensionDestinationParser.parse = function(destinationInfo) { + return new print_preview.Destination( + destinationInfo.id, + print_preview.Destination.Type.LOCAL, + print_preview.Destination.Origin.EXTENSION, + destinationInfo.name, + false /* isRecent */, + print_preview.Destination.ConnectionStatus.ONLINE, + {description: destinationInfo.description || '', + extensionId: destinationInfo.extensionId}); + }; + // Export return { LocalDestinationParser: LocalDestinationParser, - PrivetDestinationParser: PrivetDestinationParser + PrivetDestinationParser: PrivetDestinationParser, + ExtensionDestinationParser: ExtensionDestinationParser }; });
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js index d4beb89..d61da749 100644 --- a/chrome/browser/resources/print_preview/native_layer.js +++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -36,6 +36,8 @@ this.onFailedToGetPrinterCapabilities_.bind(this); global.failedToGetPrivetPrinterCapabilities = this.onFailedToGetPrivetPrinterCapabilities_.bind(this); + global.failedToGetExtensionPrinterCapabilities = + this.onFailedToGetExtensionPrinterCapabilities_.bind(this); global.reloadPrintersList = this.onReloadPrintersList_.bind(this); global.printToCloud = this.onPrintToCloud_.bind(this); global.fileSelectionCancelled = @@ -57,6 +59,10 @@ global.onPrivetCapabilitiesSet = this.onPrivetCapabilitiesSet_.bind(this); global.onPrivetPrintFailed = this.onPrivetPrintFailed_.bind(this); + global.onExtensionPrintersAdded = + this.onExtensionPrintersAdded_.bind(this); + global.onExtensionCapabilitiesSet = + this.onExtensionCapabilitiesSet_.bind(this); global.onEnableManipulateSettingsForTest = this.onEnableManipulateSettingsForTest_.bind(this); global.printPresetOptionsFromDocument = @@ -95,6 +101,10 @@ PRIVET_CAPABILITIES_SET: 'print_preview.NativeLayer.PRIVET_CAPABILITIES_SET', PRIVET_PRINT_FAILED: 'print_preview.NativeLayer.PRIVET_PRINT_FAILED', + EXTENSION_PRINTERS_ADDED: + 'print_preview.NativeLayer.EXTENSION_PRINTERS_ADDED', + EXTENSION_CAPABILITIES_SET: + 'print_preview.NativeLayer.EXTENSION_CAPABILITIES_SET', PRINT_PRESET_OPTIONS: 'print_preview.NativeLayer.PRINT_PRESET_OPTIONS', }; @@ -177,6 +187,24 @@ }, /** + * Requests that extension system dispatches an event requesting the list of + * extension managed printers. + */ + startGetExtensionDestinations: function() { + chrome.send('getExtensionPrinters'); + }, + + /** + * Requests an extension destination's printing capabilities. A + * EXTENSION_CAPABILITIES_SET event will be dispatched in response. + * @param {string} destinationId The ID of the destination whose + * capabilities are requested. + */ + startGetExtensionDestinationCapabilities: function(destinationId) { + chrome.send('getExtensionPrinterCapabilities', [destinationId]); + }, + + /** * Requests the destination's printing capabilities. A CAPABILITIES_SET * event will be dispatched in response. * @param {string} destinationId ID of the destination. @@ -299,6 +327,10 @@ assert(!opt_showSystemDialog || (cr.isWindows && destination.isLocal), 'Implemented for Windows only'); + // TODO(tbarzic): Implement this. + assert(!destination.isExtension, + 'Printing to extension printers not yet implemented.'); + var ticket = { 'pageRange': printTicketStore.pageRange.getDocumentPageRanges(), 'mediaSize': printTicketStore.mediaSize.getValue(), @@ -514,6 +546,21 @@ this.dispatchEvent(getCapsFailEvent); }, + /** + * Called when native layer fails to get settings information for a + * requested extension destination. + * @param {string} destinationId Printer affected by error. + * @private + */ + onFailedToGetExtensionPrinterCapabilities_: function(destinationId) { + var getCapsFailEvent = new Event( + NativeLayer.EventType.GET_CAPABILITIES_FAIL); + getCapsFailEvent.destinationId = destinationId; + getCapsFailEvent.destinationOrigin = + print_preview.Destination.Origin.EXTENSION; + this.dispatchEvent(getCapsFailEvent); + }, + /** Reloads the printer list. */ onReloadPrintersList_: function() { cr.dispatchSimpleEvent(this, NativeLayer.EventType.DESTINATIONS_RELOAD); @@ -720,6 +767,36 @@ }, /** + * @param {Array.<!{extensionId: string, + * id: string, + * name: string, + * description: (string|undefined)}>} printers The list + * containing information about printers added by an extension. + * @param {boolean} done Whether this is the final list of extension + * managed printers. + */ + onExtensionPrintersAdded_: function(printers, done) { + var event = new Event(NativeLayer.EventType.EXTENSION_PRINTERS_ADDED); + event.printers = printers; + event.done = done; + this.dispatchEvent(event); + }, + + /** + * Called when an extension responds to a request for an extension printer + * capabilities. + * @param {string} printerId The printer's ID. + * @param {!Object} capabilities The reported printer capabilities. + */ + onExtensionCapabilitiesSet_: function(printerId, + capabilities) { + var event = new Event(NativeLayer.EventType.EXTENSION_CAPABILITIES_SET); + event.printerId = printerId; + event.capabilities = capabilities; + this.dispatchEvent(event); + }, + + /** * Allows for onManipulateSettings to be called * from the native layer. * @private
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.js b/chrome/browser/resources/print_preview/previewarea/preview_area.js index ca06dd84..e437621 100644 --- a/chrome/browser/resources/print_preview/previewarea/preview_area.js +++ b/chrome/browser/resources/print_preview/previewarea/preview_area.js
@@ -301,11 +301,21 @@ // No scroll bar anywhere, or the active element is something else, like a // button. Note: buttons have a bigger scrollHeight than clientHeight. - this.plugin_.sendKeyEvent(e.keyCode); + this.plugin_.sendKeyEvent(e); e.preventDefault(); }, /** + * Set a callback that gets called when a key event is received that + * originates in the plugin. + * @param {function(Event)} callback The callback to be called with a key + * event. + */ + setPluginKeyEventCallback: function(callback) { + this.keyEventCallback_ = callback; + }, + + /** * Shows a custom message on the preview area's overlay. * @param {string} message Custom message to show. */ @@ -564,6 +574,7 @@ } else { this.plugin_ = /** @type {print_preview.PDFPlugin} */( PDFCreateOutOfProcessPlugin(srcUrl)); + this.plugin_.setKeyEventCallback(this.keyEventCallback_); } this.plugin_.setAttribute('class', 'preview-area-plugin');
diff --git a/chrome/browser/resources/print_preview/print_header.js b/chrome/browser/resources/print_preview/print_header.js index cc08956..6d623fa 100644 --- a/chrome/browser/resources/print_preview/print_header.js +++ b/chrome/browser/resources/print_preview/print_header.js
@@ -142,6 +142,9 @@ updatePrintButtonEnabledState_: function() { this.getChildElement('button.print').disabled = this.destinationStore_.selectedDestination == null || + // TODO(tbarzic): Remove this when print request for extension + // destinations is wired up. + this.destinationStore_.selectedDestination.isExtension || !this.isEnabled_ || !this.isPrintButtonEnabled_ || !this.printTicketStore_.isTicketValid();
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js index 3e48478..3e7cd38 100644 --- a/chrome/browser/resources/print_preview/print_preview.js +++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -412,6 +412,7 @@ this.onCancelButtonClick_.bind(this)); this.tracker.add(window, 'keydown', this.onKeyDown_.bind(this)); + this.previewArea_.setPluginKeyEventCallback(this.onKeyDown_.bind(this)); this.tracker.add( this.destinationSettings_,
diff --git a/chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h b/chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h deleted file mode 100644 index 7e0e497..0000000 --- a/chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h +++ /dev/null
@@ -1,21 +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 CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_ADD_INCIDENT_CALLBACK_H_ -#define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_ADD_INCIDENT_CALLBACK_H_ - -#include "base/callback_forward.h" -#include "base/memory/scoped_ptr.h" - -namespace safe_browsing { - -class Incident; - -// A callback used by external components to add an incident to the incident -// reporting service. -typedef base::Callback<void(scoped_ptr<Incident>)> AddIncidentCallback; - -} // namespace safe_browsing - -#endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_ADD_INCIDENT_CALLBACK_H_
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc index 7692892..4473c96 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/safe_browsing/binary_feature_extractor.h" #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/safe_browsing/csd.pb.h" @@ -51,7 +52,7 @@ #endif } -void VerifyBinaryIntegrity(const AddIncidentCallback& callback) { +void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver) { scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor( new BinaryFeatureExtractor()); @@ -78,8 +79,8 @@ incident->set_allocated_signature(signature_info.release()); // Send the report. - callback.Run(make_scoped_ptr( - new BinaryIntegrityIncident(incident.Pass()))); + incident_receiver->AddIncidentForProcess( + make_scoped_ptr(new BinaryIntegrityIncident(incident.Pass()))); } } }
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h index 1b37533..6ac4532 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h
@@ -7,7 +7,7 @@ #include <vector> -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" +#include "base/memory/scoped_ptr.h" namespace base { class FilePath; @@ -15,6 +15,8 @@ namespace safe_browsing { +class IncidentReceiver; + // Registers a process-wide analysis with the incident reporting service that // will verify the signature of the most critical binaries used by Chrome. It // will send an incident report every time a signature verification fails. @@ -22,7 +24,7 @@ // Callback to pass to the incident reporting service. The incident reporting // service will decide when to start the analysis. -void VerifyBinaryIntegrity(const AddIncidentCallback& callback); +void VerifyBinaryIntegrity(scoped_ptr<IncidentReceiver> incident_receiver); // Returns a vector containing the paths to all the binaries to verify. std::vector<base::FilePath> GetCriticalBinariesPath();
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc index 255117d..ee931d7 100644 --- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc
@@ -11,12 +11,16 @@ #include "base/path_service.h" #include "base/test/scoped_path_override.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/safe_browsing/csd.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "version.h" // NOLINT +using ::testing::_; +using ::testing::StrictMock; + namespace safe_browsing { namespace { @@ -45,18 +49,13 @@ public: BinaryIntegrityAnalyzerWinTest(); - void OnAddIncident(scoped_ptr<Incident> incident); - protected: - bool callback_called_; base::FilePath test_data_dir_; base::ScopedTempDir temp_dir_; scoped_ptr<base::ScopedPathOverride> exe_dir_override_; - scoped_ptr<Incident> incident_; }; -BinaryIntegrityAnalyzerWinTest::BinaryIntegrityAnalyzerWinTest() - : callback_called_(false) { +BinaryIntegrityAnalyzerWinTest::BinaryIntegrityAnalyzerWinTest() { temp_dir_.CreateUniqueTempDir(); base::CreateDirectory(temp_dir_.path().AppendASCII(CHROME_VERSION_STRING)); @@ -69,16 +68,6 @@ new base::ScopedPathOverride(base::DIR_EXE, temp_dir_.path())); } -// Mock the AddIncidentCallback so we can test that VerifyBinaryIntegrity -// adds an incident callback when a signature verification fails. -void BinaryIntegrityAnalyzerWinTest::OnAddIncident( - scoped_ptr<Incident> incident) { - callback_called_ = true; - - // Take ownership of the incident so that the text fixture can inspect it. - incident_ = incident.Pass(); -} - TEST_F(BinaryIntegrityAnalyzerWinTest, GetCriticalBinariesPath) { // Expected paths. std::vector<base::FilePath> critical_binaries_path_expected; @@ -112,20 +101,22 @@ ASSERT_TRUE(base::CopyFile(signed_binary_path, chrome_elf_path)); - AddIncidentCallback callback = base::Bind( - &BinaryIntegrityAnalyzerWinTest::OnAddIncident, base::Unretained(this)); - - VerifyBinaryIntegrity(callback); - ASSERT_FALSE(callback_called_); + scoped_ptr<MockIncidentReceiver> mock_receiver( + new StrictMock<MockIncidentReceiver>()); + VerifyBinaryIntegrity(mock_receiver.Pass()); ASSERT_TRUE(EraseFileContent(chrome_elf_path)); - VerifyBinaryIntegrity(callback); - ASSERT_TRUE(callback_called_); + mock_receiver.reset(new MockIncidentReceiver()); + scoped_ptr<Incident> incident; + EXPECT_CALL(*mock_receiver, DoAddIncidentForProcess(_)) + .WillOnce(TakeIncident(&incident)); + + VerifyBinaryIntegrity(mock_receiver.Pass()); // Verify that the incident report contains the expected data. scoped_ptr<ClientIncidentReport_IncidentData> incident_data( - incident_->TakePayload()); + incident->TakePayload()); ASSERT_TRUE(incident_data->has_binary_integrity()); ASSERT_TRUE(incident_data->binary_integrity().has_file_basename()); ASSERT_EQ("chrome_elf.dll",
diff --git a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.cc b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.cc index 34527eb..0bfe254 100644 --- a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.cc +++ b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" namespace safe_browsing { @@ -21,7 +21,7 @@ } #if !defined(OS_WIN) -void VerifyBlacklistLoadState(const AddIncidentCallback& callback) { +void VerifyBlacklistLoadState(scoped_ptr<IncidentReceiver> incident_receiver) { } bool GetLoadedBlacklistedModules(std::vector<base::string16>* module_names) {
diff --git a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h index 8c5d13f..d3c2cc0 100644 --- a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h +++ b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h
@@ -7,11 +7,13 @@ #include <vector> +#include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" namespace safe_browsing { +class IncidentReceiver; + // Registers a process-wide analysis with the incident reporting service that // will examine how effective the blacklist was. void RegisterBlacklistLoadAnalysis(); @@ -22,7 +24,7 @@ // Callback to pass to the incident reporting service. The incident reporting // service will decide when to start the analysis. -void VerifyBlacklistLoadState(const AddIncidentCallback& callback); +void VerifyBlacklistLoadState(scoped_ptr<IncidentReceiver> incident_receiver); } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer_win.cc b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer_win.cc index 462644f3..a40fd08 100644 --- a/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer_win.cc +++ b/chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer_win.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/install_verification/win/module_verification_common.h" #include "chrome/browser/safe_browsing/binary_feature_extractor.h" #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/path_sanitizer.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/safe_browsing/csd.pb.h" @@ -43,7 +44,7 @@ return true; } -void VerifyBlacklistLoadState(const AddIncidentCallback& callback) { +void VerifyBlacklistLoadState(scoped_ptr<IncidentReceiver> incident_receiver) { std::vector<base::string16> module_names; if (GetLoadedBlacklistedModules(&module_names)) { PathSanitizer path_sanitizer; @@ -95,7 +96,7 @@ module_path, blacklist_load->mutable_image_headers()); // Send the report. - callback.Run( + incident_receiver->AddIncidentForProcess( make_scoped_ptr(new BlacklistLoadIncident(blacklist_load.Pass()))); } }
diff --git a/chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h b/chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h index a5bf108..7840402 100644 --- a/chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h +++ b/chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h
@@ -6,15 +6,17 @@ #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_DELAYED_ANALYSIS_CALLBACK_H_ #include "base/callback_forward.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" +#include "base/memory/scoped_ptr.h" namespace safe_browsing { +class IncidentReceiver; + // A callback used by external components to register a process-wide analysis // step. The callback will be run after some delay following process launch in -// the blocking pool. The argument is a callback by which the consumer can add +// the blocking pool. The argument is a receiver by which the consumer can add // incidents to the incident reporting service. -typedef base::Callback<void(const AddIncidentCallback&)> +typedef base::Callback<void(scoped_ptr<IncidentReceiver>)> DelayedAnalysisCallback; } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_receiver.h b/chrome/browser/safe_browsing/incident_reporting/incident_receiver.h new file mode 100644 index 0000000..eb1a019 --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/incident_receiver.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 CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_RECEIVER_H_ +#define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_RECEIVER_H_ + +#include "base/memory/scoped_ptr.h" + +class Profile; + +namespace safe_browsing { + +class Incident; + +// An interface by which incidents may be added to the incident reporting +// service. +class IncidentReceiver { + public: + virtual ~IncidentReceiver() {} + + // Adds an incident relating to |profile|. Must be called from the UI thread. + virtual void AddIncidentForProfile(Profile* profile, + scoped_ptr<Incident> incident) = 0; + + // Adds an incident relating to the entire browser process. May be called from + // any thread. + virtual void AddIncidentForProcess(scoped_ptr<Incident> incident) = 0; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_INCIDENT_RECEIVER_H_
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc index f5bafc5..44ab0b1 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/safe_browsing/database_manager.h" #include "chrome/browser/safe_browsing/incident_reporting/environment_data_collection.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h" #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" @@ -166,19 +167,6 @@ pref_update.Get()->RemoveWithoutPathExpansion(incident_type, NULL); } -// Runs |callback| on the thread to which |thread_runner| belongs. The callback -// is run immediately if this function is called on |thread_runner|'s thread. -void AddIncidentOnOriginThread( - const AddIncidentCallback& callback, - scoped_refptr<base::SingleThreadTaskRunner> thread_runner, - scoped_ptr<Incident> incident) { - if (thread_runner->BelongsToCurrentThread()) - callback.Run(incident.Pass()); - else - thread_runner->PostTask(FROM_HERE, - base::Bind(callback, base::Passed(&incident))); -} - } // namespace struct IncidentReportingService::ProfileContext { @@ -217,6 +205,70 @@ DISALLOW_COPY_AND_ASSIGN(UploadContext); }; +// An IncidentReceiver that is weakly-bound to the service and transparently +// bounces process-wide incidents back to the main thread for handling. +class IncidentReportingService::Receiver : public IncidentReceiver { + public: + explicit Receiver(const base::WeakPtr<IncidentReportingService>& service); + ~Receiver() override; + + // IncidentReceiver methods: + void AddIncidentForProfile(Profile* profile, + scoped_ptr<Incident> incident) override; + void AddIncidentForProcess(scoped_ptr<Incident> incident) override; + + private: + static void AddIncidentOnMainThread( + const base::WeakPtr<IncidentReportingService>& service, + Profile* profile, + scoped_ptr<Incident> incident); + + base::WeakPtr<IncidentReportingService> service_; + scoped_refptr<base::SingleThreadTaskRunner> thread_runner_; + + DISALLOW_COPY_AND_ASSIGN(Receiver); +}; + +IncidentReportingService::Receiver::Receiver( + const base::WeakPtr<IncidentReportingService>& service) + : service_(service), + thread_runner_(base::ThreadTaskRunnerHandle::Get()) { +} + +IncidentReportingService::Receiver::~Receiver() { +} + +void IncidentReportingService::Receiver::AddIncidentForProfile( + Profile* profile, + scoped_ptr<Incident> incident) { + DCHECK(thread_runner_->BelongsToCurrentThread()); + DCHECK(profile); + AddIncidentOnMainThread(service_, profile, incident.Pass()); +} + +void IncidentReportingService::Receiver::AddIncidentForProcess( + scoped_ptr<Incident> incident) { + if (thread_runner_->BelongsToCurrentThread()) { + AddIncidentOnMainThread(service_, nullptr, incident.Pass()); + } else if (!thread_runner_->PostTask( + FROM_HERE, + base::Bind(&IncidentReportingService::Receiver::AddIncidentOnMainThread, + service_, nullptr, base::Passed(&incident)))) { + LogIncidentDataType(DISCARDED, *incident); + } +} + +// static +void IncidentReportingService::Receiver::AddIncidentOnMainThread( + const base::WeakPtr<IncidentReportingService>& service, + Profile* profile, + scoped_ptr<Incident> incident) { + if (service) + service->AddIncident(profile, incident.Pass()); + else + LogIncidentDataType(DISCARDED, *incident); +} + IncidentReportingService::ProfileContext::ProfileContext() : added() { } @@ -293,16 +345,8 @@ STLDeleteValues(&profiles_); } -AddIncidentCallback IncidentReportingService::GetAddIncidentCallback( - Profile* profile) { - // Force the context to be created so that incidents added before - // OnProfileAdded is called are held until the profile's preferences can be - // queried. - ignore_result(GetOrCreateProfileContext(profile)); - - return base::Bind(&IncidentReportingService::AddIncident, - receiver_weak_ptr_factory_.GetWeakPtr(), - profile); +scoped_ptr<IncidentReceiver> IncidentReportingService::GetIncidentReceiver() { + return make_scoped_ptr(new Receiver(receiver_weak_ptr_factory_.GetWeakPtr())); } scoped_ptr<TrackedPreferenceValidationDelegate> @@ -312,21 +356,17 @@ if (profile->IsOffTheRecord()) return scoped_ptr<TrackedPreferenceValidationDelegate>(); return scoped_ptr<TrackedPreferenceValidationDelegate>( - new PreferenceValidationDelegate(GetAddIncidentCallback(profile))); + new PreferenceValidationDelegate(profile, GetIncidentReceiver())); } void IncidentReportingService::RegisterDelayedAnalysisCallback( const DelayedAnalysisCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - // |callback| will be run on the blocking pool, so it will likely run the - // AddIncidentCallback there as well. Bounce the run of that callback back to - // the current thread via AddIncidentOnOriginThread. + // |callback| will be run on the blocking pool. The receiver will bounce back + // to the origin thread if needed. delayed_analysis_callbacks_.RegisterCallback( - base::Bind(callback, - base::Bind(&AddIncidentOnOriginThread, - GetAddIncidentCallback(NULL), - base::ThreadTaskRunnerHandle::Get()))); + base::Bind(callback, base::Passed(GetIncidentReceiver()))); // Start running the callbacks if any profiles are participating in safe // browsing. If none are now, running will commence if/when a participaing @@ -518,9 +558,11 @@ scoped_ptr<Incident> incident) { DCHECK(thread_checker_.CalledOnValidThread()); - ProfileContext* context = GetProfileContext(profile); - // It is forbidden to call this function with a destroyed profile. - DCHECK(context); + // Ignore incidents from off-the-record profiles. + if (profile && profile->IsOffTheRecord()) + return; + + ProfileContext* context = GetOrCreateProfileContext(profile); // If this is a process-wide incident, the context must not indicate that the // profile (which is NULL) has been added to the profile manager. DCHECK(profile || !context->added);
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h index 1fac481..e638da6 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
@@ -19,7 +19,6 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/safe_browsing/download_protection_service.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" #include "chrome/browser/safe_browsing/incident_reporting/delayed_analysis_callback.h" #include "chrome/browser/safe_browsing/incident_reporting/delayed_callback_runner.h" #include "chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h" @@ -54,6 +53,8 @@ class ClientIncidentReport_DownloadDetails; class ClientIncidentReport_EnvironmentData; class ClientIncidentReport_IncidentData; +class Incident; +class IncidentReceiver; // A class that manages the collection of incidents and submission of incident // reports to the safe browsing client-side detection service. The service @@ -77,17 +78,15 @@ // dropped at destruction. ~IncidentReportingService() override; - // Returns a callback by which external components can add an incident to the - // service on behalf of |profile|. The callback may outlive the service, but - // will no longer have any effect after the service is deleted. The callback - // must not be run after |profile| has been destroyed. - AddIncidentCallback GetAddIncidentCallback(Profile* profile); + // Returns an object by which external components can add an incident to the + // service. The object may outlive the service, but will no longer have any + // effect after the service is deleted. + scoped_ptr<IncidentReceiver> GetIncidentReceiver(); // Returns a preference validation delegate that adds incidents to the service // for validation failures in |profile|. The delegate may outlive the service, // but incidents reported by it will no longer have any effect after the - // service is deleted. The lifetime of the delegate should not extend beyond - // that of the profile it services. + // service is deleted. scoped_ptr<TrackedPreferenceValidationDelegate> CreatePreferenceValidationDelegate(Profile* profile); @@ -143,6 +142,7 @@ private: struct ProfileContext; class UploadContext; + class Receiver; // A mapping of profiles to contexts holding state about received incidents. typedef std::map<Profile*, ProfileContext*> ProfileContextCollection; @@ -161,8 +161,7 @@ // participating in extended safe browsing are preferred. Profile* FindEligibleProfile() const; - // Adds |incident_data| to the service. The incident_time_msec field is - // populated with the current time if the caller has not already done so. + // Adds |incident_data| relating to the optional |profile| to the service. void AddIncident(Profile* profile, scoped_ptr<Incident> incident); // Begins processing a report. If processing is already underway, ensures that @@ -321,7 +320,7 @@ // Non-NULL while such a search is outstanding. scoped_ptr<LastDownloadFinder> last_download_finder_; - // A factory for handing out weak pointers for AddIncident callbacks. + // A factory for handing out weak pointers for IncidentReceiver objects. base::WeakPtrFactory<IncidentReportingService> receiver_weak_ptr_factory_; // A factory for handing out weak pointers for internal asynchronous tasks
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc index 6625305..4202bf1 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
@@ -17,6 +17,7 @@ #include "base/threading/thread_local.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/incident_reporting/incident_report_uploader.h" #include "chrome/browser/safe_browsing/incident_reporting/last_download_finder.h" #include "chrome/browser/safe_browsing/incident_reporting/tracked_preference_incident.h" @@ -246,7 +247,12 @@ // Adds a test incident to the service. void AddTestIncident(Profile* profile) { - instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident(nullptr)); + scoped_ptr<safe_browsing::IncidentReceiver> receiver( + instance_->GetIncidentReceiver()); + if (profile) + receiver->AddIncidentForProfile(profile, MakeTestIncident(nullptr)); + else + receiver->AddIncidentForProcess(MakeTestIncident(nullptr)); } // Registers the callback to be run for delayed analysis. @@ -459,10 +465,10 @@ void OnDownloadFinderDestroyed() { download_finder_destroyed_ = true; } void OnUploaderDestroyed() { uploader_destroyed_ = true; } - void OnDelayedAnalysis(const safe_browsing::AddIncidentCallback& callback) { + void OnDelayedAnalysis(scoped_ptr<safe_browsing::IncidentReceiver> receiver) { delayed_analysis_ran_ = true; if (on_delayed_analysis_action_ == ON_DELAYED_ANALYSIS_ADD_INCIDENT) - callback.Run(MakeTestIncident(nullptr)); + receiver->AddIncidentForProcess(MakeTestIncident(nullptr)); } // A mapping of profile name to its corresponding properties. @@ -637,7 +643,8 @@ ExpectTestIncidentUploaded(1); // Add a variation on the incident to the service. - instance_->GetAddIncidentCallback(profile).Run(MakeTestIncident("leeches")); + instance_->GetIncidentReceiver()->AddIncidentForProfile( + profile, MakeTestIncident("leeches")); // Let all tasks run. task_runner_->RunUntilIdle(); @@ -755,9 +762,9 @@ nullptr); // Add the test incident. - safe_browsing::AddIncidentCallback add_incident( - instance_->GetAddIncidentCallback(NULL)); - add_incident.Run(MakeTestIncident(nullptr)); + scoped_ptr<safe_browsing::IncidentReceiver> receiver( + instance_->GetIncidentReceiver()); + receiver->AddIncidentForProcess(MakeTestIncident(nullptr)); // Let all tasks run. task_runner_->RunUntilIdle(); @@ -766,7 +773,7 @@ ExpectTestIncidentUploaded(1); // Add a variation on the incident to the service. - add_incident.Run(MakeTestIncident("leeches")); + receiver->AddIncidentForProcess(MakeTestIncident("leeches")); // Let all tasks run. task_runner_->RunUntilIdle();
diff --git a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.cc b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.cc new file mode 100644 index 0000000..4a4bd57ec --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.cc
@@ -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. + +#include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" + +#include "chrome/browser/safe_browsing/incident_reporting/incident.h" + +namespace safe_browsing { + +MockIncidentReceiver::MockIncidentReceiver() {} + +MockIncidentReceiver::~MockIncidentReceiver() {} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h new file mode 100644 index 0000000..1cd2e053 --- /dev/null +++ b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.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_SAFE_BROWSING_INCIDENT_REPORTING_MOCK_INCIDENT_RECEIVER_H_ +#define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_MOCK_INCIDENT_RECEIVER_H_ + +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace safe_browsing { + +class MockIncidentReceiver : public IncidentReceiver { + public: + MockIncidentReceiver(); + ~MockIncidentReceiver(); + + MOCK_METHOD2(DoAddIncidentForProfile, void(Profile*, scoped_ptr<Incident>*)); + MOCK_METHOD1(DoAddIncidentForProcess, void(scoped_ptr<Incident>*)); + + protected: + void AddIncidentForProfile(Profile* profile, + scoped_ptr<Incident> incident) override { + DoAddIncidentForProfile(profile, &incident); + } + + void AddIncidentForProcess(scoped_ptr<Incident> incident) override { + DoAddIncidentForProcess(&incident); + } +}; + +// An action that passes ownership of the incident in |arg0| to |recipient|. +ACTION_P(TakeIncident, recipient) { + *recipient = arg0->Pass(); +} + +// An action that passes ownership of the incident in |arg0| to the vector in +// |incidents|. +ACTION_P(TakeIncidentToVector, incidents) { + incidents->push_back(arg0->release()); +} + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_MOCK_INCIDENT_RECEIVER_H_
diff --git a/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h b/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h index fb75cae..f0ab04f0 100644 --- a/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h +++ b/chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h
@@ -42,8 +42,8 @@ }; // TODO(gab): Hook the OffDomainInclusionDetector to the - // IncidentReportingService and use an AddIncidentCallback instead of this - // custom callback type. + // IncidentReportingService and use an IncidentReceiver instead of this custom + // callback type. typedef base::Callback<void(AnalysisEvent event)> ReportAnalysisEventCallback; // Constructs an OffDomainInclusionDetector which will use |database_manager|
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.cc index 1c96036..6ac435dc 100644 --- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.cc +++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.cc
@@ -7,10 +7,10 @@ #include <string> #include <vector> -#include "base/callback.h" #include "base/json/json_writer.h" #include "chrome/browser/prefs/tracked/pref_hash_store_transaction.h" #include "chrome/browser/prefs/tracked/tracked_preference_helper.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/incident_reporting/tracked_preference_incident.h" #include "chrome/common/safe_browsing/csd.pb.h" @@ -41,8 +41,10 @@ } // namespace PreferenceValidationDelegate::PreferenceValidationDelegate( - const AddIncidentCallback& add_incident) - : add_incident_(add_incident) { + Profile* profile, + scoped_ptr<IncidentReceiver> incident_receiver) + : profile_(profile), + incident_receiver_(incident_receiver.Pass()) { } PreferenceValidationDelegate::~PreferenceValidationDelegate() { @@ -64,8 +66,9 @@ incident->clear_atomic_value(); } incident->set_value_state(proto_value_state); - add_incident_.Run(make_scoped_ptr( - new TrackedPreferenceIncident(incident.Pass(), is_personal))); + incident_receiver_->AddIncidentForProfile( + profile_, make_scoped_ptr(new TrackedPreferenceIncident(incident.Pass(), + is_personal))); } } @@ -87,8 +90,9 @@ incident->add_split_key(*scan); } incident->set_value_state(proto_value_state); - add_incident_.Run(make_scoped_ptr( - new TrackedPreferenceIncident(incident.Pass(), is_personal))); + incident_receiver_->AddIncidentForProfile( + profile_, make_scoped_ptr(new TrackedPreferenceIncident(incident.Pass(), + is_personal))); } }
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h index 6516c0c..1fb789e 100644 --- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h +++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h
@@ -5,21 +5,25 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_PREFERENCE_VALIDATION_DELEGATE_H_ #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_PREFERENCE_VALIDATION_DELEGATE_H_ -#include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" + +class Profile; namespace safe_browsing { +class IncidentReceiver; + // A preference validation delegate that adds incidents to a given receiver -// for preference validation failures. +// for preference validation failures. The profile for which the delegate +// operates must outlive the delegate itself. class PreferenceValidationDelegate : public TrackedPreferenceValidationDelegate { public: - explicit PreferenceValidationDelegate( - const AddIncidentCallback& add_incident); + PreferenceValidationDelegate(Profile* profile, + scoped_ptr<IncidentReceiver> incident_receiver); ~PreferenceValidationDelegate() override; private: @@ -36,7 +40,8 @@ PrefHashStoreTransaction::ValueState value_state, bool is_personal) override; - AddIncidentCallback add_incident_; + Profile* profile_; + scoped_ptr<IncidentReceiver> incident_receiver_; DISALLOW_COPY_AND_ASSIGN(PreferenceValidationDelegate); };
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc index 547fb09..9571f0c 100644 --- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -12,9 +12,16 @@ #include "base/memory/scoped_vector.h" #include "base/values.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h" +#include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" #include "chrome/common/safe_browsing/csd.pb.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::_; +using ::testing::IsNull; +using ::testing::NiceMock; +using ::testing::WithArg; + // A basic test harness that creates a delegate instance for which it stores all // incidents. Tests can push data to the delegate and verify that the test // instance was provided with the expected data. @@ -30,13 +37,12 @@ testing::Test::SetUp(); invalid_keys_.push_back(std::string("one")); invalid_keys_.push_back(std::string("two")); + scoped_ptr<safe_browsing::MockIncidentReceiver> receiver( + new NiceMock<safe_browsing::MockIncidentReceiver>()); + ON_CALL(*receiver, DoAddIncidentForProfile(IsNull(), _)) + .WillByDefault(WithArg<1>(TakeIncidentToVector(&incidents_))); instance_.reset(new safe_browsing::PreferenceValidationDelegate( - base::Bind(&PreferenceValidationDelegateTest::AddIncident, - base::Unretained(this)))); - } - - void AddIncident(scoped_ptr<safe_browsing::Incident> incident) { - incidents_.push_back(incident.release()); + nullptr, receiver.Pass())); } static void ExpectValueStatesEquate(
diff --git a/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.cc b/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.cc index 6fe04e1..04c2f4d1 100644 --- a/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.cc +++ b/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.cc
@@ -10,6 +10,7 @@ #include "base/location.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/variations/variations_service.h" +#include "chrome/browser/safe_browsing/incident_reporting/incident_receiver.h" #include "chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_incident.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/common/safe_browsing/csd.pb.h" @@ -20,7 +21,7 @@ namespace { void VerifyVariationsSeedSignatureOnUIThread( - const AddIncidentCallback& callback) { + scoped_ptr<IncidentReceiver> incident_receiver) { chrome_variations::VariationsService* variations_service = g_browser_process->variations_service(); if (!variations_service) @@ -33,7 +34,7 @@ variations_seed_signature( new ClientIncidentReport_IncidentData_VariationsSeedSignatureIncident()); variations_seed_signature->set_variations_seed_signature(invalid_signature); - callback.Run(make_scoped_ptr( + incident_receiver->AddIncidentForProcess(make_scoped_ptr( new VariationsSeedSignatureIncident(variations_seed_signature.Pass()))); } } @@ -48,11 +49,13 @@ base::Bind(&VerifyVariationsSeedSignature)); } -void VerifyVariationsSeedSignature(const AddIncidentCallback& callback) { +void VerifyVariationsSeedSignature( + scoped_ptr<IncidentReceiver> incident_receiver) { content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, - base::Bind(&VerifyVariationsSeedSignatureOnUIThread, callback)); + base::Bind(&VerifyVariationsSeedSignatureOnUIThread, + base::Passed(&incident_receiver))); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h b/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h index 9a56a5a..042efe2d 100644 --- a/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h +++ b/chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h
@@ -5,18 +5,21 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_VARIATIONS_SEED_SIGNATURE_ANALYZER_H_ #define CHROME_BROWSER_SAFE_BROWSING_INCIDENT_REPORTING_VARIATIONS_SEED_SIGNATURE_ANALYZER_H_ +#include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" -#include "chrome/browser/safe_browsing/incident_reporting/add_incident_callback.h" namespace safe_browsing { +class IncidentReceiver; + // Registers a process-wide analysis with the incident reporting service that // will verify the variations seed signature. void RegisterVariationsSeedSignatureAnalysis(); // Callback to pass to the incident reporting service. The incident reporting // service will verify if the variations seed signature is invalid. -void VerifyVariationsSeedSignature(const AddIncidentCallback& callback); +void VerifyVariationsSeedSignature( + scoped_ptr<IncidentReceiver> incident_receiver); } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc index 0515ecd..67f2cc4 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -175,15 +175,17 @@ interstitial_reason_ = SB_REASON_PHISHING; // This must be done after calculating |interstitial_reason_| above. - uma_helper_.reset(new SecurityInterstitialUmaHelper( - web_contents, request_url(), - GetHistogramPrefix(), GetSamplingEventName())); - uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::SHOW); - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::TOTAL_VISITS); + // Use same prefix for UMA as for Rappor. + metrics_helper_.reset(new SecurityInterstitialMetricsHelper( + web_contents, request_url(), GetMetricPrefix(), GetMetricPrefix(), + SecurityInterstitialMetricsHelper::REPORT_RAPPOR, + GetSamplingEventName())); + metrics_helper_->RecordUserDecision(SecurityInterstitialMetricsHelper::SHOW); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::TOTAL_VISITS); if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) { - uma_helper_->RecordUserDecision( - SecurityInterstitialUmaHelper::PROCEEDING_DISABLED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::PROCEEDING_DISABLED); } if (!is_main_frame_load_blocked_) { @@ -239,8 +241,8 @@ if (command == kLearnMoreCommand) { // User pressed "Learn more". - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_LEARN_MORE); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); GURL learn_more_url( interstitial_reason_ == SB_REASON_PHISHING ? kLearnMorePhishingUrlV2 : kLearnMoreMalwareUrlV2); @@ -257,8 +259,8 @@ if (command == kShowPrivacyCommand) { // User pressed "Safe Browsing privacy policy". - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_PRIVACY_POLICY); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_PRIVACY_POLICY); GURL privacy_url( l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)); privacy_url = google_util::AppendGoogleLocaleParam( @@ -277,7 +279,8 @@ if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) { proceed_blocked = true; } else { - uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::PROCEED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::PROCEED); interstitial_page()->Proceed(); // |this| has been deleted after Proceed() returns. return; @@ -333,8 +336,8 @@ std::string bad_url_spec = unsafe_resources_[element_index].url.spec(); if (command == kShowDiagnosticCommand) { // We're going to take the user to Google's SafeBrowsing diagnostic page. - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_DIAGNOSTIC); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_DIAGNOSTIC); std::string diagnostic = base::StringPrintf(kSbDiagnosticUrl, net::EscapeQueryParamValue(bad_url_spec, true).c_str()); @@ -355,8 +358,8 @@ } if (command == kExpandedSeeMoreCommand) { - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_ADVANCED); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_ADVANCED); return; } @@ -421,8 +424,8 @@ return; if (!IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) { - uma_helper_->RecordUserDecision( - SecurityInterstitialUmaHelper::DONT_PROCEED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::DONT_PROCEED); } // Send the malware details, if we opted to. @@ -555,7 +558,7 @@ return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource; } -std::string SafeBrowsingBlockingPage::GetHistogramPrefix() const { +std::string SafeBrowsingBlockingPage::GetMetricPrefix() const { switch (interstitial_reason_) { case SB_REASON_MALWARE: return "malware";
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h index 27ee2e6..424e5167 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -34,8 +34,8 @@ #include "base/gtest_prod_util.h" #include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/interstitials/security_interstitial_metrics_helper.h" #include "chrome/browser/interstitials/security_interstitial_page.h" -#include "chrome/browser/interstitials/security_interstitial_uma_helper.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "url/gurl.h" @@ -191,10 +191,10 @@ void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data); void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data); - std::string GetHistogramPrefix() const; + std::string GetMetricPrefix() const; std::string GetSamplingEventName() const; - scoped_ptr<SecurityInterstitialUmaHelper> uma_helper_; + scoped_ptr<SecurityInterstitialMetricsHelper> metrics_helper_; DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage); };
diff --git a/chrome/browser/search/contextual_search_promo_source_android.h b/chrome/browser/search/contextual_search_promo_source_android.h index 1a2319f6..4ed5bbb 100644 --- a/chrome/browser/search/contextual_search_promo_source_android.h +++ b/chrome/browser/search/contextual_search_promo_source_android.h
@@ -13,20 +13,19 @@ class ContextualSearchPromoSourceAndroid : public content::URLDataSource { public: ContextualSearchPromoSourceAndroid(); - virtual ~ContextualSearchPromoSourceAndroid(); + ~ContextualSearchPromoSourceAndroid() override; protected: // Overridden from content::URLDataSource: - virtual void StartDataRequest( + void StartDataRequest( const std::string& path_and_query, int render_process_id, int render_frame_id, const content::URLDataSource::GotDataCallback& callback) override; - virtual std::string GetSource() const override; - virtual std::string GetMimeType( - const std::string& path_and_query) const override; - virtual bool ShouldDenyXFrameOptions() const override; - virtual bool ShouldAddContentSecurityPolicy() const override; + std::string GetSource() const override; + std::string GetMimeType(const std::string& path_and_query) const override; + bool ShouldDenyXFrameOptions() const override; + bool ShouldAddContentSecurityPolicy() const override; // Sends unmodified resource bytes. void SendResource(
diff --git a/chrome/browser/search/search_android_unittest.cc b/chrome/browser/search/search_android_unittest.cc index 7c30dcb..5b8004ba 100644 --- a/chrome/browser/search/search_android_unittest.cc +++ b/chrome/browser/search/search_android_unittest.cc
@@ -25,7 +25,7 @@ class SearchUtilTest : public testing::Test { protected: - virtual void SetUp() { + void SetUp() override { field_trial_list_.reset(new base::FieldTrialList( new metrics::SHA1EntropyProvider("42"))); base::StatisticsRecorder::Initialize();
diff --git a/chrome/browser/search_engines/template_url_service_android.h b/chrome/browser/search_engines/template_url_service_android.h index 8c4971f0..7d94432 100644 --- a/chrome/browser/search_engines/template_url_service_android.h +++ b/chrome/browser/search_engines/template_url_service_android.h
@@ -56,7 +56,7 @@ static bool Register(JNIEnv* env); private: - ~TemplateUrlServiceAndroid(); + ~TemplateUrlServiceAndroid() override; bool IsPrepopulatedTemplate(TemplateURL* url);
diff --git a/chrome/browser/search_engines/ui_thread_search_terms_data.cc b/chrome/browser/search_engines/ui_thread_search_terms_data.cc index 813aa33..067a2863 100644 --- a/chrome/browser/search_engines/ui_thread_search_terms_data.cc +++ b/chrome/browser/search_engines/ui_thread_search_terms_data.cc
@@ -10,7 +10,7 @@ #include "base/prefs/pref_service.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/google/google_brand.h" -#include "chrome/browser/google/google_profile_helper.h" +#include "chrome/browser/google/google_url_tracker_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_service.h" #include "chrome/browser/search/instant_service_factory.h" @@ -19,6 +19,7 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_version_info.h" +#include "components/google/core/browser/google_url_tracker.h" #include "components/google/core/browser/google_util.h" #include "components/omnibox/omnibox_field_trial.h" #include "components/search/search.h" @@ -49,9 +50,14 @@ GURL base_url(google_util::CommandLineGoogleBaseURL()); if (base_url.is_valid()) return base_url.spec(); - return profile_ ? - google_profile_helper::GetGoogleHomePageURL(profile_).spec() : - SearchTermsData::GoogleBaseURLValue(); + + if (!profile_) + return SearchTermsData::GoogleBaseURLValue(); + + const GoogleURLTracker* tracker = + GoogleURLTrackerFactory::GetForProfile(profile_); + return tracker ? + tracker->google_url().spec() : GoogleURLTracker::kDefaultGoogleHomepage; } std::string UIThreadSearchTermsData::GetApplicationLocale() const {
diff --git a/chrome/browser/services/gcm/push_messaging_browsertest.cc b/chrome/browser/services/gcm/push_messaging_browsertest.cc index 5b20c30..b244392d 100644 --- a/chrome/browser/services/gcm/push_messaging_browsertest.cc +++ b/chrome/browser/services/gcm/push_messaging_browsertest.cc
@@ -30,6 +30,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" +#include "ui/base/window_open_disposition.h" namespace gcm { @@ -170,10 +171,16 @@ } bool RunScript(const std::string& script, std::string* result) { - return content::ExecuteScriptAndExtractString( - browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), - script, - result); + return RunScript(script, result, nullptr); + } + + bool RunScript(const std::string& script, std::string* result, + content::WebContents* web_contents) { + if (!web_contents) + web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + return content::ExecuteScriptAndExtractString(web_contents->GetMainFrame(), + script, + result); } void TryToRegisterSuccessfully( @@ -486,12 +493,30 @@ notification_manager()->CancelAll(); ASSERT_EQ(0u, notification_manager()->GetNotificationCount()); - // If the Service Worker push event handler shows a notification, we should - // not show a forced one. + // We'll need to specify the web_contents in which to eval script, since we're + // going to run script in a background tab. + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // If the site is visible in an active tab, we should not force a notification + // to be shown. GCMClient::IncomingMessage message; - message.data["data"] = "shownotification"; + message.data["data"] = "testdata"; push_service()->OnMessage(app_id.ToString(), message); ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result)); + EXPECT_EQ("testdata", script_result); + ASSERT_EQ(0u, notification_manager()->GetNotificationCount()); + + // Open a blank foreground tab so site is no longer visible. + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL("about:blank"), NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + + // If the Service Worker push event handler shows a notification, we should + // not show a forced one. + message.data["data"] = "shownotification"; + push_service()->OnMessage(app_id.ToString(), message); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); EXPECT_EQ("shownotification", script_result); ASSERT_EQ(1u, notification_manager()->GetNotificationCount()); EXPECT_EQ(base::ASCIIToUTF16("push_test_tag"), @@ -504,7 +529,7 @@ // notification, we should show a forced one. message.data["data"] = "testdata"; push_service()->OnMessage(app_id.ToString(), message); - ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result)); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); EXPECT_EQ("testdata", script_result); ASSERT_EQ(1u, notification_manager()->GetNotificationCount()); EXPECT_EQ(base::ASCIIToUTF16(kPushMessagingForcedNotificationTag), @@ -514,7 +539,7 @@ // explicitly dismisses it (though we may change this later). message.data["data"] = "shownotification"; push_service()->OnMessage(app_id.ToString(), message); - ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result)); + ASSERT_TRUE(RunScript("resultQueue.pop()", &script_result, web_contents)); EXPECT_EQ("shownotification", script_result); ASSERT_EQ(2u, notification_manager()->GetNotificationCount()); }
diff --git a/chrome/browser/services/gcm/push_messaging_service_impl.cc b/chrome/browser/services/gcm/push_messaging_service_impl.cc index 6a59cbe6..6722e11 100644 --- a/chrome/browser/services/gcm/push_messaging_service_impl.cc +++ b/chrome/browser/services/gcm/push_messaging_service_impl.cc
@@ -33,9 +33,19 @@ #include "content/public/common/child_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/common/platform_notification_data.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_ANDROID) +#include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#else +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_iterator.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#endif + namespace gcm { namespace { @@ -243,6 +253,51 @@ if (notification_count > 0) return; + // Sites with a currently visible tab don't need to show notifications. +#if defined(OS_ANDROID) + for (auto it = TabModelList::begin(); it != TabModelList::end(); ++it) { + Profile* profile = (*it)->GetProfile(); + content::WebContents* active_web_contents = + (*it)->GetActiveWebContents(); +#else + for (chrome::BrowserIterator it; !it.done(); it.Next()) { + Profile* profile = it->profile(); + content::WebContents* active_web_contents = + it->tab_strip_model()->GetActiveWebContents(); +#endif + if (!active_web_contents) + continue; + + // Don't leak information from other profiles. + if (profile != profile_) + continue; + + // Ignore minimized windows etc. + switch (active_web_contents->GetMainFrame()->GetVisibilityState()) { + case blink::WebPageVisibilityStateHidden: + case blink::WebPageVisibilityStatePrerender: + continue; + case blink::WebPageVisibilityStateVisible: + break; + } + + // Use the visible URL since that's the one the user is aware of (and it + // doesn't matter whether the page loaded successfully). + const GURL& active_url = active_web_contents->GetVisibleURL(); + + // Allow https://foo.example.com Service Worker to not show notification if + // an https://bar.example.com tab is visible (and hence might conceivably + // be showing UI in response to the push message); but http:// doesn't count + // as the Service Worker can't talk to it, even with navigator.connect. + if (application_id.origin.scheme() != active_url.scheme()) + continue; + if (net::registry_controlled_domains::SameDomainOrHost( + application_id.origin, active_url, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) { + return; + } + } + // If we haven't returned yet, the site failed to show a notification, so we // will show a generic notification. See https://crbug.com/437277 // TODO(johnme): The generic notification should probably automatically close
diff --git a/chrome/browser/sessions/in_memory_tab_restore_service.h b/chrome/browser/sessions/in_memory_tab_restore_service.h index 78557cd..deef49c2 100644 --- a/chrome/browser/sessions/in_memory_tab_restore_service.h +++ b/chrome/browser/sessions/in_memory_tab_restore_service.h
@@ -22,30 +22,29 @@ InMemoryTabRestoreService(Profile* profile, TimeFactory* time_factory); - virtual ~InMemoryTabRestoreService(); + ~InMemoryTabRestoreService() override; // TabRestoreService: - virtual void AddObserver(TabRestoreServiceObserver* observer) override; - virtual void RemoveObserver(TabRestoreServiceObserver* observer) override; - virtual void CreateHistoricalTab(content::WebContents* contents, - int index) override; - virtual void BrowserClosing(TabRestoreServiceDelegate* delegate) override; - virtual void BrowserClosed(TabRestoreServiceDelegate* delegate) override; - virtual void ClearEntries() override; - virtual const Entries& entries() const override; - virtual std::vector<content::WebContents*> RestoreMostRecentEntry( + void AddObserver(TabRestoreServiceObserver* observer) override; + void RemoveObserver(TabRestoreServiceObserver* observer) override; + void CreateHistoricalTab(content::WebContents* contents, int index) override; + void BrowserClosing(TabRestoreServiceDelegate* delegate) override; + void BrowserClosed(TabRestoreServiceDelegate* delegate) override; + void ClearEntries() override; + const Entries& entries() const override; + std::vector<content::WebContents*> RestoreMostRecentEntry( TabRestoreServiceDelegate* delegate, chrome::HostDesktopType host_desktop_type) override; - virtual Tab* RemoveTabEntryById(SessionID::id_type id) override; - virtual std::vector<content::WebContents*> - RestoreEntryById(TabRestoreServiceDelegate* delegate, - SessionID::id_type id, - chrome::HostDesktopType host_desktop_type, - WindowOpenDisposition disposition) override; - virtual void LoadTabsFromLastSession() override; - virtual bool IsLoaded() const override; - virtual void DeleteLastSession() override; - virtual void Shutdown() override; + Tab* RemoveTabEntryById(SessionID::id_type id) override; + std::vector<content::WebContents*> RestoreEntryById( + TabRestoreServiceDelegate* delegate, + SessionID::id_type id, + chrome::HostDesktopType host_desktop_type, + WindowOpenDisposition disposition) override; + void LoadTabsFromLastSession() override; + bool IsLoaded() const override; + void DeleteLastSession() override; + void Shutdown() override; private: TabRestoreServiceHelper helper_;
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.cc b/chrome/browser/signin/android_profile_oauth2_token_service.cc index abccb27..e62353cb 100644 --- a/chrome/browser/signin/android_profile_oauth2_token_service.cc +++ b/chrome/browser/signin/android_profile_oauth2_token_service.cc
@@ -39,13 +39,13 @@ public: AndroidAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, const std::string& account_id); - virtual ~AndroidAccessTokenFetcher(); + ~AndroidAccessTokenFetcher() override; // Overrides from OAuth2AccessTokenFetcher: - virtual void Start(const std::string& client_id, - const std::string& client_secret, - const std::vector<std::string>& scopes) override; - virtual void CancelRequest() override; + void Start(const std::string& client_id, + const std::string& client_secret, + const std::vector<std::string>& scopes) override; + void CancelRequest() override; // Handles an access token response. void OnAccessTokenResponse(const GoogleServiceAuthError& error,
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.h b/chrome/browser/signin/android_profile_oauth2_token_service.h index cae22f71..f4cb0a5 100644 --- a/chrome/browser/signin/android_profile_oauth2_token_service.h +++ b/chrome/browser/signin/android_profile_oauth2_token_service.h
@@ -44,15 +44,12 @@ } // ProfileOAuth2TokenService overrides: - virtual void Initialize( - SigninClient* client, - SigninErrorController* signin_error_controller) override; - virtual bool RefreshTokenIsAvailable( - const std::string& account_id) const override; - virtual void UpdateAuthError( - const std::string& account_id, - const GoogleServiceAuthError& error) override; - virtual std::vector<std::string> GetAccounts() override; + void Initialize(SigninClient* client, + SigninErrorController* signin_error_controller) override; + bool RefreshTokenIsAvailable(const std::string& account_id) const override; + void UpdateAuthError(const std::string& account_id, + const GoogleServiceAuthError& error) override; + std::vector<std::string> GetAccounts() override; // Lists account at the OS level. std::vector<std::string> GetSystemAccounts(); @@ -86,32 +83,31 @@ // Overridden from OAuth2TokenService to complete signout of all // OA2TService aware accounts. - virtual void RevokeAllCredentials() override; + void RevokeAllCredentials() override; protected: friend class ProfileOAuth2TokenServiceFactory; AndroidProfileOAuth2TokenService(); - virtual ~AndroidProfileOAuth2TokenService(); + ~AndroidProfileOAuth2TokenService() override; - virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher( + OAuth2AccessTokenFetcher* CreateAccessTokenFetcher( const std::string& account_id, net::URLRequestContextGetter* getter, OAuth2AccessTokenConsumer* consumer) override; // Overridden from OAuth2TokenService to intercept token fetch requests and // redirect them to the Account Manager. - virtual void InvalidateOAuth2Token(const std::string& account_id, - const std::string& client_id, - const ScopeSet& scopes, - const std::string& access_token) override; + void InvalidateOAuth2Token(const std::string& account_id, + const std::string& client_id, + const ScopeSet& scopes, + const std::string& access_token) override; // Called to notify observers when a refresh token is available. - virtual void FireRefreshTokenAvailable( - const std::string& account_id) override; + void FireRefreshTokenAvailable(const std::string& account_id) override; // Called to notify observers when a refresh token has been revoked. - virtual void FireRefreshTokenRevoked(const std::string& account_id) override; + void FireRefreshTokenRevoked(const std::string& account_id) override; // Called to notify observers when refresh tokans have been loaded. - virtual void FireRefreshTokensLoaded() override; + void FireRefreshTokensLoaded() override; private: // Return whether |signed_in_account| is valid and we have access
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc index d3d2746..3315642 100644 --- a/chrome/browser/signin/chrome_signin_client.cc +++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -248,7 +248,7 @@ #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) // Don't store password hash except when lock is available for the user. if (!password.empty() && profiles::IsLockAvailable(profile_)) - chrome::SetLocalAuthCredentials(profile_, password); + LocalAuth::SetLocalAuthCredentials(profile_, password); #endif }
diff --git a/chrome/browser/signin/local_auth.cc b/chrome/browser/signin/local_auth.cc index 7748898..9b20c322 100644 --- a/chrome/browser/signin/local_auth.cc +++ b/chrome/browser/signin/local_auth.cc
@@ -22,21 +22,81 @@ namespace { +struct HashEncoding { + char version; + unsigned hash_bits; + unsigned hash_bytes; + unsigned iteration_count; + unsigned stored_bits; + unsigned stored_bytes; + + public: + HashEncoding(char version, + unsigned hash_bits, + unsigned hash_bytes, + unsigned iteration_count, + unsigned stored_bits, + unsigned stored_bytes) : + version(version), + hash_bits(hash_bits), + hash_bytes(hash_bytes), + iteration_count(iteration_count), + stored_bits(stored_bits), + stored_bytes(stored_bytes) {} +}; + // WARNING: Changing these values will make it impossible to do off-line // authentication until the next successful on-line authentication. To change -// these safely, change the "encoding" version below and make verification -// handle multiple values. -const char kHash1Encoding = '1'; +// these safely, add a new HashEncoding object below and increment +// NUM_HASH_ENCODINGS. +const char kHash1Version = '1'; const unsigned kHash1Bits = 256; const unsigned kHash1Bytes = kHash1Bits / 8; const unsigned kHash1IterationCount = 100000; +// Store 13 bits to provide pin-like security (8192 possible values), without +// providing a complete oracle for the user's GAIA password. +const char kHash2Version = '2'; +const unsigned kHash2Bits = 256; +const unsigned kHash2Bytes = kHash2Bits / 8; +const unsigned kHash2IterationCount = 100000; +const unsigned kHash2StoredBits = 13; +const unsigned kHash2StoredBytes = (kHash2StoredBits + 7) / 8; + +const int NUM_HASH_ENCODINGS = 2; +HashEncoding encodings[NUM_HASH_ENCODINGS] = { + HashEncoding( + kHash1Version, kHash1Bits, kHash1Bytes, kHash1IterationCount, 0, 0), + HashEncoding( + kHash2Version, kHash2Bits, kHash2Bytes, kHash2IterationCount, + kHash2StoredBits, kHash2StoredBytes) +}; + +const HashEncoding* GetEncodingForVersion(char version) { + // Note that versions are 1-indexed. + DCHECK(version > '0' && version <= ('0' + NUM_HASH_ENCODINGS)); + return &encodings[(version - '0') - 1]; +} + +std::string TruncateStringByBits(const std::string& str, + const size_t len_bits) { + if (len_bits % 8 == 0) + return str.substr(0, len_bits / 8); + + // The initial truncation copies whole bytes + int number_bytes = (len_bits + 7) / 8; + std::string truncated_string = str.substr(0, number_bytes); + + // Keep the prescribed number of bits from the last byte. + unsigned last_char_bitmask = (1 << (len_bits % 8)) - 1; + truncated_string[number_bytes - 1] &= last_char_bitmask; + return truncated_string; +} + std::string CreateSecurePasswordHash(const std::string& salt, const std::string& password, - char encoding) { - DCHECK_EQ(kHash1Bytes, salt.length()); - DCHECK_EQ(kHash1Encoding, encoding); // Currently support only one method. - + const HashEncoding& encoding) { + DCHECK_EQ(encoding.hash_bytes, salt.length()); base::Time start_time = base::Time::Now(); // Library call to create secure password hash as SymmetricKey (uses PBKDF2). @@ -44,22 +104,26 @@ crypto::SymmetricKey::DeriveKeyFromPassword( crypto::SymmetricKey::AES, password, salt, - kHash1IterationCount, kHash1Bits)); + encoding.iteration_count, encoding.hash_bits)); std::string password_hash; const bool success = password_key->GetRawKey(&password_hash); DCHECK(success); - DCHECK_EQ(kHash1Bytes, password_hash.length()); + DCHECK_EQ(encoding.hash_bytes, password_hash.length()); UMA_HISTOGRAM_TIMES("PasswordHash.CreateTime", base::Time::Now() - start_time); + if (encoding.stored_bits) { + password_hash = TruncateStringByBits(password_hash, encoding.stored_bits); + DCHECK_EQ(encoding.stored_bytes, password_hash.length()); + } + DCHECK_EQ(encoding.stored_bytes ? encoding.stored_bytes : encoding.hash_bytes, + password_hash.length()); return password_hash; } std::string EncodePasswordHashRecord(const std::string& record, - char encoding) { - DCHECK_EQ(kHash1Encoding, encoding); // Currently support only one method. - + const HashEncoding& encoding) { // Encrypt the hash using the OS account-password protection (if available). std::string encoded; const bool success = OSCrypt::EncryptString(record, &encoded); @@ -70,7 +134,7 @@ base::Base64Encode(encoded, &encoded64); // Stuff the "encoding" value into the first byte. - encoded64.insert(0, &encoding, sizeof(encoding)); + encoded64.insert(0, &encoding.version, sizeof(encoding.version)); return encoded64; } @@ -82,7 +146,7 @@ if (encoded.length() < 1) return false; *encoding = encoded[0]; - if (*encoding != kHash1Encoding) + if (!GetEncodingForVersion(*encoding)) return false; // Stored record is base64; convert to binary. @@ -104,33 +168,33 @@ } // namespace -namespace chrome { +std::string LocalAuth::TruncateStringByBits(const std::string& str, + const size_t len_bits) { + return ::TruncateStringByBits(str, len_bits); +} -void RegisterLocalAuthPrefs(user_prefs::PrefRegistrySyncable* registry) { +void LocalAuth::RegisterLocalAuthPrefs( + user_prefs::PrefRegistrySyncable* registry) { registry->RegisterStringPref( prefs::kGoogleServicesPasswordHash, std::string(), user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); } -void SetLocalAuthCredentials(size_t info_index, - const std::string& password) { - if (info_index == std::string::npos) { - NOTREACHED(); - return; - } - DCHECK(password.length()); +void LocalAuth::SetLocalAuthCredentialsWithEncoding(size_t info_index, + const std::string& password, + char encoding_version) { + const HashEncoding& encoding = encodings[(encoding_version - '0') - 1]; // Salt should be random data, as long as the hash length, and different with // every save. std::string salt_str; - crypto::RandBytes(WriteInto(&salt_str, kHash1Bytes + 1), kHash1Bytes); - DCHECK_EQ(kHash1Bytes, salt_str.length()); + crypto::RandBytes(WriteInto(&salt_str, encoding.hash_bytes + 1), + encoding.hash_bytes); // Perform secure hash of password for storage. std::string password_hash = CreateSecurePasswordHash( - salt_str, password, kHash1Encoding); - DCHECK_EQ(kHash1Bytes, password_hash.length()); + salt_str, password, encoding); // Group all fields into a single record for storage; std::string record; @@ -138,19 +202,30 @@ record.append(password_hash); // Encode it and store it. - std::string encoded = EncodePasswordHashRecord(record, kHash1Encoding); + std::string encoded = EncodePasswordHashRecord(record, encoding); ProfileInfoCache& info = g_browser_process->profile_manager()->GetProfileInfoCache(); info.SetLocalAuthCredentialsOfProfileAtIndex(info_index, encoded); } -void SetLocalAuthCredentials(const Profile* profile, - const std::string& password) { +void LocalAuth::SetLocalAuthCredentials(size_t info_index, + const std::string& password) { + if (info_index == std::string::npos) { + NOTREACHED(); + return; + } + DCHECK(password.length()); + SetLocalAuthCredentialsWithEncoding( + info_index, password, '0' + NUM_HASH_ENCODINGS); +} + +void LocalAuth::SetLocalAuthCredentials(const Profile* profile, + const std::string& password) { SetLocalAuthCredentials(GetProfileInfoIndexOfProfile(profile), password); } -bool ValidateLocalAuthCredentials(size_t info_index, - const std::string& password) { +bool LocalAuth::ValidateLocalAuthCredentials(size_t info_index, + const std::string& password) { if (info_index == std::string::npos) { NOTREACHED(); return false; @@ -174,28 +249,31 @@ const char* password_check; size_t password_length; - if (encoding == '1') { - // Validate correct length; extract salt and password hash. - if (record.length() != 2 * kHash1Bytes) - return false; - std::string salt_str(record.data(), kHash1Bytes); - password_saved = record.data() + kHash1Bytes; - password_hash = CreateSecurePasswordHash(salt_str, password, encoding); - password_check = password_hash.data(); - password_length = kHash1Bytes; - } else { - // unknown encoding + const HashEncoding* hash_encoding = GetEncodingForVersion(encoding); + if (!hash_encoding) { + // Unknown encoding. return false; } - return crypto::SecureMemEqual(password_saved, password_check, - password_length); + // Extract salt. + std::string salt_str(record.data(), hash_encoding->hash_bytes); + // Extract password. + password_saved = record.data() + hash_encoding->hash_bytes; + password_hash = CreateSecurePasswordHash(salt_str, password, *hash_encoding); + password_length = hash_encoding->stored_bytes; + password_check = password_hash.data(); + + bool passwords_match = crypto::SecureMemEqual( + password_saved, password_check, password_length); + + // Update the stored credentials to the latest encoding if necessary. + if (passwords_match && (hash_encoding->version - '0') != NUM_HASH_ENCODINGS) + SetLocalAuthCredentials(info_index, password); + return passwords_match; } -bool ValidateLocalAuthCredentials(const Profile* profile, - const std::string& password) { +bool LocalAuth::ValidateLocalAuthCredentials(const Profile* profile, + const std::string& password) { return ValidateLocalAuthCredentials(GetProfileInfoIndexOfProfile(profile), password); } - -} // namespace chrome
diff --git a/chrome/browser/signin/local_auth.h b/chrome/browser/signin/local_auth.h index 2342a81..570b5bc3 100644 --- a/chrome/browser/signin/local_auth.h +++ b/chrome/browser/signin/local_auth.h
@@ -11,28 +11,46 @@ #include <string> +#include "base/gtest_prod_util.h" + +class LocalAuthTest; class Profile; namespace user_prefs { class PrefRegistrySyncable; } -namespace chrome { +class LocalAuth { + public: + static void RegisterLocalAuthPrefs( + user_prefs::PrefRegistrySyncable* registry); -void RegisterLocalAuthPrefs(user_prefs::PrefRegistrySyncable* registry); + static void SetLocalAuthCredentials(size_t profile_info_index, + const std::string& password); -void SetLocalAuthCredentials(size_t profile_info_index, - const std::string& password); -void SetLocalAuthCredentials(const Profile* profile, - const std::string& password); + static void SetLocalAuthCredentials(const Profile* profile, + const std::string& password); -bool ValidateLocalAuthCredentials(size_t profile_info_index, - const std::string& password); + static bool ValidateLocalAuthCredentials(size_t profile_info_index, + const std::string& password); -bool ValidateLocalAuthCredentials(const Profile* profile, - const std::string& password); + static bool ValidateLocalAuthCredentials(const Profile* profile, + const std::string& password); -} // namespace chrome + private: + FRIEND_TEST_ALL_PREFIXES(LocalAuthTest, SetUpgradeAndCheckCredentials); + FRIEND_TEST_ALL_PREFIXES(LocalAuthTest, TruncateStringEvenly); + FRIEND_TEST_ALL_PREFIXES(LocalAuthTest, TruncateStringUnevenly); + + // Return only the first |len_bits| bits of the string |str|. Defined here for + // testing. + static std::string TruncateStringByBits(const std::string& str, + const size_t len_bits); + + static void SetLocalAuthCredentialsWithEncoding(size_t profile_info_index, + const std::string& password, + char encoding_version); +}; #endif // CHROME_BROWSER_SIGNIN_LOCAL_AUTH_H_
diff --git a/chrome/browser/signin/local_auth_unittest.cc b/chrome/browser/signin/local_auth_unittest.cc index 68ee397..14aea881 100644 --- a/chrome/browser/signin/local_auth_unittest.cc +++ b/chrome/browser/signin/local_auth_unittest.cc
@@ -15,8 +15,6 @@ #include "testing/gtest/include/gtest/gtest.h" -using namespace chrome; - TEST(LocalAuthTest, SetAndCheckCredentials) { TestingProfileManager testing_profile_manager( TestingBrowserProcess::GetGlobal()); @@ -32,9 +30,9 @@ #endif std::string password("Some Password"); - EXPECT_FALSE(ValidateLocalAuthCredentials(prof, password)); + EXPECT_FALSE(LocalAuth::ValidateLocalAuthCredentials(prof, password)); - SetLocalAuthCredentials(prof, password); + LocalAuth::SetLocalAuthCredentials(prof, password); std::string passhash = cache.GetLocalAuthCredentialsOfProfileAtIndex(0); // We perform basic validation on the written record to ensure bugs don't slip @@ -42,7 +40,7 @@ // - The encoding exists (we can guarantee future backward compatibility). // - The plaintext version of the password is not mistakenly stored anywhere. EXPECT_FALSE(passhash.empty()); - EXPECT_EQ('1', passhash[0]); + EXPECT_EQ('2', passhash[0]); EXPECT_EQ(passhash.find(password), std::string::npos); std::string decodedhash; @@ -50,9 +48,68 @@ EXPECT_FALSE(decodedhash.empty()); EXPECT_EQ(decodedhash.find(password), std::string::npos); - EXPECT_TRUE(ValidateLocalAuthCredentials(prof, password)); - EXPECT_FALSE(ValidateLocalAuthCredentials(prof, password + "1")); + EXPECT_TRUE(LocalAuth::ValidateLocalAuthCredentials(prof, password)); + EXPECT_FALSE(LocalAuth::ValidateLocalAuthCredentials(prof, password + "1")); - SetLocalAuthCredentials(prof, password); // makes different salt + LocalAuth::SetLocalAuthCredentials(prof, password); // makes different salt EXPECT_NE(passhash, cache.GetLocalAuthCredentialsOfProfileAtIndex(0)); } + + +TEST(LocalAuthTest, SetUpgradeAndCheckCredentials) { + TestingProfileManager testing_profile_manager( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(testing_profile_manager.SetUp()); + Profile* prof = testing_profile_manager.CreateTestingProfile("p1"); + ProfileInfoCache& cache = + testing_profile_manager.profile_manager()->GetProfileInfoCache(); + +#if defined(OS_MACOSX) + OSCrypt::UseMockKeychain(true); +#endif + + std::string password("Some Password"); + size_t profile_index = cache.GetIndexOfProfileWithPath(prof->GetPath()); + LocalAuth::SetLocalAuthCredentialsWithEncoding(profile_index, password, '1'); + + // Ensure we indeed persisted the correct encoding. + std::string oldpasshash = cache.GetLocalAuthCredentialsOfProfileAtIndex( + profile_index); + EXPECT_EQ('1', oldpasshash[0]); + + // Validate, ensure we can validate against the old encoding. + EXPECT_TRUE(LocalAuth::ValidateLocalAuthCredentials(prof, password)); + + // Ensure we updated the encoding. + std::string newpasshash = cache.GetLocalAuthCredentialsOfProfileAtIndex( + profile_index); + EXPECT_EQ('2', newpasshash[0]); + // Encoding '2' writes fewer bytes than encoding '1'. + EXPECT_LE(newpasshash.length(), oldpasshash.length()); + + // Validate, ensure we validate against the new encoding. + EXPECT_TRUE(LocalAuth::ValidateLocalAuthCredentials(prof, password)); +} + +// Test truncation where each byte is left whole. +TEST(LocalAuthTest, TruncateStringEvenly) { + std::string two_chars = "A6"; + std::string three_chars = "A6C"; + EXPECT_EQ(two_chars, LocalAuth::TruncateStringByBits(two_chars, 16)); + EXPECT_EQ(two_chars, LocalAuth::TruncateStringByBits(three_chars, 16)); + + EXPECT_EQ(two_chars, LocalAuth::TruncateStringByBits(two_chars, 14)); + EXPECT_EQ(two_chars, LocalAuth::TruncateStringByBits(three_chars, 14)); +} + +// Test truncation that affects the results within a byte. +TEST(LocalAuthTest, TruncateStringUnevenly) { + std::string two_chars = "Az"; + std::string three_chars = "AzC"; + // 'z' = 0x7A, ':' = 0x3A. + std::string two_chars_truncated = "A:"; + EXPECT_EQ(two_chars_truncated, + LocalAuth::TruncateStringByBits(two_chars, 14)); + EXPECT_EQ(two_chars_truncated, + LocalAuth::TruncateStringByBits(three_chars, 14)); +}
diff --git a/chrome/browser/signin/signin_manager_factory.cc b/chrome/browser/signin/signin_manager_factory.cc index a7915f3..7867c69 100644 --- a/chrome/browser/signin/signin_manager_factory.cc +++ b/chrome/browser/signin/signin_manager_factory.cc
@@ -103,7 +103,7 @@ prefs::kSignedInTime, base::Time().ToInternalValue(), user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); - chrome::RegisterLocalAuthPrefs(registry); + LocalAuth::RegisterLocalAuthPrefs(registry); } // static
diff --git a/chrome/browser/speech/tts_android.h b/chrome/browser/speech/tts_android.h index 898418bb..6dcf02b 100644 --- a/chrome/browser/speech/tts_android.h +++ b/chrome/browser/speech/tts_android.h
@@ -12,18 +12,17 @@ class TtsPlatformImplAndroid : public TtsPlatformImpl { public: // TtsPlatformImpl implementation. - virtual bool PlatformImplAvailable() override; - virtual bool Speak( - int utterance_id, - const std::string& utterance, - const std::string& lang, - const VoiceData& voice, - const UtteranceContinuousParameters& params) override; - virtual bool StopSpeaking() override; - virtual void Pause() override; - virtual void Resume() override; - virtual bool IsSpeaking() override; - virtual void GetVoices(std::vector<VoiceData>* out_voices) override; + bool PlatformImplAvailable() override; + bool Speak(int utterance_id, + const std::string& utterance, + const std::string& lang, + const VoiceData& voice, + const UtteranceContinuousParameters& params) override; + bool StopSpeaking() override; + void Pause() override; + void Resume() override; + bool IsSpeaking() override; + void GetVoices(std::vector<VoiceData>* out_voices) override; // Methods called from Java via JNI. void VoicesChanged(JNIEnv* env, jobject obj); @@ -39,7 +38,7 @@ friend struct DefaultSingletonTraits<TtsPlatformImplAndroid>; TtsPlatformImplAndroid(); - virtual ~TtsPlatformImplAndroid(); + ~TtsPlatformImplAndroid() override; void SendFinalTtsEvent( int utterance_id, TtsEventType event_type, int char_index);
diff --git a/chrome/browser/ssl/captive_portal_blocking_page.cc b/chrome/browser/ssl/captive_portal_blocking_page.cc index 5c954774..9d9d23f 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page.cc
@@ -34,38 +34,44 @@ CAPTIVE_PORTAL_BLOCKING_PAGE_EVENT_COUNT }; +const char kOpenLoginPageCommand[] = "openLoginPage"; + void RecordUMA(CaptivePortalBlockingPageEvent event) { UMA_HISTOGRAM_ENUMERATION("interstitial.captive_portal", event, CAPTIVE_PORTAL_BLOCKING_PAGE_EVENT_COUNT); } -bool IsWifiConnection() { - // |net::NetworkChangeNotifier::GetConnectionType| isn't accurate on Linux and - // Windows. See https://crbug.com/160537 for details. - // TODO(meacer): Add heuristics to get a more accurate connection type on - // these platforms. - return net::NetworkChangeNotifier::GetConnectionType() == - net::NetworkChangeNotifier::CONNECTION_WIFI; -} +class ConnectionInfoDelegate : public CaptivePortalBlockingPage::Delegate { + public: + ConnectionInfoDelegate() {} + ~ConnectionInfoDelegate() override {} -std::string GetWiFiName() { - std::string ssid; + bool IsWifiConnection() const override { + // |net::NetworkChangeNotifier::GetConnectionType| isn't accurate on Linux + // and Windows. See https://crbug.com/160537 for details. + // TODO(meacer): Add heuristics to get a more accurate connection type on + // these platforms. + return net::NetworkChangeNotifier::GetConnectionType() == + net::NetworkChangeNotifier::CONNECTION_WIFI; + } + + std::string GetWiFiSSID() const override { + std::string ssid; #if defined(OS_WIN) || defined(OS_MACOSX) - scoped_ptr<wifi::WiFiService> wifi_service(wifi::WiFiService::Create()); - wifi_service->Initialize(NULL); - std::string error; - wifi_service->GetConnectedNetworkSSID(&ssid, &error); - if (!error.empty()) - return ""; + scoped_ptr<wifi::WiFiService> wifi_service(wifi::WiFiService::Create()); + wifi_service->Initialize(NULL); + std::string error; + wifi_service->GetConnectedNetworkSSID(&ssid, &error); + if (!error.empty()) + return ""; #endif - // TODO(meacer): Handle non UTF8 SSIDs. - if (!base::IsStringUTF8(ssid)) - return ""; - return ssid; -} - -const char kOpenLoginPageCommand[] = "openLoginPage"; + // TODO(meacer): Handle non UTF8 SSIDs. + if (!base::IsStringUTF8(ssid)) + return ""; + return ssid; + } +}; } // namespace @@ -80,7 +86,7 @@ const base::Callback<void(bool)>& callback) : SecurityInterstitialPage(web_contents, request_url), login_url_(login_url), - is_wifi_connection_(IsWifiConnection()), + delegate_(new ConnectionInfoDelegate), callback_(callback) { DCHECK(login_url_.is_valid()); RecordUMA(SHOW_ALL); @@ -109,81 +115,67 @@ load_time_data->SetString("type", "CAPTIVE_PORTAL"); load_time_data->SetBoolean("overridable", false); + // |IsWifiConnection| isn't accurate on some platforms, so always try to get + // the Wi-Fi SSID even if |IsWifiConnection| is false. + std::string wifi_ssid = delegate_.get()->GetWiFiSSID(); + bool is_wifi_connection = !wifi_ssid.empty() || + delegate_.get()->IsWifiConnection(); + load_time_data->SetString( "primaryButtonText", l10n_util::GetStringUTF16(IDS_CAPTIVE_PORTAL_BUTTON_OPEN_LOGIN_PAGE)); - load_time_data->SetString("tabTitle", - l10n_util::GetStringUTF16( - is_wifi_connection_ ? - IDS_CAPTIVE_PORTAL_HEADING_WIFI : - IDS_CAPTIVE_PORTAL_HEADING_WIRED)); - load_time_data->SetString("heading", - l10n_util::GetStringUTF16( - is_wifi_connection_ ? - IDS_CAPTIVE_PORTAL_HEADING_WIFI : - IDS_CAPTIVE_PORTAL_HEADING_WIRED)); + load_time_data->SetString( + "tabTitle", l10n_util::GetStringUTF16( + is_wifi_connection ? IDS_CAPTIVE_PORTAL_HEADING_WIFI + : IDS_CAPTIVE_PORTAL_HEADING_WIRED)); + load_time_data->SetString( + "heading", l10n_util::GetStringUTF16( + is_wifi_connection ? IDS_CAPTIVE_PORTAL_HEADING_WIFI + : IDS_CAPTIVE_PORTAL_HEADING_WIRED)); if (login_url_.spec() == captive_portal::CaptivePortalDetector::kDefaultURL) { // Captive portal may intercept requests without HTTP redirects, in which // case the login url would be the same as the captive portal detection url. // Don't show the login url in that case. - if (is_wifi_connection_) { - if (wifi_ssid_.empty()) - wifi_ssid_ = GetWiFiName(); - if (wifi_ssid_.empty()) { - load_time_data->SetString( - "primaryParagraph", - l10n_util::GetStringUTF16( - IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI)); - } else { - load_time_data->SetString( - "primaryParagraph", - l10n_util::GetStringFUTF16( - IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI_SSID, - net::EscapeForHTML(base::UTF8ToUTF16(wifi_ssid_)))); - } - } else { - // Non-WiFi connection: + if (wifi_ssid.empty()) { load_time_data->SetString( "primaryParagraph", l10n_util::GetStringUTF16( - IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIRED)); + is_wifi_connection + ? IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI + : IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIRED)); + } else { + load_time_data->SetString( + "primaryParagraph", + l10n_util::GetStringFUTF16( + IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI_SSID, + net::EscapeForHTML(base::UTF8ToUTF16(wifi_ssid)))); } } else { - // Portal redirection was done with HTTP redirects, show the login URL. + // Portal redirection was done with HTTP redirects, so show the login URL. + // If |languages| is empty, punycode in |login_host| will always be decoded. std::string languages; Profile* profile = Profile::FromBrowserContext( web_contents()->GetBrowserContext()); if (profile) languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); - base::string16 login_host = net::IDNToUnicode(login_url_.host(), languages); if (base::i18n::IsRTL()) base::i18n::WrapStringWithLTRFormatting(&login_host); - if (is_wifi_connection_) { - if (wifi_ssid_.empty()) - wifi_ssid_ = GetWiFiName(); - if (wifi_ssid_.empty()) { - load_time_data->SetString( - "primaryParagraph", - l10n_util::GetStringFUTF16( - IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI, - login_host)); - } else { - load_time_data->SetString( - "primaryParagraph", - l10n_util::GetStringFUTF16( - IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI_SSID, - net::EscapeForHTML(base::UTF8ToUTF16(wifi_ssid_)), - login_host)); - } - } else { - // Non-WiFi connection: + if (wifi_ssid.empty()) { load_time_data->SetString( "primaryParagraph", - l10n_util::GetStringFUTF16(IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIRED, - login_host)); + l10n_util::GetStringFUTF16( + is_wifi_connection ? IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI + : IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIRED, + login_host)); + } else { + load_time_data->SetString( + "primaryParagraph", + l10n_util::GetStringFUTF16( + IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI_SSID, + net::EscapeForHTML(base::UTF8ToUTF16(wifi_ssid)), login_host)); } }
diff --git a/chrome/browser/ssl/captive_portal_blocking_page.h b/chrome/browser/ssl/captive_portal_blocking_page.h index e5cdd897..0b150cb6 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page.h +++ b/chrome/browser/ssl/captive_portal_blocking_page.h
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/interstitials/security_interstitial_page.h" #include "url/gurl.h" @@ -28,6 +29,16 @@ // Interstitial type, for testing. static const void* kTypeForTesting; + class Delegate { + public: + virtual ~Delegate() {} + + // Returns true if the connection is a Wi-Fi connection. + virtual bool IsWifiConnection() const = 0; + // Returns the SSID of the connected Wi-Fi network, if any. + virtual std::string GetWiFiSSID() const = 0; + }; + CaptivePortalBlockingPage(content::WebContents* web_contents, const GURL& request_url, const GURL& login_url, @@ -37,13 +48,7 @@ // SecurityInterstitialPage method: const void* GetTypeForTesting() const override; - void SetWiFiConnectionForTesting(bool is_wifi_connection) { - is_wifi_connection_ = is_wifi_connection; - } - - void SetWiFiSSIDForTesting(const std::string& wifi_ssid) { - wifi_ssid_ = wifi_ssid; - } + void SetDelegateForTesting(Delegate* delegate) { delegate_.reset(delegate); } protected: // SecurityInterstitialPage methods: @@ -57,11 +62,7 @@ private: // URL of the login page, opened when the user clicks the "Connect" button. GURL login_url_; - // True if on a Wi-Fi connection. - bool is_wifi_connection_; - // SSID of the connected network if the connection is a Wi-Fi connection. - std::string wifi_ssid_; - + scoped_ptr<Delegate> delegate_; base::Callback<void(bool)> callback_; DISALLOW_COPY_AND_ASSIGN(CaptivePortalBlockingPage);
diff --git a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc index 857d469..2e6b6cd 100644 --- a/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc +++ b/chrome/browser/ssl/captive_portal_blocking_page_browsertest.cc
@@ -64,6 +64,22 @@ } // namespace +class FakeConnectionInfoDelegate : public CaptivePortalBlockingPage::Delegate { + public: + FakeConnectionInfoDelegate(bool is_wifi_connection, std::string wifi_ssid) + : is_wifi_connection_(is_wifi_connection), wifi_ssid_(wifi_ssid) {} + ~FakeConnectionInfoDelegate() override {} + + bool IsWifiConnection() const override { return is_wifi_connection_; } + std::string GetWiFiSSID() const override { return wifi_ssid_; } + + private: + const bool is_wifi_connection_; + const std::string wifi_ssid_; + + DISALLOW_COPY_AND_ASSIGN(FakeConnectionInfoDelegate); +}; + class CaptivePortalBlockingPageTest : public InProcessBrowserTest { public: CaptivePortalBlockingPageTest() {} @@ -98,11 +114,13 @@ content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); DCHECK(contents); + // Delegate is owned by the blocking page. + FakeConnectionInfoDelegate* delegate = + new FakeConnectionInfoDelegate(is_wifi_connection, wifi_ssid); // Blocking page is owned by the interstitial. CaptivePortalBlockingPage* blocking_page = new CaptivePortalBlockingPage( contents, GURL(kBrokenSSL), login_url, base::Callback<void(bool)>()); - blocking_page->SetWiFiConnectionForTesting(is_wifi_connection); - blocking_page->SetWiFiSSIDForTesting(wifi_ssid); + blocking_page->SetDelegateForTesting(delegate); blocking_page->Show(); WaitForInterstitialAttach(contents); @@ -140,9 +158,16 @@ // captive portal interstitial should be displayed. IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest, WiredNetwork_LoginURL) { - TestInterstitial(false, kWiFiSSID, GURL("http://captive.portal/landing_url"), + TestInterstitial(false, "", GURL("http://captive.portal/landing_url"), EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_YES); +} +// Same as above, but SSID is available, so the connection should be assumed to +// be Wi-Fi. +IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest, + WiredNetwork_LoginURL_With_SSID) { + TestInterstitial(false, kWiFiSSID, GURL("http://captive.portal/landing_url"), + EXPECT_WIFI_YES, EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_YES); } // Same as above, expect the login URL is the same as the captive portal ping @@ -151,8 +176,17 @@ IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest, WiredNetwork_NoLoginURL) { const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL); - TestInterstitial(false, kWiFiSSID, kLandingUrl, - EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_NO); + TestInterstitial(false, "", kLandingUrl, EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, + EXPECT_LOGIN_URL_NO); +} + +// Same as above, but SSID is available, so the connection should be assumed to +// be Wi-Fi. +IN_PROC_BROWSER_TEST_F(CaptivePortalBlockingPageTest, + WiredNetwork_NoLoginURL_With_SSID) { + const GURL kLandingUrl(captive_portal::CaptivePortalDetector::kDefaultURL); + TestInterstitial(false, kWiFiSSID, kLandingUrl, EXPECT_WIFI_YES, + EXPECT_WIFI_SSID_YES, EXPECT_LOGIN_URL_NO); } // If the connection is a Wi-Fi connection, the Wi-Fi version of the captive @@ -209,7 +243,6 @@ base::StringPrintf("http://%s/landing_url", kHostname); GURL landing_url(landing_url_spec); - TestInterstitial(false, kWiFiSSID, landing_url, - EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, EXPECT_LOGIN_URL_YES, - kHostnameJSUnicode); + TestInterstitial(false, "", landing_url, EXPECT_WIFI_NO, EXPECT_WIFI_SSID_NO, + EXPECT_LOGIN_URL_YES, kHostnameJSUnicode); }
diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc index 214c0353..7ef848d01 100644 --- a/chrome/browser/ssl/ssl_blocking_page.cc +++ b/chrome/browser/ssl/ssl_blocking_page.cc
@@ -87,6 +87,9 @@ END_OF_SSL_EXPIRATION_AND_DECISION, }; +// Rappor prefix +const char kSSLRapporPrefix[] = "ssl"; + void RecordSSLExpirationPageEventState(bool expired_but_previously_allowed, bool proceed, bool overridable) { @@ -233,12 +236,19 @@ IsErrorDueToBadClock(base::Time::NowFromSystemTime(), cert_error_) ? SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; + // We collapse the Rappor metric name to just "ssl" so we don't leak + // the "overridable" bit. We skip Rappor altogether for bad clocks. // This must be done after calculating |interstitial_reason_| above. - uma_helper_.reset(new SecurityInterstitialUmaHelper( - web_contents, request_url, GetHistogramPrefix(), GetSamplingEventName())); - uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::SHOW); - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::TOTAL_VISITS); + metrics_helper_.reset(new SecurityInterstitialMetricsHelper( + web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, + (interstitial_reason_ == SSL_REASON_BAD_CLOCK + ? SecurityInterstitialMetricsHelper::SKIP_RAPPOR + : SecurityInterstitialMetricsHelper::REPORT_RAPPOR), + GetSamplingEventName())); + + metrics_helper_->RecordUserDecision(SecurityInterstitialMetricsHelper::SHOW); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::TOTAL_VISITS); ssl_error_classification_.reset(new SSLErrorClassification( web_contents, @@ -267,8 +277,8 @@ if (!callback_.is_null()) { // The page is closed without the user having chosen what to do, default to // deny. - uma_helper_->RecordUserDecision( - SecurityInterstitialUmaHelper::DONT_PROCEED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::DONT_PROCEED); RecordSSLExpirationPageEventState( expired_but_previously_allowed_, false, overridable_); NotifyDenyCertificate(); @@ -451,20 +461,20 @@ break; } case CMD_MORE: { - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_ADVANCED); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_ADVANCED); break; } case CMD_RELOAD: { - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::RELOAD); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::RELOAD); // The interstitial can't refresh itself. web_contents()->GetController().Reload(true); break; } case CMD_HELP: { - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::SHOW_LEARN_MORE); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::SHOW_LEARN_MORE); content::NavigationController::LoadURLParams help_page_params( google_util::AppendGoogleLocaleParam( GURL(kHelpURL), g_browser_process->GetApplicationLocale())); @@ -472,8 +482,8 @@ break; } case CMD_CLOCK: { - uma_helper_->RecordUserInteraction( - SecurityInterstitialUmaHelper::OPEN_TIME_SETTINGS); + metrics_helper_->RecordUserInteraction( + SecurityInterstitialMetricsHelper::OPEN_TIME_SETTINGS); LaunchDateAndTimeSettings(); break; } @@ -492,7 +502,8 @@ } void SSLBlockingPage::OnProceed() { - uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::PROCEED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::PROCEED); RecordSSLExpirationPageEventState( expired_but_previously_allowed_, true, overridable_); // Accepting the certificate resumes the loading of the page. @@ -500,7 +511,8 @@ } void SSLBlockingPage::OnDontProceed() { - uma_helper_->RecordUserDecision(SecurityInterstitialUmaHelper::DONT_PROCEED); + metrics_helper_->RecordUserDecision( + SecurityInterstitialMetricsHelper::DONT_PROCEED); RecordSSLExpirationPageEventState( expired_but_previously_allowed_, false, overridable_); NotifyDenyCertificate(); @@ -524,7 +536,7 @@ callback_.Reset(); } -std::string SSLBlockingPage::GetHistogramPrefix() const { +std::string SSLBlockingPage::GetUmaHistogramPrefix() const { switch (interstitial_reason_) { case SSL_REASON_SSL: if (overridable_)
diff --git a/chrome/browser/ssl/ssl_blocking_page.h b/chrome/browser/ssl/ssl_blocking_page.h index 1a6b3da..dac5ab41 100644 --- a/chrome/browser/ssl/ssl_blocking_page.h +++ b/chrome/browser/ssl/ssl_blocking_page.h
@@ -12,8 +12,8 @@ #include "base/strings/string16.h" #include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" +#include "chrome/browser/interstitials/security_interstitial_metrics_helper.h" #include "chrome/browser/interstitials/security_interstitial_page.h" -#include "chrome/browser/interstitials/security_interstitial_uma_helper.h" #include "net/ssl/ssl_info.h" #include "url/gurl.h" @@ -95,7 +95,7 @@ void NotifyDenyCertificate(); void NotifyAllowCertificate(); - std::string GetHistogramPrefix() const; + std::string GetUmaHistogramPrefix() const; std::string GetSamplingEventName() const; base::Callback<void(bool)> callback_; @@ -117,9 +117,9 @@ // expired? const bool expired_but_previously_allowed_; scoped_ptr<SSLErrorClassification> ssl_error_classification_; - scoped_ptr<SecurityInterstitialUmaHelper> uma_helper_; + scoped_ptr<SecurityInterstitialMetricsHelper> metrics_helper_; - // Which type of Safe Browsing interstitial this is. + // Which type of interstitial this is. enum SSLInterstitialReason { SSL_REASON_SSL, SSL_REASON_BAD_CLOCK
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.h b/chrome/browser/sync/glue/synced_tab_delegate_android.h index cd485ea3..15168727 100644 --- a/chrome/browser/sync/glue/synced_tab_delegate_android.h +++ b/chrome/browser/sync/glue/synced_tab_delegate_android.h
@@ -22,31 +22,31 @@ class SyncedTabDelegateAndroid : public browser_sync::SyncedTabDelegate { public: explicit SyncedTabDelegateAndroid(TabAndroid* owning_tab_); - virtual ~SyncedTabDelegateAndroid(); + ~SyncedTabDelegateAndroid() override; // Methods from SyncedTabDelegate. - virtual SessionID::id_type GetWindowId() const override; - virtual SessionID::id_type GetSessionId() const override; - virtual bool IsBeingDestroyed() const override; - virtual Profile* profile() const override; - virtual std::string GetExtensionAppId() const override; - virtual int GetCurrentEntryIndex() const override; - virtual int GetEntryCount() const override; - virtual int GetPendingEntryIndex() const override; - virtual content::NavigationEntry* GetPendingEntry() const override; - virtual content::NavigationEntry* GetEntryAtIndex(int i) const override; - virtual content::NavigationEntry* GetActiveEntry() const override; - virtual bool IsPinned() const override; - virtual bool HasWebContents() const override; - virtual content::WebContents* GetWebContents() const override; - virtual int GetSyncId() const override; - virtual void SetSyncId(int sync_id) override; + SessionID::id_type GetWindowId() const override; + SessionID::id_type GetSessionId() const override; + bool IsBeingDestroyed() const override; + Profile* profile() const override; + std::string GetExtensionAppId() const override; + int GetCurrentEntryIndex() const override; + int GetEntryCount() const override; + int GetPendingEntryIndex() const override; + content::NavigationEntry* GetPendingEntry() const override; + content::NavigationEntry* GetEntryAtIndex(int i) const override; + content::NavigationEntry* GetActiveEntry() const override; + bool IsPinned() const override; + bool HasWebContents() const override; + content::WebContents* GetWebContents() const override; + int GetSyncId() const override; + void SetSyncId(int sync_id) override; // Supervised user related methods. - virtual bool ProfileIsSupervised() const override; - virtual const std::vector<const content::NavigationEntry*>* - GetBlockedNavigations() const override; + bool ProfileIsSupervised() const override; + const std::vector<const content::NavigationEntry*>* GetBlockedNavigations() + const override; // Set the web contents for this tab. Also creates // TabContentsSyncedTabDelegate for this tab.
diff --git a/chrome/browser/sync/glue/synced_window_delegate_android.h b/chrome/browser/sync/glue/synced_window_delegate_android.h index 13b717f9..0c3d1f48 100644 --- a/chrome/browser/sync/glue/synced_window_delegate_android.h +++ b/chrome/browser/sync/glue/synced_window_delegate_android.h
@@ -18,21 +18,21 @@ class SyncedWindowDelegateAndroid : public browser_sync::SyncedWindowDelegate { public: explicit SyncedWindowDelegateAndroid(TabModel* tab_model); - virtual ~SyncedWindowDelegateAndroid(); + ~SyncedWindowDelegateAndroid() override; // browser_sync::SyncedWindowDelegate implementation. - virtual bool HasWindow() const override; - virtual SessionID::id_type GetSessionId() const override; - virtual int GetTabCount() const override; - virtual int GetActiveIndex() const override; - virtual bool IsApp() const override; - virtual bool IsTypeTabbed() const override; - virtual bool IsTypePopup() const override; - virtual bool IsTabPinned(const SyncedTabDelegate* tab) const override; - virtual SyncedTabDelegate* GetTabAt(int index) const override; - virtual SessionID::id_type GetTabIdAt(int index) const override; - virtual bool IsSessionRestoreInProgress() const override; + bool HasWindow() const override; + SessionID::id_type GetSessionId() const override; + int GetTabCount() const override; + int GetActiveIndex() const override; + bool IsApp() const override; + bool IsTypeTabbed() const override; + bool IsTypePopup() const override; + bool IsTabPinned(const SyncedTabDelegate* tab) const override; + SyncedTabDelegate* GetTabAt(int index) const override; + SessionID::id_type GetTabIdAt(int index) const override; + bool IsSessionRestoreInProgress() const override; private: TabModel* tab_model_;
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 721c174..cb305b5 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc
@@ -62,6 +62,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" +#include "components/autofill/core/common/autofill_pref_names.h" #include "components/gcm_driver/gcm_driver.h" #include "components/invalidation/invalidation_service.h" #include "components/invalidation/profile_invalidation_provider.h" @@ -1153,6 +1154,9 @@ profile()->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, experiments.gcm_invalidations_enabled); + profile()->GetPrefs()->SetBoolean( + autofill::prefs::kAutofillWalletSyncExperimentEnabled, + experiments.wallet_sync_enabled); if (experiments.enhanced_bookmarks_enabled) { profile_->GetPrefs()->SetString(
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h index 703c69e..2b2f34e 100644 --- a/chrome/browser/sync/profile_sync_service_android.h +++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -187,7 +187,7 @@ jint GetAuthError(JNIEnv* env, jobject obj); // ProfileSyncServiceObserver: - virtual void OnStateChanged() override; + void OnStateChanged() override; // Returns a timestamp for when a sync was last executed. The return value is // the internal value of base::Time. @@ -217,7 +217,7 @@ int64, syncer::ObjectIdLessThan> ObjectIdVersionMap; - virtual ~ProfileSyncServiceAndroid(); + ~ProfileSyncServiceAndroid() override; // Remove observers to profile sync service. void RemoveObserver();
diff --git a/chrome/browser/sync/profile_sync_service_android_unittest.cc b/chrome/browser/sync/profile_sync_service_android_unittest.cc index ef5d248..14c6d0b 100644 --- a/chrome/browser/sync/profile_sync_service_android_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_android_unittest.cc
@@ -37,9 +37,9 @@ public: ProfileSyncServiceAndroidTest() : command_line_(base::CommandLine::NO_PROGRAM) {} - virtual ~ProfileSyncServiceAndroidTest() {} + ~ProfileSyncServiceAndroidTest() override {} - virtual void SetUp() override { + void SetUp() override { ProfileOAuth2TokenService* token_service = ProfileOAuth2TokenServiceFactory::GetForProfile(&profile_); ProfileSyncComponentsFactory* factory =
diff --git a/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc b/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc index 4c2b4731..84ffaf19e 100644 --- a/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc
@@ -70,9 +70,10 @@ context_.reset(new SyncEngineContext(fake_drive_service.Pass(), drive_uploader.Pass(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); context_->SetRemoteChangeProcessor(remote_change_processor_.get()); RegisterSyncableFileSystem(); @@ -80,7 +81,8 @@ sync_task_manager_.reset(new SyncTaskManager( base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_->Initialize(SYNC_STATUS_OK); }
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc index f98da48..ce49be9 100644 --- a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
@@ -118,6 +118,7 @@ new SyncEngine(base::ThreadTaskRunnerHandle::Get(), // ui_task_runner worker_task_runner_.get(), drive_task_runner.get(), + worker_pool.get(), base_dir_.path(), nullptr, // task_logger nullptr, // notification_manager
diff --git a/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc b/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc index 479b92c..ee4fd8d 100644 --- a/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc
@@ -59,14 +59,16 @@ sync_task_manager_.reset(new SyncTaskManager( base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_->Initialize(SYNC_STATUS_OK); context_.reset(new SyncEngineContext(fake_drive_service.Pass(), drive_uploader.Pass(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); SetUpRemoteFolders();
diff --git a/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc index 9131454..9364d1c 100644 --- a/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc
@@ -71,9 +71,10 @@ context_.reset(new SyncEngineContext(fake_drive_service.Pass(), drive_uploader.Pass(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); context_->SetRemoteChangeProcessor(remote_change_processor_.get()); RegisterSyncableFileSystem(); @@ -81,7 +82,8 @@ sync_task_manager_.reset(new SyncTaskManager( base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_->Initialize(SYNC_STATUS_OK); }
diff --git a/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc b/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc index 2b87fd0..1de4b37 100644 --- a/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc
@@ -60,9 +60,10 @@ context_.reset(new SyncEngineContext(fake_drive_service.Pass(), drive_uploader.Pass(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); ASSERT_EQ(google_apis::HTTP_CREATED, fake_drive_service_helper_->AddOrphanedFolder(
diff --git a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc index 22cbbfdd..0541e95c 100644 --- a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc
@@ -71,9 +71,10 @@ context_.reset(new SyncEngineContext(fake_drive_service.Pass(), drive_uploader.Pass(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool*/)); context_->SetRemoteChangeProcessor(remote_change_processor_.get()); RegisterSyncableFileSystem(); @@ -81,7 +82,8 @@ sync_task_manager_.reset(new SyncTaskManager( base::WeakPtr<SyncTaskManager::Client>(), 10 /* max_parallel_task */, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_->Initialize(SYNC_STATUS_OK); }
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc index af03581..890cfed 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
@@ -164,25 +164,6 @@ callback.Run(status); } -template <typename T> -void DeleteSoonHelper(scoped_ptr<T>) {} - -template <typename T> -void DeleteSoon(const tracked_objects::Location& from_here, - base::TaskRunner* task_runner, - scoped_ptr<T> obj) { - if (!obj) - return; - - T* obj_ptr = obj.get(); - base::Closure deleter = - base::Bind(&DeleteSoonHelper<T>, base::Passed(&obj)); - if (!task_runner->PostTask(from_here, deleter)) { - obj_ptr->DetachFromSequence(); - deleter.Run(); - } -} - } // namespace scoped_ptr<SyncEngine> SyncEngine::CreateForBrowserContext( @@ -218,6 +199,7 @@ new SyncEngine(ui_task_runner.get(), worker_task_runner.get(), drive_task_runner.get(), + worker_pool.get(), GetSyncFileSystemDir(context->GetPath()), task_logger, notification_manager, @@ -256,11 +238,10 @@ if (drive_service_) drive_service_->RemoveObserver(this); - DeleteSoon(FROM_HERE, worker_task_runner_.get(), sync_worker_.Pass()); - DeleteSoon(FROM_HERE, worker_task_runner_.get(), worker_observer_.Pass()); - DeleteSoon(FROM_HERE, - worker_task_runner_.get(), - remote_change_processor_on_worker_.Pass()); + worker_task_runner_->DeleteSoon(FROM_HERE, sync_worker_.release()); + worker_task_runner_->DeleteSoon(FROM_HERE, worker_observer_.release()); + worker_task_runner_->DeleteSoon(FROM_HERE, + remote_change_processor_on_worker_.release()); drive_service_wrapper_.reset(); drive_service_.reset(); @@ -326,7 +307,8 @@ drive_uploader_on_worker.Pass(), task_logger_, ui_task_runner_.get(), - worker_task_runner_.get())); + worker_task_runner_.get(), + worker_pool_.get())); worker_observer_.reset(new WorkerObserver(ui_task_runner_.get(), weak_ptr_factory_.GetWeakPtr())); @@ -736,6 +718,7 @@ const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner, const scoped_refptr<base::SequencedTaskRunner>& drive_task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool, const base::FilePath& sync_file_system_dir, TaskLogger* task_logger, drive::DriveNotificationManager* notification_manager, @@ -748,6 +731,7 @@ : ui_task_runner_(ui_task_runner), worker_task_runner_(worker_task_runner), drive_task_runner_(drive_task_runner), + worker_pool_(worker_pool), sync_file_system_dir_(sync_file_system_dir), task_logger_(task_logger), notification_manager_(notification_manager),
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.h b/chrome/browser/sync_file_system/drive_backend/sync_engine.h index fc5388e..81315db 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine.h +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.h
@@ -159,6 +159,7 @@ SyncEngine(const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner, const scoped_refptr<base::SequencedTaskRunner>& drive_task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool, const base::FilePath& sync_file_system_dir, TaskLogger* task_logger, drive::DriveNotificationManager* notification_manager, @@ -184,6 +185,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; scoped_refptr<base::SequencedTaskRunner> worker_task_runner_; scoped_refptr<base::SequencedTaskRunner> drive_task_runner_; + scoped_refptr<base::SequencedWorkerPool> worker_pool_; const base::FilePath sync_file_system_dir_; TaskLogger* task_logger_;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc index 867075e..e487003 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc
@@ -23,14 +23,16 @@ scoped_ptr<drive::DriveUploaderInterface> drive_uploader, TaskLogger* task_logger, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner) + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) : drive_service_(drive_service.Pass()), drive_uploader_(drive_uploader.Pass()), task_logger_(task_logger ? task_logger->AsWeakPtr() : base::WeakPtr<TaskLogger>()), remote_change_processor_(nullptr), ui_task_runner_(ui_task_runner), - worker_task_runner_(worker_task_runner) { + worker_task_runner_(worker_task_runner), + worker_pool_(worker_pool) { sequence_checker_.DetachFromSequence(); } @@ -78,6 +80,11 @@ return worker_task_runner_.get(); } +base::SequencedWorkerPool* SyncEngineContext::GetWorkerPool() { + DCHECK(sequence_checker_.CalledOnValidSequencedThread()); + return worker_pool_.get(); +} + void SyncEngineContext::SetMetadataDatabase( scoped_ptr<MetadataDatabase> metadata_database) { DCHECK(sequence_checker_.CalledOnValidSequencedThread());
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h index ee1d4cd..8aaaf15 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h
@@ -37,7 +37,8 @@ scoped_ptr<drive::DriveUploaderInterface> drive_uploader, TaskLogger* task_logger, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, - const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner); + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); ~SyncEngineContext(); void SetMetadataDatabase(scoped_ptr<MetadataDatabase> metadata_database); @@ -51,6 +52,7 @@ RemoteChangeProcessor* GetRemoteChangeProcessor(); base::SingleThreadTaskRunner* GetUITaskRunner(); base::SequencedTaskRunner* GetWorkerTaskRunner(); + base::SequencedWorkerPool* GetWorkerPool(); scoped_ptr<MetadataDatabase> PassMetadataDatabase(); @@ -67,6 +69,7 @@ scoped_ptr<MetadataDatabase> metadata_database_; scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; scoped_refptr<base::SequencedTaskRunner> worker_task_runner_; + scoped_refptr<base::SequencedWorkerPool> worker_pool_; base::SequenceChecker sequence_checker_;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc index 2ff8196..06e3ba1 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc
@@ -54,14 +54,16 @@ sync_context_.reset(new SyncEngineContext( fake_drive_service.Pass(), scoped_ptr<drive::DriveUploaderInterface>(), - nullptr, + nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_.reset(new SyncTaskManager( base::WeakPtr<SyncTaskManager::Client>(), 1 /* maximum_parallel_task */, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); sync_task_manager_->Initialize(SYNC_STATUS_OK); }
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc index 0519881..8bab99c6 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
@@ -49,6 +49,7 @@ ui_task_runner.get(), worker_task_runner_.get(), nullptr /* drive_task_runner */, + worker_pool_.get(), profile_dir_.path(), nullptr /* task_logger */, nullptr /* notification_manager */,
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc index d6ecbae..16e1f9bf 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc
@@ -55,12 +55,14 @@ SyncTaskManager::SyncTaskManager( base::WeakPtr<Client> client, size_t maximum_background_task, - const scoped_refptr<base::SequencedTaskRunner>& task_runner) + const scoped_refptr<base::SequencedTaskRunner>& task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) : client_(client), maximum_background_task_(maximum_background_task), pending_task_seq_(0), task_token_seq_(SyncTaskToken::kMinimumBackgroundTaskTokenID), task_runner_(task_runner), + worker_pool_(worker_pool), weak_ptr_factory_(this) { } @@ -204,6 +206,10 @@ sequence_checker_.DetachFromSequence(); } +bool SyncTaskManager::ShouldTrackTaskToken() const { + return !worker_pool_ || !worker_pool_->IsShutdownInProgress(); +} + void SyncTaskManager::NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token, SyncStatusCode status) { DCHECK(sequence_checker_.CalledOnValidSequencedThread());
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h index de03d577..656e646 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h +++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager.h
@@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h" #include "chrome/browser/sync_file_system/sync_callbacks.h" #include "chrome/browser/sync_file_system/sync_status_code.h" @@ -70,7 +71,8 @@ // If |maximum_background_tasks| is zero, all task runs as foreground task. SyncTaskManager(base::WeakPtr<Client> client, size_t maximum_background_task, - const scoped_refptr<base::SequencedTaskRunner>& task_runner); + const scoped_refptr<base::SequencedTaskRunner>& task_runner, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); virtual ~SyncTaskManager(); // This needs to be called to start task scheduling. @@ -120,6 +122,7 @@ bool IsRunningTask(int64 task_token_id) const; void DetachFromSequence(); + bool ShouldTrackTaskToken() const; private: struct PendingTask { @@ -195,6 +198,7 @@ TaskDependencyManager dependency_manager_; scoped_refptr<base::SequencedTaskRunner> task_runner_; + scoped_refptr<base::SequencedWorkerPool> worker_pool_; base::SequenceChecker sequence_checker_; base::WeakPtrFactory<SyncTaskManager> weak_ptr_factory_;;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc index cd24f6e..cf01a067 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_task_manager_unittest.cc
@@ -62,7 +62,8 @@ last_operation_status_(SYNC_STATUS_OK) { task_manager_.reset(new SyncTaskManager( AsWeakPtr(), maximum_background_task, - base::ThreadTaskRunnerHandle::Get())); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */)); task_manager_->Initialize(SYNC_STATUS_OK); base::MessageLoop::current()->RunUntilIdle(); maybe_schedule_next_task_count_ = 0; @@ -392,7 +393,8 @@ { SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 0 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); message_loop.RunUntilIdle(); task_manager.ScheduleSyncTask( @@ -414,7 +416,8 @@ base::MessageLoop message_loop; SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 0 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); message_loop.RunUntilIdle(); @@ -475,7 +478,8 @@ base::MessageLoop message_loop; SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); SyncStatusCode status = SYNC_STATUS_FAILED; @@ -516,7 +520,8 @@ base::MessageLoop message_loop; SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); SyncStatusCode status = SYNC_STATUS_FAILED; @@ -557,7 +562,8 @@ base::MessageLoop message_loop; SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 2 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); SyncStatusCode status = SYNC_STATUS_FAILED; @@ -598,7 +604,8 @@ base::MessageLoop message_loop; SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(), 10 /* maximum_background_task */, - base::ThreadTaskRunnerHandle::Get()); + base::ThreadTaskRunnerHandle::Get(), + nullptr /* worker_pool */); task_manager.Initialize(SYNC_STATUS_OK); SyncStatusCode status1 = SYNC_STATUS_FAILED;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_task_token.cc b/chrome/browser/sync_file_system/drive_backend/sync_task_token.cc index 590e9a80..b4d58bf8 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_task_token.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_task_token.cc
@@ -70,6 +70,9 @@ // dropped by a task without returning. if (task_runner_.get() && task_runner_->RunsTasksOnCurrentThread() && manager_ && manager_->IsRunningTask(token_id_)) { + if (!manager_->ShouldTrackTaskToken()) + return; + NOTREACHED() << "Unexpected TaskToken deletion from: " << location_.ToString();
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_worker.cc b/chrome/browser/sync_file_system/drive_backend/sync_worker.cc index 9ae8560..e73ad16 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_worker.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_worker.cc
@@ -73,7 +73,8 @@ task_manager_.reset(new SyncTaskManager( weak_ptr_factory_.GetWeakPtr(), 0 /* maximum_background_task */, - context_->GetWorkerTaskRunner())); + context_->GetWorkerTaskRunner(), + context_->GetWorkerPool())); task_manager_->Initialize(SYNC_STATUS_OK); PostInitializeTask();
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_worker_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_worker_unittest.cc index 8c2d173..7240de9 100644 --- a/chrome/browser/sync_file_system/drive_backend/sync_worker_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/sync_worker_unittest.cc
@@ -113,7 +113,8 @@ nullptr /* drive_uploader */, nullptr /* task_logger */, base::ThreadTaskRunnerHandle::Get() /* ui_task_runner */, - base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */)); + base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */, + nullptr /* worker_pool */)); sync_worker_.reset(new SyncWorker( profile_dir_.path(),
diff --git a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc index 69d1fb2..21209e8 100644 --- a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc +++ b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
@@ -10,6 +10,7 @@ #include "base/location.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/thread_task_runner_handle.h" #include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h" #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" @@ -131,6 +132,7 @@ SCOPED_TRACE(testing::Message() << location.ToString()); EXPECT_EQ(expect, status); ++callback_count_; + base::MessageLoop::current()->Quit(); } bool CreateTempFile(base::FilePath* path) { @@ -170,13 +172,13 @@ file_system_.operation_runner()->Truncate( URL(kFile), 1, ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, callback_count_); // Read operations are not blocked (and are executed before queued ones). file_system_.operation_runner()->FileExists( URL(kFile), ExpectStatus(FROM_HERE, File::FILE_ERROR_NOT_FOUND)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback_count_); // End syncing (to enable write). @@ -184,14 +186,14 @@ ASSERT_TRUE(sync_status()->IsWritable(URL(kFile))); ResetCallbackStatus(); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(2, callback_count_); // Now the file must have been created and updated. ResetCallbackStatus(); file_system_.operation_runner()->FileExists( URL(kFile), ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback_count_); } @@ -211,13 +213,13 @@ file_system_.operation_runner()->Remove( URL(kParent), true /* recursive */, ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, callback_count_); // Read operations are not blocked (and are executed before queued ones). file_system_.operation_runner()->DirectoryExists( URL(kDir), ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(1, callback_count_); // Writes to unrelated files must succeed as well. @@ -225,7 +227,7 @@ file_system_.operation_runner()->CreateDirectory( URL(kOther), false /* exclusive */, false /* recursive */, ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(1, callback_count_); // End syncing (to enable write). @@ -233,7 +235,7 @@ ASSERT_TRUE(sync_status()->IsWritable(URL(kDir))); ResetCallbackStatus(); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(2, callback_count_); } @@ -259,7 +261,7 @@ URL("dest-move"), storage::FileSystemOperation::OPTION_NONE, ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(1, callback_count_); // Only "dest-copy1" should exist. @@ -279,13 +281,13 @@ storage::FileSystemOperation::OPTION_NONE, storage::FileSystemOperationRunner::CopyProgressCallback(), ExpectStatus(FROM_HERE, File::FILE_OK)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, callback_count_); // Finish syncing the "dest-copy2" directory to unlock Copy. sync_status()->EndSyncing(URL("dest-copy2")); ResetCallbackStatus(); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(1, callback_count_); // Now we should have "dest-copy2". @@ -295,7 +297,7 @@ // Finish syncing the kParent to unlock Move. sync_status()->EndSyncing(URL(kParent)); ResetCallbackStatus(); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(1, callback_count_); // Now we should have "dest-move". @@ -314,7 +316,7 @@ file_system_.operation_runner()->Write( &url_request_context_, URL(kFile), blob.GetBlobDataHandle(), 0, GetWriteCallback(FROM_HERE)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, callback_count_); sync_status()->EndSyncing(URL(kFile)); @@ -404,7 +406,7 @@ URL(kFile), 10, ExpectStatus(FROM_HERE, File::FILE_OK)); file_system_.operation_runner()->Cancel( id, ExpectStatus(FROM_HERE, File::FILE_ERROR_INVALID_OPERATION)); - base::MessageLoop::current()->RunUntilIdle(); + base::RunLoop().Run(); EXPECT_EQ(2, callback_count_); }
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc index 5f30648..6d345e9 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.cc +++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -494,7 +494,12 @@ // Local side of initialization for the app is done. // Continue on initializing the remote side. - GetRemoteService(app_origin)->RegisterOrigin( + if (!remote_service_) { + callback.Run(SYNC_STATUS_ABORT); + return; + } + + remote_service_->RegisterOrigin( app_origin, base::Bind(&SyncFileSystemService::DidRegisterOrigin, AsWeakPtr(), app_origin, callback)); @@ -509,8 +514,13 @@ app_origin.spec().c_str(), SyncStatusCodeToString(status)); + if (!remote_service_) { + callback.Run(SYNC_STATUS_ABORT); + return; + } + UMA_HISTOGRAM_ENUMERATION("SyncFileSystem.RegisterOriginResult", - GetRemoteService(app_origin)->GetCurrentState(), + remote_service_->GetCurrentState(), REMOTE_SERVICE_STATE_MAX); if (status == SYNC_STATUS_FAILED) { @@ -541,6 +551,11 @@ return; } + if (!remote_service_) { + callback.Run(base::ListValue()); + return; + } + GetRemoteService(origin)->DumpFiles( origin, base::Bind( @@ -554,7 +569,8 @@ const GURL& origin, const DumpFilesCallback& callback, scoped_ptr<base::ListValue> dump_files) { - if (!dump_files || !dump_files->GetSize()) { + if (!dump_files || !dump_files->GetSize() || + !local_service_ || !remote_service_) { callback.Run(base::ListValue()); return; }
diff --git a/chrome/browser/test_presubmit.py b/chrome/browser/test_presubmit.py index d37a6b3e..ac0e13b90 100755 --- a/chrome/browser/test_presubmit.py +++ b/chrome/browser/test_presubmit.py
@@ -804,7 +804,7 @@ -webkit-margin-before: 10px; (replace with margin-top) -webkit-padding-after: 3px; (replace with padding-bottom)""") - def testCssZeroLengthTerms(self): + def testCssZeroWidthLengths(self): self.VerifyContentsProducesOutput(""" @-webkit-keyframe anim { 0% { /* Ignore key frames */ @@ -836,10 +836,7 @@ .media-button[state='0']:not(.disabled):hover > .state0.hover { -webkit-animation: anim 0s; -webkit-animation-duration: anim 0ms; - -webkit-transform: scale(0%), - translateX(0deg), - translateY(0rad), - translateZ(0grad); + -webkit-transform: scale(0%); background-position-x: 0em; background-position-y: 0ex; border-width: 0em; @@ -854,15 +851,9 @@ height: 0cm; width: 0in; }""", """ -- Make all zero length terms (i.e. 0px) 0 unless inside of hsl() or part of""" -""" @keyframe. +- Use "0" for zero-width lengths (i.e. 0px -> 0) width: 0px; - -webkit-animation: anim 0s; - -webkit-animation-duration: anim 0ms; - -webkit-transform: scale(0%), - translateX(0deg), - translateY(0rad), - translateZ(0grad); + -webkit-transform: scale(0%); background-position-x: 0em; background-position-y: 0ex; border-width: 0em;
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h index 07e9be1..fa66a0b 100644 --- a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h +++ b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h
@@ -30,12 +30,12 @@ const GURL& source_url, const AutofillClient::ResultCallback& callback); - virtual ~AutofillDialogControllerAndroid(); + ~AutofillDialogControllerAndroid() override; // AutofillDialogController implementation: - virtual void Show() override; - virtual void Hide() override; - virtual void TabActivated() override; + void Show() override; + void Hide() override; + void TabActivated() override; // JNI bindings for Java-side AutofillDialogDelegate: void DialogCancel(JNIEnv* env, jobject obj);
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.h b/chrome/browser/ui/android/autofill/autofill_popup_view_android.h index d6c7c74..8d4211b 100644 --- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.h +++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.h
@@ -35,13 +35,13 @@ protected: // AutofillPopupView implementation. - virtual void Show() override; - virtual void Hide() override; - virtual void InvalidateRow(size_t row) override; - virtual void UpdateBoundsAndRedrawPopup() override; + void Show() override; + void Hide() override; + void InvalidateRow(size_t row) override; + void UpdateBoundsAndRedrawPopup() override; private: - virtual ~AutofillPopupViewAndroid(); + ~AutofillPopupViewAndroid() override; AutofillPopupController* controller_; // weak.
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 e155ff6..d4437cba 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
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.h" +#include "chrome/browser/android/resource_mapper.h" #include "chrome/browser/ui/autofill/card_unmask_prompt_controller.h" #include "content/public/browser/web_contents.h" #include "jni/CardUnmaskBridge_jni.h" @@ -43,7 +44,9 @@ env, controller_->GetInstructionsMessage()); java_object_.Reset(Java_CardUnmaskBridge_create( env, reinterpret_cast<intptr_t>(this), dialog_title.obj(), - instructions.obj(), controller_->ShouldRequestExpirationDate(), + instructions.obj(), + ResourceMapper::MapFromChromiumId(controller_->GetCvcImageRid()), + controller_->ShouldRequestExpirationDate(), view_android->GetWindowAndroid()->GetJavaObject().obj())); Java_CardUnmaskBridge_show(env, java_object_.obj());
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 fbed584..1b8570e 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
@@ -36,7 +36,7 @@ static bool Register(JNIEnv* env); private: - virtual ~CardUnmaskPromptViewAndroid(); + ~CardUnmaskPromptViewAndroid() override; // The corresponding java object. base::android::ScopedJavaGlobalRef<jobject> java_object_;
diff --git a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h index c904870..806efa48 100644 --- a/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h +++ b/chrome/browser/ui/android/autofill/password_generation_popup_view_android.h
@@ -39,12 +39,12 @@ virtual ~PasswordGenerationPopupViewAndroid(); // PasswordGenerationPopupView implementation. - virtual void Show() override; - virtual void Hide() override; - virtual gfx::Size GetPreferredSizeOfPasswordView() override; - virtual void UpdateBoundsAndRedrawPopup() override; - virtual void PasswordSelectionUpdated() override; - virtual bool IsPointInPasswordBounds(const gfx::Point& point) override; + void Show() override; + void Hide() override; + gfx::Size GetPreferredSizeOfPasswordView() override; + void UpdateBoundsAndRedrawPopup() override; + void PasswordSelectionUpdated() override; + bool IsPointInPasswordBounds(const gfx::Point& point) override; // Weak pointer to the controller. PasswordGenerationPopupController* controller_;
diff --git a/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h b/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h index 6a1790e..3296ead 100644 --- a/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h +++ b/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h
@@ -20,7 +20,7 @@ // |infobar_service|. static void Create(content::WebContents* web_contents, int num_popups); - virtual ~PopupBlockedInfoBarDelegate(); + ~PopupBlockedInfoBarDelegate() override; private: PopupBlockedInfoBarDelegate(int num_popups, @@ -28,12 +28,12 @@ HostContentSettingsMap* map); // ConfirmInfoBarDelegate: - virtual int GetIconID() const override; - virtual PopupBlockedInfoBarDelegate* AsPopupBlockedInfoBarDelegate() override; - virtual base::string16 GetMessageText() const override; - virtual int GetButtons() const override; - virtual base::string16 GetButtonLabel(InfoBarButton button) const override; - virtual bool Accept() override; + int GetIconID() const override; + PopupBlockedInfoBarDelegate* AsPopupBlockedInfoBarDelegate() override; + base::string16 GetMessageText() const override; + int GetButtons() const override; + base::string16 GetButtonLabel(InfoBarButton button) const override; + bool Accept() override; int num_popups_; GURL url_;
diff --git a/chrome/browser/ui/android/context_menu_helper.h b/chrome/browser/ui/android/context_menu_helper.h index cf018186..e66e351 100644 --- a/chrome/browser/ui/android/context_menu_helper.h +++ b/chrome/browser/ui/android/context_menu_helper.h
@@ -19,7 +19,7 @@ class ContextMenuHelper : public content::WebContentsUserData<ContextMenuHelper> { public: - virtual ~ContextMenuHelper(); + ~ContextMenuHelper() override; void ShowContextMenu(const content::ContextMenuParams& params);
diff --git a/chrome/browser/ui/android/infobars/app_banner_infobar.cc b/chrome/browser/ui/android/infobars/app_banner_infobar.cc new file mode 100644 index 0000000..367586f --- /dev/null +++ b/chrome/browser/ui/android/infobars/app_banner_infobar.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 "chrome/browser/ui/android/infobars/app_banner_infobar.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "chrome/browser/android/banners/app_banner_infobar_delegate.h" +#include "jni/AppBannerInfoBarDelegate_jni.h" +#include "ui/gfx/android/java_bitmap.h" +#include "ui/gfx/image/image.h" + +AppBannerInfoBar::AppBannerInfoBar( + scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, + const GURL& app_url) + : ConfirmInfoBar(delegate.Pass()), + app_url_(app_url) { +} + +AppBannerInfoBar::~AppBannerInfoBar() { +} + +base::android::ScopedJavaLocalRef<jobject> +AppBannerInfoBar::CreateRenderInfoBar(JNIEnv* env) { + java_delegate_.Reset(Java_AppBannerInfoBarDelegate_create(env)); + + base::android::ScopedJavaLocalRef<jstring> ok_button_text = + base::android::ConvertUTF16ToJavaString( + env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK)); + + ConfirmInfoBarDelegate* delegate = GetDelegate(); + base::android::ScopedJavaLocalRef<jstring> app_title = + base::android::ConvertUTF16ToJavaString( + env, delegate->GetMessageText()); + + base::android::ScopedJavaLocalRef<jstring> app_url = + base::android::ConvertUTF8ToJavaString(env, app_url_.spec()); + + ScopedJavaLocalRef<jobject> java_bitmap; + if (!delegate->GetIcon().IsEmpty()) { + java_bitmap = gfx::ConvertToJavaBitmap(delegate->GetIcon().ToSkBitmap()); + } + + return Java_AppBannerInfoBarDelegate_showInfoBar( + env, + java_delegate_.obj(), + reinterpret_cast<intptr_t>(this), + app_title.obj(), + java_bitmap.obj(), + ok_button_text.obj(), + app_url.obj()); +} + +// Native JNI methods --------------------------------------------------------- + +bool RegisterAppBannerInfoBarDelegate(JNIEnv* env) { + return RegisterNativesImpl(env); +}
diff --git a/chrome/browser/ui/android/infobars/app_banner_infobar.h b/chrome/browser/ui/android/infobars/app_banner_infobar.h new file mode 100644 index 0000000..b43462c --- /dev/null +++ b/chrome/browser/ui/android/infobars/app_banner_infobar.h
@@ -0,0 +1,41 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_ANDROID_INFOBARS_APP_BANNER_INFOBAR_H_ +#define CHROME_BROWSER_UI_ANDROID_INFOBARS_APP_BANNER_INFOBAR_H_ + +#include "base/android/scoped_java_ref.h" +#include "base/basictypes.h" +#include "chrome/browser/ui/android/infobars/confirm_infobar.h" +#include "url/gurl.h" + +namespace banners { +class AppBannerInfoBarDelegate; +} // namespace banners + + +class AppBannerInfoBar : public ConfirmInfoBar { + public: + // Constructs an AppBannerInfoBar promoting a web app. + AppBannerInfoBar( + scoped_ptr<banners::AppBannerInfoBarDelegate> delegate, + const GURL& app_url); + + ~AppBannerInfoBar() override; + + private: + // InfoBarAndroid overrides. + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + JNIEnv* env) override; + + // Web app: URL for the app. + GURL app_url_; + + // Java delegate for creating AppBannerInfoBars. + base::android::ScopedJavaGlobalRef<jobject> java_delegate_; + + DISALLOW_COPY_AND_ASSIGN(AppBannerInfoBar); +}; + +#endif // CHROME_BROWSER_UI_ANDROID_INFOBARS_APP_BANNER_INFOBAR_H_
diff --git a/chrome/browser/ui/android/infobars/confirm_infobar.h b/chrome/browser/ui/android/infobars/confirm_infobar.h index 55e43d41..68e305d3 100644 --- a/chrome/browser/ui/android/infobars/confirm_infobar.h +++ b/chrome/browser/ui/android/infobars/confirm_infobar.h
@@ -13,19 +13,19 @@ class ConfirmInfoBar : public InfoBarAndroid { public: explicit ConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate> delegate); - virtual ~ConfirmInfoBar(); + ~ConfirmInfoBar() override; + + protected: + base::string16 GetTextFor(ConfirmInfoBarDelegate::InfoBarButton button); + ConfirmInfoBarDelegate* GetDelegate(); + + // InfoBarAndroid overrides. + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + JNIEnv* env) override; private: - // InfoBarAndroid: - virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( - JNIEnv* env) override; - virtual void OnLinkClicked(JNIEnv* env, jobject obj) override; - virtual void ProcessButton(int action, - const std::string& action_value) override; - - base::string16 GetTextFor(ConfirmInfoBarDelegate::InfoBarButton button); - - ConfirmInfoBarDelegate* GetDelegate(); + void OnLinkClicked(JNIEnv* env, jobject obj) override; + void ProcessButton(int action, const std::string& action_value) override; base::android::ScopedJavaGlobalRef<jobject> java_confirm_delegate_;
diff --git a/chrome/browser/ui/android/infobars/data_reduction_proxy_infobar.h b/chrome/browser/ui/android/infobars/data_reduction_proxy_infobar.h index 4658a03..2a22524 100644 --- a/chrome/browser/ui/android/infobars/data_reduction_proxy_infobar.h +++ b/chrome/browser/ui/android/infobars/data_reduction_proxy_infobar.h
@@ -22,11 +22,11 @@ explicit DataReductionProxyInfoBar( scoped_ptr<DataReductionProxyInfoBarDelegate> delegate); - virtual ~DataReductionProxyInfoBar(); + ~DataReductionProxyInfoBar() override; private: // ConfirmInfoBar: - virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( JNIEnv* env) override; DataReductionProxyInfoBarDelegate* GetDelegate();
diff --git a/chrome/browser/ui/android/infobars/generated_password_saved_infobar.h b/chrome/browser/ui/android/infobars/generated_password_saved_infobar.h index 9999e46..4bf80e6 100644 --- a/chrome/browser/ui/android/infobars/generated_password_saved_infobar.h +++ b/chrome/browser/ui/android/infobars/generated_password_saved_infobar.h
@@ -24,11 +24,10 @@ private: // InfoBarAndroid implementation: - virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( JNIEnv* env) override; - virtual void OnLinkClicked(JNIEnv* env, jobject obj) override; - virtual void ProcessButton(int action, - const std::string& action_value) override; + void OnLinkClicked(JNIEnv* env, jobject obj) override; + void ProcessButton(int action, const std::string& action_value) override; DISALLOW_COPY_AND_ASSIGN(GeneratedPasswordSavedInfoBar); };
diff --git a/chrome/browser/ui/android/infobars/infobar_android.h b/chrome/browser/ui/android/infobars/infobar_android.h index 14112191..39bd0e44 100644 --- a/chrome/browser/ui/android/infobars/infobar_android.h +++ b/chrome/browser/ui/android/infobars/infobar_android.h
@@ -35,7 +35,7 @@ }; explicit InfoBarAndroid(scoped_ptr<infobars::InfoBarDelegate> delegate); - virtual ~InfoBarAndroid(); + ~InfoBarAndroid() override; // InfoBar: virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar(
diff --git a/chrome/browser/ui/android/infobars/infobar_container_android.h b/chrome/browser/ui/android/infobars/infobar_container_android.h index 83432587..f29942e 100644 --- a/chrome/browser/ui/android/infobars/infobar_container_android.h +++ b/chrome/browser/ui/android/infobars/infobar_container_android.h
@@ -31,16 +31,14 @@ } private: - virtual ~InfoBarContainerAndroid() override; + ~InfoBarContainerAndroid() override; // InfobarContainer: - virtual void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar, - size_t position) override; - virtual void PlatformSpecificRemoveInfoBar(infobars::InfoBar* infobar) - override; - virtual void PlatformSpecificReplaceInfoBar( - infobars::InfoBar* old_infobar, - infobars::InfoBar* new_infobar) override; + void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar, + size_t position) override; + void PlatformSpecificRemoveInfoBar(infobars::InfoBar* infobar) override; + void PlatformSpecificReplaceInfoBar(infobars::InfoBar* old_infobar, + infobars::InfoBar* new_infobar) override; // Create the Java equivalent of |android_bar| and add it to the java // container.
diff --git a/chrome/browser/ui/android/infobars/translate_infobar.h b/chrome/browser/ui/android/infobars/translate_infobar.h index f03148c..e210a0ca 100644 --- a/chrome/browser/ui/android/infobars/translate_infobar.h +++ b/chrome/browser/ui/android/infobars/translate_infobar.h
@@ -18,7 +18,7 @@ public: explicit TranslateInfoBar( scoped_ptr<translate::TranslateInfoBarDelegate> delegate); - virtual ~TranslateInfoBar(); + ~TranslateInfoBar() override; // JNI methods specific to translate. void ApplyTranslateOptions(JNIEnv* env, @@ -31,11 +31,10 @@ private: // InfoBarAndroid: - virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( + base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar( JNIEnv* env) override; - virtual void ProcessButton(int action, - const std::string& action_value) override; - virtual void PassJavaInfoBar(InfoBarAndroid* source) override; + void ProcessButton(int action, const std::string& action_value) override; + void PassJavaInfoBar(InfoBarAndroid* source) override; void TransferOwnership(TranslateInfoBar* destination, translate::TranslateStep new_type);
diff --git a/chrome/browser/ui/android/javascript_app_modal_dialog_android.h b/chrome/browser/ui/android/javascript_app_modal_dialog_android.h index 18c2fd6..bef14655 100644 --- a/chrome/browser/ui/android/javascript_app_modal_dialog_android.h +++ b/chrome/browser/ui/android/javascript_app_modal_dialog_android.h
@@ -21,13 +21,13 @@ gfx::NativeWindow parent); // NativeAppModalDialog: - virtual int GetAppModalDialogButtons() const override; - virtual void ShowAppModalDialog() override; - virtual void ActivateAppModalDialog() override; - virtual void CloseAppModalDialog() override; - virtual void AcceptAppModalDialog() override; - virtual void CancelAppModalDialog() override; - virtual bool IsShowing() const override; + int GetAppModalDialogButtons() const override; + void ShowAppModalDialog() override; + void ActivateAppModalDialog() override; + void CloseAppModalDialog() override; + void AcceptAppModalDialog() override; + void CancelAppModalDialog() override; + bool IsShowing() const override; // Called when java confirms or cancels the dialog. void DidAcceptAppModalDialog(JNIEnv* env, @@ -42,7 +42,7 @@ private: // The object deletes itself. - virtual ~JavascriptAppModalDialogAndroid(); + ~JavascriptAppModalDialogAndroid() override; scoped_ptr<app_modal::JavaScriptAppModalDialog> dialog_; base::android::ScopedJavaGlobalRef<jobject> dialog_jobject_;
diff --git a/chrome/browser/ui/android/login_prompt_android.cc b/chrome/browser/ui/android/login_prompt_android.cc index 9f5058a..a62e761 100644 --- a/chrome/browser/ui/android/login_prompt_android.cc +++ b/chrome/browser/ui/android/login_prompt_android.cc
@@ -28,19 +28,17 @@ // LoginHandler methods: - virtual void OnAutofillDataAvailable( - const base::string16& username, - const base::string16& password) override { + void OnAutofillDataAvailable(const base::string16& username, + const base::string16& password) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(chrome_http_auth_handler_.get() != NULL); chrome_http_auth_handler_->OnAutofillDataAvailable( username, password); } - virtual void OnLoginModelDestroying() override {} + void OnLoginModelDestroying() override {} - virtual void BuildViewForPasswordManager( - password_manager::PasswordManager* manager, - const base::string16& explanation) override { + void BuildViewForPasswordManager(password_manager::PasswordManager* manager, + const base::string16& explanation) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Get pointer to TabAndroid @@ -68,9 +66,9 @@ } protected: - virtual ~LoginHandlerAndroid() {} + ~LoginHandlerAndroid() override {} - virtual void CloseDialog() override {} + void CloseDialog() override {} private: scoped_ptr<ChromeHttpAuthHandler> chrome_http_auth_handler_;
diff --git a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h index 054ba11..10afe4a 100644 --- a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h +++ b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h
@@ -20,15 +20,14 @@ public: explicit ChromeWebContentsViewDelegateAndroid( content::WebContents* web_contents); - virtual ~ChromeWebContentsViewDelegateAndroid(); + ~ChromeWebContentsViewDelegateAndroid() override; // WebContentsViewDelegate: - virtual void ShowContextMenu( - content::RenderFrameHost* render_frame_host, - const content::ContextMenuParams& params) override; + void ShowContextMenu(content::RenderFrameHost* render_frame_host, + const content::ContextMenuParams& params) override; // WebContentsViewDelegate: - virtual content::WebDragDestDelegate* GetDragDestDelegate() override; + content::WebDragDestDelegate* GetDragDestDelegate() override; private: // The WebContents that owns the view and this delegate transitively.
diff --git a/chrome/browser/ui/android/tab_model/tab_model.cc b/chrome/browser/ui/android/tab_model/tab_model.cc index 2d5bd6a0..1c07f77 100644 --- a/chrome/browser/ui/android/tab_model/tab_model.cc +++ b/chrome/browser/ui/android/tab_model/tab_model.cc
@@ -14,6 +14,10 @@ using content::NotificationService; +// Keep this in sync with +// chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabList.java +static int INVALID_TAB_INDEX = -1; + TabModel::TabModel(Profile* profile) : profile_(profile), synced_window_delegate_( @@ -58,6 +62,13 @@ return session_id_.id(); } +content::WebContents* TabModel::GetActiveWebContents() const { + int active_index = GetActiveIndex(); + if (active_index == INVALID_TAB_INDEX) + return nullptr; + return GetWebContentsAt(active_index); +} + void TabModel::BroadcastSessionRestoreComplete() { if (profile_) { NotificationService::current()->Notify(
diff --git a/chrome/browser/ui/android/tab_model/tab_model.h b/chrome/browser/ui/android/tab_model/tab_model.h index 0125f97..8a48f09 100644 --- a/chrome/browser/ui/android/tab_model/tab_model.h +++ b/chrome/browser/ui/android/tab_model/tab_model.h
@@ -37,6 +37,7 @@ virtual int GetTabCount() const = 0; virtual int GetActiveIndex() const = 0; + virtual content::WebContents* GetActiveWebContents() const; virtual content::WebContents* GetWebContentsAt(int index) const = 0; // This will return NULL if the tab has not yet been initialized. virtual TabAndroid* GetTabAt(int index) const = 0;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h index 77a614d2..0de051d 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h
@@ -28,7 +28,7 @@ public: TabModelJniBridge(JNIEnv* env, jobject obj, bool is_incognito); void Destroy(JNIEnv* env, jobject obj); - virtual ~TabModelJniBridge(); + ~TabModelJniBridge() override; // Registers the JNI bindings. static bool Register(JNIEnv* env); @@ -39,22 +39,21 @@ void TabAddedToModel(JNIEnv* env, jobject obj, jobject jtab); // TabModel:: - virtual int GetTabCount() const override; - virtual int GetActiveIndex() const override; - virtual content::WebContents* GetWebContentsAt(int index) const override; - virtual TabAndroid* GetTabAt(int index) const override; + int GetTabCount() const override; + int GetActiveIndex() const override; + content::WebContents* GetWebContentsAt(int index) const override; + TabAndroid* GetTabAt(int index) const override; - virtual void SetActiveIndex(int index) override; - virtual void CloseTabAt(int index) override; + void SetActiveIndex(int index) override; + void CloseTabAt(int index) override; - virtual void CreateTab(content::WebContents* web_contents, - int parent_tab_id) override; + void CreateTab(content::WebContents* web_contents, + int parent_tab_id) override; - virtual content::WebContents* CreateNewTabForDevTools( - const GURL& url) override; + content::WebContents* CreateNewTabForDevTools(const GURL& url) override; // Return true if we are currently restoring sessions asynchronously. - virtual bool IsSessionRestoreInProgress() const override; + bool IsSessionRestoreInProgress() const override; // Instructs the TabModel to broadcast a notification that all tabs are now // loaded from storage.
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc index 1fb6b4b0..5cc57f3 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_list_unittest.cc
@@ -17,21 +17,20 @@ public: explicit TestTabModel(Profile* profile) : TabModel(profile), tab_count_(0) {} - virtual int GetTabCount() const override { return tab_count_; } - virtual int GetActiveIndex() const override { return 0; } - virtual content::WebContents* GetWebContentsAt(int index) const override { + int GetTabCount() const override { return tab_count_; } + int GetActiveIndex() const override { return 0; } + content::WebContents* GetWebContentsAt(int index) const override { return nullptr; } - virtual void CreateTab(content::WebContents* web_contents, - int parent_tab_id) override {} - virtual content::WebContents* CreateNewTabForDevTools( - const GURL& url) override { + void CreateTab(content::WebContents* web_contents, + int parent_tab_id) override {} + content::WebContents* CreateNewTabForDevTools(const GURL& url) override { return nullptr; } - virtual bool IsSessionRestoreInProgress() const override { return false; } - virtual TabAndroid* GetTabAt(int index) const override { return nullptr; } - virtual void SetActiveIndex(int index) override {} - virtual void CloseTabAt(int index) override {} + bool IsSessionRestoreInProgress() const override { return false; } + TabAndroid* GetTabAt(int index) const override { return nullptr; } + void SetActiveIndex(int index) override {} + void CloseTabAt(int index) override {} // A fake value for the current number of tabs. int tab_count_;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc index 9808857..8f099e0a 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_unittest.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_unittest.cc
@@ -29,23 +29,20 @@ explicit TestTabModel(Profile* profile) : TabModel(profile) {} - virtual int GetTabCount() const override { return 0; } - virtual int GetActiveIndex() const override { return 0; } - virtual content::WebContents* GetWebContentsAt(int index) const override { + int GetTabCount() const override { return 0; } + int GetActiveIndex() const override { return 0; } + content::WebContents* GetWebContentsAt(int index) const override { return NULL; } - virtual void CreateTab(content::WebContents* web_contents, - int parent_tab_id) override {} - virtual content::WebContents* CreateNewTabForDevTools( - const GURL& url) override { + void CreateTab(content::WebContents* web_contents, + int parent_tab_id) override {} + content::WebContents* CreateNewTabForDevTools(const GURL& url) override { return NULL; } - virtual bool IsSessionRestoreInProgress() const override { return false; } - virtual TabAndroid* GetTabAt(int index) const override { - return NULL; - } - virtual void SetActiveIndex(int index) override {} - virtual void CloseTabAt(int index) override {} + bool IsSessionRestoreInProgress() const override { return false; } + TabAndroid* GetTabAt(int index) const override { return NULL; } + void SetActiveIndex(int index) override {} + void CloseTabAt(int index) override {} }; TEST_F(TabModelTest, TestProfileHandling) {
diff --git a/chrome/browser/ui/android/toolbar/toolbar_model_android.h b/chrome/browser/ui/android/toolbar/toolbar_model_android.h index 210f17e..60015e4 100644 --- a/chrome/browser/ui/android/toolbar/toolbar_model_android.h +++ b/chrome/browser/ui/android/toolbar/toolbar_model_android.h
@@ -21,7 +21,7 @@ class ToolbarModelAndroid : public ToolbarModelDelegate { public: explicit ToolbarModelAndroid(JNIEnv* env, jobject jdelegate); - virtual ~ToolbarModelAndroid(); + ~ToolbarModelAndroid() override; void Destroy(JNIEnv* env, jobject obj); base::android::ScopedJavaLocalRef<jstring> GetText( @@ -35,8 +35,8 @@ jobject obj); // ToolbarDelegate: - virtual content::WebContents* GetActiveWebContents() const override; - virtual bool InTabbedBrowser() const override; + content::WebContents* GetActiveWebContents() const override; + bool InTabbedBrowser() const override; static bool RegisterToolbarModelAndroid(JNIEnv* env);
diff --git a/chrome/browser/ui/android/website_settings_popup_android.h b/chrome/browser/ui/android/website_settings_popup_android.h index 57f5ec0..33bb7713 100644 --- a/chrome/browser/ui/android/website_settings_popup_android.h +++ b/chrome/browser/ui/android/website_settings_popup_android.h
@@ -33,7 +33,7 @@ WebsiteSettingsPopupAndroid(JNIEnv* env, jobject java_website_settings, content::WebContents* web_contents); - virtual ~WebsiteSettingsPopupAndroid(); + ~WebsiteSettingsPopupAndroid() override; void Destroy(JNIEnv* env, jobject obj); void OnPermissionSettingChanged(JNIEnv* env, jobject obj, @@ -41,12 +41,12 @@ jint setting); // WebsiteSettingsUI implementations. - virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) override; - virtual void SetPermissionInfo( + void SetCookieInfo(const CookieInfoList& cookie_info_list) override; + void SetPermissionInfo( const PermissionInfoList& permission_info_list) override; - virtual void SetIdentityInfo(const IdentityInfo& identity_info) override; - virtual void SetFirstVisit(const base::string16& first_visit) override; - virtual void SetSelectedTab(WebsiteSettingsUI::TabId tab_id) override; + void SetIdentityInfo(const IdentityInfo& identity_info) override; + void SetFirstVisit(const base::string16& first_visit) override; + void SetSelectedTab(WebsiteSettingsUI::TabId tab_id) override; static bool RegisterWebsiteSettingsPopupAndroid(JNIEnv* env);
diff --git a/chrome/browser/ui/android/website_settings_popup_legacy_android.h b/chrome/browser/ui/android/website_settings_popup_legacy_android.h index 66a8d8f..10f2b8c5 100644 --- a/chrome/browser/ui/android/website_settings_popup_legacy_android.h +++ b/chrome/browser/ui/android/website_settings_popup_legacy_android.h
@@ -22,7 +22,7 @@ WebsiteSettingsPopupLegacyAndroid(JNIEnv* env, jobject java_website_settings, content::WebContents* web_contents); - virtual ~WebsiteSettingsPopupLegacyAndroid(); + ~WebsiteSettingsPopupLegacyAndroid() override; void Destroy(JNIEnv* env, jobject obj); // Revokes any current user exceptions for bypassing SSL error interstitials @@ -30,12 +30,12 @@ void ResetCertDecisions(JNIEnv* env, jobject obj, jobject java_web_contents); // WebsiteSettingsUI implementations. - virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) override; - virtual void SetPermissionInfo( + void SetCookieInfo(const CookieInfoList& cookie_info_list) override; + void SetPermissionInfo( const PermissionInfoList& permission_info_list) override; - virtual void SetIdentityInfo(const IdentityInfo& identity_info) override; - virtual void SetFirstVisit(const base::string16& first_visit) override; - virtual void SetSelectedTab(WebsiteSettingsUI::TabId tab_id) override; + void SetIdentityInfo(const IdentityInfo& identity_info) override; + void SetFirstVisit(const base::string16& first_visit) override; + void SetSelectedTab(WebsiteSettingsUI::TabId tab_id) override; static bool RegisterWebsiteSettingsPopupLegacyAndroid(JNIEnv* env);
diff --git a/chrome/browser/ui/android/window_android_helper.h b/chrome/browser/ui/android/window_android_helper.h index 925ca67..e097d11 100644 --- a/chrome/browser/ui/android/window_android_helper.h +++ b/chrome/browser/ui/android/window_android_helper.h
@@ -15,7 +15,7 @@ class WindowAndroidHelper : public content::WebContentsUserData<WindowAndroidHelper> { public: - virtual ~WindowAndroidHelper(); + ~WindowAndroidHelper() override; void SetWindowAndroid(ui::WindowAndroid* window_android); ui::WindowAndroid* GetWindowAndroid();
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc index e08d8ef3..833d3bbe 100644 --- a/chrome/browser/ui/app_list/start_page_service.cc +++ b/chrome/browser/ui/app_list/start_page_service.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/json/json_string_value_serializer.h" #include "base/memory/singleton.h" #include "base/metrics/user_metrics.h" #include "base/prefs/pref_service.h" @@ -17,10 +18,14 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/hotword_service.h" #include "chrome/browser/search/hotword_service_factory.h" +#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/browser/ui/app_list/speech_auth_helper.h" #include "chrome/browser/ui/app_list/speech_recognizer.h" #include "chrome/browser/ui/app_list/start_page_observer.h" #include "chrome/browser/ui/app_list/start_page_service_factory.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -37,7 +42,9 @@ #include "extensions/browser/extension_system_provider.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/common/extension.h" +#include "net/base/load_flags.h" #include "net/base/network_change_notifier.h" +#include "net/url_request/url_fetcher.h" #include "ui/app_list/app_list_switches.h" #if defined(OS_CHROMEOS) @@ -51,6 +58,12 @@ namespace { +// Path to google.com's doodle JSON. +const char kDoodleJsonPath[] = "async/ddljson"; + +// Delay between checking for a new doodle when no doodle is found. +const int kDefaultDoodleRecheckDelayMinutes = 30; + bool InSpeechRecognition(SpeechRecognitionState state) { return state == SPEECH_RECOGNITION_RECOGNIZING || state == SPEECH_RECOGNITION_IN_SPEECH; @@ -88,7 +101,7 @@ class StartPageService::StartPageWebContentsDelegate : public content::WebContentsDelegate { public: - StartPageWebContentsDelegate() {} + explicit StartPageWebContentsDelegate(Profile* profile) : profile_(profile) {} ~StartPageWebContentsDelegate() override {} void RequestMediaAccessPermission( @@ -106,7 +119,50 @@ ->CheckMediaAccessPermission(web_contents, security_origin, type); } + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture, + bool* was_blocked) override { + chrome::ScopedTabbedBrowserDisplayer displayer( + profile_, chrome::GetActiveDesktop()); + // Force all links to open in a new tab, even if they were trying to open a + // new window. + disposition = + disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; + chrome::AddWebContents(displayer.browser(), + nullptr, + new_contents, + disposition, + initial_pos, + user_gesture, + was_blocked); + } + + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override { + // Force all links to open in a new tab, even if they were trying to open a + // window. + chrome::NavigateParams new_tab_params( + static_cast<Browser*>(nullptr), params.url, params.transition); + if (params.disposition == NEW_BACKGROUND_TAB) { + new_tab_params.disposition = NEW_BACKGROUND_TAB; + } else { + new_tab_params.disposition = NEW_FOREGROUND_TAB; + new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW; + } + + new_tab_params.initiating_profile = profile_; + chrome::Navigate(&new_tab_params); + + return new_tab_params.target_contents; + } + private: + Profile* profile_; + DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate); }; @@ -283,6 +339,7 @@ if (HotwordService::IsExperimentalHotwordingEnabled() && speech_recognizer_) { speech_recognizer_->Stop(); + speech_recognizer_.reset(); } #if defined(OS_CHROMEOS) @@ -472,12 +529,14 @@ for (const auto& cb : pending_webui_callbacks_) cb.Run(); pending_webui_callbacks_.clear(); + + FetchDoodleJson(); } void StartPageService::LoadContents() { contents_.reset(content::WebContents::Create( content::WebContents::CreateParams(profile_))); - contents_delegate_.reset(new StartPageWebContentsDelegate()); + contents_delegate_.reset(new StartPageWebContentsDelegate(profile_)); contents_->SetDelegate(contents_delegate_.get()); // The ZoomController needs to be created before the web contents is observed @@ -498,4 +557,63 @@ webui_finished_loading_ = false; } +void StartPageService::FetchDoodleJson() { + // SetPathStr() requires its argument to stay in scope as long as + // |replacements| is, so a std::string is needed, instead of a char*. + std::string path = kDoodleJsonPath; + GURL::Replacements replacements; + replacements.SetPathStr(path); + + GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()); + GURL doodle_url = google_base_url.ReplaceComponents(replacements); + doodle_fetcher_.reset( + net::URLFetcher::Create(0, doodle_url, net::URLFetcher::GET, this)); + doodle_fetcher_->SetRequestContext(profile_->GetRequestContext()); + doodle_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); + doodle_fetcher_->Start(); +} + +void StartPageService::OnURLFetchComplete(const net::URLFetcher* source) { + std::string json_data; + source->GetResponseAsString(&json_data); + + // Remove XSSI guard for JSON parsing. + size_t json_start_index = json_data.find("{"); + if (json_start_index != std::string::npos) + json_data.erase(0, json_start_index); + + JSONStringValueSerializer deserializer(json_data); + deserializer.set_allow_trailing_comma(true); + int error_code = 0; + scoped_ptr<base::Value> doodle_json( + deserializer.Deserialize(&error_code, nullptr)); + + base::TimeDelta recheck_delay = + base::TimeDelta::FromMinutes(kDefaultDoodleRecheckDelayMinutes); + + if (error_code == 0) { + base::DictionaryValue* doodle_dictionary = nullptr; + // Use the supplied TTL as the recheck delay if available. + if (doodle_json->GetAsDictionary(&doodle_dictionary)) { + int time_to_live = 0; + if (doodle_dictionary->GetInteger("ddljson.time_to_live_ms", + &time_to_live)) { + recheck_delay = base::TimeDelta::FromMilliseconds(time_to_live); + } + } + + contents_->GetWebUI()->CallJavascriptFunction( + "appList.startPage.onAppListDoodleUpdated", *doodle_json, + base::StringValue( + UIThreadSearchTermsData(profile_).GoogleBaseURLValue())); + } + + // Check for a new doodle. + content::BrowserThread::PostDelayedTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&StartPageService::FetchDoodleJson, + weak_factory_.GetWeakPtr()), + recheck_delay); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/start_page_service.h b/chrome/browser/ui/app_list/start_page_service.h index 84590fb..7a7872b 100644 --- a/chrome/browser/ui/app_list/start_page_service.h +++ b/chrome/browser/ui/app_list/start_page_service.h
@@ -21,6 +21,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "net/url_request/url_fetcher_delegate.h" #include "ui/app_list/speech_ui_model_observer.h" namespace content { @@ -33,6 +34,10 @@ class Extension; } +namespace net { +class URLFetcher; +} + class Profile; namespace app_list { @@ -45,6 +50,7 @@ // and hosts the start page contents. class StartPageService : public KeyedService, public content::WebContentsObserver, + public net::URLFetcherDelegate, public SpeechRecognizerDelegate { public: typedef std::vector<scoped_refptr<const extensions::Extension> > @@ -112,6 +118,12 @@ void LoadContents(); void UnloadContents(); + // Fetch the Google Doodle JSON data and update the app list start page. + void FetchDoodleJson(); + + // net::URLFetcherDelegate overrides: + void OnURLFetchComplete(const net::URLFetcher* source) override; + // KeyedService overrides: void Shutdown() override; @@ -152,6 +164,8 @@ #endif scoped_ptr<NetworkChangeObserver> network_change_observer_; + scoped_ptr<net::URLFetcher> doodle_fetcher_; + base::WeakPtrFactory<StartPageService> weak_factory_; DISALLOW_COPY_AND_ASSIGN(StartPageService);
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.cc b/chrome/browser/ui/apps/chrome_app_delegate.cc index 36a96d22..d5740a1 100644 --- a/chrome/browser/ui/apps/chrome_app_delegate.cc +++ b/chrome/browser/ui/apps/chrome_app_delegate.cc
@@ -219,7 +219,7 @@ void ChromeAppDelegate::AddNewContents(content::BrowserContext* context, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { if (!disable_external_open_for_testing_) { @@ -240,7 +240,7 @@ NULL, new_contents, disposition, - initial_pos, + initial_rect, user_gesture, was_blocked); }
diff --git a/chrome/browser/ui/apps/chrome_app_delegate.h b/chrome/browser/ui/apps/chrome_app_delegate.h index 4e7c7d4f..e1224a3 100644 --- a/chrome/browser/ui/apps/chrome_app_delegate.h +++ b/chrome/browser/ui/apps/chrome_app_delegate.h
@@ -40,7 +40,7 @@ void AddNewContents(content::BrowserContext* context, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index 930954b..504d04e4 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -50,7 +50,7 @@ #include "ash/test/test_session_state_delegate.h" #include "ash/test/test_shell_delegate.h" #include "chrome/browser/apps/scoped_keep_alive.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/ui/apps/chrome_app_delegate.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" @@ -62,6 +62,7 @@ #include "chrome/common/chrome_switches.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 "content/public/browser/web_contents_observer.h" #include "content/public/test/test_utils.h" #include "extensions/browser/app_window/app_window_contents.h" @@ -779,8 +780,8 @@ profile_manager_->SetLoggedIn(true); // Initialize the UserManager singleton to a fresh FakeUserManager instance. - user_manager_enabler_.reset( - new chromeos::ScopedUserManagerEnabler(new chromeos::FakeUserManager)); + user_manager_enabler_.reset(new chromeos::ScopedUserManagerEnabler( + new chromeos::FakeChromeUserManager)); // Initialize the rest. ChromeLauncherControllerTest::SetUp(); @@ -906,8 +907,8 @@ typedef std::map<Profile*, std::string> ProfileToNameMap; TestingProfileManager* profile_manager() { return profile_manager_.get(); } - chromeos::FakeUserManager* GetFakeUserManager() { - return static_cast<chromeos::FakeUserManager*>( + chromeos::FakeChromeUserManager* GetFakeUserManager() { + return static_cast<chromeos::FakeChromeUserManager*>( user_manager::UserManager::Get()); }
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc index 8f0b79f..37da1a4b 100644 --- a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
@@ -8,7 +8,7 @@ #include <vector> #include "base/run_loop.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/policy/policy_cert_service.h" @@ -50,8 +50,9 @@ ~SessionStateDelegateChromeOSTest() override {} void SetUp() override { - // Initialize the UserManager singleton to a fresh FakeUserManager instance. - user_manager_ = new chromeos::FakeUserManager; + // Initialize the UserManager singleton to a fresh FakeChromeUserManager + // instance. + user_manager_ = new FakeChromeUserManager; user_manager_enabler_.reset( new chromeos::ScopedUserManagerEnabler(user_manager_)); @@ -89,7 +90,7 @@ return user_manager::UserManager::Get()->GetActiveUser()->email(); } - chromeos::FakeUserManager* user_manager() { return user_manager_; } + FakeChromeUserManager* user_manager() { return user_manager_; } SessionStateDelegateChromeos* session_state_delegate() { return session_state_delegate_.get(); } @@ -119,7 +120,7 @@ scoped_ptr<SessionStateDelegateChromeos> session_state_delegate_; // Not owned. - chromeos::FakeUserManager* user_manager_; + FakeChromeUserManager* user_manager_; DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateChromeOSTest); };
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.cc b/chrome/browser/ui/auto_login_infobar_delegate.cc index c4e20c0f..9cb09d7 100644 --- a/chrome/browser/ui/auto_login_infobar_delegate.cc +++ b/chrome/browser/ui/auto_login_infobar_delegate.cc
@@ -49,15 +49,15 @@ public: AutoLoginRedirector(content::WebContents* web_contents, const std::string& args); - virtual ~AutoLoginRedirector(); + ~AutoLoginRedirector() override; private: // Overriden from UbertokenConsumer: - virtual void OnUbertokenSuccess(const std::string& token) override; - virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) override; + void OnUbertokenSuccess(const std::string& token) override; + void OnUbertokenFailure(const GoogleServiceAuthError& error) override; // Implementation of content::WebContentsObserver - virtual void WebContentsDestroyed() override; + void WebContentsDestroyed() override; // Redirect tab to MergeSession URL, logging the user in and navigating // to the desired page.
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.h b/chrome/browser/ui/auto_login_infobar_delegate.h index 7877240b..07b4f5b 100644 --- a/chrome/browser/ui/auto_login_infobar_delegate.h +++ b/chrome/browser/ui/auto_login_infobar_delegate.h
@@ -50,24 +50,24 @@ }; AutoLoginInfoBarDelegate(const Params& params, Profile* profile); - virtual ~AutoLoginInfoBarDelegate(); + ~AutoLoginInfoBarDelegate() override; void RecordHistogramAction(Actions action); private: // ConfirmInfoBarDelegate: - virtual void InfoBarDismissed() override; - virtual int GetIconID() const override; - virtual Type GetInfoBarType() const override; - virtual AutoLoginInfoBarDelegate* AsAutoLoginInfoBarDelegate() override; - virtual base::string16 GetMessageText() const override; - virtual base::string16 GetButtonLabel(InfoBarButton button) const override; - virtual bool Accept() override; - virtual bool Cancel() override; + void InfoBarDismissed() override; + int GetIconID() const override; + Type GetInfoBarType() const override; + AutoLoginInfoBarDelegate* AsAutoLoginInfoBarDelegate() override; + base::string16 GetMessageText() const override; + base::string16 GetButtonLabel(InfoBarButton button) const override; + bool Accept() override; + bool Cancel() override; // SigninManagerBase::Observer: - virtual void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + void GoogleSignedOut(const std::string& account_id, + const std::string& username) override; const Params params_;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.cc b/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.cc index b1737ea..5dba33b 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.cc
@@ -89,12 +89,12 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { chrome::AddWebContents( chrome::FindBrowserWithWebContents(originating_web_contents_), - source, new_contents, disposition, initial_pos, user_gesture, + source, new_contents, disposition, initial_rect, user_gesture, was_blocked); }
diff --git a/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h b/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h index cd4b6378..e81bf808 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h +++ b/chrome/browser/ui/autofill/autofill_dialog_sign_in_delegate.h
@@ -38,7 +38,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; bool PreHandleGestureEvent(content::WebContents* source,
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 436a15ed..f438efd2 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1391,10 +1391,10 @@ void Browser::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { - chrome::AddWebContents(this, source, new_contents, disposition, initial_pos, + chrome::AddWebContents(this, source, new_contents, disposition, initial_rect, user_gesture, was_blocked); }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 8478d97..ff72aa55 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -548,7 +548,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void ActivateContents(content::WebContents* contents) override;
diff --git a/chrome/browser/ui/browser_tabstrip.cc b/chrome/browser/ui/browser_tabstrip.cc index b307c93a..bb20e62 100644 --- a/chrome/browser/ui/browser_tabstrip.cc +++ b/chrome/browser/ui/browser_tabstrip.cc
@@ -48,7 +48,7 @@ content::WebContents* source_contents, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { // No code for this yet. @@ -59,7 +59,7 @@ NavigateParams params(browser, new_contents); params.source_contents = source_contents; params.disposition = disposition; - params.window_bounds = initial_pos; + params.window_bounds = initial_rect; params.window_action = NavigateParams::SHOW_WINDOW; // At this point, we're already beyond the popup blocker. Even if the popup // was created without a user gesture, we have to set |user_gesture| to true,
diff --git a/chrome/browser/ui/browser_tabstrip.h b/chrome/browser/ui/browser_tabstrip.h index 6a21c28..958b5815 100644 --- a/chrome/browser/ui/browser_tabstrip.h +++ b/chrome/browser/ui/browser_tabstrip.h
@@ -37,14 +37,15 @@ // Creates a new tab with the already-created WebContents 'new_contents'. // The window for the added contents will be reparented correctly when this -// method returns. If |disposition| is NEW_POPUP, |pos| should hold the -// initial position. If |was_blocked| is non-NULL, then |*was_blocked| will be -// set to true if the popup gets blocked, and left unchanged otherwise. +// method returns. If |disposition| is NEW_POPUP, |initial_rect| should hold +// the initial position and size. If |was_blocked| is non-NULL, then +// |*was_blocked| will be set to true if the popup gets blocked, and left +// unchanged otherwise. void AddWebContents(Browser* browser, content::WebContents* source_contents, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was__blocked);
diff --git a/chrome/browser/ui/cocoa/background_gradient_view.h b/chrome/browser/ui/cocoa/background_gradient_view.h index e8b6c2d..1f6c7e8 100644 --- a/chrome/browser/ui/cocoa/background_gradient_view.h +++ b/chrome/browser/ui/cocoa/background_gradient_view.h
@@ -7,9 +7,11 @@ #import <Cocoa/Cocoa.h> +#import "chrome/browser/ui/cocoa/themed_window.h" + // A custom view that draws a 'standard' background gradient. // Base class for other Chromium views. -@interface BackgroundGradientView : NSView { +@interface BackgroundGradientView : NSView<ThemedWindowDrawing> { @private BOOL showsDivider_; }
diff --git a/chrome/browser/ui/cocoa/background_gradient_view.mm b/chrome/browser/ui/cocoa/background_gradient_view.mm index 1cb6c2f6..fe58356 100644 --- a/chrome/browser/ui/cocoa/background_gradient_view.mm +++ b/chrome/browser/ui/cocoa/background_gradient_view.mm
@@ -111,43 +111,14 @@ return themeProvider->GetNSImageColorNamed(IDR_THEME_TOOLBAR); } -- (void)windowFocusDidChange:(NSNotification*)notification { - // Some child views will indirectly use BackgroundGradientView by calling an - // ancestor's draw function (e.g, BookmarkButtonView). Call setNeedsDisplay - // on all descendants to ensure that these views re-draw. - // TODO(ccameron): Enable these views to listen for focus notifications - // directly. - [self cr_recursivelySetNeedsDisplay:YES]; -} - -- (void)viewWillMoveToWindow:(NSWindow*)window { +- (void)viewDidMoveToWindow { + [super viewDidMoveToWindow]; if ([self window]) { - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:NSWindowDidBecomeKeyNotification - object:[self window]]; - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:NSWindowDidBecomeMainNotification - object:[self window]]; - } - if (window) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(windowFocusDidChange:) - name:NSWindowDidBecomeMainNotification - object:window]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(windowFocusDidChange:) - name:NSWindowDidResignMainNotification - object:window]; // The new window for the view may have a different focus state than the // last window this view was part of. Force a re-draw to ensure that the // view draws the right state. - [self windowFocusDidChange:nil]; + [self windowDidChangeActive]; } - [super viewWillMoveToWindow:window]; } - (void)setFrameOrigin:(NSPoint)origin { @@ -159,4 +130,14 @@ [super setFrameOrigin:origin]; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h index 83c6fbe..51bad93 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.h
@@ -5,6 +5,7 @@ #import <Cocoa/Cocoa.h> #include <vector> #import "chrome/browser/ui/cocoa/draggable_button.h" +#import "chrome/browser/ui/cocoa/themed_window.h" #include "ui/base/window_open_disposition.h" @class BookmarkBarFolderController; @@ -189,7 +190,7 @@ // Class for bookmark bar buttons that can be drag sources. -@interface BookmarkButton : DraggableButton { +@interface BookmarkButton : DraggableButton<ThemedWindowDrawing> { @private IBOutlet NSObject<BookmarkButtonDelegate>* delegate_; // Weak.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm index ffaefda..449e766 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm
@@ -416,6 +416,16 @@ [super drawRect:rect]; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end @implementation BookmarkButton(Private)
diff --git a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.h b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.h index 7293b4b..cfcd3452 100644 --- a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.h +++ b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.h
@@ -48,8 +48,6 @@ ui::ScopedCrTrackingArea trackingArea_; } -@property(nonatomic) ZoomBubbleControllerDelegate* delegate; - // Creates the bubble for a parent window but does not show it. - (id)initWithParentWindow:(NSWindow*)parentWindow delegate:(ZoomBubbleControllerDelegate*)delegate;
diff --git a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm index 05c9221..234eb6d 100644 --- a/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/browser/zoom_bubble_controller.mm
@@ -75,8 +75,6 @@ @implementation ZoomBubbleController -@synthesize delegate = delegate_; - - (id)initWithParentWindow:(NSWindow*)parentWindow delegate:(ZoomBubbleControllerDelegate*)delegate { base::scoped_nsobject<InfoBubbleWindow> window( @@ -128,10 +126,6 @@ } - (void)onZoomChanged { - // |delegate_| may be set null by this object's owner. - if (!delegate_) - return; - // TODO(shess): It may be appropriate to close the window if // |contents| or |zoomController| are NULL. But they can be NULL in // tests. @@ -175,11 +169,8 @@ } - (void)windowWillClose:(NSNotification*)notification { - // |delegate_| may be set null by this object's owner. - if (delegate_) { - delegate_->OnClose(); - delegate_ = NULL; - } + delegate_->OnClose(); + delegate_ = NULL; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(autoCloseBubble) object:nil];
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index dbc7b22..151ae0e 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -619,26 +619,20 @@ BrowserList::SetLastActive(browser_.get()); [self saveWindowPositionIfNeeded]; - // TODO(dmaclach): Instead of redrawing the whole window, views that care - // about the active window state should be registering for notifications. - [[self window] setViewsNeedDisplay:YES]; - - // TODO(viettrungluu): For some reason, the above doesn't suffice. - if ([self isInAnyFullscreenMode]) - [floatingBarBackingView_ setNeedsDisplay:YES]; // Okay even if nil. + [[[self window] contentView] cr_recursivelyInvokeBlock:^(id view) { + if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)]) + [view windowDidChangeActive]; + }]; extensions::ExtensionCommandsGlobalRegistry::Get(browser_->profile()) ->set_registry_for_active_window(extension_keybinding_registry_.get()); } - (void)windowDidResignMain:(NSNotification*)notification { - // TODO(dmaclach): Instead of redrawing the whole window, views that care - // about the active window state should be registering for notifications. - [[self window] setViewsNeedDisplay:YES]; - - // TODO(viettrungluu): For some reason, the above doesn't suffice. - if ([self isInAnyFullscreenMode]) - [floatingBarBackingView_ setNeedsDisplay:YES]; // Okay even if nil. + [[[self window] contentView] cr_recursivelyInvokeBlock:^(id view) { + if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)]) + [view windowDidChangeActive]; + }]; extensions::ExtensionCommandsGlobalRegistry::Get(browser_->profile()) ->set_registry_for_active_window(nullptr); @@ -1702,7 +1696,15 @@ } - (void)userChangedTheme { - [[[[self window] contentView] superview] cr_recursivelySetNeedsDisplay:YES]; + NSView* rootView = [[[self window] contentView] superview]; + [rootView cr_recursivelyInvokeBlock:^(id view) { + if ([view conformsToProtocol:@protocol(ThemedWindowDrawing)]) + [view windowDidChangeTheme]; + + // TODO(andresantoso): Remove this once all themed views respond to + // windowDidChangeTheme above. + [view setNeedsDisplay:YES]; + }]; } - (ui::ThemeProvider*)themeProvider {
diff --git a/chrome/browser/ui/cocoa/download/download_item_button.h b/chrome/browser/ui/cocoa/download/download_item_button.h index ecc2ee3..e012491 100644 --- a/chrome/browser/ui/cocoa/download/download_item_button.h +++ b/chrome/browser/ui/cocoa/download/download_item_button.h
@@ -6,12 +6,14 @@ #include "base/files/file_path.h" #import "chrome/browser/ui/cocoa/draggable_button.h" +#import "chrome/browser/ui/cocoa/themed_window.h" @class DownloadItemController; // A button that is a drag source for a file and that displays a context menu // instead of firing an action when clicked in a certain area. -@interface DownloadItemButton : DraggableButton<NSMenuDelegate> { +@interface DownloadItemButton + : DraggableButton<NSMenuDelegate, ThemedWindowDrawing> { @private base::FilePath downloadPath_; DownloadItemController* controller_; // weak
diff --git a/chrome/browser/ui/cocoa/download/download_item_button.mm b/chrome/browser/ui/cocoa/download/download_item_button.mm index 7c88b1d1..141976df 100644 --- a/chrome/browser/ui/cocoa/download/download_item_button.mm +++ b/chrome/browser/ui/cocoa/download/download_item_button.mm
@@ -74,4 +74,14 @@ [super drawRect:rect]; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/download/download_show_all_button.h b/chrome/browser/ui/cocoa/download/download_show_all_button.h index ceb51f6..6e1afe1 100644 --- a/chrome/browser/ui/cocoa/download/download_show_all_button.h +++ b/chrome/browser/ui/cocoa/download/download_show_all_button.h
@@ -4,7 +4,9 @@ #import <Cocoa/Cocoa.h> +#import "chrome/browser/ui/cocoa/themed_window.h" + // The "Show All" button on the download shelf. This is a subclass for custom // -sizeToFit logic. -@interface DownloadShowAllButton : NSButton +@interface DownloadShowAllButton : NSButton<ThemedWindowDrawing> @end
diff --git a/chrome/browser/ui/cocoa/download/download_show_all_button.mm b/chrome/browser/ui/cocoa/download/download_show_all_button.mm index 12201122..6a91543 100644 --- a/chrome/browser/ui/cocoa/download/download_show_all_button.mm +++ b/chrome/browser/ui/cocoa/download/download_show_all_button.mm
@@ -48,4 +48,14 @@ [super drawRect:rect]; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/floating_bar_backing_view.h b/chrome/browser/ui/cocoa/floating_bar_backing_view.h index 9240d063..bfd4114 100644 --- a/chrome/browser/ui/cocoa/floating_bar_backing_view.h +++ b/chrome/browser/ui/cocoa/floating_bar_backing_view.h
@@ -7,8 +7,10 @@ #import <Cocoa/Cocoa.h> +#import "chrome/browser/ui/cocoa/themed_window.h" + // A custom view that draws the tab strip background for fullscreen windows. -@interface FloatingBarBackingView : NSView +@interface FloatingBarBackingView : NSView<ThemedWindowDrawing> @end #endif // CHROME_BROWSER_UI_COCOA_FLOATING_BAR_BACKING_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/floating_bar_backing_view.mm b/chrome/browser/ui/cocoa/floating_bar_backing_view.mm index 8e54948..96a5fff 100644 --- a/chrome/browser/ui/cocoa/floating_bar_backing_view.mm +++ b/chrome/browser/ui/cocoa/floating_bar_backing_view.mm
@@ -45,4 +45,14 @@ ui::WindowTitlebarReceivedDoubleClick([self window], self); } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end // @implementation FloatingBarBackingView
diff --git a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.h b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.h index db09902..90ef008 100644 --- a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.h
@@ -33,7 +33,6 @@ // Shows the zoom bubble for this decoration. If |auto_close| is YES, then // the bubble will automatically close after a fixed period of time. - // If a bubble is already showing, the |auto_close| timer is reset. void ShowBubble(BOOL auto_close); // Closes the zoom bubble.
diff --git a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm index 3db743d..7306dd1 100644 --- a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
@@ -23,7 +23,6 @@ ZoomDecoration::~ZoomDecoration() { [bubble_ closeWithoutAnimation]; - bubble_.delegate = nil; } bool ZoomDecoration::UpdateIfNecessary( @@ -49,11 +48,8 @@ } void ZoomDecoration::ShowBubble(BOOL auto_close) { - if (bubble_) { - bubble_.delegate = nil; - [bubble_.window orderOut:nil]; - [bubble_ closeWithoutAnimation]; - } + if (bubble_) + return; content::WebContents* web_contents = owner_->GetWebContents(); if (!web_contents) @@ -142,7 +138,6 @@ } void ZoomDecoration::OnClose() { - bubble_.delegate = nil; bubble_ = nil; // If the page is at default zoom then hiding the zoom decoration
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm index b86fd554..cc43140 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -25,7 +25,6 @@ #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/signin/local_auth.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_header_helper.h" #include "chrome/browser/signin/signin_manager_factory.h"
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index c08665e..f309e443 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -276,9 +276,6 @@ return NO; } -- (void)drawRect:(NSRect)rect { -} - - (id)initWithFrame:(NSRect)frameRect controller:(TabStripController*)controller { if ((self = [super initWithFrame:frameRect])) {
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view.h b/chrome/browser/ui/cocoa/tabs/tab_strip_view.h index c919671..931ad3f 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_view.h +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view.h
@@ -8,7 +8,7 @@ #import <Cocoa/Cocoa.h> #include "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/background_gradient_view.h" +#import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/url_drop_target.h" @class NewTabButton; @@ -17,7 +17,7 @@ // A view class that handles rendering the tab strip and drops of URLS with // a positioning locator for drop feedback. -@interface TabStripView : BackgroundGradientView<URLDropTarget> { +@interface TabStripView : NSView<ThemedWindowDrawing, URLDropTarget> { @private TabStripController* controller_; // Weak; owns us.
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm index e3ccd72..c2951e43 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm
@@ -64,8 +64,8 @@ // Themes don't have an inactive image so only look for one if there's no // theme. - bool active = [[self window] isKeyWindow] || [[self window] isMainWindow] || - !themeProvider->UsingDefaultTheme(); + bool active = + [[self window] isMainWindow] || !themeProvider->UsingDefaultTheme(); int resource_id = active ? IDR_THEME_TOOLBAR : IDR_THEME_TOOLBAR_INACTIVE; [themeProvider->GetNSImageColorNamed(resource_id) set]; NSRectFill( @@ -81,7 +81,7 @@ borderRect.size.height = [image size].height; borderRect.origin.y = 0; - BOOL focused = [[self window] isKeyWindow] || [[self window] isMainWindow]; + BOOL focused = [[self window] isMainWindow]; NSDrawThreePartImage(borderRect, nil, image, nil, /*vertical=*/ NO, NSCompositeSourceOver, focused ? 1.0 : tabs::kImageNoFocusAlpha, @@ -296,4 +296,14 @@ controller_ = controller; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.h b/chrome/browser/ui/cocoa/tabs/tab_view.h index a307bab..e549e0c 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view.h +++ b/chrome/browser/ui/cocoa/tabs/tab_view.h
@@ -11,6 +11,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsobject.h" #import "chrome/browser/ui/cocoa/hover_close_button.h" +#import "chrome/browser/ui/cocoa/themed_window.h" namespace tabs { @@ -42,7 +43,7 @@ // on the tab strip. Relies on an associated TabController to provide a // target/action for selecting the tab. -@interface TabView : NSView { +@interface TabView : NSView<ThemedWindowDrawing> { @private TabController* controller_; base::scoped_nsobject<NSTextField> titleView_;
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm index 640e194..34acb5c 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_view.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm
@@ -314,8 +314,8 @@ // Themes don't have an inactive image so only look for one if there's no // theme. - bool active = [[self window] isKeyWindow] || [[self window] isMainWindow] || - !themeProvider->UsingDefaultTheme(); + bool active = + [[self window] isMainWindow] || !themeProvider->UsingDefaultTheme(); return themeProvider->GetNSImageColorNamed(bitmapResources[active][selected]); } @@ -429,7 +429,7 @@ // Draws the tab outline. - (void)drawStroke:(NSRect)dirtyRect { - BOOL focused = [[self window] isKeyWindow] || [[self window] isMainWindow]; + BOOL focused = [[self window] isMainWindow]; CGFloat alpha = focused ? 1.0 : tabs::kImageNoFocusAlpha; ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); @@ -641,6 +641,16 @@ return VIEW_ID_TAB; } +// ThemedWindowDrawing implementation. + +- (void)windowDidChangeTheme { + [self setNeedsDisplay:YES]; +} + +- (void)windowDidChangeActive { + [self setNeedsDisplay:YES]; +} + @end // @implementation TabView @implementation TabView (TabControllerInterface)
diff --git a/chrome/browser/ui/cocoa/themed_window.h b/chrome/browser/ui/cocoa/themed_window.h index 592e5672..ab4b18c 100644 --- a/chrome/browser/ui/cocoa/themed_window.h +++ b/chrome/browser/ui/cocoa/themed_window.h
@@ -32,7 +32,6 @@ }; // Implemented by windows that support theming. - @interface NSWindow (ThemeProvider) - (ThemeProvider*)themeProvider; - (ThemedWindowStyle)themedWindowStyle; @@ -45,4 +44,17 @@ - (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment; @end +// Adopted by views that want to redraw when the theme changed, or when the +// window's active status changed. +@protocol ThemedWindowDrawing + +// Called by the window controller when the theme changed. +- (void)windowDidChangeTheme; + +// Called by the window controller when the window gained or lost main window +// status. +- (void)windowDidChangeActive; + +@end + #endif // CHROME_BROWSER_UI_COCOA_THEMED_WINDOW_H_
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm index f4ef84d8..3034b38 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm
@@ -7,6 +7,7 @@ #import "chrome/browser/ui/cocoa/themed_window.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #import "ui/base/cocoa/nsgraphics_context_additions.h" +#import "ui/base/cocoa/nsview_additions.h" @implementation ToolbarView @@ -48,4 +49,11 @@ return YES; } +// ThemedWindowDrawing overrides. + +- (void)windowDidChangeActive { + // Need to redraw the omnibox and toolbar buttons as well. + [self cr_recursivelySetNeedsDisplay:YES]; +} + @end
diff --git a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm index 2c9f2db..b66c86c 100644 --- a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm +++ b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
@@ -67,7 +67,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void LoadingStateChanged(content::WebContents* source, @@ -225,15 +225,15 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { if (delegate_ && delegate_->HandleAddNewContents( - source, new_contents, disposition, initial_pos, user_gesture)) { + source, new_contents, disposition, initial_rect, user_gesture)) { return; } WebDialogWebContentsDelegate::AddNewContents( - source, new_contents, disposition, initial_pos, user_gesture, + source, new_contents, disposition, initial_rect, user_gesture, was_blocked); }
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index 0b55989..f2d1ce3 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -288,7 +288,8 @@ if (popup_host_) { // Lazily register for notifications about extension host destructions. static const int kType = extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED; - content::Source<content::BrowserContext> source(browser_->profile()); + content::Source<content::BrowserContext> source( + browser_->profile()->GetOriginalProfile()); if (!registrar_.IsRegistered(this, kType, source)) registrar_.Add(this, kType, source);
diff --git a/chrome/browser/ui/navigation_correction_tab_observer.cc b/chrome/browser/ui/navigation_correction_tab_observer.cc index d59f3e9e..6be6a9f 100644 --- a/chrome/browser/ui/navigation_correction_tab_observer.cc +++ b/chrome/browser/ui/navigation_correction_tab_observer.cc
@@ -7,9 +7,9 @@ #include "base/prefs/pref_service.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/google/google_profile_helper.h" #include "chrome/browser/google/google_url_tracker_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "components/google/core/browser/google_util.h" @@ -95,13 +95,12 @@ void NavigationCorrectionTabObserver::UpdateNavigationCorrectionInfo( RenderViewHost* rvh) { RenderFrameHost* rfh = rvh->GetMainFrame(); + GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()); rfh->Send(new ChromeViewMsg_SetNavigationCorrectionInfo( rfh->GetRoutingID(), GetNavigationCorrectionURL(), google_util::GetGoogleLocale(g_browser_process->GetApplicationLocale()), - google_util::GetGoogleCountryCode( - google_profile_helper::GetGoogleHomePageURL(profile_)), + google_util::GetGoogleCountryCode(google_base_url), google_apis::GetAPIKey(), - google_util::GetGoogleSearchURL( - google_profile_helper::GetGoogleHomePageURL(profile_)))); + google_util::GetGoogleSearchURL(google_base_url))); }
diff --git a/chrome/browser/ui/panels/panel_host.cc b/chrome/browser/ui/panels/panel_host.cc index c3353cf..e1113d8 100644 --- a/chrome/browser/ui/panels/panel_host.cc +++ b/chrome/browser/ui/panels/panel_host.cc
@@ -138,7 +138,7 @@ void PanelHost::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { chrome::NavigateParams navigate_params(profile_, new_contents->GetURL(), @@ -150,7 +150,7 @@ navigate_params.disposition = disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; - navigate_params.window_bounds = initial_pos; + navigate_params.window_bounds = initial_rect; navigate_params.user_gesture = user_gesture; navigate_params.extension_app_id = panel_->extension_id(); chrome::Navigate(&navigate_params);
diff --git a/chrome/browser/ui/panels/panel_host.h b/chrome/browser/ui/panels/panel_host.h index 960aa17..ccca8415 100644 --- a/chrome/browser/ui/panels/panel_host.h +++ b/chrome/browser/ui/panels/panel_host.h
@@ -56,7 +56,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void ActivateContents(content::WebContents* contents) override;
diff --git a/chrome/browser/ui/screen_capture_notification_ui_stub.cc b/chrome/browser/ui/screen_capture_notification_ui_stub.cc index 18dafa2d..0eab3ee9 100644 --- a/chrome/browser/ui/screen_capture_notification_ui_stub.cc +++ b/chrome/browser/ui/screen_capture_notification_ui_stub.cc
@@ -10,10 +10,9 @@ class ScreenCaptureNotificationUIStub : public ScreenCaptureNotificationUI { public: ScreenCaptureNotificationUIStub() {} - virtual ~ScreenCaptureNotificationUIStub() {} + ~ScreenCaptureNotificationUIStub() override {} - virtual gfx::NativeViewId OnStarted(const base::Closure& stop_callback) - override { + gfx::NativeViewId OnStarted(const base::Closure& stop_callback) override { NOTIMPLEMENTED(); return 0; }
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 238fdb5a..50e42fa 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -600,6 +600,11 @@ silent_launch = true; } + // If --no-startup-window is specified and Chrome is already running then do + // not open a new window. + if (!process_startup && command_line.HasSwitch(switches::kNoStartupWindow)) + silent_launch = true; + // If we don't want to launch a new browser window or tab we are done here. if (silent_launch) return true;
diff --git a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc index be34584..fcc3f7a 100644 --- a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc +++ b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc
@@ -69,6 +69,10 @@ DCHECK(!popup_); // We should never have a visible popup at shutdown. if (context_menu_owner == this) context_menu_owner = nullptr; + // Since the popup close process is asynchronous, it might not be fully closed + // at shutdown. We still need to cleanup, though. + if (popup_) + CleanupPopup(true); UnregisterCommand(false); }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index f511213..cd9b39d6 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -64,6 +64,7 @@ #include "components/search_engines/template_url_service.h" #include "components/translate/core/browser/language_state.h" #include "components/ui/zoom/zoom_controller.h" +#include "components/ui/zoom/zoom_event_manager.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" @@ -193,6 +194,9 @@ if (browser_) browser_->search_model()->AddObserver(this); + + ui_zoom::ZoomEventManager::GetForBrowserContext(profile) + ->AddZoomEventManagerObserver(this); } LocationBarView::~LocationBarView() { @@ -200,6 +204,9 @@ template_url_service_->RemoveObserver(this); if (browser_) browser_->search_model()->RemoveObserver(this); + + ui_zoom::ZoomEventManager::GetForBrowserContext(profile()) + ->RemoveZoomEventManagerObserver(this); } //////////////////////////////////////////////////////////////////////////////// @@ -1153,6 +1160,10 @@ return was_visible != zoom_view_->visible(); } +void LocationBarView::OnDefaultZoomLevelChanged() { + RefreshZoomView(); +} + void LocationBarView::RefreshTranslateIcon() { if (!TranslateService::IsTranslateBubbleEnabled()) return;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 17385d9..38fa64d1 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -20,6 +20,7 @@ #include "chrome/browser/ui/views/extensions/extension_popup.h" #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" #include "components/search_engines/template_url_service_observer.h" +#include "components/ui/zoom/zoom_event_manager_observer.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/font.h" #include "ui/gfx/geometry/rect.h" @@ -83,7 +84,8 @@ public DropdownBarHostDelegate, public gfx::AnimationDelegate, public TemplateURLServiceObserver, - public SearchModelObserver { + public SearchModelObserver, + public ui_zoom::ZoomEventManagerObserver { public: // The location bar view's class name. static const char kViewClassName[]; @@ -259,6 +261,10 @@ ToolbarModel* GetToolbarModel() override; content::WebContents* GetWebContents() override; + // ZoomEventManagerObserver: + // Updates the view for the zoom icon when default zoom levels change. + void OnDefaultZoomLevelChanged() override; + // Thickness of the edges of the omnibox background images, in normal mode. static const int kNormalEdgeThickness; // The same, but for popup mode.
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 86f0e2a..188dc8c7 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/profiles/profile_metrics.h" #include "chrome/browser/profiles/profile_window.h" #include "chrome/browser/profiles/profiles_state.h" -#include "chrome/browser/signin/local_auth.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_header_helper.h" #include "chrome/browser/signin/signin_manager_factory.h"
diff --git a/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc b/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc index f27a5dd..10187367 100644 --- a/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc +++ b/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
@@ -119,6 +119,7 @@ *accel = ui::Accelerator(ui::VKEY_R, ui::EF_CONTROL_DOWN); return true; + case IDC_CONTENT_CONTEXT_SAVEAVAS: case IDC_SAVE_PAGE: *accel = ui::Accelerator(ui::VKEY_S, ui::EF_CONTROL_DOWN); return true;
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc index ca1bec93..286863e4 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -22,8 +22,6 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/test/test_utils.h" @@ -54,6 +52,7 @@ file_selected_ = true; path_ = path; params_ = params; + QuitMessageLoop(); } void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& selected_file_info, int index, @@ -61,17 +60,31 @@ FileSelected(selected_file_info.local_path, index, params); } void MultiFilesSelected(const std::vector<base::FilePath>& files, - void* params) override {} + void* params) override { + QuitMessageLoop(); + } void FileSelectionCanceled(void* params) override { canceled_ = true; params_ = params; + QuitMessageLoop(); + } + + void WaitForCalled() { + message_loop_runner_ = new content::MessageLoopRunner(); + message_loop_runner_->Run(); } private: + void QuitMessageLoop() { + if (message_loop_runner_.get()) + message_loop_runner_->Quit(); + } + bool file_selected_; bool canceled_; base::FilePath path_; void* params_; + scoped_refptr<content::MessageLoopRunner> message_loop_runner_; DISALLOW_COPY_AND_ASSIGN(MockSelectFileDialogListener); }; @@ -190,9 +203,6 @@ const gfx::NativeWindow& owning_window) { // Inject JavaScript to click the cancel button and wait for notification // that the window has closed. - content::WindowedNotificationObserver host_destroyed( - content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, - content::NotificationService::AllSources()); content::RenderViewHost* host = dialog_->GetRenderViewHost(); std::string button_class = (button_type == DIALOG_BTN_OK) ? ".button-panel .ok" : @@ -204,7 +214,7 @@ // to JavaScript, so do not wait for return values. host->GetMainFrame()->ExecuteJavaScript(script); LOG(INFO) << "Waiting for window close notification."; - host_destroyed.Wait(); + listener_->WaitForCalled(); // Dialog no longer believes it is running. ASSERT_FALSE(dialog_->IsRunning(owning_window));
diff --git a/chrome/browser/ui/webui/app_list/OWNERS b/chrome/browser/ui/webui/app_list/OWNERS new file mode 100644 index 0000000..2aebc091 --- /dev/null +++ b/chrome/browser/ui/webui/app_list/OWNERS
@@ -0,0 +1,3 @@ +calamity@chromium.org +mgiuca@chromium.org +tapted@chromium.org
diff --git a/chrome/browser/ui/webui/app_list/start_page_browsertest.js b/chrome/browser/ui/webui/app_list/start_page_browsertest.js index 9cdecbb..eb2099e 100644 --- a/chrome/browser/ui/webui/app_list/start_page_browsertest.js +++ b/chrome/browser/ui/webui/app_list/start_page_browsertest.js
@@ -123,6 +123,43 @@ assertEquals(this.browsePreload, document.location.href); }); +TEST_F('AppListStartPageWebUITest', 'LoadDoodle', function() { + var doodleData = { + 'ddljson': { + 'transparent_large_image': { + 'url': 'doodle.png' + }, + 'alt_text': 'Doodle alt text', + 'target_url': '/target.html' + } + }; + + assertEquals(null, $('doodle')); + + // Load the doodle with a target url and alt text. + appList.startPage.onAppListDoodleUpdated(doodleData, + 'http://example.com/x/'); + assertNotEquals(null, $('doodle')); + assertEquals('http://example.com/x/doodle.png', $('doodle_image').src); + assertEquals(doodleData.ddljson.alt_text, $('doodle_image').title); + assertEquals('http://example.com/target.html', $('doodle_link').href); + + // Reload the doodle without a target url and alt text. + doodleData.ddljson.alt_text = undefined; + doodleData.ddljson.target_url = undefined; + appList.startPage.onAppListDoodleUpdated(doodleData, + 'http://example.com/x/'); + assertNotEquals(null, $('doodle')); + assertEquals('http://example.com/x/doodle.png', $('doodle_image').src); + assertEquals('', $('doodle_image').title); + assertEquals(null, $('doodle_link')); + + + appList.startPage.onAppListDoodleUpdated({}, + 'http://example.com/'); + assertEquals(null, $('doodle')); +}); + TEST_F('AppListStartPageWebUITest', 'SpeechRecognitionState', function() { this.mockHandler.expects(once()).setSpeechRecognitionState('READY'); appList.startPage.onAppListShown();
diff --git a/chrome/browser/ui/webui/chrome_web_contents_handler.cc b/chrome/browser/ui/webui/chrome_web_contents_handler.cc index c733afe..9b21e21 100644 --- a/chrome/browser/ui/webui/chrome_web_contents_handler.cc +++ b/chrome/browser/ui/webui/chrome_web_contents_handler.cc
@@ -72,15 +72,15 @@ // Creates a new tab with |new_contents|. |context| is the browser context that // the browser should be owned by. |source| is the WebContent where the // operation originated. |disposition| controls how the new tab should be -// opened. |initial_pos| is the position of the window if a new window is -// created. |user_gesture| is true if the operation was started by a user +// opened. |initial_rect| is the position and size of the window if a new window +// is created. |user_gesture| is true if the operation was started by a user // gesture. void ChromeWebContentsHandler::AddNewContents( content::BrowserContext* context, WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { if (!context) return; @@ -102,7 +102,7 @@ chrome::NavigateParams params(browser, new_contents); params.source_contents = source; params.disposition = disposition; - params.window_bounds = initial_pos; + params.window_bounds = initial_rect; params.window_action = chrome::NavigateParams::SHOW_WINDOW; params.user_gesture = true; chrome::Navigate(¶ms);
diff --git a/chrome/browser/ui/webui/chrome_web_contents_handler.h b/chrome/browser/ui/webui/chrome_web_contents_handler.h index c0a084b..2755a16 100644 --- a/chrome/browser/ui/webui/chrome_web_contents_handler.h +++ b/chrome/browser/ui/webui/chrome_web_contents_handler.h
@@ -23,7 +23,7 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; private:
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 f22a6906..a6678216 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/language_preferences.h" #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" +#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/policy/consumer_management_stage.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -79,7 +80,7 @@ message_id = IDS_CREATE_SUPERVISED_USER_CREATION_RESTRICTED_TEXT; } if (supervised_users_can_create && - user_manager::UserManager::Get() + ChromeUserManager::Get() ->GetUsersAllowedForSupervisedUsersCreation() .empty()) { supervised_users_can_create = false;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 7ad3e72..44de6a9 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -405,10 +405,6 @@ return core_handler_; } -UpdateScreenActor* OobeUI::GetUpdateScreenActor() { - return update_screen_handler_; -} - NetworkView* OobeUI::GetNetworkView() { return network_view_; } @@ -417,6 +413,10 @@ return eula_view_; } +UpdateView* OobeUI::GetUpdateView() { + return update_screen_handler_; +} + EnableDebuggingScreenActor* OobeUI::GetEnableDebuggingScreenActor() { return debugging_screen_actor_; }
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h index 02085325..888d9ca 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -100,9 +100,9 @@ // OobeDisplay implementation: CoreOobeActor* GetCoreOobeActor() override; - UpdateScreenActor* GetUpdateScreenActor() override; NetworkView* GetNetworkView() override; EulaView* GetEulaView() override; + UpdateView* GetUpdateView() override; EnableDebuggingScreenActor* GetEnableDebuggingScreenActor() override; EnrollmentScreenActor* GetEnrollmentScreenActor() override; ResetScreenActor* GetResetScreenActor() override;
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc index 34925a6..2846abd 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
@@ -4,7 +4,7 @@ #include "base/compiler_specific.h" #include "chrome/browser/chromeos/login/screens/user_selection_screen.h" -#include "chrome/browser/chromeos/login/users/fake_user_manager.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" #include "chrome/browser/chromeos/login/users/multi_profile_user_controller_delegate.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" @@ -35,9 +35,8 @@ public MultiProfileUserControllerDelegate { public: SigninPrepareUserListTest() - : fake_user_manager_(new FakeUserManager()), - user_manager_enabler_(fake_user_manager_) { - } + : fake_user_manager_(new FakeChromeUserManager()), + user_manager_enabler_(fake_user_manager_) {} ~SigninPrepareUserListTest() override {} @@ -66,7 +65,7 @@ // MultiProfileUserControllerDelegate overrides: void OnUserNotAllowed(const std::string& user_email) override {} - FakeUserManager* fake_user_manager_; + FakeChromeUserManager* fake_user_manager_; ScopedUserManagerEnabler user_manager_enabler_; scoped_ptr<TestingProfileManager> profile_manager_; std::map<std::string,
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc index 0bb7b32a..7f0ad01 100644 --- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -211,8 +211,7 @@ scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); scoped_ptr<base::ListValue> users_list(new base::ListValue()); const user_manager::UserList& users = - user_manager::UserManager::Get() - ->GetUsersAllowedForSupervisedUsersCreation(); + ChromeUserManager::Get()->GetUsersAllowedForSupervisedUsersCreation(); std::string owner; chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc index be62834..1818dea 100644 --- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
@@ -6,6 +6,7 @@ #include "base/memory/scoped_ptr.h" #include "base/values.h" +#include "chrome/browser/chromeos/login/screens/update_model.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -20,14 +21,12 @@ namespace chromeos { UpdateScreenHandler::UpdateScreenHandler() - : BaseScreenHandler(kJsScreenPath), - screen_(NULL), - show_on_init_(false) { + : BaseScreenHandler(kJsScreenPath), model_(nullptr), show_on_init_(false) { } UpdateScreenHandler::~UpdateScreenHandler() { - if (screen_) - screen_->OnActorDestroyed(this); + if (model_) + model_->OnViewDestroyed(this); } void UpdateScreenHandler::DeclareLocalizedValues( @@ -62,8 +61,7 @@ } } -void UpdateScreenHandler::SetDelegate(UpdateScreenActor::Delegate* screen) { - screen_ = screen; +void UpdateScreenHandler::PrepareToShow() { } void UpdateScreenHandler::Show() { @@ -72,79 +70,24 @@ return; } ShowScreen(OobeUI::kScreenOobeUpdate, NULL); -#if !defined(OFFICIAL_BUILD) - CallJS("enableUpdateCancel"); -#endif } void UpdateScreenHandler::Hide() { } -void UpdateScreenHandler::PrepareToShow() { +void UpdateScreenHandler::Bind(UpdateModel& model) { + model_ = &model; + BaseScreenHandler::SetBaseScreen(model_); } -void UpdateScreenHandler::ShowManualRebootInfo() { - CallJS("setUpdateMessage", l10n_util::GetStringUTF16(IDS_UPDATE_COMPLETED)); -} - -void UpdateScreenHandler::SetProgress(int progress) { - CallJS("setUpdateProgress", progress); -} - -void UpdateScreenHandler::ShowEstimatedTimeLeft(bool visible) { - CallJS("showEstimatedTimeLeft", visible); -} - -void UpdateScreenHandler::SetEstimatedTimeLeft(const base::TimeDelta& time) { - CallJS("setEstimatedTimeLeft", time.InSecondsF()); -} - -void UpdateScreenHandler::ShowProgressMessage(bool visible) { - CallJS("showProgressMessage", visible); -} - -void UpdateScreenHandler::SetProgressMessage(ProgressMessage message) { - int ids = 0; - switch (message) { - case PROGRESS_MESSAGE_UPDATE_AVAILABLE: - ids = IDS_UPDATE_AVAILABLE; - break; - case PROGRESS_MESSAGE_INSTALLING_UPDATE: - ids = IDS_INSTALLING_UPDATE; - break; - case PROGRESS_MESSAGE_VERIFYING: - ids = IDS_UPDATE_VERIFYING; - break; - case PROGRESS_MESSAGE_FINALIZING: - ids = IDS_UPDATE_FINALIZING; - break; - default: - NOTREACHED(); - return; - } - - CallJS("setProgressMessage", l10n_util::GetStringUTF16(ids)); -} - -void UpdateScreenHandler::ShowCurtain(bool visible) { - CallJS("showUpdateCurtain", visible); -} - -void UpdateScreenHandler::RegisterMessages() { -#if !defined(OFFICIAL_BUILD) - AddCallback("cancelUpdate", &UpdateScreenHandler::HandleUpdateCancel); -#endif +void UpdateScreenHandler::Unbind() { + model_ = nullptr; + BaseScreenHandler::SetBaseScreen(nullptr); } void UpdateScreenHandler::OnConnectToNetworkRequested() { - if (screen_) - screen_->OnConnectToNetworkRequested(); + if (model_) + model_->OnConnectToNetworkRequested(); } -#if !defined(OFFICIAL_BUILD) -void UpdateScreenHandler::HandleUpdateCancel() { - screen_->CancelUpdate(); -} -#endif - } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.h index 92f20b0..88c1454 100644 --- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.h
@@ -8,49 +8,35 @@ #include <string> #include "base/compiler_specific.h" -#include "chrome/browser/chromeos/login/screens/update_screen_actor.h" +#include "chrome/browser/chromeos/login/screens/update_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h" namespace chromeos { -class UpdateScreenHandler : public UpdateScreenActor, +class UpdateScreenHandler : public UpdateView, public BaseScreenHandler, public NetworkDropdownHandler::Observer { public: UpdateScreenHandler(); ~UpdateScreenHandler() override; - // BaseScreenHandler implementation: - void DeclareLocalizedValues(LocalizedValuesBuilder* builder) override; - void Initialize() override; - - // UpdateScreenActor implementation: - void SetDelegate(UpdateScreenActor::Delegate* screen) override; + // UpdateView: + void PrepareToShow() override; void Show() override; void Hide() override; - void PrepareToShow() override; - void ShowManualRebootInfo() override; - void SetProgress(int progress) override; - void ShowEstimatedTimeLeft(bool visible) override; - void SetEstimatedTimeLeft(const base::TimeDelta& time) override; - void ShowProgressMessage(bool visible) override; - void SetProgressMessage(ProgressMessage message) override; - void ShowCurtain(bool visible) override; + void Bind(UpdateModel& model) override; + void Unbind() override; - // WebUIMessageHandler implementation: - void RegisterMessages() override; + // BaseScreenHandler: + void DeclareLocalizedValues(LocalizedValuesBuilder* builder) override; + void Initialize() override; private: // NetworkDropdownHandler::Observer implementation: void OnConnectToNetworkRequested() override; -#if !defined(OFFICIAL_BUILD) - // Called when user presses Escape to cancel update. - void HandleUpdateCancel(); -#endif - - UpdateScreenActor::Delegate* screen_; + UpdateModel* model_; // Keeps whether screen should be shown right after initialization. bool show_on_init_;
diff --git a/chrome/browser/ui/webui/omnibox/omnibox.mojom b/chrome/browser/ui/webui/omnibox/omnibox.mojom index 04a3d32..5e1d7b0 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox.mojom +++ b/chrome/browser/ui/webui/omnibox/omnibox.mojom
@@ -47,13 +47,13 @@ array<AutocompleteResultsForProviderMojo> results_by_provider; }; -[Client=OmniboxPage] interface OmniboxUIHandlerMojo { StartOmniboxQuery(string input_string, int32 cursor_position, bool prevent_inline_autocomplete, bool prefer_keyword, - int32 page_classification); + int32 page_classification, + OmniboxPage page); }; interface OmniboxPage {
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc index 2301d87..644d4b2 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc
@@ -114,7 +114,8 @@ ResetController(); } -OmniboxUIHandler::~OmniboxUIHandler() {} +OmniboxUIHandler::~OmniboxUIHandler() { +} void OmniboxUIHandler::OnResultChanged(bool default_match_changed) { OmniboxResultMojoPtr result(OmniboxResultMojo::New()); @@ -159,7 +160,7 @@ } } - client()->HandleNewAutocompleteResult(result.Pass()); + page_->HandleNewAutocompleteResult(result.Pass()); } bool OmniboxUIHandler::LookupIsTypedHost(const base::string16& host, @@ -179,13 +180,15 @@ int32_t cursor_position, bool prevent_inline_autocomplete, bool prefer_keyword, - int32_t page_classification) { + int32_t page_classification, + OmniboxPagePtr page) { // Reset the controller. If we don't do this, then the // AutocompleteController might inappropriately set its |minimal_changes| // variable (or something else) and some providers will short-circuit // important logic and return stale results. In short, we want the // actual results to not depend on the state of the previous request. ResetController(); + page_ = page.Pass(); time_omnibox_started_ = base::Time::Now(); input_ = AutocompleteInput( input_string.To<base::string16>(), cursor_position, std::string(), GURL(),
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h index 81763a1..c60b7b27 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h +++ b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.h
@@ -42,7 +42,8 @@ int32_t cursor_position, bool prevent_inline_autocomplete, bool prefer_keyword, - int32_t page_classification) override; + int32_t page_classification, + OmniboxPagePtr page) override; private: // Looks up whether the hostname is a typed host (i.e., has received @@ -66,6 +67,9 @@ // The input used when starting the AutocompleteController. AutocompleteInput input_; + // Handle back to the page by which we can pass results. + OmniboxPagePtr page_; + // The Profile* handed to us in our constructor. Profile* profile_;
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.cc b/chrome/browser/ui/webui/options/autofill_options_handler.cc index f564aa3..374337b 100644 --- a/chrome/browser/ui/webui/options/autofill_options_handler.cc +++ b/chrome/browser/ui/webui/options/autofill_options_handler.cc
@@ -332,13 +332,16 @@ IDS_AUTOFILL_OPTIONS_TITLE); localized_strings->SetString("helpUrl", autofill::kHelpURL); + + personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile( + Profile::FromWebUI(web_ui())); + SetAddressOverlayStrings(localized_strings); SetCreditCardOverlayStrings(localized_strings); localized_strings->SetBoolean( "enableAutofillWalletIntegration", - base::CommandLine::ForCurrentProcess()->HasSwitch( - autofill::switches::kEnableWalletCardImport)); + personal_data_->IsExperimentalWalletIntegrationEnabled()); localized_strings->SetString( "manageWalletAddressesUrl", autofill::wallet::GetManageAddressesUrl(0).spec()); @@ -359,9 +362,6 @@ } void AutofillOptionsHandler::RegisterMessages() { - personal_data_ = autofill::PersonalDataManagerFactory::GetForProfile( - Profile::FromWebUI(web_ui())); - #if defined(OS_MACOSX) && !defined(OS_IOS) web_ui()->RegisterMessageCallback( "accessAddressBook",
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index 72b1c38..d00be98 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -681,11 +681,11 @@ "showWakeOnWifi", chromeos::WakeOnWifiManager::Get()->WakeOnWifiSupported() && chromeos::switches::WakeOnWifiEnabled()); - const bool have_enable_time_zone_tracking_option_switch = + const bool have_disable_time_zone_tracking_option_switch = base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableTimeZoneTrackingOption); + chromeos::switches::kDisableTimeZoneTrackingOption); values->SetBoolean("enableTimeZoneTrackingOption", - have_enable_time_zone_tracking_option_switch && + !have_disable_time_zone_tracking_option_switch && !chromeos::system::HasSystemTimezonePolicy()); #endif }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index 335e6083..b9cf3f3 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -89,6 +89,10 @@ #include "chrome/browser/local_discovery/privet_constants.h" #endif +#if defined(ENABLE_EXTENSIONS) +#include "extensions/browser/api/printer_provider/printer_provider_api.h" +#endif + using content::BrowserThread; using content::RenderViewHost; using content::WebContents; @@ -647,6 +651,14 @@ web_ui()->RegisterMessageCallback("getPrivetPrinterCapabilities", base::Bind(&PrintPreviewHandler::HandleGetPrivetPrinterCapabilities, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getExtensionPrinters", + base::Bind(&PrintPreviewHandler::HandleGetExtensionPrinters, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getExtensionPrinterCapabilities", + base::Bind(&PrintPreviewHandler::HandleGetExtensionPrinterCapabilities, + base::Unretained(this))); RegisterForMergeSession(); } @@ -706,6 +718,42 @@ #endif } +void PrintPreviewHandler::HandleGetExtensionPrinters( + const base::ListValue* args) { +#if defined(ENABLE_EXTENSIONS) + // TODO(tbarzic): Handle case where a new search is initiated before the + // previous one finishes. Currently, in this case Web UI layer may get + // multiple events with printer list from some extensions, and it may get + // fooled by |done| flag from the first search into marking the search + // complete. + extensions::PrinterProviderAPI::GetFactoryInstance() + ->Get(preview_web_contents()->GetBrowserContext()) + ->DispatchGetPrintersRequested( + base::Bind(&PrintPreviewHandler::OnGotPrintersForExtension, + weak_factory_.GetWeakPtr())); +#else + OnGotPrintersForExtension(base::ListValue(), true /* done */); +#endif +} + +void PrintPreviewHandler::HandleGetExtensionPrinterCapabilities( + const base::ListValue* args) { + std::string printer_id; + bool ok = args->GetString(0, &printer_id); + DCHECK(ok); + +#if defined(ENABLE_EXTENSIONS) + extensions::PrinterProviderAPI::GetFactoryInstance() + ->Get(preview_web_contents()->GetBrowserContext()) + ->DispatchGetCapabilityRequested( + printer_id, + base::Bind(&PrintPreviewHandler::OnGotExtensionPrinterCapabilities, + weak_factory_.GetWeakPtr(), printer_id)); +#else + OnGotExtensionPrinterCapabilities(printer_id, base::DictionaryValue()); +#endif +} + void PrintPreviewHandler::HandleGetPreview(const base::ListValue* args) { DCHECK_EQ(3U, args->GetSize()); scoped_ptr<base::DictionaryValue> settings(GetSettingsDictionary(args)); @@ -1588,6 +1636,26 @@ #endif // defined(ENABLE_SERVICE_DISCOVERY) +void PrintPreviewHandler::OnGotPrintersForExtension( + const base::ListValue& printers, + bool done) { + web_ui()->CallJavascriptFunction("onExtensionPrintersAdded", printers, + base::FundamentalValue(done)); +} + +void PrintPreviewHandler::OnGotExtensionPrinterCapabilities( + const std::string& printer_id, + const base::DictionaryValue& capabilities) { + if (capabilities.empty()) { + web_ui()->CallJavascriptFunction("failedToGetExtensionPrinterCapabilities", + base::StringValue(printer_id)); + return; + } + + web_ui()->CallJavascriptFunction("onExtensionCapabilitiesSet", + base::StringValue(printer_id), capabilities); +} + void PrintPreviewHandler::RegisterForMergeSession() { DCHECK(!reconcilor_); Profile* profile = Profile::FromWebUI(web_ui());
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h index cbc6e1b..f6bf882 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -124,6 +124,9 @@ // Starts getting all local privet printers. |arg| is unused. void HandleGetPrivetPrinters(const base::ListValue* args); + // Starts getting all local extension managed printers. |arg| is unused. + void HandleGetExtensionPrinters(const base::ListValue* args); + // Stops getting all local privet printers. |arg| is unused. void HandleStopGetPrivetPrinters(const base::ListValue* args); @@ -196,6 +199,10 @@ void HandleGetPrivetPrinterCapabilities(const base::ListValue* arg); + // Requests an extension managed printer's capabilities. + // |arg| contains the ID of the printer whose capabilities are requested. + void HandleGetExtensionPrinterCapabilities(const base::ListValue* args); + void SendInitialSettings(const std::string& default_printer); // Send OAuth2 access token. @@ -282,6 +289,20 @@ base::DictionaryValue* printer_value); #endif + // Called when a list of printers is reported by an extension. + // |printers|: The list of printers managed by the extension. + // |done|: Whether all the extensions have reported the list of printers + // they manage. + void OnGotPrintersForExtension(const base::ListValue& printers, bool done); + + // Called when an extension reports the set of print capabilites for a + // printer. + // |printer_id|: The id of the printer whose capabilities are reported. + // |capabilities|: The printer capabilities. + void OnGotExtensionPrinterCapabilities( + const std::string& printer_id, + const base::DictionaryValue& capabilities); + // Register/unregister from notifications of changes done to the GAIA // cookie. void RegisterForMergeSession();
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 308460c..d9ed6882 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -140,7 +140,7 @@ switches::IsNewProfileManagement() && !password_.empty() && profiles::IsLockAvailable(profile_)) { - chrome::SetLocalAuthCredentials(profile_, password_); + LocalAuth::SetLocalAuthCredentials(profile_, password_); } if (source == signin_metrics::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT ||
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc index 0ba5513e..46ad3397 100644 --- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc +++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -414,7 +414,7 @@ } authenticating_profile_index_ = profile_index; - if (!chrome::ValidateLocalAuthCredentials(profile_index, password)) { + if (!LocalAuth::ValidateLocalAuthCredentials(profile_index, password)) { // Make a second attempt via an on-line authentication call. This handles // profiles that are missing sign-in credentials and also cases where the // password has been changed externally. @@ -525,8 +525,8 @@ void UserManagerScreenHandler::OnClientLoginSuccess( const ClientLoginResult& result) { - chrome::SetLocalAuthCredentials(authenticating_profile_index_, - password_attempt_); + LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_, + password_attempt_); ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE); } @@ -547,8 +547,8 @@ // profile was locked. Save the password to streamline future unlocks. if (success) { DCHECK(!password_attempt_.empty()); - chrome::SetLocalAuthCredentials(authenticating_profile_index_, - password_attempt_); + LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_, + password_attempt_); } bool offline = (state == GoogleServiceAuthError::CONNECTION_FAILED || @@ -728,7 +728,7 @@ kKeyProfilePath, base::CreateFilePathValue(profile_path)); profile_value->SetBoolean(kKeyPublicAccount, false); profile_value->SetBoolean( - kKeySupervisedUser, info_cache.ProfileIsSupervisedAtIndex(i)); + kKeySupervisedUser, info_cache.ProfileIsLegacySupervisedAtIndex(i)); profile_value->SetBoolean( kKeyChildUser, info_cache.ProfileIsChildAtIndex(i)); profile_value->SetBoolean(
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc index c063a6a..c389169 100644 --- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc +++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
@@ -71,6 +71,8 @@ // set this manually. host_zoom_map_->SetDefaultZoomLevel(level); default_zoom_changed_callbacks_.Notify(); + if (zoom_event_manager_) + zoom_event_manager_->OnDefaultZoomLevelChanged(); } double ChromeZoomLevelPrefs::GetDefaultZoomLevelPref() const {
diff --git a/chrome/browser/web_dev_style/css_checker.py b/chrome/browser/web_dev_style/css_checker.py index 5707e1a..37f19a5 100644 --- a/chrome/browser/web_dev_style/css_checker.py +++ b/chrome/browser/web_dev_style/css_checker.py
@@ -258,18 +258,18 @@ def webkit_before_or_after(line): return webkit_before_or_after_reg.search(line) - def zero_length_values(contents): + def zero_width_lengths(contents): hsl_reg = re.compile(r""" hsl\([^\)]* # hsl(<maybe stuff> (?:[, ]|(?<=\()) # a comma or space not followed by a ( (?:0?\.?)?0% # some equivalent to 0%""", re.VERBOSE) zeros_reg = re.compile(r""" - ^.*(?:^|[^0-9.]) # start/non-number - (?:\.0|0(?:\.0? # .0, 0, or 0.0 - |px|em|%|in|cm|mm|pc|pt|ex|deg|g?rad|m?s|k?hz)) # a length unit - (?:\D|$) # non-number/end - (?=[^{}]+?}).*$ # only { rules }""", + ^.*(?:^|[^0-9.]) # start/non-number + (?:\.0|0(?:\.0? # .0, 0, or 0.0 + |px|em|%|in|cm|mm|pc|pt|ex)) # a length unit + (?:\D|$) # non-number/end + (?=[^{}]+?}).*$ # only { rules }""", re.MULTILINE | re.VERBOSE) errors = [] for z in re.finditer(zeros_reg, contents): @@ -336,9 +336,8 @@ 'test': webkit_before_or_after, 'after': suggest_top_or_bottom, }, - { 'desc': 'Make all zero length terms (i.e. 0px) 0 unless inside of ' - 'hsl() or part of @keyframe.', - 'test': zero_length_values, + { 'desc': 'Use "0" for zero-width lengths (i.e. 0px -> 0)', + 'test': zero_width_lengths, 'multiline': True, }, ]
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate index eaf72eb8..912fbca6 100644 --- a/chrome/browser_tests.isolate +++ b/chrome/browser_tests.isolate
@@ -12,6 +12,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -174,6 +176,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/chrome/child/BUILD.gn b/chrome/child/BUILD.gn new file mode 100644 index 0000000..1b268f1 --- /dev/null +++ b/chrome/child/BUILD.gn
@@ -0,0 +1,17 @@ +# 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. + +static_library("child") { + sources = [ + "pdf_child_init.cc", + "pdf_child_init.h", + ] + + configs += [ "//build/config/compiler:wexit_time_destructors" ] + + deps = [ + "//base", + "//content/public/child", + ] +}
diff --git a/chrome/child/DEPS b/chrome/child/DEPS new file mode 100644 index 0000000..ad94e88 --- /dev/null +++ b/chrome/child/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+content/public/child", +]
diff --git a/chrome/child/pdf_child_init.cc b/chrome/child/pdf_child_init.cc new file mode 100644 index 0000000..338403cc --- /dev/null +++ b/chrome/child/pdf_child_init.cc
@@ -0,0 +1,78 @@ +// 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/child/pdf_child_init.h" + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" +#include "content/public/child/child_thread.h" + +#if defined(OS_WIN) +#include "base/win/iat_patch_function.h" +#endif + +namespace chrome { +namespace { +#if defined(OS_WIN) +static base::win::IATPatchFunction g_iat_patch_createdca; +HDC WINAPI CreateDCAPatch(LPCSTR driver_name, + LPCSTR device_name, + LPCSTR output, + const void* init_data) { + DCHECK(std::string("DISPLAY") == std::string(driver_name)); + DCHECK(!device_name); + DCHECK(!output); + DCHECK(!init_data); + + // CreateDC fails behind the sandbox, but not CreateCompatibleDC. + return CreateCompatibleDC(NULL); +} + +static base::win::IATPatchFunction g_iat_patch_get_font_data; +DWORD WINAPI GetFontDataPatch(HDC hdc, + DWORD table, + DWORD offset, + LPVOID buffer, + DWORD length) { + int rv = GetFontData(hdc, table, offset, buffer, length); + if (rv == GDI_ERROR && hdc) { + HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); + + LOGFONT logfont; + if (GetObject(font, sizeof(LOGFONT), &logfont)) { + std::vector<char> font_data; + content::ChildThread::Get()->PreCacheFont(logfont); + rv = GetFontData(hdc, table, offset, buffer, length); + content::ChildThread::Get()->ReleaseCachedFonts(); + } + } + return rv; +} +#endif // OS_WIN + +} // namespace + +void InitializePDF() { +#if defined(OS_WIN) + // Need to patch a few functions for font loading to work correctly. This can + // be removed once we switch PDF to use Skia. + HMODULE current_module = NULL; + wchar_t current_module_name[MAX_PATH]; + CHECK(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + reinterpret_cast<LPCWSTR>(InitializePDF), + ¤t_module)); + DWORD result = GetModuleFileNameW(current_module, current_module_name, + MAX_PATH); + if (!result || result == MAX_PATH) + return; + g_iat_patch_createdca.Patch(current_module_name, "gdi32.dll", "CreateDCA", + CreateDCAPatch); + g_iat_patch_get_font_data.Patch(current_module_name, "gdi32.dll", + "GetFontData", GetFontDataPatch); +#endif // OS_WIN +} + +} // namespace chrome
diff --git a/chrome/child/pdf_child_init.h b/chrome/child/pdf_child_init.h new file mode 100644 index 0000000..1aac5c6fb --- /dev/null +++ b/chrome/child/pdf_child_init.h
@@ -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. + +#ifndef CHROME_CHILD_PDF_CHILD_INIT_H_ +#define CHROME_CHILD_PDF_CHILD_INIT_H_ + +namespace chrome { + +// Initializes child-process specific code for the PDF module. +void InitializePDF(); + +} // namespace chrome + +#endif // CHROME_CHILD_PDF_CHILD_INIT_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index ce0b5ce..639f2c83 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp
@@ -32,6 +32,7 @@ '../ppapi/ppapi_internal.gyp:ppapi_host', ], 'chromium_child_dependencies': [ + 'child', 'plugin', 'renderer', 'utility', @@ -122,6 +123,7 @@ 'includes': [ '../apps/apps.gypi', 'app_installer/app_installer.gypi', + 'chrome_child.gypi', 'chrome_debugger.gypi', 'chrome_dll.gypi', 'chrome_exe.gypi', @@ -604,7 +606,6 @@ 'chrome_version_java', 'document_tab_model_info_proto_java', 'profile_account_management_metrics_java', - 'add_web_contents_result_java', 'content_setting_java', 'content_settings_type_java', 'page_info_connection_type_java',
diff --git a/chrome/chrome.isolate b/chrome/chrome.isolate index 9ebce299..64ae230 100644 --- a/chrome/chrome.isolate +++ b/chrome/chrome.isolate
@@ -8,7 +8,6 @@ 'files': [ '<(PRODUCT_DIR)/libffmpegsumo.so', '<(PRODUCT_DIR)/libosmesa.so', - '<(PRODUCT_DIR)/libpdf.so', ], }, }], @@ -88,7 +87,6 @@ '<(PRODUCT_DIR)/ffmpegsumo.dll', '<(PRODUCT_DIR)/libexif.dll', '<(PRODUCT_DIR)/osmesa.dll', - '<(PRODUCT_DIR)/pdf.dll', ], }, }],
diff --git a/chrome/chrome_android.gypi b/chrome/chrome_android.gypi index 7ecfda0..3c62104a9 100644 --- a/chrome/chrome_android.gypi +++ b/chrome/chrome_android.gypi
@@ -24,6 +24,7 @@ 'dependencies': [ 'chrome.gyp:browser', 'chrome.gyp:browser_ui', + 'chrome.gyp:child', 'chrome.gyp:plugin', 'chrome.gyp:renderer', 'chrome.gyp:utility',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 1fb6f309..d111cba 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -109,6 +109,8 @@ 'browser/android/location_settings.h', 'browser/android/location_settings_impl.cc', 'browser/android/location_settings_impl.h', + 'browser/android/manifest_icon_selector.cc', + 'browser/android/manifest_icon_selector.h', 'browser/android/most_visited_sites.cc', 'browser/android/most_visited_sites.h', 'browser/android/omnibox/answers_image_bridge.cc', @@ -141,6 +143,8 @@ 'browser/android/resource_id.h', 'browser/android/shortcut_helper.cc', 'browser/android/shortcut_helper.h', + 'browser/android/shortcut_info.cc', + 'browser/android/shortcut_info.h', 'browser/android/signin/account_management_screen_helper.cc', 'browser/android/signin/account_management_screen_helper.h', 'browser/android/signin/signin_manager_android.cc', @@ -422,8 +426,8 @@ 'browser/internal_auth.h', 'browser/interstitials/security_interstitial_page.cc', 'browser/interstitials/security_interstitial_page.h', - 'browser/interstitials/security_interstitial_uma_helper.cc', - 'browser/interstitials/security_interstitial_uma_helper.h', + 'browser/interstitials/security_interstitial_metrics_helper.cc', + 'browser/interstitials/security_interstitial_metrics_helper.h', 'browser/intranet_redirect_detector.cc', 'browser/intranet_redirect_detector.h', 'browser/invalidation/invalidation_service_factory_android.cc', @@ -1472,8 +1476,6 @@ 'browser/google/google_brand.h', 'browser/google/google_brand_chromeos.cc', 'browser/google/google_brand_chromeos.h', - 'browser/google/google_profile_helper.cc', - 'browser/google/google_profile_helper.h', 'browser/google/google_search_counter.cc', 'browser/google/google_search_counter.h', 'browser/google/google_search_counter_android.cc', @@ -1609,6 +1611,7 @@ 'android/java/src/org/chromium/chrome/browser/VoiceSearchTabHelper.java', 'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java', 'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopupLegacy.java', + 'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegate.java', 'android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBarDelegate.java', 'android/java/src/org/chromium/chrome/browser/infobar/DataReductionProxyInfoBarDelegate.java', 'android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBarDelegate.java', @@ -2286,7 +2289,6 @@ 'browser/safe_browsing/download_feedback_service.h', 'browser/safe_browsing/download_protection_service.cc', 'browser/safe_browsing/download_protection_service.h', - 'browser/safe_browsing/incident_reporting/add_incident_callback.h', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer.cc', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h', 'browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc', @@ -2310,6 +2312,7 @@ 'browser/safe_browsing/incident_reporting/incident.h', 'browser/safe_browsing/incident_reporting/incident_handler_util.cc', 'browser/safe_browsing/incident_reporting/incident_handler_util.h', + 'browser/safe_browsing/incident_reporting/incident_receiver.h', 'browser/safe_browsing/incident_reporting/incident_report_uploader.cc', 'browser/safe_browsing/incident_reporting/incident_report_uploader.h', 'browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc', @@ -3634,15 +3637,6 @@ 'includes': [ '../build/android/java_cpp_enum.gypi' ], }, { - # GN: //chrome/android:chrome_android_java_enums_srcjar - 'target_name': 'add_web_contents_result_java', - 'type': 'none', - 'variables': { - 'source_file': 'browser/android/chrome_web_contents_delegate_android.h', - }, - 'includes': [ '../build/android/java_cpp_enum.gypi' ], - }, - { # GN: //chrome/android:chrome_android_java_enums_srcjar 'target_name': 'profile_sync_service_model_type_selection_java', 'type': 'none',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 98971e87..a57b9cf 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -543,9 +543,10 @@ 'browser/chromeos/login/screens/terms_of_service_screen.cc', 'browser/chromeos/login/screens/terms_of_service_screen.h', 'browser/chromeos/login/screens/terms_of_service_screen_actor.h', + 'browser/chromeos/login/screens/update_model.cc', + 'browser/chromeos/login/screens/update_model.h', 'browser/chromeos/login/screens/update_screen.cc', 'browser/chromeos/login/screens/update_screen.h', - 'browser/chromeos/login/screens/update_screen_actor.h', 'browser/chromeos/login/screens/user_image_model.cc', 'browser/chromeos/login/screens/user_image_model.h', 'browser/chromeos/login/screens/user_image_screen.cc', @@ -665,6 +666,7 @@ 'browser/chromeos/login/users/supervised_user_manager.h', 'browser/chromeos/login/users/supervised_user_manager_impl.cc', 'browser/chromeos/login/users/supervised_user_manager_impl.h', + 'browser/chromeos/login/users/user_manager_interface.h', 'browser/chromeos/login/users/wallpaper/wallpaper_manager.cc', 'browser/chromeos/login/users/wallpaper/wallpaper_manager.h', 'browser/chromeos/login/version_info_updater.cc', @@ -727,8 +729,12 @@ 'browser/chromeos/platform_keys/platform_keys_service.h', 'browser/chromeos/platform_keys/platform_keys_service_factory.cc', 'browser/chromeos/platform_keys/platform_keys_service_factory.h', + 'browser/chromeos/policy/affiliated_cloud_policy_invalidator.cc', + 'browser/chromeos/policy/affiliated_cloud_policy_invalidator.h', 'browser/chromeos/policy/affiliated_invalidation_service_provider.cc', 'browser/chromeos/policy/affiliated_invalidation_service_provider.h', + 'browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc', + 'browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h', 'browser/chromeos/policy/auto_enrollment_client.cc', 'browser/chromeos/policy/auto_enrollment_client.h', 'browser/chromeos/policy/browser_policy_connector_chromeos.cc', @@ -759,8 +765,6 @@ 'browser/chromeos/policy/consumer_unenrollment_handler_factory.h', 'browser/chromeos/policy/device_cloud_policy_initializer.cc', 'browser/chromeos/policy/device_cloud_policy_initializer.h', - 'browser/chromeos/policy/device_cloud_policy_invalidator.cc', - 'browser/chromeos/policy/device_cloud_policy_invalidator.h', 'browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc', 'browser/chromeos/policy/device_cloud_policy_manager_chromeos.h', 'browser/chromeos/policy/device_cloud_policy_store_chromeos.cc', @@ -1099,6 +1103,7 @@ '../components/components.gyp:ownership', '../components/components.gyp:pairing', '../components/components.gyp:policy', + '../components/components.gyp:user_manager', # This depends directly on the variations target, rather than just # transitively via the common target because the proto sources need to # be generated before code in this target can start building. @@ -1140,6 +1145,7 @@ '../third_party/zlib/zlib.gyp:zlib', '../ui/base/ui_base.gyp:ui_base', '../ui/display/display.gyp:display', + '../ui/events/devices/events_devices.gyp:events_devices', '../ui/events/events.gyp:dom4_keycode_converter', '../ui/events/platform/events_platform.gyp:events_platform', '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_resources',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 1f97eb8..67dedf5e 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi
@@ -5,9 +5,6 @@ { 'variables': { 'chrome_browser_extensions_chromeos_sources': [ - 'browser/extensions/api/diagnostics/diagnostics_api.cc', - 'browser/extensions/api/diagnostics/diagnostics_api.h', - 'browser/extensions/api/diagnostics/diagnostics_api_chromeos.cc', 'browser/extensions/api/document_scan/document_scan_interface_chromeos.cc', 'browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc', 'browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index dfda52e..16899e2 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -27,6 +27,8 @@ 'browser/ui/android/autofill/password_generation_popup_view_android.h', 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc', 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.h', + 'browser/ui/android/infobars/app_banner_infobar.cc', + 'browser/ui/android/infobars/app_banner_infobar.h', 'browser/ui/android/infobars/confirm_infobar.cc', 'browser/ui/android/infobars/confirm_infobar.h', 'browser/ui/android/infobars/data_reduction_proxy_infobar.cc',
diff --git a/chrome/chrome_child.gypi b/chrome/chrome_child.gypi new file mode 100644 index 0000000..6464a39 --- /dev/null +++ b/chrome/chrome_child.gypi
@@ -0,0 +1,24 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'child', + 'type': 'static_library', + 'variables': { 'enable_wexit_time_destructors': 1, }, + 'dependencies': [ + '../base/base.gyp:base', + '../content/content.gyp:content_child', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'child/pdf_child_init.cc', + 'child/pdf_child_init.h', + ], + }, + ], +}
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 024f34db..0885668 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi
@@ -256,6 +256,11 @@ '../content/content.gyp:content_app_browser', ], }], + ['chrome_multiple_dll==0 and enable_plugins==1', { + 'dependencies': [ + '../pdf/pdf.gyp:pdf', + ], + }], ['cld_version==1', { 'dependencies': [ '<(DEPTH)/third_party/cld/cld.gyp:cld', @@ -278,9 +283,6 @@ # sets -order_file. 'ORDER_FILE': 'app/framework.order', }, - 'dependencies': [ - '../pdf/pdf.gyp:pdf', - ], 'include_dirs': [ '<(grit_out_dir)', ], @@ -372,6 +374,11 @@ }], ] }], + ['enable_plugins==1', { + 'dependencies': [ + '../pdf/pdf.gyp:pdf', + ], + }], ], }, # target chrome_child_dll ],
diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi index c522f2f..dd01c01 100644 --- a/chrome/chrome_dll_bundle.gypi +++ b/chrome/chrome_dll_bundle.gypi
@@ -76,7 +76,6 @@ # Bring in pdfsqueeze and run it on all pdfs '../build/temp_gyp/pdfsqueeze.gyp:pdfsqueeze', '../crypto/crypto.gyp:crypto', - '../pdf/pdf.gyp:pdf', # On Mac, Flash gets put into the framework, so we need this # dependency here. flash_player.gyp will copy the Flash bundle # into PRODUCT_DIR. @@ -147,9 +146,6 @@ }, { 'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Internet Plug-Ins', - 'files': [ - '<(PRODUCT_DIR)/PDF.plugin', - ], 'conditions': [ ['disable_nacl!=1', { 'conditions': [
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index e27baa8..2713e9b 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi
@@ -62,6 +62,8 @@ 'app/chrome_exe_main_mac.cc', 'app/chrome_exe_main_win.cc', 'app/chrome_exe_resource.h', + 'app/chrome_watcher_client_win.cc', + 'app/chrome_watcher_client_win.h', 'app/chrome_watcher_command_line_win.cc', 'app/chrome_watcher_command_line_win.h', 'app/client_util.cc', @@ -188,6 +190,11 @@ '../build/linux/system.gyp:xext', ], }], + ['enable_plugins==1', { + 'dependencies': [ + '../pdf/pdf.gyp:pdf', + ], + }], ], 'sources': [ 'app/chrome_dll_resource.h', @@ -426,20 +433,6 @@ # NOTE: chrome/app/theme/chromium/BRANDING and # chrome/app/theme/google_chrome/BRANDING have the short name # "chrome" etc.; should we try to extract from there instead? - - # CrOS does this in a separate build step. - ['OS=="linux" and chromeos==0 and linux_dump_symbols==1', { - 'dependencies': [ - '../pdf/pdf.gyp:pdf_linux_symbols', - ], - }], # OS=="linux" and chromeos==0 and linux_dump_symbols==1 - # Android doesn't use pdfium. - ['OS!="android"', { - 'dependencies': [ - # On Mac, this is done in chrome_dll.gypi. - '../pdf/pdf.gyp:pdf', - ], - }], # OS=="android" ], 'dependencies': [ '../components/components.gyp:startup_metric_utils',
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi index c771597d..ed2bcd51 100644 --- a/chrome/chrome_installer.gypi +++ b/chrome/chrome_installer.gypi
@@ -461,7 +461,6 @@ '<(PRODUCT_DIR)/chrome', '<(PRODUCT_DIR)/chrome_sandbox', '<(PRODUCT_DIR)/libffmpegsumo.so', - '<(PRODUCT_DIR)/libpdf.so', '<(PRODUCT_DIR)/xdg-mime', '<(PRODUCT_DIR)/xdg-settings', '<(PRODUCT_DIR)/locales/en-US.pak',
diff --git a/chrome/chrome_syzygy.gyp b/chrome/chrome_syzygy.gyp index 7ffd1c6..47fa23b 100644 --- a/chrome/chrome_syzygy.gyp +++ b/chrome/chrome_syzygy.gyp
@@ -9,14 +9,18 @@ ['syzyasan==1', { 'variables': { 'syzygy_exe_dir': '<(DEPTH)/third_party/syzygy/binaries/exe', + 'kasko_exe_dir': '<(DEPTH)/third_party/kasko', }, # Copy the SyzyASan runtime and logger to the syzygy directory. + # TODO(erikwright): Decouple Kasko from SyzyASAN. 'targets': [ { 'target_name': 'copy_syzyasan_binaries', 'type': 'none', 'outputs': [ '<(dest_dir)/agent_logger.exe', + '<(dest_dir)/kasko.dll', + '<(dest_dir)/kasko.dll.pdb', '<(dest_dir)/syzyasan_rtl.dll', '<(dest_dir)/syzyasan_rtl.dll.pdb', ], @@ -24,6 +28,8 @@ { 'destination': '<(dest_dir)', 'files': [ + '<(kasko_exe_dir)/kasko.dll', + '<(kasko_exe_dir)/kasko.dll.pdb', '<(syzygy_exe_dir)/agent_logger.exe', '<(syzygy_exe_dir)/syzyasan_rtl.dll', '<(syzygy_exe_dir)/syzyasan_rtl.dll.pdb',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 4276759..4c72b47 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi
@@ -1449,7 +1449,6 @@ '../net/net.gyp:net', '../net/net.gyp:net_resources', '../net/net.gyp:net_test_support', - '../pdf/pdf.gyp:pdf', '../ppapi/ppapi_internal.gyp:ppapi_tests', '../skia/skia.gyp:skia', '../sync/sync.gyp:sync',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index ddfc850..eaad070 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -15,12 +15,12 @@ # All unittests in browser, common, renderer and service. 'browser/about_flags_unittest.cc', 'browser/android/bookmarks/partner_bookmarks_shim_unittest.cc', + 'browser/android/manifest_icon_selector_unittest.cc', # TODO(newt): move this to test_support_unit? 'browser/android/mock_location_settings.cc', 'browser/android/mock_location_settings.h', 'browser/android/preferences/pref_service_bridge_unittest.cc', 'browser/android/thumbnail/scoped_ptr_expiring_cache_unittest.cc', - 'browser/android/shortcut_helper_unittest.cc', 'browser/app_controller_mac_unittest.mm', 'browser/autocomplete/autocomplete_provider_unittest.cc', 'browser/autocomplete/bookmark_provider_unittest.cc', @@ -627,12 +627,6 @@ 'browser/background/background_contents_service_unittest.cc', 'browser/background/background_mode_manager_unittest.cc', ], - 'chrome_unit_tests_nacl_sources': [ - # TODO(yael): Move to //components/components_tests.gypi once - # nacl_defines is moved out of chrome.gyp into a common place. - '../components/nacl/loader/nacl_ipc_adapter_unittest.cc', - '../components/nacl/loader/nacl_validation_query_unittest.cc', - ], 'chrome_unit_tests_extensions_sources': [ '../apps/saved_files_service_unittest.cc', 'browser/apps/app_shim/app_shim_host_mac_unittest.cc', @@ -1009,6 +1003,8 @@ 'browser/safe_browsing/incident_reporting/incident_report_uploader_impl_unittest.cc', 'browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc', 'browser/safe_browsing/incident_reporting/last_download_finder_unittest.cc', + 'browser/safe_browsing/incident_reporting/mock_incident_receiver.cc', + 'browser/safe_browsing/incident_reporting/mock_incident_receiver.h', 'browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc', 'browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h', 'browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc', @@ -1235,7 +1231,8 @@ 'browser/chromeos/ownership/fake_owner_settings_service.cc', 'browser/chromeos/ownership/fake_owner_settings_service.h', 'browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc', - 'browser/chromeos/policy/affiliated_invalidation_service_provider_unittest.cc', + 'browser/chromeos/policy/affiliated_cloud_policy_invalidator_unittest.cc', + 'browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc', 'browser/chromeos/policy/auto_enrollment_client_unittest.cc', 'browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc', 'browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc', @@ -1248,11 +1245,12 @@ 'browser/chromeos/policy/consumer_management_service_unittest.cc', 'browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc', - 'browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc', 'browser/chromeos/policy/device_local_account_policy_service_unittest.cc', 'browser/chromeos/policy/enterprise_install_attributes_unittest.cc', + 'browser/chromeos/policy/fake_affiliated_invalidation_service_provider.cc', + 'browser/chromeos/policy/fake_affiliated_invalidation_service_provider.h', 'browser/chromeos/policy/network_configuration_updater_unittest.cc', 'browser/chromeos/policy/recommendation_restorer_unittest.cc', 'browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc', @@ -1750,6 +1748,7 @@ 'conditions': [ ['OS!="ios"', { 'dependencies': [ + 'child', 'plugin', 'renderer', 'utility', @@ -1789,6 +1788,7 @@ 'dependencies': [ '../build/linux/system.gyp:dbus', '../chromeos/chromeos.gyp:chromeos_test_support', + '../components/components.gyp:user_manager_test_support', ], 'sources': [ # Note: sources list duplicated in GN build. @@ -1820,8 +1820,8 @@ 'browser/chromeos/login/users/avatar/mock_user_image_manager.h', 'browser/chromeos/login/users/fake_supervised_user_manager.cc', 'browser/chromeos/login/users/fake_supervised_user_manager.h', - 'browser/chromeos/login/users/fake_user_manager.cc', - 'browser/chromeos/login/users/fake_user_manager.h', + 'browser/chromeos/login/users/fake_chrome_user_manager.cc', + 'browser/chromeos/login/users/fake_chrome_user_manager.h', 'browser/chromeos/login/users/mock_user_manager.cc', 'browser/chromeos/login/users/mock_user_manager.h', 'browser/chromeos/net/network_portal_detector_test_utils.cc', @@ -1984,6 +1984,9 @@ 'test/ppapi/ppapi_test.cc', 'test/ppapi/ppapi_test.h', ], + 'dependencies': [ + '../pdf/pdf.gyp:pdf', + ], }], ['enable_plugins==1 and disable_nacl==0', { 'dependencies': [ @@ -2059,7 +2062,6 @@ '../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icuuc', '../third_party/libxml/libxml.gyp:libxml', - '../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer', '../ui/base/ui_base.gyp:ui_base_test_support', '../ui/gfx/gfx.gyp:gfx_test_support', '../ui/resources/ui_resources.gyp:ui_resources', @@ -2156,9 +2158,6 @@ }], ], }], - ['disable_nacl==0', { - 'sources':[ '<@(chrome_unit_tests_nacl_sources)' ], - }], ['enable_extensions==1', { 'sources': [ '<@(chrome_unit_tests_extensions_sources)' ], 'dependencies': [ @@ -2607,6 +2606,8 @@ '..', ], 'sources': [ + 'app/chrome_watcher_client_unittest_win.cc', + 'app/chrome_watcher_client_win.cc', 'app/chrome_watcher_command_line_unittest_win.cc', 'app/chrome_watcher_command_line_win.cc', 'app/delay_load_hook_win.cc',
diff --git a/chrome/chrome_watcher/chrome_watcher_main.cc b/chrome/chrome_watcher/chrome_watcher_main.cc index 0b455418..4e294dc 100644 --- a/chrome/chrome_watcher/chrome_watcher_main.cc +++ b/chrome/chrome_watcher/chrome_watcher_main.cc
@@ -34,23 +34,27 @@ { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; // Takes care of monitoring a browser. This class watches for a browser's exit -// code, as well as listening for WM_ENDSESSION messages. Events are recorded -// in an exit funnel, for reporting the next time Chrome runs. +// code, as well as listening for WM_ENDSESSION messages. Events are recorded in +// an exit funnel, for reporting the next time Chrome runs. class BrowserMonitor { public: BrowserMonitor(base::RunLoop* run_loop, const base::char16* registry_path); ~BrowserMonitor(); - // Starts the monitor, returns true on success. + // Initiates the asynchronous monitoring process, returns true on success. + // |on_initialized_event| will be signaled immediately before blocking on the + // exit of |process|. bool StartWatching(const base::char16* registry_path, - base::Process process); + base::Process process, + base::win::ScopedHandle on_initialized_event); private: // Called from EndSessionWatcherWindow on a end session messages. void OnEndSessionMessage(UINT message, LPARAM lparam); - // Blocking function that runs on |background_thread_|. - void Watch(); + // Blocking function that runs on |background_thread_|. Signals + // |on_initialized_event| before waiting for the browser process to exit. + void Watch(base::win::ScopedHandle on_initialized_event); // Posted to main thread from Watch when browser exits. void BrowserExited(); @@ -89,8 +93,10 @@ BrowserMonitor::~BrowserMonitor() { } -bool BrowserMonitor::StartWatching(const base::char16* registry_path, - base::Process process) { +bool BrowserMonitor::StartWatching( + const base::char16* registry_path, + base::Process process, + base::win::ScopedHandle on_initialized_event) { if (!exit_code_watcher_.Initialize(process.Pass())) return false; @@ -104,8 +110,9 @@ return false; } - if (!background_thread_.task_runner()->PostTask(FROM_HERE, - base::Bind(&BrowserMonitor::Watch, base::Unretained(this)))) { + if (!background_thread_.task_runner()->PostTask( + FROM_HERE, base::Bind(&BrowserMonitor::Watch, base::Unretained(this), + base::Passed(on_initialized_event.Pass())))) { background_thread_.Stop(); return false; } @@ -137,10 +144,15 @@ run_loop_->Quit(); } -void BrowserMonitor::Watch() { +void BrowserMonitor::Watch(base::win::ScopedHandle on_initialized_event) { // This needs to run on an IO thread. DCHECK_NE(main_thread_, base::MessageLoopProxy::current()); + // Signal our client now that the Kasko reporter is initialized and we have + // cleared all of the obstacles that might lead to an early exit. + ::SetEvent(on_initialized_event.Get()); + on_initialized_event.Close(); + exit_code_watcher_.WaitForExit(); exit_funnel_.RecordEvent(L"BrowserExit"); @@ -177,8 +189,10 @@ // The main entry point to the watcher, declared as extern "C" to avoid name // mangling. extern "C" int WatcherMain(const base::char16* registry_path, - HANDLE process_handle) { + HANDLE process_handle, + HANDLE on_initialized_event_handle) { base::Process process(process_handle); + base::win::ScopedHandle on_initialized_event(on_initialized_event_handle); // The exit manager is in charge of calling the dtors of singletons. base::AtExitManager exit_manager; @@ -197,8 +211,10 @@ base::RunLoop run_loop; BrowserMonitor monitor(&run_loop, registry_path); - if (!monitor.StartWatching(registry_path, process.Pass())) + if (!monitor.StartWatching(registry_path, process.Pass(), + on_initialized_event.Pass())) { return 1; + } run_loop.Run();
diff --git a/chrome/chrome_watcher/chrome_watcher_main_api.h b/chrome/chrome_watcher/chrome_watcher_main_api.h index 491b550..22dbf9b 100644 --- a/chrome/chrome_watcher/chrome_watcher_main_api.h +++ b/chrome/chrome_watcher/chrome_watcher_main_api.h
@@ -16,8 +16,11 @@ // The type of the watcher DLL's main entry point. // Watches |parent_process| and records its exit code under |registry_path| in -// HKCU. Takes ownership of |parent_process|. -typedef int (*ChromeWatcherMainFunction)(const base::char16* registry_path, - HANDLE parent_process); +// HKCU. |on_initialized_event| will be signaled once the process is fully +// initialized. Takes ownership of |parent_process| and |on_initialized_event|. +typedef int (*ChromeWatcherMainFunction)( + const base::char16* registry_path, + HANDLE parent_process, + HANDLE on_initialized_event); #endif // CHROME_CHROME_WATCHER_CHROME_WATCHER_MAIN_API_H_
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 587b2aa..21df9e0 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -64,11 +64,8 @@ namespace { #if defined(ENABLE_PLUGINS) -const char kPDFPluginMimeType[] = "application/pdf"; const char kPDFPluginExtension[] = "pdf"; const char kPDFPluginDescription[] = "Portable Document Format"; -const char kPDFPluginPrintPreviewMimeType[] = - "application/x-google-chrome-print-preview-pdf"; const char kPDFPluginOutOfProcessMimeType[] = "application/x-google-chrome-pdf"; const uint32 kPDFPluginPermissions = ppapi::PERMISSION_PRIVATE | @@ -95,6 +92,10 @@ const uint32 kGTalkPluginPermissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV; +content::PepperPluginInfo::GetInterfaceFunc g_pdf_get_interface; +content::PepperPluginInfo::PPP_InitializeModuleFunc g_pdf_initialize_module; +content::PepperPluginInfo::PPP_ShutdownModuleFunc g_pdf_shutdown_module; + #if defined(ENABLE_REMOTING) content::PepperPluginInfo::GetInterfaceFunc g_remoting_get_interface; @@ -133,43 +134,25 @@ // not marked internal, aside from being automatically registered, they're just // regular plugins). void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) { - // PDF. - // - // Once we're sandboxed, we can't know if the PDF plugin is available or not; - // but (on Linux) this function is always called once before we're sandboxed. - // So the first time through test if the file is available and then skip the - // check on subsequent calls if yes. - static bool skip_pdf_file_check = false; - base::FilePath path; - if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) { - if (skip_pdf_file_check || base::PathExists(path)) { - content::PepperPluginInfo pdf; - pdf.path = path; - pdf.name = ChromeContentClient::kPDFPluginName; - if (switches::OutOfProcessPdfEnabled()) { - pdf.is_out_of_process = true; - content::WebPluginMimeType pdf_mime_type(kPDFPluginOutOfProcessMimeType, - kPDFPluginExtension, - kPDFPluginDescription); - pdf.mime_types.push_back(pdf_mime_type); - // TODO(raymes): Make print preview work with out of process PDF. - } else { - content::WebPluginMimeType pdf_mime_type(kPDFPluginMimeType, - kPDFPluginExtension, - kPDFPluginDescription); - content::WebPluginMimeType print_preview_pdf_mime_type( - kPDFPluginPrintPreviewMimeType, - kPDFPluginExtension, - kPDFPluginDescription); - pdf.mime_types.push_back(pdf_mime_type); - pdf.mime_types.push_back(print_preview_pdf_mime_type); - } - pdf.permissions = kPDFPluginPermissions; - plugins->push_back(pdf); + content::PepperPluginInfo pdf_info; + pdf_info.is_internal = true; + pdf_info.is_out_of_process = true; + pdf_info.name = ChromeContentClient::kPDFPluginName; + pdf_info.description = kPDFPluginDescription; + pdf_info.path = base::FilePath::FromUTF8Unsafe( + ChromeContentClient::kPDFPluginPath); + content::WebPluginMimeType pdf_mime_type( + kPDFPluginOutOfProcessMimeType, + kPDFPluginExtension, + kPDFPluginDescription); + pdf_info.mime_types.push_back(pdf_mime_type); + pdf_info.internal_entry_points.get_interface = g_pdf_get_interface; + pdf_info.internal_entry_points.initialize_module = g_pdf_initialize_module; + pdf_info.internal_entry_points.shutdown_module = g_pdf_shutdown_module; + pdf_info.permissions = kPDFPluginPermissions; + plugins->push_back(pdf_info); - skip_pdf_file_check = true; - } - } + base::FilePath path; #if !defined(DISABLE_NACL) // Handle Native Client just like the PDF plugin. This means that it is @@ -454,6 +437,17 @@ } #endif +#if defined(ENABLE_PLUGINS) +void ChromeContentClient::SetPDFEntryFunctions( + content::PepperPluginInfo::GetInterfaceFunc get_interface, + content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module, + content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module) { + g_pdf_get_interface = get_interface; + g_pdf_initialize_module = initialize_module; + g_pdf_shutdown_module = shutdown_module; +} +#endif + void ChromeContentClient::SetActiveURL(const GURL& url) { base::debug::SetCrashKeyValue(crash_keys::kActiveURL, url.possibly_invalid_spec());
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index 968db7c..fd00d31 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h
@@ -22,6 +22,7 @@ class ChromeContentClient : public content::ContentClient { public: static const char* const kPDFPluginName; + static const char* const kPDFPluginPath; static const char* const kRemotingViewerPluginPath; // The methods below are called by child processes to set the function @@ -42,6 +43,13 @@ content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module); #endif +#if defined(ENABLE_PLUGINS) + static void SetPDFEntryFunctions( + content::PepperPluginInfo::GetInterfaceFunc get_interface, + content::PepperPluginInfo::PPP_InitializeModuleFunc initialize_module, + content::PepperPluginInfo::PPP_ShutdownModuleFunc shutdown_module); +#endif + void SetActiveURL(const GURL& url) override; void SetGpuInfo(const gpu::GPUInfo& gpu_info) override; void AddPepperPlugins(
diff --git a/chrome/common/chrome_content_client_constants.cc b/chrome/common/chrome_content_client_constants.cc index aeda5340..f0a59f8 100644 --- a/chrome/common/chrome_content_client_constants.cc +++ b/chrome/common/chrome_content_client_constants.cc
@@ -4,6 +4,12 @@ #include "chrome/common/chrome_content_client.h" +#if defined(GOOGLE_CHROME_BUILD) const char* const ChromeContentClient::kPDFPluginName = "Chrome PDF Viewer"; +#else +const char* const ChromeContentClient::kPDFPluginName = "Chromium PDF Viewer"; +#endif +const char* const ChromeContentClient::kPDFPluginPath = + "internal-pdf-viewer"; const char* const ChromeContentClient::kRemotingViewerPluginPath = "internal-remoting-viewer";
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index af56236..9537376 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc
@@ -50,16 +50,6 @@ FILE_PATH_LITERAL("Macromed\\Flash"); #endif -// File name of the internal PDF plugin on different platforms. -const base::FilePath::CharType kInternalPDFPluginFileName[] = -#if defined(OS_WIN) - FILE_PATH_LITERAL("pdf.dll"); -#elif defined(OS_MACOSX) - FILE_PATH_LITERAL("PDF.plugin"); -#else // Linux and Chrome OS - FILE_PATH_LITERAL("libpdf.so"); -#endif - const base::FilePath::CharType kInternalNaClPluginFileName[] = FILE_PATH_LITERAL("internal-nacl-plugin"); @@ -294,11 +284,6 @@ return false; cur = cur.Append(chrome::kPepperFlashPluginFilename); break; - case chrome::FILE_PDF_PLUGIN: - if (!GetInternalPluginsDirectory(&cur)) - return false; - cur = cur.Append(kInternalPDFPluginFileName); - break; case chrome::FILE_EFFECTS_PLUGIN: if (!GetInternalPluginsDirectory(&cur)) return false;
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h index a22600ed..34c85fb 100644 --- a/chrome/common/chrome_paths.h +++ b/chrome/common/chrome_paths.h
@@ -83,7 +83,6 @@ // matter the file exists or not. FILE_PEPPER_FLASH_PLUGIN, // Full path to the bundled Pepper Flash plugin // file. - FILE_PDF_PLUGIN, // Full path to the internal PDF plugin file. FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file. DIR_PNACL_BASE, // Full path to the base dir for PNaCl.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 220bf60e..6986eee 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -451,6 +451,9 @@ // Enables experimentation with launching ephemeral apps via hyperlinks. const char kEnableLinkableEphemeralApps[] = "enable-linkable-ephemeral-apps"; +// Enables the material design Settings feature. +const char kEnableMaterialDesignSettings[] = "enable-md-settings"; + // Runs the Native Client inside the renderer process and enables GPU plugin // (internally adds lEnableGpuPlugin to the command line). const char kEnableNaCl[] = "enable-nacl";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index d39824a..d877231 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -132,6 +132,7 @@ extern const char kEnableFastUnload[]; extern const char kEnableIPv6[]; extern const char kEnableLinkableEphemeralApps[]; +extern const char kEnableMaterialDesignSettings[]; extern const char kEnableNaCl[]; extern const char kEnableNetBenchmarking[]; extern const char kEnableNewBookmarkApps[];
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index b68b8cb..65518e95 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -262,11 +262,6 @@ "dependencies": ["manifest:devtools_page"], "contexts": ["blessed_extension"] }, - "diagnostics": { - "dependencies": ["permission:diagnostics"], - "extension_types": ["platform_app"], - "contexts": ["blessed_extension"] - }, "dial": { "dependencies": ["permission:dial"], "contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index acc6795..aedc4e1 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -249,21 +249,6 @@ "852290F2442EEE45EF673B8DA6090112079012A2" // http://crbug.com/375484 ] }, - "diagnostics": [ - { - "channel": "dev", - "extension_types": ["platform_app"] - }, - { - "channel": "stable", - "extension_types": ["platform_app"], - "whitelist": [ - "7AE714FFD394E073F0294CFA134C9F91DB5FBAA4", // CCD Development - "C7DA3A55C2355F994D3FDDAD120B426A0DF63843", // CCD Testing - "75E3CFFFC530582C583E4690EF97C70B9C8423B7" // CCD Release - ] - } - ], "debugger": [ { "channel": "stable",
diff --git a/chrome/common/extensions/api/content_settings.json b/chrome/common/extensions/api/content_settings.json index 126e7ee..3d6e4ad4 100644 --- a/chrome/common/extensions/api/content_settings.json +++ b/chrome/common/extensions/api/content_settings.json
@@ -229,6 +229,14 @@ {"type":"string", "enum": ["allow", "block", "ask"]} ] }, + "fullscreen": { + "$ref": "ContentSetting", + "description": "Whether to allow sites to toggle the fullscreen mode. One of<br><var>allow</var>: Allow sites to toggle the fullscreen mode,<br><var>ask</var>: Ask when a site wants to toggle the fullscreen mode. <br>Default is <var>ask</var>.<br>The primary URL is the URL of the document which requested to toggle the fullscreen mode. The secondary URL is the URL of the top-level frame (which may or may not differ from the requesting URL).", + "value": [ + "fullscreen", + {"type":"string", "enum": ["allow", "ask"]} + ] + }, "mouselock": { "$ref": "ContentSetting", "description": "Whether to allow sites to disable the mouse cursor. One of <br><var>allow</var>: Allow sites to disable the mouse cursor,<br><var>block</var>: Don't allow sites to disable the mouse cursor,<br><var>ask</var>: Ask when a site wants to disable the mouse cursor. <br>Default is <var>ask</var>.<br>The primary URL is the URL of the top-level frame. The secondary URL is not used.", @@ -252,6 +260,22 @@ "media-stream-camera", {"type":"string", "enum": ["allow", "block", "ask"]} ] + }, + "unsandboxedPlugins": { + "$ref": "ContentSetting", + "description": "Whether to allow sites to run plug-ins unsandboxed. One of <br><var>allow</var>: Allow sites to run plug-ins unsandboxed,<br><var>block</var>: Don't allow sites to run plug-ins unsandboxed,<br><var>ask</var>: Ask when a site wants to run a plug-in unsandboxed. <br>Default is <var>ask</var>.<br>The primary URL is the URL of the top-level frame. The secondary URL is not used.", + "value": [ + "ppapi-broker", + {"type":"string", "enum": ["allow", "block", "ask"]} + ] + }, + "automaticDownloads": { + "$ref": "ContentSetting", + "description": "Whether to allow sites to download multiple files automatically. One of <br><var>allow</var>: Allow sites to download multiple files automatically,<br><var>block</var>: Don't allow sites to download multiple files automatically,<br><var>ask</var>: Ask when a site wants to download files automatically after the first file. <br>Default is <var>ask</var>.<br>The primary URL is the URL of the top-level frame. The secondary URL is not used.", + "value": [ + "multiple-automatic-downloads", + {"type":"string", "enum": ["allow", "block", "ask"]} + ] } } }
diff --git a/chrome/common/extensions/api/document_scan.idl b/chrome/common/extensions/api/document_scan.idl index 0428d4a1..97baa91c 100644 --- a/chrome/common/extensions/api/document_scan.idl +++ b/chrome/common/extensions/api/document_scan.idl
@@ -18,18 +18,19 @@ // an image tag. DOMString[] dataUrls; - // The MIME type of |dataUrls|. + // The MIME type of <code>dataUrls</code>. DOMString mimeType; }; - // Callback from the <code>scan</code> method; on success - // the results from the scan is returned in |results|. - callback ScanCallback = void (ScanResults results); + // Callback from the <code>scan</code> method. + // |result| The results from the scan, if successful. + // Otherwise will return null and set runtime.lastError. + callback ScanCallback = void (ScanResults result); interface Functions { // Performs a document scan. On success, the PNG data will be // sent to the callback. - // |options| : <code>Options</code> object containing scan parameters. + // |options| : Object containing scan parameters. // |callback| : Called with the result and data from the scan. static void scan(ScanOptions options, ScanCallback callback); };
diff --git a/chrome/common/extensions/api/notifications.idl b/chrome/common/extensions/api/notifications.idl index fb1fe65..7b41605 100644 --- a/chrome/common/extensions/api/notifications.idl +++ b/chrome/common/extensions/api/notifications.idl
@@ -124,31 +124,40 @@ interface Functions { // Creates and displays a notification. - // |notificationId|: Identifier of the notification. If it is empty, this - // method generates an id. If it matches an existing notification, this - // method first clears that notification before proceeding with the create - // operation. + // |notificationId|: Identifier of the notification. If not set or empty, an + // ID will automatically be generated. If it matches an existing + // notification, this method first clears that notification before + // proceeding with the create operation. + // + // The <code>notificationId</code> parameter is required before Chrome 42. // |options|: Contents of the notification. // |callback|: Returns the notification id (either supplied or generated) // that represents the created notification. - static void create(DOMString notificationId, + // + // The callback is required before Chrome 42. + static void create(optional DOMString notificationId, NotificationOptions options, - CreateCallback callback); + optional CreateCallback callback); // Updates an existing notification. // |notificationId|: The id of the notification to be updated. This is // returned by $(ref:notifications.create) method. // |options|: Contents of the notification to update to. // |callback|: Called to indicate whether a matching notification existed. + // + // The callback is required before Chrome 42. static void update(DOMString notificationId, NotificationOptions options, - UpdateCallback callback); + optional UpdateCallback callback); // Clears the specified notification. // |notificationId|: The id of the notification to be cleared. This is // returned by $(ref:notifications.create) method. // |callback|: Called to indicate whether a matching notification existed. - static void clear(DOMString notificationId, ClearCallback callback); + // + // The callback is required before Chrome 42. + static void clear(DOMString notificationId, + optional ClearCallback callback); // Retrieves all the notifications. // |callback|: Returns the set of notification_ids currently in the system.
diff --git a/chrome/common/extensions/api/schemas.gypi b/chrome/common/extensions/api/schemas.gypi index 7b630c00..d02d0a1 100644 --- a/chrome/common/extensions/api/schemas.gypi +++ b/chrome/common/extensions/api/schemas.gypi
@@ -107,7 +107,6 @@ # ChromeOS-specific schemas. 'chromeos_schema_files': [ 'accessibility_features.json', - 'diagnostics.idl', 'enterprise_platform_keys.idl', 'enterprise_platform_keys_internal.idl', 'file_browser_handler_internal.json',
diff --git a/chrome/common/extensions/docs/server2/admin_servlets.py b/chrome/common/extensions/docs/server2/admin_servlets.py new file mode 100644 index 0000000..7990761 --- /dev/null +++ b/chrome/common/extensions/docs/server2/admin_servlets.py
@@ -0,0 +1,111 @@ +# 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 appengine_wrappers import taskqueue +from commit_tracker import CommitTracker +from future import All +from object_store_creator import ObjectStoreCreator +from refresh_tracker import RefreshTracker +from servlet import Servlet, Response + + +class EnqueueServlet(Servlet): + '''This Servlet can be used to manually enqueue tasks on the default + taskqueue. Useful for when an admin wants to manually force a specific + DataSource refresh, but the refresh operation takes longer than the 60 sec + timeout of a non-taskqueue request. For example, you might query + + /_enqueue/_refresh/content_providers/cr-native-client?commit=123ff65468dcafff0 + + which will enqueue a task (/_refresh/content_providers/cr-native-client) to + refresh the NaCl documentation cache for commit 123ff65468dcafff0. + + Access to this servlet should always be restricted to administrative users. + ''' + def __init__(self, request): + Servlet.__init__(self, request) + + def Get(self): + queue = taskqueue.Queue() + queue.add(taskqueue.Task(url='/%s' % self._request.path, + params=self._request.arguments)) + return Response.Ok('Task enqueued.') + + +class QueryCommitServlet(Servlet): + '''Provides read access to the commit ID cache within the server. For example: + + /_query_commit/master + + will return the commit ID stored under the commit key "master" within the + commit cache. Currently "master" is the only named commit we cache, and it + corresponds to the commit ID whose data currently populates the data cache + used by live instances. + ''' + def __init__(self, request): + Servlet.__init__(self, request) + + def Get(self): + object_store_creator = ObjectStoreCreator(start_empty=False) + commit_tracker = CommitTracker(object_store_creator) + + def generate_response(result): + commit_id, history = result + history_log = ''.join('%s: %s<br>' % (entry.datetime, entry.commit_id) + for entry in reversed(history)) + response = 'Current commit: %s<br><br>Most recent commits:<br>%s' % ( + commit_id, history_log) + return response + + commit_name = self._request.path + id_future = commit_tracker.Get(commit_name) + history_future = commit_tracker.GetHistory(commit_name) + return Response.Ok( + All((id_future, history_future)).Then(generate_response).Get()) + + +class DumpRefreshServlet(Servlet): + def __init__(self, request): + Servlet.__init__(self, request) + + def Get(self): + object_store_creator = ObjectStoreCreator(start_empty=False) + refresh_tracker = RefreshTracker(object_store_creator) + commit_id = self._request.path + work_order = refresh_tracker._GetWorkOrder(commit_id).Get() + task_names = ['%s@%s' % (commit_id, task) for task in work_order.tasks] + completions = refresh_tracker._task_completions.GetMulti(task_names).Get() + missing = [] + for task in task_names: + if task not in completions: + missing.append(task) + response = 'Missing:<br>%s' % ''.join('%s<br>' % task for task in missing) + return Response.Ok(response) + +class ResetCommitServlet(Servlet): + '''Writes a new commit ID to the commit cache. For example: + + /_reset_commit/master/123456 + + will reset the 'master' commit ID to '123456'. The provided commit MUST be + in the named commit's recent history or it will be ignored. + ''' + + class Delegate(object): + def CreateCommitTracker(self): + return CommitTracker(ObjectStoreCreator(start_empty=False)) + + def __init__(self, request, delegate=Delegate()): + Servlet.__init__(self, request) + self._delegate = delegate + + def Get(self): + commit_tracker = self._delegate.CreateCommitTracker() + commit_name, commit_id = self._request.path.split('/', 1) + history = commit_tracker.GetHistory(commit_name).Get() + if not any(entry.commit_id == commit_id for entry in history): + return Response.BadRequest('Commit %s not cached.' % commit_id) + commit_tracker.Set(commit_name, commit_id).Get() + return Response.Ok('Commit "%s" updated to %s' % (commit_name, commit_id)) +
diff --git a/chrome/common/extensions/docs/server2/admin_servlets_test.py b/chrome/common/extensions/docs/server2/admin_servlets_test.py new file mode 100755 index 0000000..3fe9535 --- /dev/null +++ b/chrome/common/extensions/docs/server2/admin_servlets_test.py
@@ -0,0 +1,89 @@ +#!/usr/bin/env python +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import unittest + +from admin_servlets import ResetCommitServlet +from commit_tracker import CommitTracker +from object_store_creator import ObjectStoreCreator +from servlet import Request + + +_COMMIT_HISTORY_DATA = ( + '1234556789abcdef1234556789abcdef12345567', + 'f00f00f00f00f00f00f00f00f00f00f00f00f00f', + '1010101010101010101010101010101010101010', + 'abcdefabcdefabcdefabcdefabcdefabcdefabcd', + '4242424242424242424242424242424242424242', +) + + +class _ResetCommitDelegate(ResetCommitServlet.Delegate): + def __init__(self, commit_tracker): + self._commit_tracker = commit_tracker + + def CreateCommitTracker(self): + return self._commit_tracker + + +class AdminServletsTest(unittest.TestCase): + def setUp(self): + object_store_creator = ObjectStoreCreator(start_empty=True) + self._commit_tracker = CommitTracker(object_store_creator) + for id in _COMMIT_HISTORY_DATA: + self._commit_tracker.Set('master', id).Get() + + def _ResetCommit(self, commit_name, commit_id): + return ResetCommitServlet( + Request.ForTest('%s/%s' % (commit_name, commit_id)), + _ResetCommitDelegate(self._commit_tracker)).Get() + + def _AssertBadRequest(self, commit_name, commit_id): + response = self._ResetCommit(commit_name, commit_id) + self.assertEqual(response.status, 400, + 'Should have failed to reset to commit %s to %s.' % + (commit_name, commit_id)) + + def _AssertOk(self, commit_name, commit_id): + response = self._ResetCommit(commit_name, commit_id) + self.assertEqual(response.status, 200, + 'Failed to reset commit %s to %s.' % (commit_name, commit_id)) + + def testResetCommitServlet(self): + # Make sure all the valid commits can be used for reset. + for id in _COMMIT_HISTORY_DATA: + self._AssertOk('master', id) + + # Non-existent commit should fail to update + self._AssertBadRequest('master', + 'b000000000000000000000000000000000000000') + + # Commit 'master' should still point to the last valid entry + self.assertEqual(self._commit_tracker.Get('master').Get(), + _COMMIT_HISTORY_DATA[-1]) + + # Reset to a valid commit but older + self._AssertOk('master', _COMMIT_HISTORY_DATA[0]) + + # Commit 'master' should point to the first history entry + self.assertEqual(self._commit_tracker.Get('master').Get(), + _COMMIT_HISTORY_DATA[0]) + + # Add a new entry to the history and validate that it can be used for reset. + _NEW_ENTRY = '9999999999999999999999999999999999999999' + self._commit_tracker.Set('master', _NEW_ENTRY).Get() + self._AssertOk('master', _NEW_ENTRY) + + # Add a bunch (> 50) of entries to ensure that _NEW_ENTRY has been flushed + # out of the history. + for i in xrange(0, 20): + for id in _COMMIT_HISTORY_DATA: + self._commit_tracker.Set('master', id).Get() + + # Verify that _NEW_ENTRY is no longer valid for reset. + self._AssertBadRequest('master', _NEW_ENTRY) + +if __name__ == '__main__': + unittest.main()
diff --git a/chrome/common/extensions/docs/server2/app.yaml b/chrome/common/extensions/docs/server2/app.yaml index 698bd396..f8d6f30 100644 --- a/chrome/common/extensions/docs/server2/app.yaml +++ b/chrome/common/extensions/docs/server2/app.yaml
@@ -22,6 +22,10 @@ script: appengine_main.py secure: always login: admin +- url: /_reset_commit/.* + script: appengine_main.py + secure: always + login: admin - url: /.* script: appengine_main.py secure: always
diff --git a/chrome/common/extensions/docs/server2/availability_finder.py b/chrome/common/extensions/docs/server2/availability_finder.py index 69ecf356..bc470f5e 100644 --- a/chrome/common/extensions/docs/server2/availability_finder.py +++ b/chrome/common/extensions/docs/server2/availability_finder.py
@@ -174,7 +174,7 @@ schema_fs = self._CreateAPISchemaFileSystem(file_system) api_schemas = schema_fs.GetFromFile(api_filename).Get() matching_schemas = [api for api in api_schemas - if api['namespace'] == api_name] + if api and api['namespace'] == api_name] # There should only be a single matching schema per file, or zero in the # case of no API data being found in _EXTENSION_API. assert len(matching_schemas) <= 1
diff --git a/chrome/common/extensions/docs/server2/commit_tracker.py b/chrome/common/extensions/docs/server2/commit_tracker.py index 53bb90c9..874c4b7b 100644 --- a/chrome/common/extensions/docs/server2/commit_tracker.py +++ b/chrome/common/extensions/docs/server2/commit_tracker.py
@@ -2,20 +2,55 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import collections +import datetime + from object_store_creator import ObjectStoreCreator from future import Future +# The maximum number of commit IDs to retain in a named commit's history deque. +_MAX_COMMIT_HISTORY_LENGTH = 50 + + +class CachedCommit(object): + '''Object type which is stored for each entry in a named commit's history. + |datetime| is used as a timestamp for when the commit cache was completed, + and is only meant to provide a loose ordering of commits for administrative + servlets to display.''' + def __init__(self, commit_id, datetime): + self.commit_id = commit_id + self.datetime = datetime + + class CommitTracker(object): '''Utility class for managing and querying the storage of various named commit IDs.''' def __init__(self, object_store_creator): - # The object store should never be created empty since the sole purpose of + # The object stores should never be created empty since the sole purpose of # this tracker is to persist named commit data across requests. self._store = object_store_creator.Create(CommitTracker, start_empty=False) + self._history_store = object_store_creator.Create(CommitTracker, + category='history', start_empty=False) def Get(self, key): return self._store.Get(key) def Set(self, key, commit): - return self._store.Set(key, commit) + return (self._store.Set(key, commit) + .Then(lambda _: self._UpdateHistory(key, commit))) + + def GetHistory(self, key): + '''Fetches the commit ID history for a named commit. If the commit has no + history, this will return an empty collection.''' + return (self._history_store.Get(key) + .Then(lambda history: () if history is None else history)) + + def _UpdateHistory(self, key, commit): + '''Appends a commit ID to a named commit's tracked history.''' + def create_or_amend_history(history): + if history is None: + history = collections.deque([], maxlen=50) + history.append(CachedCommit(commit, datetime.datetime.now())) + return self._history_store.Set(key, history) + return self._history_store.Get(key).Then(create_or_amend_history)
diff --git a/chrome/common/extensions/docs/server2/handler.py b/chrome/common/extensions/docs/server2/handler.py index a0e044e..c6a2eed 100644 --- a/chrome/common/extensions/docs/server2/handler.py +++ b/chrome/common/extensions/docs/server2/handler.py
@@ -4,11 +4,10 @@ import time -from appengine_wrappers import taskqueue -from commit_tracker import CommitTracker +from admin_servlets import (DumpRefreshServlet, EnqueueServlet, + QueryCommitServlet, ResetCommitServlet) from cron_servlet import CronServlet from instance_servlet import InstanceServlet -from object_store_creator import ObjectStoreCreator from patch_servlet import PatchServlet from refresh_servlet import RefreshServlet from servlet import Servlet, Request, Response @@ -18,55 +17,15 @@ _DEFAULT_SERVLET = InstanceServlet.GetConstructor() -class _EnqueueServlet(Servlet): - '''This Servlet can be used to manually enqueue tasks on the default - taskqueue. Useful for when an admin wants to manually force a specific - DataSource refresh, but the refresh operation takes longer than the 60 sec - timeout of a non-taskqueue request. For example, you might query - - /_enqueue/_refresh/content_providers/cr-native-client?commit=123ff65468dcafff0 - - which will enqueue a task (/_refresh/content_providers/cr-native-client) to - refresh the NaCl documentation cache for commit 123ff65468dcafff0. - - Access to this servlet should always be restricted to administrative users. - ''' - def __init__(self, request): - Servlet.__init__(self, request) - - def Get(self): - queue = taskqueue.Queue() - queue.add(taskqueue.Task(url='/%s' % self._request.path, - params=self._request.arguments)) - return Response.Ok('Task enqueued.') - - -class _QueryCommitServlet(Servlet): - '''Provides read access to the commit ID cache within the server. For example: - - /_query_commit/master - - will return the commit ID stored under the commit key "master" within the - commit cache. Currently "master" is the only named commit we cache, and it - corresponds to the commit ID whose data currently populates the data cache - used by live instances. - ''' - def __init__(self, request): - Servlet.__init__(self, request) - - def Get(self): - object_store_creator = ObjectStoreCreator(start_empty=False) - commit_tracker = CommitTracker(object_store_creator) - return Response.Ok(commit_tracker.Get(self._request.path).Get()) - - _SERVLETS = { 'cron': CronServlet, - 'enqueue': _EnqueueServlet, + 'enqueue': EnqueueServlet, 'patch': PatchServlet, - 'query_commit': _QueryCommitServlet, + 'query_commit': QueryCommitServlet, 'refresh': RefreshServlet, + 'reset_commit': ResetCommitServlet, 'test': TestServlet, + 'dump_refresh': DumpRefreshServlet, }
diff --git a/chrome/common/extensions/docs/server2/servlet.py b/chrome/common/extensions/docs/server2/servlet.py index 5465d81..61917ff 100644 --- a/chrome/common/extensions/docs/server2/servlet.py +++ b/chrome/common/extensions/docs/server2/servlet.py
@@ -96,6 +96,12 @@ return Response(headers={'Location': url}, status=status) @staticmethod + def BadRequest(content, headers=None): + '''Returns a bad request (400) response. + ''' + return Response(content=content, headers=headers, status=400) + + @staticmethod def NotFound(content, headers=None): '''Returns a not found (404) response. '''
diff --git a/chrome/common/extensions/docs/templates/public/apps/copresenceEndpoints.html b/chrome/common/extensions/docs/templates/public/apps/copresenceEndpoints.html deleted file mode 100644 index bf67990..0000000 --- a/chrome/common/extensions/docs/templates/public/apps/copresenceEndpoints.html +++ /dev/null
@@ -1 +0,0 @@ -{{+partials.standard_apps_api api:apis.apps.copresence_endpoints/}}
diff --git a/chrome/common/extensions/docs/templates/public/apps/documentScan.html b/chrome/common/extensions/docs/templates/public/apps/documentScan.html new file mode 100644 index 0000000..755908d --- /dev/null +++ b/chrome/common/extensions/docs/templates/public/apps/documentScan.html
@@ -0,0 +1 @@ +{{+partials.standard_apps_api api:apis.apps.document_scan intro:intros.documentScan/}}
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index a40fe6a..4ca22c0 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -229,9 +229,6 @@ {APIPermission::kDeveloperPrivate, "developerPrivate", APIPermissionInfo::kFlagCannotBeOptional}, - {APIPermission::kDiagnostics, - "diagnostics", - APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kDial, "dial", APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kDownloadsInternal, "downloadsInternal"}, {APIPermission::kExperienceSamplingPrivate,
diff --git a/chrome/common/extensions/update_manifest_unittest.cc b/chrome/common/extensions/update_manifest_unittest.cc index 36ea5d5b..8915ab75 100644 --- a/chrome/common/extensions/update_manifest_unittest.cc +++ b/chrome/common/extensions/update_manifest_unittest.cc
@@ -17,14 +17,14 @@ "</gupdate>"; static const char valid_xml_with_hash[] = -"<?xml version='1.0' encoding='UTF-8'?>" -"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" -" <app appid='12345'>" -" <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" -" version='1.2.3.4' prodversionmin='2.0.143.0' " -" hash='1234'/>" -" </app>" -"</gupdate>"; + "<?xml version='1.0' encoding='UTF-8'?>" + "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>" + " <app appid='12345'>" + " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" + " version='1.2.3.4' prodversionmin='2.0.143.0' " + " hash_sha256='1234'/>" + " </app>" + "</gupdate>"; static const char kMissingAppId[] = "<?xml version='1.0'?>"
diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include index 81bb746..3ff0fd6 100644 --- a/chrome/installer/linux/common/installer.include +++ b/chrome/installer/linux/common/installer.include
@@ -172,11 +172,6 @@ install -m 644 "${PEPPERFLASH_SRCDIR}/manifest.json" \ "${PEPPERFLASH_DESTDIR}/" - # pdf plugin - if [ -f "${BUILDDIR}/libpdf.so" ]; then - install -m 644 -s "${BUILDDIR}/libpdf.so" "${STAGEDIR}/${INSTALLDIR}/" - fi - # peerconnection shared library if [ -f "${BUILDDIR}/lib/libpeerconnection.so" ]; then install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/"
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index 5b07489..0c92e6d 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release
@@ -9,7 +9,7 @@ chrome.exe: %(ChromeDir)s\ wow_helper.exe: %(ChromeDir)s\ # -# Chrome version dir aseembly manifest. +# Chrome version dir assembly manifest. # The name of this file must match the name of the version dir, so we cannot # hard-code it. # // TODO(caitkp): Find a way to do this without wildcards. @@ -25,6 +25,7 @@ chrome_watcher.dll: %(VersionDir)s\ d3dcompiler_47.dll: %(VersionDir)s\ ffmpegsumo.dll: %(VersionDir)s\ +kasko.dll: %(VersionDir)s\ icudt.dll: %(VersionDir)s\ icudtl.dat: %(VersionDir)s\ libEGL.dll: %(VersionDir)s\ @@ -34,7 +35,6 @@ nacl_irt_x86_32.nexe: %(VersionDir)s\ nacl_irt_x86_64.nexe: %(VersionDir)s\ natives_blob.bin: %(VersionDir)s\ -pdf.dll: %(VersionDir)s\ resources.pak: %(VersionDir)s\ snapshot_blob.bin: %(VersionDir)s\ syzyasan_rtl.dll: %(VersionDir)s\
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 2372e9d3..5454e8d 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc
@@ -170,15 +170,15 @@ archive_helper->set_patch_source(patch_source); // Try courgette first. Failing that, try bspatch. - if ((installer_state.UpdateStage(installer::ENSEMBLE_PATCHING), - !archive_helper->EnsemblePatch()) && - (installer_state.UpdateStage(installer::BINARY_PATCHING), - !archive_helper->BinaryPatch())) { - *install_status = installer::APPLY_DIFF_PATCH_FAILED; - installer_state.WriteInstallerResult(*install_status, - IDS_INSTALL_UNCOMPRESSION_FAILED_BASE, - NULL); - return false; + installer_state.UpdateStage(installer::ENSEMBLE_PATCHING); + if (!archive_helper->EnsemblePatch()) { + installer_state.UpdateStage(installer::BINARY_PATCHING); + if (!archive_helper->BinaryPatch()) { + *install_status = installer::APPLY_DIFF_PATCH_FAILED; + installer_state.WriteInstallerResult( + *install_status, IDS_INSTALL_UNCOMPRESSION_FAILED_BASE, NULL); + return false; + } } *archive_type = installer::INCREMENTAL_ARCHIVE_TYPE;
diff --git a/chrome/interactive_ui_tests.isolate b/chrome/interactive_ui_tests.isolate index bef04953..d968a7d 100644 --- a/chrome/interactive_ui_tests.isolate +++ b/chrome/interactive_ui_tests.isolate
@@ -12,6 +12,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -76,6 +78,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index 9367b98..0987379 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -43,10 +43,6 @@ #include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/WebKit/public/web/WebView.h" -#if defined(OS_WIN) -#include "base/win/iat_patch_function.h" -#endif - #if defined(ENABLE_EXTENSIONS) #include "chrome/renderer/extensions/extension_localization_peer.h" #endif @@ -112,43 +108,6 @@ DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate); }; -#if defined(OS_WIN) -static base::win::IATPatchFunction g_iat_patch_createdca; -HDC WINAPI CreateDCAPatch(LPCSTR driver_name, - LPCSTR device_name, - LPCSTR output, - const void* init_data) { - DCHECK(std::string("DISPLAY") == std::string(driver_name)); - DCHECK(!device_name); - DCHECK(!output); - DCHECK(!init_data); - - // CreateDC fails behind the sandbox, but not CreateCompatibleDC. - return CreateCompatibleDC(NULL); -} - -static base::win::IATPatchFunction g_iat_patch_get_font_data; -DWORD WINAPI GetFontDataPatch(HDC hdc, - DWORD table, - DWORD offset, - LPVOID buffer, - DWORD length) { - int rv = GetFontData(hdc, table, offset, buffer, length); - if (rv == GDI_ERROR && hdc) { - HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); - - LOGFONT logfont; - if (GetObject(font, sizeof(LOGFONT), &logfont)) { - std::vector<char> font_data; - RenderThread::Get()->PreCacheFont(logfont); - rv = GetFontData(hdc, table, offset, buffer, length); - RenderThread::Get()->ReleaseCachedFonts(); - } - } - return rv; -} -#endif // OS_WIN - static const int kWaitForWorkersStatsTimeoutMS = 20; class HeapStatisticsCollector { @@ -280,22 +239,6 @@ // Configure modules that need access to resources. net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); -#if defined(OS_WIN) - // TODO(scottmg): http://crbug.com/448473. This code should be removed once - // PDF is always OOP and/or PDF is made to use Skia instead of GDI directly. - if (!command_line.HasSwitch(switches::kEnableOutOfProcessPdf)) { - // Need to patch a few functions for font loading to work correctly. - base::FilePath pdf; - if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && - base::PathExists(pdf)) { - g_iat_patch_createdca.Patch(pdf.value().c_str(), "gdi32.dll", "CreateDCA", - CreateDCAPatch); - g_iat_patch_get_font_data.Patch(pdf.value().c_str(), "gdi32.dll", - "GetFontData", GetFontDataPatch); - } - } -#endif - #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_NSS) // On platforms where we use system NSS shared libraries, // initialize NSS now because it won't be able to load the .so's
diff --git a/chrome/renderer/media/OWNERS b/chrome/renderer/media/OWNERS index 43bd1e5..cbadb65a 100644 --- a/chrome/renderer/media/OWNERS +++ b/chrome/renderer/media/OWNERS
@@ -5,7 +5,6 @@ scherkus@chromium.org sergeyu@chromium.org tommi@chromium.org -vrk@chromium.org xhwang@chromium.org per-file cast_*=hclam@chromium.org
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index 9dcf6261..309edacb 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -728,7 +728,7 @@ // TODO(dtseng): Make into set listing all hosting node roles. if (nodeData.role == schema.RoleType.webView) { - if (nodeImpl.pendingChildFrame === undefined) + if (nodeImpl.childTreeID !== nodeData.intAttributes.childTreeId) nodeImpl.pendingChildFrame = true; if (nodeImpl.pendingChildFrame) {
diff --git a/chrome/renderer/resources/extensions/notifications_custom_bindings.js b/chrome/renderer/resources/extensions/notifications_custom_bindings.js index eebf290..fc6b4425 100644 --- a/chrome/renderer/resources/extensions/notifications_custom_bindings.js +++ b/chrome/renderer/resources/extensions/notifications_custom_bindings.js
@@ -7,6 +7,7 @@ var binding = require('binding').Binding.create('notifications'); var sendRequest = require('sendRequest').sendRequest; +var exceptionHandler = require('uncaught_exception_handler'); var imageUtil = require('imageUtil'); var lastError = require('lastError'); var notificationsPrivate = requireNative('notifications_private'); @@ -111,20 +112,21 @@ return function(id, input_notification_details, callback) { // TODO(dewittj): Remove this hack. This is used as a way to deep // copy a complex JSON object. - var notification_details = JSON.parse( - JSON.stringify(input_notification_details)); + var notification_details = $JSON.parse( + $JSON.stringify(input_notification_details)); var that = this; + var stack = exceptionHandler.getExtensionStackTrace(); replaceNotificationOptionURLs(notification_details, function(success) { if (success) { sendRequest(that.name, [id, notification_details, callback], - that.definition.parameters); + that.definition.parameters, {stack: stack}); return; } lastError.run(name, 'Unable to download all specified images.', - null, - failure_function, [callback, id]) + stack, + failure_function, [callback || function() {}, id]); }); }; }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 588a4b4..1c24f05 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -124,6 +124,7 @@ if (!is_ios) { deps += [ + "//chrome/child", "//chrome/plugin", "//chrome/renderer", "//chrome/utility", @@ -136,6 +137,7 @@ "//components/captive_portal:test_support", "//components/infobars/core", "//components/sessions:test_support", + "//components/user_manager:test_support", "//components/web_resource:test_support", "//google_apis:test_support", "//ipc:test_support", @@ -174,6 +176,7 @@ "ppapi/ppapi_test.cc", "ppapi/ppapi_test.h", ] + deps += [ "//pdf" ] } if (use_ash) { @@ -245,7 +248,6 @@ "//net", "//net:net_resources", "//net:test_support", - "//pdf", #"//ppapi:ppapi_tests", # TODO(GYP) this doesn't exist yet. "//skia", @@ -627,6 +629,7 @@ "//components/resources", "//components/strings", "//components/translate/core/common", + "//components/user_manager:test_support", "//crypto:platform", "//crypto:test_support", "//device/bluetooth:mocks", @@ -1211,7 +1214,6 @@ "//third_party/cacheinvalidation", "//third_party/icu", "//third_party/libxml", - "//ui/accelerometer", "//ui/base:test_support", "//ui/gfx:test_support", "//ui/resources", @@ -1670,7 +1672,7 @@ } if (use_ozone) { # crbug.com/354036 - sources -= [ "browser/chromeos/events/event_rewriter_unittest.cc" ] + sources -= [ "../browser/chromeos/events/event_rewriter_unittest.cc" ] } if (!enable_plugin_installation) { sources -= [ "../browser/plugins/plugin_installer_unittest.cc" ]
diff --git a/chrome/test/base/extension_js_browser_test.h b/chrome/test/base/extension_js_browser_test.h index 34cecdd..439e169 100644 --- a/chrome/test/base/extension_js_browser_test.h +++ b/chrome/test/base/extension_js_browser_test.h
@@ -17,7 +17,7 @@ public: ExtensionJSBrowserTest(); - virtual ~ExtensionJSBrowserTest(); + ~ExtensionJSBrowserTest() override; protected: // Waits for an extension to load; returns immediately if already loaded.
diff --git a/chrome/test/base/extension_load_waiter_one_shot.h b/chrome/test/base/extension_load_waiter_one_shot.h index 47d22d6..15cae65 100644 --- a/chrome/test/base/extension_load_waiter_one_shot.h +++ b/chrome/test/base/extension_load_waiter_one_shot.h
@@ -19,16 +19,16 @@ class ExtensionLoadWaiterOneShot : public content::NotificationObserver { public: ExtensionLoadWaiterOneShot(); - virtual ~ExtensionLoadWaiterOneShot(); + ~ExtensionLoadWaiterOneShot() override; // Waits for extension with |extension_id| to load. The id should be a pointer // to a static char array. void WaitForExtension(const char* extension_id, const base::Closure& load_cb); // content::NotificationObserver overrides. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; // Get the browser context associated with the loaded extension. Returns // NULL if |WaitForExtension| was not previously called.
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 7f49296f..3c2a90f 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -569,21 +569,15 @@ this, BuildHistoryService)); if (!history_service->Init( no_db, history::HistoryDatabaseParamsForPath(this->GetPath()))) { - HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(this, NULL); + HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr); + return false; } // Disable WebHistoryService by default, since it makes network requests. - WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this, NULL); + WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr); return true; } void TestingProfile::DestroyHistoryService() { - // TODO(sdefresne): remove this once ChromeHistoryClient is no longer an - // HistoryServiceObserver, http://crbug.com/373326 - ChromeHistoryClient* history_client = - ChromeHistoryClientFactory::GetForProfileWithoutCreating(this); - if (history_client) - history_client->Shutdown(); - HistoryService* history_service = HistoryServiceFactory::GetForProfileWithoutCreating(this); if (!history_service)
diff --git a/chrome/test/data/extensions/api_test/content_settings/standard/test.js b/chrome/test/data/extensions/api_test/content_settings/standard/test.js index c2237d3e..72dad15 100644 --- a/chrome/test/data/extensions/api_test/content_settings/standard/test.js +++ b/chrome/test/data/extensions/api_test/content_settings/standard/test.js
@@ -14,9 +14,12 @@ "popups": "block", "location": "ask", "notifications": "ask", + "fullscreen": "ask", "mouselock": "ask", "microphone": "ask", "camera": "ask", + "unsandboxedPlugins": "ask", + "automaticDownloads": "ask" }; var settings = { @@ -27,9 +30,12 @@ "popups": "allow", "location": "block", "notifications": "block", + "fullscreen": "allow", "mouselock": "block", "microphone": "block", - "camera": "block" + "camera": "block", + "unsandboxedPlugins": "block", + "automaticDownloads": "block" }; Object.prototype.forEach = function(f) {
diff --git a/chrome/test/data/extensions/api_test/notifications/api/basic_usage/background.js b/chrome/test/data/extensions/api_test/notifications/api/basic_usage/background.js index e1d0106..001f6db 100644 --- a/chrome/test/data/extensions/api_test/notifications/api/basic_usage/background.js +++ b/chrome/test/data/extensions/api_test/notifications/api/basic_usage/background.js
@@ -325,7 +325,32 @@ create("largeImage", options).then(succeed, fail); } +function testOptionalParameters() { + var testName = "testOptionalParameters"; + var succeed = succeedTest(testName); + var fail = failTest(testName); + function createCallback(notificationId) { + new Promise(function() { + chrome.test.assertNoLastError(); + chrome.test.assertEq("string", typeof notificationId); + // Optional callback - should run without problems + chrome.notifications.clear(notificationId); + // Note: The point of the previous line is to show that a callback can be + // optional. Because .clear is asynchronous, we have to be careful with + // calling .clear again. Since .clear is processed in order, calling + // clear() synchronously is okay. + // If this assumption does not hold and leaks to flaky tests, file a bug + // report and/or put the following call in a setTimeout call. + + // The notification should not exist any more, so clear() should fail. + clear(notificationId).then(fail, succeed); + }).then(null, fail); + } + // .create should succeed even when notificationId is omitted. + chrome.notifications.create(basicNotificationOptions, createCallback); +} + chrome.test.runTests([ testIdUsage, testBaseFormat, testListItem, testGetAll, testProgress, - testLargeImage + testLargeImage, testOptionalParameters ]);
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js index 91e7db8..763b63d 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js +++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -1421,16 +1421,14 @@ // chrome URL is provided. function testLoadAbortIllegalChromeURL() { var webview = document.createElement('webview'); - var onFirstLoadStop = function(e) { - webview.removeEventListener('loadstop', onFirstLoadStop); - webview.setAttribute('src', 'chrome://newtab'); - }; - webview.addEventListener('loadstop', onFirstLoadStop); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); - webview.setAttribute('src', 'about:blank'); + webview.src = 'chrome://newtab'; document.body.appendChild(webview); } @@ -1438,9 +1436,12 @@ var webview = document.createElement('webview'); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); - webview.setAttribute('src', 'file://foo'); + webview.src = 'file://foo'; document.body.appendChild(webview); } @@ -1448,6 +1449,9 @@ var webview = document.createElement('webview'); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.setAttribute('src', 'javascript:void(document.bgColor="#0000FF")'); @@ -1457,17 +1461,19 @@ // Verifies that navigating to invalid URL (e.g. 'http:') doesn't cause a crash. function testLoadAbortInvalidNavigation() { var webview = document.createElement('webview'); - var validSchemeWithEmptyURL = 'http:'; webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); embedder.test.assertEq('', e.url); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.addEventListener('exit', function(e) { // We should not crash. embedder.test.fail(); }); - webview.setAttribute('src', validSchemeWithEmptyURL); + webview.src = 'http:'; document.body.appendChild(webview); } @@ -1475,17 +1481,20 @@ // pseudo-scheme fires loadabort and doesn't cause a crash. function testLoadAbortNonWebSafeScheme() { var webview = document.createElement('webview'); - var chromeGuestURL = 'chrome-guest://abc123'; + var chromeGuestURL = 'chrome-guest://abc123/'; webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); - embedder.test.assertEq('chrome-guest://abc123/', e.url); + embedder.test.assertEq(chromeGuestURL, e.url); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.addEventListener('exit', function(e) { // We should not crash. embedder.test.fail(); }); - webview.setAttribute('src', chromeGuestURL); + webview.src = chromeGuestURL; document.body.appendChild(webview); };
diff --git a/chrome/test/data/frame_tree/page_with_two_frames_remote_and_local.html b/chrome/test/data/frame_tree/page_with_two_frames_remote_and_local.html new file mode 100644 index 0000000..4e5f365 --- /dev/null +++ b/chrome/test/data/frame_tree/page_with_two_frames_remote_and_local.html
@@ -0,0 +1,9 @@ +<!doctype html> +<html> +<head></head> +<body> + This page has two iframes: one is cross-site, the other is same-site. + <iframe src="/cross-site/bar.com/title1.html"></iframe> + <iframe src="/title1.html"></iframe> +</body> +</html>
diff --git a/chrome/test/data/webui/history_browsertest.js b/chrome/test/data/webui/history_browsertest.js index 8aacf42..03350b7 100644 --- a/chrome/test/data/webui/history_browsertest.js +++ b/chrome/test/data/webui/history_browsertest.js
@@ -787,7 +787,7 @@ TEST_F('HistoryWebUIRealBackendTest', 'atLeastOneFocusable', function() { var results = document.querySelectorAll('#results-display [tabindex="0"]'); - expectEquals(1, results.length); + expectGE(results.length, 1); testDone(); }); @@ -1004,7 +1004,7 @@ TEST_F('HistoryWebUIDeleteProhibitedTest', 'atLeastOneFocusable', function() { var results = document.querySelectorAll('#results-display [tabindex="0"]'); - expectEquals(1, results.length); + expectGE(results.length, 1); testDone(); });
diff --git a/chrome/test/data/webui/net_internals/chromeos_view.js b/chrome/test/data/webui/net_internals/chromeos_view.js index 4420225..35454b1 100644 --- a/chrome/test/data/webui/net_internals/chromeos_view.js +++ b/chrome/test/data/webui/net_internals/chromeos_view.js
@@ -47,10 +47,13 @@ }; TEST_F('NetInternalsTest', - 'DISABLED_netInternalsChromeOSViewStoreDebugLogs', + 'netInternalsChromeOSViewStoreDebugLogs', function() { - if (!cr.isChromeOS) + if (!cr.isChromeOS) { testDone(); + return; + } + // #chromeos-view-import-onc fails accessibility check. this.runAccessibilityChecks = false; NetInternalsTest.switchToView('chromeos');
diff --git a/chrome/tools/build/chromeos/FILES.cfg b/chrome/tools/build/chromeos/FILES.cfg index 801a5a7..ee70795 100644 --- a/chrome/tools/build/chromeos/FILES.cfg +++ b/chrome/tools/build/chromeos/FILES.cfg
@@ -113,11 +113,6 @@ 'buildtype': ['official'], 'direct_archive': 1, }, - # PDF Plugin files: - { - 'filename': 'libpdf.so', - 'buildtype': ['dev', 'official'], - }, # Native Client plugin files: { 'filename': 'nacl_irt_x86_32.nexe',
diff --git a/chrome/tools/build/linux/FILES.cfg b/chrome/tools/build/linux/FILES.cfg index d406d7ae..0862176 100644 --- a/chrome/tools/build/linux/FILES.cfg +++ b/chrome/tools/build/linux/FILES.cfg
@@ -130,11 +130,6 @@ 'filename': 'PepperFlash', 'buildtype': ['official'], }, - # PDF Plugin files: - { - 'filename': 'libpdf.so', - 'buildtype': ['dev', 'official'], - }, # Native Client plugin files: { 'filename': 'nacl_irt_x86_32.nexe', @@ -195,18 +190,6 @@ 'archive': 'breakpad-info.zip', }, { - 'filename': 'libpdf.so.breakpad.ia32', - 'arch': ['32bit'], - 'buildtype': ['official'], - 'archive': 'breakpad-info.zip', - }, - { - 'filename': 'libpdf.so.breakpad.x64', - 'arch': ['64bit'], - 'buildtype': ['official'], - 'archive': 'breakpad-info.zip', - }, - { 'filename': 'nacl_irt_x86_32.nexe.debug', 'arch': ['32bit'], 'buildtype': ['official'],
diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index bbdfa7e1..fb547cb 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg
@@ -369,12 +369,6 @@ 'filename': 'widevinecdmadapter.dll', 'buildtype': ['official'], }, - # PDF Plugin files: - { - 'filename': 'pdf.dll', - 'buildtype': ['dev', 'official'], - 'filegroup': ['default', 'symsrc'], - }, # ANGLE files: { 'filename': 'D3DCompiler_47.dll', @@ -595,6 +589,14 @@ 'buildtype': ['dev', 'official'], 'optional': ['dev', 'official'], }, + { + 'filename': 'syzygy/kasko.dll', + 'arch': ['32bit'], + 'buildtype': ['dev', 'official'], + 'archive': 'syzygy/kasko.dll', + 'filegroup': ['symsrc'], + 'optional': ['dev', 'official'], + }, # Test binaries for external QA: { 'filename': 'interactive_ui_tests.exe', @@ -709,11 +711,6 @@ 'archive': 'chrome-win32-syms.zip', }, { - 'filename': 'pdf.dll.pdb', - 'buildtype': ['dev', 'official'], - 'archive': 'chrome-win32-syms.zip', - }, - { 'filename': 'setup.exe.pdb', 'buildtype': ['dev', 'official'], 'archive': 'chrome-win32-syms.zip', @@ -766,6 +763,13 @@ 'optional': ['dev', 'official'], }, { + 'filename': 'syzygy/kasko.dll.pdb', + 'arch': ['32bit'], + 'buildtype': ['dev', 'official'], + 'archive': 'chrome-win32-syms.zip', + 'optional': ['dev', 'official'], + }, + { 'filename': 'nacl_irt_x86_32.nexe.debug', 'arch': ['32bit'], 'buildtype': ['official'],
diff --git a/chrome/tools/crash_service/caps/caps.gyp b/chrome/tools/crash_service/caps/caps.gyp index f18f84d..bcbe414 100644 --- a/chrome/tools/crash_service/caps/caps.gyp +++ b/chrome/tools/crash_service/caps/caps.gyp
@@ -39,14 +39,21 @@ 'target_name': 'caps', 'type': 'executable', 'include_dirs': [ - '../..', + '..', ], 'sources': [ + 'exit_codes.h', + 'logger_win.cc', + 'logger_win.h', 'main_win.cc', + 'process_singleton_win.cc', + 'process_singleton_win.h', '<(SHARED_INTERMEDIATE_DIR)/caps/caps_version.rc', ], 'dependencies': [ 'caps_resources', + '../../../../base/base.gyp:base', + '../../../../chrome/chrome.gyp:common_version', ], 'msvs_settings': { 'VCLinkerTool': {
diff --git a/chrome/tools/crash_service/caps/exit_codes.h b/chrome/tools/crash_service/caps/exit_codes.h new file mode 100644 index 0000000..583e0a5c --- /dev/null +++ b/chrome/tools/crash_service/caps/exit_codes.h
@@ -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. + +#ifndef CHROME_TOOLS_CRASH_SERVICE_CAPS_EXIT_CODES_H_ +#define CHROME_TOOLS_CRASH_SERVICE_CAPS_EXIT_CODES_H_ + +namespace caps { + +// Exit codes for CAPS. Don't reorder these values. +enum ExitCodes { + EC_NORMAL_EXIT = 0, + EC_EXISTING_INSTANCE, + EC_INIT_ERROR, + EC_LAST_CODE +}; + +} // namespace caps + +#endif // CHROME_TOOLS_CRASH_SERVICE_CAPS_EXIT_CODES_H_ +
diff --git a/chrome/tools/crash_service/caps/logger_win.cc b/chrome/tools/crash_service/caps/logger_win.cc new file mode 100644 index 0000000..2e4a1cf --- /dev/null +++ b/chrome/tools/crash_service/caps/logger_win.cc
@@ -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. + +#include <windows.h> +#include <time.h> + +#include "base/files/file_path.h" +#include "base/strings/stringprintf.h" +#include "chrome/common/chrome_version_info_values.h" +#include "chrome/tools/crash_service/caps/logger_win.h" + +namespace { +// Every message has this structure: +// <index>~ <tick_count> <message> ~\n" +const char kMessageHeader[] = "%03d~ %08x %s ~\n"; + +// Do not re-order these messages. Only add at the end. +const char* kMessages[] { + "start pid(%lu) version(%s) time(%s)", // 0 + "exit pid(%lu) time(%s)", // 1 + "instance found", // 2 +}; + +bool WriteLogLine(HANDLE file, const std::string& txt) { + if (txt.empty()) + return true; + DWORD written; + auto rc = ::WriteFile(file, txt.c_str(), + static_cast<DWORD>(txt.size()), + &written, + nullptr); + return (rc == TRUE); +} + +// Uses |kMessages| at |index| above to write to disk a formatted log line. +bool WriteFormattedLogLine(HANDLE file, size_t index, ...) { + va_list ap; + va_start(ap, index); + auto fmt = base::StringPrintf( + kMessageHeader, index, ::GetTickCount(), kMessages[index]); + auto msg = base::StringPrintV(fmt.c_str(), ap); + auto rc = WriteLogLine(file, msg.c_str()); + va_end(ap); + return rc; +} + +// Returns the current time and date formatted in standard C style. +std::string DateTime() { + time_t current_time = 0; + time(¤t_time); + struct tm local_time = {0}; + char time_buf[26] = {0}; + localtime_s(&local_time, ¤t_time); + asctime_s(time_buf, &local_time); + time_buf[24] = '\0'; + return time_buf; +} + +} // namespace + +namespace caps { + +Logger::Logger(const base::FilePath& path) : file_(INVALID_HANDLE_VALUE) { + auto logfile = path.Append(L"caps_log.txt"); + // Opening a file like so allows atomic appends, but can't be used + // for anything else. + DWORD kShareAll = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + file_ = ::CreateFile(logfile.value().c_str(), + FILE_APPEND_DATA, kShareAll, + nullptr, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, + nullptr); + if (file_ == INVALID_HANDLE_VALUE) + return; + WriteFormattedLogLine( + file_, 0, ::GetCurrentProcessId(), PRODUCT_VERSION, DateTime().c_str()); +} + +Logger::~Logger() { + if (file_ != INVALID_HANDLE_VALUE) { + WriteFormattedLogLine( + file_, 1, ::GetCurrentProcessId(), DateTime().c_str()); + ::CloseHandle(file_); + } +} + +} // namespace caps +
diff --git a/chrome/tools/crash_service/caps/logger_win.h b/chrome/tools/crash_service/caps/logger_win.h new file mode 100644 index 0000000..efa0b94 --- /dev/null +++ b/chrome/tools/crash_service/caps/logger_win.h
@@ -0,0 +1,32 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TOOLS_CRASH_SERVICE_CAPS_LOGGER_WIN_H_ +#define CHROME_TOOLS_CRASH_SERVICE_CAPS_LOGGER_WIN_H_ + +#include <windows.h> + +#include "base/macros.h" + +namespace base { +class FilePath; +} + +namespace caps { +// Creates a human-readable activity log file. +class Logger { +public: + explicit Logger(const base::FilePath& path); + ~Logger(); + +private: + HANDLE file_; + + DISALLOW_COPY_AND_ASSIGN(Logger); +}; + +} // namespace caps + +#endif // CHROME_TOOLS_CRASH_SERVICE_CAPS_LOGGER_WIN_H_ +
diff --git a/chrome/tools/crash_service/caps/main_win.cc b/chrome/tools/crash_service/caps/main_win.cc index b2c01745..61461652 100644 --- a/chrome/tools/crash_service/caps/main_win.cc +++ b/chrome/tools/crash_service/caps/main_win.cc
@@ -4,6 +4,33 @@ #include <windows.h> +#include "base/at_exit.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/version.h" +#include "chrome/tools/crash_service/caps/exit_codes.h" +#include "chrome/tools/crash_service/caps/logger_win.h" +#include "chrome/tools/crash_service/caps/process_singleton_win.h" + int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { - return 0; + base::AtExitManager at_exit_manager; + base::FilePath dir_exe; + if (!PathService::Get(base::DIR_EXE, &dir_exe)) + return caps::EC_INIT_ERROR; + + // What directory we write depends if we are being run from the actual + // location (a versioned directory) or from a build output directory. + base::Version version(dir_exe.BaseName().MaybeAsASCII()); + auto data_path = version.IsValid() ? dir_exe.DirName() : dir_exe; + + // Start logging. + caps::Logger logger(data_path); + + // Check for an existing running instance. + caps::ProcessSingleton process_singleton; + if (process_singleton.other_instance()) + return caps::EC_EXISTING_INSTANCE; + + return caps::EC_NORMAL_EXIT; } +
diff --git a/chrome/tools/crash_service/caps/process_singleton_win.cc b/chrome/tools/crash_service/caps/process_singleton_win.cc new file mode 100644 index 0000000..f51accc --- /dev/null +++ b/chrome/tools/crash_service/caps/process_singleton_win.cc
@@ -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. + +#include <windows.h> + +#include "chrome/tools/crash_service/caps/process_singleton_win.h" + +namespace caps { + +ProcessSingleton::ProcessSingleton() : mutex_(nullptr) { + auto mutex = ::CreateMutex(nullptr, TRUE, L"CHROME.CAPS.V1"); + if (!mutex) + return; + if (::GetLastError() == ERROR_ALREADY_EXISTS) { + ::CloseHandle(mutex); + return; + } + // We are now the single instance. + mutex_ = mutex; +} + +ProcessSingleton::~ProcessSingleton() { + if (mutex_) + ::CloseHandle(mutex_); +} + +} // namespace caps +
diff --git a/chrome/tools/crash_service/caps/process_singleton_win.h b/chrome/tools/crash_service/caps/process_singleton_win.h new file mode 100644 index 0000000..5440d9c --- /dev/null +++ b/chrome/tools/crash_service/caps/process_singleton_win.h
@@ -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. + +#ifndef CHROME_TOOLS_CRASH_SERVICE_CAPS_PROCESS_SINGLETON_WIN_H_ +#define CHROME_TOOLS_CRASH_SERVICE_CAPS_PROCESS_SINGLETON_WIN_H_ + +#include <windows.h> + +#include "base/macros.h" + +namespace caps { +// Uses a named mutex to make sure that only one process of +// with this particular version is launched. +class ProcessSingleton { +public: + ProcessSingleton(); + ~ProcessSingleton(); + bool other_instance() const { return mutex_ == NULL; } + +private: + HANDLE mutex_; + + DISALLOW_COPY_AND_ASSIGN(ProcessSingleton); +}; + +} // namespace caps + +#endif // CHROME_TOOLS_CRASH_SERVICE_CAPS_PROCESS_SINGLETON_WIN_H_ +
diff --git a/chrome/unit_tests.isolate b/chrome/unit_tests.isolate index 446550b8..a03f8a5 100644 --- a/chrome/unit_tests.isolate +++ b/chrome/unit_tests.isolate
@@ -49,6 +49,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -102,6 +104,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index e06aebc..843b1f3 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -166,10 +166,6 @@ extensions::ExtensionsHandler::PreSandboxStartup(); #endif -#if defined(ENABLE_PRINT_PREVIEW) || defined(OS_WIN) - PrintingHandler::PreSandboxStartup(); -#endif - #if defined(ENABLE_MDNS) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUtilityProcessEnableMDns)) {
diff --git a/chrome/utility/printing_handler.cc b/chrome/utility/printing_handler.cc index b69d6ea..9e282ad 100644 --- a/chrome/utility/printing_handler.cc +++ b/chrome/utility/printing_handler.cc
@@ -13,11 +13,11 @@ #include "chrome/utility/cloud_print/bitmap_image.h" #include "chrome/utility/cloud_print/pwg_encoder.h" #include "content/public/utility/utility_thread.h" +#include "pdf/pdf.h" #include "printing/page_range.h" #include "printing/pdf_render_settings.h" #if defined(OS_WIN) -#include "base/win/iat_patch_function.h" #include "printing/emf_win.h" #include "ui/gfx/gdi_util.h" #endif @@ -37,225 +37,12 @@ content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } -class PdfFunctionsBase { - public: - PdfFunctionsBase() : render_pdf_to_bitmap_func_(NULL), - get_pdf_doc_info_func_(NULL) {} - - bool Init() { - base::FilePath pdf_module_path; - if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path) || - !base::PathExists(pdf_module_path)) { - return false; - } - - pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); - if (!pdf_lib_.is_valid()) { - LOG(WARNING) << "Couldn't load PDF plugin"; - return false; - } - - render_pdf_to_bitmap_func_ = - reinterpret_cast<RenderPDFPageToBitmapProc>( - pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); - LOG_IF(WARNING, !render_pdf_to_bitmap_func_) << - "Missing RenderPDFPageToBitmap"; - - get_pdf_doc_info_func_ = - reinterpret_cast<GetPDFDocInfoProc>( - pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); - LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; - - if (!render_pdf_to_bitmap_func_ || !get_pdf_doc_info_func_ || - !PlatformInit(pdf_module_path, pdf_lib_)) { - Reset(); - } - - return IsValid(); - } - - bool IsValid() const { - return pdf_lib_.is_valid(); - } - - void Reset() { - pdf_lib_.Reset(NULL); - } - - bool RenderPDFPageToBitmap(const void* pdf_buffer, - int pdf_buffer_size, - int page_number, - void* bitmap_buffer, - int bitmap_width, - int bitmap_height, - int dpi_x, - int dpi_y, - bool autorotate) { - if (!render_pdf_to_bitmap_func_) - return false; - return render_pdf_to_bitmap_func_(pdf_buffer, pdf_buffer_size, page_number, - bitmap_buffer, bitmap_width, - bitmap_height, dpi_x, dpi_y, autorotate); - } - - bool GetPDFDocInfo(const void* pdf_buffer, - int buffer_size, - int* page_count, - double* max_page_width) { - if (!get_pdf_doc_info_func_) - return false; - return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, - max_page_width); - } - - protected: - virtual bool PlatformInit( - const base::FilePath& pdf_module_path, - const base::ScopedNativeLibrary& pdf_lib) { - return true; - } - - private: - // Exported by PDF plugin. - typedef bool (*RenderPDFPageToBitmapProc)(const void* pdf_buffer, - int pdf_buffer_size, - int page_number, - void* bitmap_buffer, - int bitmap_width, - int bitmap_height, - int dpi_x, - int dpi_y, - bool autorotate); - typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, - int buffer_size, int* page_count, - double* max_page_width); - - RenderPDFPageToBitmapProc render_pdf_to_bitmap_func_; - GetPDFDocInfoProc get_pdf_doc_info_func_; - - base::ScopedNativeLibrary pdf_lib_; - DISALLOW_COPY_AND_ASSIGN(PdfFunctionsBase); -}; - -#if defined(OS_WIN) -// The 2 below IAT patch functions are almost identical to the code in -// render_process_impl.cc. This is needed to work around specific Windows APIs -// used by the Chrome PDF plugin that will fail in the sandbox. -static base::win::IATPatchFunction g_iat_patch_createdca; -HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, - LPCSTR device_name, - LPCSTR output, - const DEVMODEA* init_data) { - if (driver_name && (std::string("DISPLAY") == driver_name)) { - // CreateDC fails behind the sandbox, but not CreateCompatibleDC. - return CreateCompatibleDC(NULL); - } - - NOTREACHED(); - return CreateDCA(driver_name, device_name, output, init_data); -} - -static base::win::IATPatchFunction g_iat_patch_get_font_data; -DWORD WINAPI UtilityProcess_GetFontDataPatch( - HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { - int rv = GetFontData(hdc, table, offset, buffer, length); - if (rv == GDI_ERROR && hdc) { - HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); - - LOGFONT logfont; - if (GetObject(font, sizeof(LOGFONT), &logfont)) { - content::UtilityThread::Get()->PreCacheFont(logfont); - rv = GetFontData(hdc, table, offset, buffer, length); - content::UtilityThread::Get()->ReleaseCachedFonts(); - } - } - return rv; -} - -class PdfFunctionsWin : public PdfFunctionsBase { - public: - PdfFunctionsWin() : render_pdf_to_dc_func_(NULL) { - } - - bool PlatformInit( - const base::FilePath& pdf_module_path, - const base::ScopedNativeLibrary& pdf_lib) override { - // Patch the IAT for handling specific APIs known to fail in the sandbox. - if (!g_iat_patch_createdca.is_patched()) { - g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), - "gdi32.dll", "CreateDCA", - UtilityProcess_CreateDCAPatch); - } - - if (!g_iat_patch_get_font_data.is_patched()) { - g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), - "gdi32.dll", "GetFontData", - UtilityProcess_GetFontDataPatch); - } - render_pdf_to_dc_func_ = - reinterpret_cast<RenderPDFPageToDCProc>( - pdf_lib.GetFunctionPointer("RenderPDFPageToDC")); - LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; - - return render_pdf_to_dc_func_ != NULL; - } - - bool RenderPDFPageToDC(const void* pdf_buffer, - int buffer_size, - int page_number, - HDC dc, - int dpi_x, - int dpi_y, - int bounds_origin_x, - int bounds_origin_y, - int bounds_width, - int bounds_height, - bool fit_to_bounds, - bool stretch_to_bounds, - bool keep_aspect_ratio, - bool center_in_bounds, - bool autorotate) { - if (!render_pdf_to_dc_func_) - return false; - return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, - dc, dpi_x, dpi_y, bounds_origin_x, - bounds_origin_y, bounds_width, bounds_height, - fit_to_bounds, stretch_to_bounds, - keep_aspect_ratio, center_in_bounds, - autorotate); - } - - private: - // Exported by PDF plugin. - typedef bool (*RenderPDFPageToDCProc)( - const void* pdf_buffer, int buffer_size, int page_number, HDC dc, - int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, - int bounds_width, int bounds_height, bool fit_to_bounds, - bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, - bool autorotate); - RenderPDFPageToDCProc render_pdf_to_dc_func_; - - DISALLOW_COPY_AND_ASSIGN(PdfFunctionsWin); -}; - -typedef PdfFunctionsWin PdfFunctions; -#else // OS_WIN -typedef PdfFunctionsBase PdfFunctions; -#endif // OS_WIN - -base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER; - } // namespace PrintingHandler::PrintingHandler() {} PrintingHandler::~PrintingHandler() {} -// static -void PrintingHandler::PreSandboxStartup() { - g_pdf_lib.Get().Init(); -} - bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) @@ -328,9 +115,6 @@ #if defined(OS_WIN) int PrintingHandler::LoadPDF(base::File pdf_file) { - if (!g_pdf_lib.Get().IsValid()) - return 0; - int64 length64 = pdf_file.GetLength(); if (length64 <= 0 || length64 > std::numeric_limits<int>::max()) return 0; @@ -341,7 +125,7 @@ return 0; int total_page_count = 0; - if (!g_pdf_lib.Get().GetPDFDocInfo( + if (!chrome_pdf::GetPDFDocInfo( &pdf_data_.front(), pdf_data_.size(), &total_page_count, NULL)) { return 0; } @@ -370,13 +154,12 @@ // The underlying metafile is of type Emf and ignores the arguments passed // to StartPage. metafile.StartPage(gfx::Size(), gfx::Rect(), 1); - if (!g_pdf_lib.Get().RenderPDFPageToDC( + if (!chrome_pdf::RenderPDFPageToDC( &pdf_data_.front(), pdf_data_.size(), page_number, metafile.context(), pdf_rendering_settings_.dpi(), - pdf_rendering_settings_.dpi(), pdf_rendering_settings_.area().x(), pdf_rendering_settings_.area().y(), pdf_rendering_settings_.area().width(), @@ -402,9 +185,6 @@ const printing::PwgRasterSettings& bitmap_settings, base::File bitmap_file) { bool autoupdate = true; - if (!g_pdf_lib.Get().IsValid()) - return false; - base::File::Info info; if (!pdf_file.GetInfo(&info) || info.size <= 0 || info.size > std::numeric_limits<int>::max()) @@ -416,8 +196,8 @@ return false; int total_page_count = 0; - if (!g_pdf_lib.Get().GetPDFDocInfo(data.data(), data_size, - &total_page_count, NULL)) { + if (!chrome_pdf::GetPDFDocInfo(data.data(), data_size, + &total_page_count, NULL)) { return false; } @@ -438,15 +218,14 @@ page_number = total_page_count - 1 - page_number; } - if (!g_pdf_lib.Get().RenderPDFPageToBitmap(data.data(), - data_size, - page_number, - image.pixel_data(), - image.size().width(), - image.size().height(), - settings.dpi(), - settings.dpi(), - autoupdate)) { + if (!chrome_pdf::RenderPDFPageToBitmap(data.data(), + data_size, + page_number, + image.pixel_data(), + image.size().width(), + image.size().height(), + settings.dpi(), + autoupdate)) { return false; }
diff --git a/chrome/utility/printing_handler.h b/chrome/utility/printing_handler.h index cc490ba..341a358 100644 --- a/chrome/utility/printing_handler.h +++ b/chrome/utility/printing_handler.h
@@ -27,8 +27,6 @@ PrintingHandler(); ~PrintingHandler() override; - static void PreSandboxStartup(); - // IPC::Listener: bool OnMessageReceived(const IPC::Message& message) override;
diff --git a/chromecast/browser/android/cast_window_android.cc b/chromecast/browser/android/cast_window_android.cc index 8503fd6..eef789c 100644 --- a/chromecast/browser/android/cast_window_android.cc +++ b/chromecast/browser/android/cast_window_android.cc
@@ -107,7 +107,7 @@ void CastWindowAndroid::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { NOTIMPLEMENTED();
diff --git a/chromecast/browser/android/cast_window_android.h b/chromecast/browser/android/cast_window_android.h index 281f140..b7073619 100644 --- a/chromecast/browser/android/cast_window_android.h +++ b/chromecast/browser/android/cast_window_android.h
@@ -59,7 +59,7 @@ virtual void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; virtual void CloseContents(content::WebContents* source) override;
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index e7bcbc9..263d595 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -168,12 +168,21 @@ } int CastBrowserMainParts::PreCreateThreads() { -#if !defined(OS_ANDROID) +#if defined(OS_ANDROID) + // GPU process is started immediately after threads are created, requiring + // CrashDumpManager to be initialized beforehand. + base::FilePath crash_dumps_dir; + if (!chromecast::CrashHandler::GetCrashDumpLocation(&crash_dumps_dir)) { + LOG(ERROR) << "Could not find crash dump location."; + } + cast_browser_process_->SetCrashDumpManager( + make_scoped_ptr(new breakpad::CrashDumpManager(crash_dumps_dir))); +#else base::FilePath home_dir; CHECK(PathService::Get(DIR_CAST_HOME, &home_dir)); if (!base::CreateDirectory(home_dir)) return 1; -#endif // !defined(OS_ANDROID) +#endif return 0; } @@ -199,15 +208,6 @@ cast_browser_process_->pref_service(), cast_browser_process_->browser_context()->GetRequestContext())); -#if defined(OS_ANDROID) - base::FilePath crash_dumps_dir; - if (!chromecast::CrashHandler::GetCrashDumpLocation(&crash_dumps_dir)) { - LOG(ERROR) << "Could not find crash dump location."; - } - cast_browser_process_->SetCrashDumpManager( - make_scoped_ptr(new breakpad::CrashDumpManager(crash_dumps_dir))); -#endif - if (!PlatformClientAuth::Initialize()) LOG(ERROR) << "PlatformClientAuth::Initialize failed.";
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp index df70201..db35e6f 100644 --- a/chromecast/chromecast.gyp +++ b/chromecast/chromecast.gyp
@@ -45,6 +45,29 @@ ], }, # end of target 'cast_base' { + 'target_name': 'cast_crash_client', + 'type': '<(component)', + 'dependencies': [ + '../breakpad/breakpad.gyp:breakpad_client', + '../components/components.gyp:crash_component', + ], + 'sources': [ + 'crash/cast_crash_reporter_client.cc', + 'crash/cast_crash_reporter_client.h', + ], + 'conditions': [ + ['chromecast_branding=="Chrome"', { + 'dependencies': [ + '<(cast_internal_gyp):crash_internal', + ], + }, { + 'sources': [ + 'crash/cast_crash_reporter_client_simple.cc', + ], + }], + ] + }, # end of target 'cast_crash_client' + { 'target_name': 'cast_net', 'type': '<(component)', 'sources': [ @@ -113,6 +136,7 @@ 'type': '<(component)', 'dependencies': [ 'cast_base', + 'cast_crash_client', 'cast_shell_pak', 'cast_shell_resources', 'cast_version_header', @@ -423,29 +447,6 @@ }, { # OS != "android" 'targets': [ { - 'target_name': 'cast_crash_client', - 'type': '<(component)', - 'dependencies': [ - '../breakpad/breakpad.gyp:breakpad_client', - '../components/components.gyp:crash_component', - ], - 'sources': [ - 'crash/cast_crash_reporter_client.cc', - 'crash/cast_crash_reporter_client.h', - ], - 'conditions': [ - ['chromecast_branding=="Chrome"', { - 'dependencies': [ - '<(cast_internal_gyp):crash_internal', - ], - }, { - 'sources': [ - 'crash/cast_crash_reporter_client_simple.cc', - ], - }], - ] - }, # end of target 'cast_crash_client' - { 'target_name': 'cast_shell_media', 'type': '<(component)', 'dependencies': [ @@ -492,7 +493,6 @@ 'target_name': 'cast_shell_core', 'type': '<(component)', 'dependencies': [ - 'cast_crash_client', 'cast_net', 'cast_shell_media', 'cast_shell_common',
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 947c0e7..6b7bad4e 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -34,7 +34,6 @@ "//third_party/icu", "//third_party/libxml", "//third_party/protobuf:protobuf_lite", - "//ui/accelerometer", "//ui/gfx/geometry", "//url", ":cryptohome_proto",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 1d221b46..89a4b21b 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -6750.0.0 \ No newline at end of file +6752.0.0 \ No newline at end of file
diff --git a/chromeos/DEPS b/chromeos/DEPS index a398cc6..8bc2f79 100644 --- a/chromeos/DEPS +++ b/chromeos/DEPS
@@ -11,6 +11,4 @@ # Some targets may not have any UI, so explictly exclude src/ui. "-ui", - # TODO(stevenjb/flackr): Remove these dependencies. - "+ui/accelerometer" ]
diff --git a/chromeos/accelerometer/accelerometer_reader.cc b/chromeos/accelerometer/accelerometer_reader.cc index e2a5e79..4d68ebf0 100644 --- a/chromeos/accelerometer/accelerometer_reader.cc +++ b/chromeos/accelerometer/accelerometer_reader.cc
@@ -41,8 +41,7 @@ // The names of the accelerometers. Matches up with the enum AccelerometerSource // in ui/accelerometer/accelerometer_types.h. -const char kAccelerometerNames[ui::ACCELEROMETER_SOURCE_COUNT][5] = { - "lid", "base"}; +const char kAccelerometerNames[ACCELEROMETER_SOURCE_COUNT][5] = {"lid", "base"}; // The axes on each accelerometer. const char kAccelerometerAxes[][2] = {"y", "x", "z"}; @@ -59,10 +58,6 @@ // The mean acceleration due to gravity on Earth in m/s^2. const float kMeanGravity = 9.80665f; -// The maximum deviation from the acceleration expected due to gravity under -// which to detect hinge angle and screen rotation in m/s^2 -const float kDeviationFromGravityThreshold = 1.0f; - // Reads |path| to the unsigned int pointed to by |value|. Returns true on // success or false on failure. bool ReadFileToInt(const base::FilePath& path, int* value) { @@ -126,14 +121,14 @@ // Adjust the directions of accelerometers to match the AccelerometerUpdate // type specified in ui/accelerometer/accelerometer_types.h. - configuration->data.scale[ui::ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f; + configuration->data.scale[ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f; for (int i = 0; i < 3; ++i) { - configuration->data.scale[ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *= + configuration->data.scale[ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *= -1.0f; } // Verify indices are within bounds. - for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) { + for (int i = 0; i < ACCELEROMETER_SOURCE_COUNT; ++i) { if (!configuration->data.has[i]) continue; for (int j = 0; j < 3; ++j) { @@ -176,7 +171,7 @@ AccelerometerReader::ConfigurationData::ConfigurationData() : count(0) { - for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) { + for (int i = 0; i < ACCELEROMETER_SOURCE_COUNT; ++i) { has[i] = false; for (int j = 0; j < 3; ++j) { scale[i][j] = 0; @@ -215,13 +210,6 @@ observers_.RemoveObserver(observer); } -bool AccelerometerReader::IsReadingStable(const ui::AccelerometerUpdate& update, - ui::AccelerometerSource source) { - return update.has(source) && - std::abs(update.get(source).Length() - kMeanGravity) <= - kDeviationFromGravityThreshold; -} - AccelerometerReader::AccelerometerReader() : configuration_(new AccelerometerReader::Configuration()), weak_factory_(this) { @@ -257,12 +245,12 @@ DCHECK(!task_runner_->RunsTasksOnCurrentThread()); if (success) { - for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) { + for (int i = 0; i < ACCELEROMETER_SOURCE_COUNT; ++i) { if (!configuration_->data.has[i]) continue; int16* values = reinterpret_cast<int16*>(reading->data); - update_.Set(static_cast<ui::AccelerometerSource>(i), + update_.Set(static_cast<AccelerometerSource>(i), values[configuration_->data.index[i][0]] * configuration_->data.scale[i][0], values[configuration_->data.index[i][1]] *
diff --git a/chromeos/accelerometer/accelerometer_reader.h b/chromeos/accelerometer/accelerometer_reader.h index 15115da..c2adde8 100644 --- a/chromeos/accelerometer/accelerometer_reader.h +++ b/chromeos/accelerometer/accelerometer_reader.h
@@ -8,8 +8,8 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "chromeos/accelerometer/accelerometer_types.h" #include "chromeos/chromeos_export.h" -#include "ui/accelerometer/accelerometer_types.h" template <typename T> struct DefaultSingletonTraits; @@ -36,13 +36,13 @@ size_t length; // Which accelerometers are present on device. - bool has[ui::ACCELEROMETER_SOURCE_COUNT]; + bool has[ACCELEROMETER_SOURCE_COUNT]; // Scale of accelerometers (i.e. raw value * scale = m/s^2). - float scale[ui::ACCELEROMETER_SOURCE_COUNT][3]; + float scale[ACCELEROMETER_SOURCE_COUNT][3]; // Index of each accelerometer axis in data stream. - int index[ui::ACCELEROMETER_SOURCE_COUNT][3]; + int index[ACCELEROMETER_SOURCE_COUNT][3]; }; typedef base::RefCountedData<ConfigurationData> Configuration; typedef base::RefCountedData<char[12]> Reading; @@ -50,8 +50,7 @@ // An interface to receive data from the AccelerometerReader. class Observer { public: - virtual void OnAccelerometerUpdated( - const ui::AccelerometerUpdate& update) = 0; + virtual void OnAccelerometerUpdated(const AccelerometerUpdate& update) = 0; protected: virtual ~Observer() {} @@ -65,12 +64,6 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - // A reading is considered stable if its deviation from gravity is small. This - // returns false if the deviation is too higher, or if |source| is not present - // in the update. - static bool IsReadingStable(const ui::AccelerometerUpdate& update, - ui::AccelerometerSource source); - protected: AccelerometerReader(); virtual ~AccelerometerReader(); @@ -95,7 +88,7 @@ scoped_refptr<base::TaskRunner> task_runner_; // The last seen accelerometer data. - ui::AccelerometerUpdate update_; + AccelerometerUpdate update_; // The accelerometer configuration. scoped_refptr<Configuration> configuration_;
diff --git a/ui/accelerometer/accelerometer_types.cc b/chromeos/accelerometer/accelerometer_types.cc similarity index 78% rename from ui/accelerometer/accelerometer_types.cc rename to chromeos/accelerometer/accelerometer_types.cc index e5aa0ea..a08fbdd 100644 --- a/ui/accelerometer/accelerometer_types.cc +++ b/chromeos/accelerometer/accelerometer_types.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 "ui/accelerometer/accelerometer_types.h" +#include "chromeos/accelerometer/accelerometer_types.h" -namespace ui { +namespace chromeos { AccelerometerReading::AccelerometerReading() : present(false) { } @@ -18,4 +18,4 @@ AccelerometerUpdate::~AccelerometerUpdate() { } -} // namespace ui +} // namespace chromeos
diff --git a/ui/accelerometer/accelerometer_types.h b/chromeos/accelerometer/accelerometer_types.h similarity index 69% rename from ui/accelerometer/accelerometer_types.h rename to chromeos/accelerometer/accelerometer_types.h index b3e513dd..f72e296 100644 --- a/ui/accelerometer/accelerometer_types.h +++ b/chromeos/accelerometer/accelerometer_types.h
@@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_ACCELEROMETER_ACCELEROMETER_TYPES_H_ -#define UI_ACCELEROMETER_ACCELEROMETER_TYPES_H_ +#ifndef CHROMEOS_ACCELEROMETER_ACCELEROMETER_TYPES_H_ +#define CHROMEOS_ACCELEROMETER_ACCELEROMETER_TYPES_H_ #include "base/macros.h" -#include "ui/accelerometer/ui_accelerometer_export.h" -#include "ui/gfx/geometry/vector3d_f.h" +#include "chromeos/chromeos_export.h" -namespace ui { +namespace chromeos { enum AccelerometerSource { // Accelerometer is located in the device's screen. In the screen's natural @@ -30,47 +29,48 @@ ACCELEROMETER_SOURCE_COUNT }; -struct UI_ACCELEROMETER_EXPORT AccelerometerReading { +struct CHROMEOS_EXPORT AccelerometerReading { AccelerometerReading(); ~AccelerometerReading(); // If true, this accelerometer is being updated. bool present; - // The reading from this accelerometer measured in m/s^2. - gfx::Vector3dF reading; + // The readings from this accelerometer measured in m/s^2. + float x; + float y; + float z; }; // An accelerometer update contains the last known value for each of the // accelerometers present on the device. -class UI_ACCELEROMETER_EXPORT AccelerometerUpdate { +class CHROMEOS_EXPORT AccelerometerUpdate { public: AccelerometerUpdate(); ~AccelerometerUpdate(); // Returns true if |source| has a valid value in this update. - bool has(AccelerometerSource source) const { - return data_[source].present; - } + bool has(AccelerometerSource source) const { return data_[source].present; } // Returns the last known value for |source|. - const gfx::Vector3dF& get(AccelerometerSource source) const { - return data_[source].reading; + const AccelerometerReading& get(AccelerometerSource source) const { + return data_[source]; } void Set(AccelerometerSource source, float x, float y, float z) { data_[source].present = true; - data_[source].reading.set_x(x); - data_[source].reading.set_y(y); - data_[source].reading.set_z(z); + data_[source].x = x; + data_[source].y = y; + data_[source].z = z; } protected: AccelerometerReading data_[ACCELEROMETER_SOURCE_COUNT]; + private: DISALLOW_COPY_AND_ASSIGN(AccelerometerUpdate); }; -} // namespace ui +} // namespace chromeos -#endif // UI_ACCELEROMETER_ACCELEROMETER_TYPES_H_ +#endif // CHROMEOS_ACCELEROMETER_ACCELEROMETER_TYPES_H_
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 7d89d07..7175ebf 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp
@@ -9,6 +9,8 @@ 'chromeos_sources': [ 'accelerometer/accelerometer_reader.cc', 'accelerometer/accelerometer_reader.h', + 'accelerometer/accelerometer_types.cc', + 'accelerometer/accelerometer_types.h', 'app_mode/kiosk_oem_manifest_parser.cc', 'app_mode/kiosk_oem_manifest_parser.h', 'audio/audio_device.cc', @@ -521,7 +523,6 @@ '../third_party/libxml/libxml.gyp:libxml', '../third_party/protobuf/protobuf.gyp:protobuf_lite', '../ui/gfx/gfx.gyp:gfx_geometry', - '../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer', '../url/url.gyp:url_lib', 'cryptohome_proto', 'ime/input_method.gyp:gencode',
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 20c55c80..5c019c9b 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -304,8 +304,9 @@ const char kEnableCaptivePortalBypassProxy[] = "enable-captive-portal-bypass-proxy"; -// Enable automatic timezone update. -const char kEnableTimeZoneTrackingOption[] = "enable-timezone-tracking-option"; +// Disable automatic timezone update. +const char kDisableTimeZoneTrackingOption[] = + "disable-timezone-tracking-option"; bool WakeOnWifiEnabled() { return !base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableWakeOnWifi);
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 1ddddeb..23cb788 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -99,7 +99,7 @@ CHROMEOS_EXPORT extern const char kTestAutoUpdateUI[]; CHROMEOS_EXPORT extern const char kWakeOnPackets[]; CHROMEOS_EXPORT extern const char kEnableCaptivePortalBypassProxy[]; -CHROMEOS_EXPORT extern const char kEnableTimeZoneTrackingOption[]; +CHROMEOS_EXPORT extern const char kDisableTimeZoneTrackingOption[]; CHROMEOS_EXPORT bool WakeOnWifiEnabled();
diff --git a/chromeos/dbus/fake_privet_daemon_client.cc b/chromeos/dbus/fake_privet_daemon_client.cc index 9f9bfa0..bc252f0 100644 --- a/chromeos/dbus/fake_privet_daemon_client.cc +++ b/chromeos/dbus/fake_privet_daemon_client.cc
@@ -4,6 +4,8 @@ #include "chromeos/dbus/fake_privet_daemon_client.h" +#include <string> + #include "base/callback.h" namespace chromeos { @@ -17,6 +19,17 @@ void FakePrivetDaemonClient::Init(dbus::Bus* bus) { } +void FakePrivetDaemonClient::AddObserver(Observer* observer) { +} + +void FakePrivetDaemonClient::RemoveObserver(Observer* observer) { +} + +std::string FakePrivetDaemonClient::GetWifiBootstrapState() { + // Simulate Wi-Fi being configured already. + return privetd::kWiFiBootstrapStateMonitoring; +} + void FakePrivetDaemonClient::Ping(const PingCallback& callback) { callback.Run(true /* success */); }
diff --git a/chromeos/dbus/fake_privet_daemon_client.h b/chromeos/dbus/fake_privet_daemon_client.h index e15ea95..1b86e41 100644 --- a/chromeos/dbus/fake_privet_daemon_client.h +++ b/chromeos/dbus/fake_privet_daemon_client.h
@@ -20,6 +20,9 @@ void Init(dbus::Bus* bus) override; // PrivetClient overrides: + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::string GetWifiBootstrapState() override; void Ping(const PingCallback& callback) override; private:
diff --git a/chromeos/dbus/privet_daemon_client.cc b/chromeos/dbus/privet_daemon_client.cc index 21b0980..cd75d67c 100644 --- a/chromeos/dbus/privet_daemon_client.cc +++ b/chromeos/dbus/privet_daemon_client.cc
@@ -9,9 +9,12 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "dbus/bus.h" #include "dbus/message.h" +#include "dbus/object_manager.h" #include "dbus/object_proxy.h" +#include "dbus/property.h" namespace chromeos { namespace { @@ -19,57 +22,206 @@ // The expected response to the Ping D-Bus method. const char kPingResponse[] = "Hello world!"; -// The PrivetClient implementation used in production. -class PrivetClientImpl : public PrivetDaemonClient { +// The PrivetDaemonClient implementation used in production. Note that privetd +// is not available on all devices. If privetd is not running this object +// returns empty property values and logs errors for attempted method calls but +// will not crash. +class PrivetDaemonClientImpl : public PrivetDaemonClient, + public dbus::ObjectManager::Interface { public: - PrivetClientImpl(); - ~PrivetClientImpl() override; + // Setup state properties. The object manager reads the initial values. + struct Properties : public dbus::PropertySet { + // Network bootstrap state. Read-only. + dbus::Property<std::string> wifi_bootstrap_state; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + PrivetDaemonClientImpl(); + ~PrivetDaemonClientImpl() override; // DBusClient overrides: void Init(dbus::Bus* bus) override; - // PrivetClient overrides: + // PrivetDaemonClient overrides: + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::string GetWifiBootstrapState() override; void Ping(const PingCallback& callback) override; private: - // Callback for the Ping DBus method. + // dbus::ObjectManager::Interface overrides: + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override; + + // Called with the owner of the privetd service at startup and again if the + // owner changes. + void OnServiceOwnerChanged(const std::string& service_owner); + + // Cleans up |object_manager_|. + void CleanUpObjectManager(); + + // Returns the instance of the property set or null if privetd is not running. + Properties* GetProperties(); + + // Called by dbus::PropertySet when a property value is changed, either by + // result of a signal or response to a GetAll() or Get() call. Informs + // observers. + void OnPropertyChanged(const std::string& property_name); + + // Callback for the Ping D-Bus method. void OnPing(const PingCallback& callback, dbus::Response* response); - // Called when the object is connected to the signal. - void OnSignalConnected(const std::string& interface_name, - const std::string& signal_name, - bool success); + // The current bus, usually the system bus. Not owned. + dbus::Bus* bus_; - dbus::ObjectProxy* privetd_proxy_; - base::WeakPtrFactory<PrivetClientImpl> weak_ptr_factory_; + // Object manager used to read D-Bus properties. Null if privetd is not + // running. Not owned. + dbus::ObjectManager* object_manager_; - DISALLOW_COPY_AND_ASSIGN(PrivetClientImpl); + // Callback that monitors for service owner changes. + dbus::Bus::GetServiceOwnerCallback service_owner_callback_; + + // The current service owner or the empty string is privetd is not running. + std::string service_owner_; + + ObserverList<Observer> observers_; + base::WeakPtrFactory<PrivetDaemonClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PrivetDaemonClientImpl); }; -PrivetClientImpl::PrivetClientImpl() - : privetd_proxy_(nullptr), weak_ptr_factory_(this) { +/////////////////////////////////////////////////////////////////////////////// + +PrivetDaemonClientImpl::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(privetd::kWiFiBootstrapStateProperty, &wifi_bootstrap_state); } -PrivetClientImpl::~PrivetClientImpl() { +PrivetDaemonClientImpl::Properties::~Properties() { } -void PrivetClientImpl::Ping(const PingCallback& callback) { +/////////////////////////////////////////////////////////////////////////////// + +PrivetDaemonClientImpl::PrivetDaemonClientImpl() + : bus_(nullptr), object_manager_(nullptr), weak_ptr_factory_(this) { +} + +PrivetDaemonClientImpl::~PrivetDaemonClientImpl() { + CleanUpObjectManager(); + if (bus_) { + bus_->UnlistenForServiceOwnerChange(privetd::kPrivetdServiceName, + service_owner_callback_); + } +} + +void PrivetDaemonClientImpl::Init(dbus::Bus* bus) { + bus_ = bus; + // privetd may not be running. Watch for it starting up later. + service_owner_callback_ = + base::Bind(&PrivetDaemonClientImpl::OnServiceOwnerChanged, + weak_ptr_factory_.GetWeakPtr()); + bus_->ListenForServiceOwnerChange(privetd::kPrivetdServiceName, + service_owner_callback_); + // Also explicitly check for its existence on startup. + bus_->GetServiceOwner(privetd::kPrivetdServiceName, service_owner_callback_); +} + +void PrivetDaemonClientImpl::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void PrivetDaemonClientImpl::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::string PrivetDaemonClientImpl::GetWifiBootstrapState() { + Properties* properties = GetProperties(); + if (!properties) + return ""; + return properties->wifi_bootstrap_state.value(); +} + +dbus::PropertySet* PrivetDaemonClientImpl::CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) { + return new Properties(object_proxy, interface_name, + base::Bind(&PrivetDaemonClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr())); +} + +void PrivetDaemonClientImpl::Ping(const PingCallback& callback) { + if (!object_manager_) { + LOG(ERROR) << "privetd not available."; + return; + } + dbus::ObjectProxy* proxy = object_manager_->GetObjectProxy( + dbus::ObjectPath(privetd::kPrivetdManagerServicePath)); + if (!proxy) { + LOG(ERROR) << "Object not available."; + return; + } dbus::MethodCall method_call(privetd::kPrivetdManagerInterface, privetd::kPingMethod); - privetd_proxy_->CallMethod( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - base::Bind(&PrivetClientImpl::OnPing, weak_ptr_factory_.GetWeakPtr(), - callback)); + proxy->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&PrivetDaemonClientImpl::OnPing, + weak_ptr_factory_.GetWeakPtr(), callback)); } -void PrivetClientImpl::Init(dbus::Bus* bus) { - privetd_proxy_ = bus->GetObjectProxy( - privetd::kPrivetdServiceName, - dbus::ObjectPath(privetd::kPrivetdManagerServicePath)); +void PrivetDaemonClientImpl::OnServiceOwnerChanged( + const std::string& service_owner) { + // If |service_owner| and |service_owner_| are both empty then the service + // hasn't started yet. If they match the owner hasn't changed. + if (service_owner == service_owner_) + return; + + service_owner_ = service_owner; + if (service_owner_.empty()) { + LOG(ERROR) << "Lost privetd service."; + CleanUpObjectManager(); + return; + } + + // Finish initialization (or re-initialize if privetd restarted). + object_manager_ = + bus_->GetObjectManager(privetd::kPrivetdServiceName, + dbus::ObjectPath(privetd::kPrivetdServicePath)); + object_manager_->RegisterInterface(privetd::kPrivetdManagerInterface, this); } -void PrivetClientImpl::OnPing(const PingCallback& callback, - dbus::Response* response) { +void PrivetDaemonClientImpl::CleanUpObjectManager() { + if (object_manager_) { + object_manager_->UnregisterInterface(privetd::kPrivetdManagerInterface); + object_manager_ = nullptr; + } +} + +PrivetDaemonClientImpl::Properties* PrivetDaemonClientImpl::GetProperties() { + if (!object_manager_) + return nullptr; + + return static_cast<Properties*>(object_manager_->GetProperties( + dbus::ObjectPath(privetd::kPrivetdManagerServicePath), + privetd::kPrivetdManagerInterface)); +} + +void PrivetDaemonClientImpl::OnPropertyChanged( + const std::string& property_name) { + FOR_EACH_OBSERVER(PrivetDaemonClient::Observer, observers_, + OnPrivetDaemonPropertyChanged(property_name)); +} + +void PrivetDaemonClientImpl::OnPing(const PingCallback& callback, + dbus::Response* response) { if (!response) { LOG(ERROR) << "Error calling " << privetd::kPingMethod; callback.Run(false); @@ -85,12 +237,6 @@ callback.Run(value == kPingResponse); } -void PrivetClientImpl::OnSignalConnected(const std::string& interface_name, - const std::string& signal_name, - bool success) { - LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name; -} - } // namespace ////////////////////////////////////////////////////////////////////////////// @@ -103,7 +249,7 @@ // static PrivetDaemonClient* PrivetDaemonClient::Create() { - return new PrivetClientImpl(); + return new PrivetDaemonClientImpl(); } } // namespace chromeos
diff --git a/chromeos/dbus/privet_daemon_client.h b/chromeos/dbus/privet_daemon_client.h index 61f55e50..04e9df7 100644 --- a/chromeos/dbus/privet_daemon_client.h +++ b/chromeos/dbus/privet_daemon_client.h
@@ -17,8 +17,19 @@ // interface is finalized. namespace privetd { const char kPrivetdServiceName[] = "org.chromium.privetd"; -const char kPrivetdManagerServicePath[] = "/org/chromium/privetd/Manager"; +const char kPrivetdServicePath[] = "/org/chromium/privetd"; const char kPrivetdManagerInterface[] = "org.chromium.privetd.Manager"; +const char kPrivetdManagerServicePath[] = "/org/chromium/privetd/Manager"; + +// Properties. +const char kWiFiBootstrapStateProperty[] = "WiFiBootstrapState"; + +// Property values. +const char kWiFiBootstrapStateDisabled[] = "disabled"; +const char kWiFiBootstrapStateWaiting[] = "waiting"; +const char kWiFiBootstrapStateConnecting[] = "connecting"; +const char kWiFiBootstrapStateMonitoring[] = "monitoring"; + // Methods. const char kPingMethod[] = "Ping"; } // namespace privetd @@ -30,11 +41,27 @@ // embedded Chrome OS Core device. class CHROMEOS_EXPORT PrivetDaemonClient : public DBusClient { public: - ~PrivetDaemonClient() override; - // Returns true if privetd correctly responded to Ping(). using PingCallback = base::Callback<void(bool success)>; + // Interface for observing changes in setup state. + class Observer { + public: + virtual ~Observer() {} + + // Notifies the observer when a named |property| changes. + virtual void OnPrivetDaemonPropertyChanged(const std::string& property) = 0; + }; + + ~PrivetDaemonClient() override; + + // The usual observer interface. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the current properties. + virtual std::string GetWifiBootstrapState() = 0; + // Asynchronously pings the daemon. virtual void Ping(const PingCallback& callback) = 0; @@ -46,8 +73,6 @@ PrivetDaemonClient(); private: - friend class PrivetDaemonClientTest; - DISALLOW_COPY_AND_ASSIGN(PrivetDaemonClient); };
diff --git a/components/BUILD.gn b/components/BUILD.gn index b7ecabd..10d0d89 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -28,7 +28,6 @@ "//components/component_updater", "//components/content_settings/core/browser", "//components/content_settings/core/common", - "//components/copresence_endpoints", "//components/crash/app", "//components/crash/browser", "//components/crx_file", @@ -126,7 +125,6 @@ } if (is_ios) { deps -= [ - "//components/copresence_endpoints", "//components/history/content/browser", "//components/keyed_service/content", ]
diff --git a/components/OWNERS b/components/OWNERS index e40e825..8216783 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -43,6 +43,7 @@ per-file data_reduction_proxy*=bengr@chromium.org per-file data_reduction_proxy*=marq@chromium.org per-file data_reduction_proxy*=bolian@chromium.org +per-file data_reduction_proxy*=sclittle@chromium.org per-file devtools_bridge.gyp=mnaganov@chromium.org per-file devtools_bridge.gyp=serya@chromium.org
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 0d0ac39..ee889cff 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -175,6 +175,11 @@ true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref( + prefs::kAutofillWalletSyncExperimentEnabled, + false, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); + // TODO(estade): Should this be syncable? + registry->RegisterBooleanPref( prefs::kAutofillWalletImportEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); @@ -561,8 +566,7 @@ unmasking_query_id_ = query_id; unmasking_form_ = form; unmasking_field_ = field; - // TODO(estade): uncomment this after the demo. - // real_pan_client_.Prepare(); + real_pan_client_.Prepare(); client()->ShowUnmaskPrompt(unmasking_card_, weak_ptr_factory_.GetWeakPtr()); return; @@ -690,23 +694,9 @@ void AutofillManager::OnUnmaskResponse(const base::string16& cvc, const base::string16& exp_month, const base::string16& exp_year) { - // Most of this function is demo code. The real code should look something - // like: - // real_pan_client_.UnmaskCard(unmasking_card_, cvc, exp_month, exp_year); - unmasking_cvc_ = cvc; - // TODO(estade): fake verification: assume 123/1234 is the correct cvc. - if (StartsWithASCII(base::UTF16ToASCII(cvc), "123", true)) { - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&AutofillManager::OnUnmaskVerificationResult, - base::Unretained(this), true), - base::TimeDelta::FromSeconds(2)); - } else { - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, base::Bind(&AutofillManager::OnUnmaskVerificationResult, - base::Unretained(this), false), - base::TimeDelta::FromSeconds(2)); - } + // TODO(estade): use month/year. + real_pan_client_.UnmaskCard(unmasking_card_, base::UTF16ToASCII(cvc)); } void AutofillManager::OnUnmaskPromptClosed() { @@ -721,25 +711,15 @@ } void AutofillManager::OnDidGetRealPan(const std::string& real_pan) { - NOTIMPLEMENTED(); -} - -void AutofillManager::OnUnmaskVerificationResult(bool success) { - if (success) { + if (!real_pan.empty()) { unmasking_card_.set_record_type(CreditCard::FULL_SERVER_CARD); - if (unmasking_card_.type() == kAmericanExpressCard) { - unmasking_card_.SetNumber(base::ASCIIToUTF16("371449635398431")); - } else if (unmasking_card_.type() == kVisaCard) { - unmasking_card_.SetNumber(base::ASCIIToUTF16("4012888888881881")); - } else { - DCHECK_EQ(kDiscoverCard, unmasking_card_.type()); - unmasking_card_.SetNumber(base::ASCIIToUTF16("6011000990139424")); - } + unmasking_card_.SetNumber(base::UTF8ToUTF16(real_pan)); personal_data_->UpdateServerCreditCard(unmasking_card_); FillCreditCardForm(unmasking_query_id_, unmasking_form_, unmasking_field_, unmasking_card_); } - client()->OnUnmaskVerificationResult(success); + + client()->OnUnmaskVerificationResult(!real_pan.empty()); } void AutofillManager::OnDidEndTextFieldEditing() {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 7e29820a..eb61b56 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -238,9 +238,6 @@ IdentityProvider* GetIdentityProvider() override; void OnDidGetRealPan(const std::string& real_pan) override; - // A toy method called when the (fake) unmasking process has finished. - void OnUnmaskVerificationResult(bool success); - // Returns false if Autofill is disabled or if no Autofill data is available. bool RefreshDataModels() const;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 911d07b..fcc36877 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -675,8 +675,7 @@ credit_cards_.clear(); credit_cards_.insert(credit_cards_.end(), local_credit_cards_.begin(), local_credit_cards_.end()); - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableWalletCardImport) && + if (IsExperimentalWalletIntegrationEnabled() && pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) { credit_cards_.insert(credit_cards_.end(), server_credit_cards_.begin(), server_credit_cards_.end()); @@ -960,6 +959,13 @@ return default_country_code_; } +bool PersonalDataManager::IsExperimentalWalletIntegrationEnabled() const { + // The feature can be enabled by sync experiment *or* command line flag. + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableWalletCardImport) || + pref_service_->GetBoolean(prefs::kAutofillWalletSyncExperimentEnabled); +} + void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) { if (is_off_the_record_) return;
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index ef66ce6..4ac72bb 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -219,6 +219,10 @@ void BinaryChanging(); #endif // defined(OS_MACOSX) && !defined(OS_IOS) + // Returns true if the wallet integration feature is enabled. Note that the + // feature can still disabled by a user pref. + bool IsExperimentalWalletIntegrationEnabled() const; + protected: // Only PersonalDataManagerFactory and certain tests can create instances of // PersonalDataManager.
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 35c6cbd..41ce19a2 100644 --- a/components/autofill/core/browser/wallet/real_pan_wallet_client.cc +++ b/components/autofill/core/browser/wallet/real_pan_wallet_client.cc
@@ -4,6 +4,7 @@ #include "components/autofill/core/browser/wallet/real_pan_wallet_client.h" +#include "base/base64.h" #include "base/bind.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" @@ -23,12 +24,11 @@ namespace { const char kUnmaskCardRequestFormat[] = - "request_content_type=application/json&request=%s&cvc=%s"; + "requestContentType=application/json; charset=utf-8&request=%s&cvc=%s"; -// TODO(estade): use a sandbox server on dev builds? const char kUnmaskCardRequestUrl[] = - "https://wallet.google.com/payments/apis-secure/creditcardservice" - "/GetRealPan?s7e=cvc"; + "https://sandbox.google.com/payments/apis-secure/creditcardservice" + "/getrealpan?s7e=cvc"; const char kTokenServiceConsumerId[] = "real_pan_wallet_client"; const char kWalletOAuth2Scope[] = @@ -64,8 +64,13 @@ base::DictionaryValue request_dict; request_dict.SetString("encrypted_cvc", "__param:cvc"); - // TODO(estade): is this the correct "token"? request_dict.SetString("credit_card_token", card.server_id()); + + // TODO(estade): add real risk data. + std::string base64_risk; + base::Base64Encode("{}", &base64_risk); + request_dict.SetString("risk_data_base64", base64_risk); + std::string json_request; base::JSONWriter::Write(&request_dict, &json_request); std::string post_body = base::StringPrintf(kUnmaskCardRequestFormat, @@ -91,6 +96,8 @@ scoped_ptr<net::URLFetcher> scoped_request(request_.Pass()); scoped_ptr<base::DictionaryValue> response_dict; int response_code = source->GetResponseCode(); + 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? @@ -98,41 +105,40 @@ switch (response_code) { // Valid response. case net::HTTP_OK: { - std::string data; - source->GetResponseAsString(&data); scoped_ptr<base::Value> message_value(base::JSONReader::Read(data)); if (message_value.get() && message_value->IsType(base::Value::TYPE_DICTIONARY)) { response_dict.reset( static_cast<base::DictionaryValue*>(message_value.release())); - } else { - NOTIMPLEMENTED(); } break; } // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying. case net::HTTP_BAD_REQUEST: { - NOTIMPLEMENTED(); break; } // Response contains an error to show the user. case net::HTTP_FORBIDDEN: case net::HTTP_INTERNAL_SERVER_ERROR: { - NOTIMPLEMENTED(); break; } // Handle anything else as a generic error. default: - NOTIMPLEMENTED(); break; } std::string real_pan; if (response_dict) response_dict->GetString("pan", &real_pan); + + if (real_pan.empty()) { + NOTIMPLEMENTED() << "Unhandled error: " << response_code << + " with data: " << data; + } + delegate_->OnDidGetRealPan(real_pan); } @@ -157,7 +163,7 @@ delegate_->OnDidGetRealPan(std::string()); } // TODO(estade): what do we do in the failure case? - NOTIMPLEMENTED(); + NOTIMPLEMENTED() << "Unhandled OAuth2 error: " << error.ToString(); access_token_request_.reset(); } @@ -178,7 +184,7 @@ } void RealPanWalletClient::SetOAuth2TokenAndStartRequest() { - request_->AddExtraRequestHeader("Authorization: " + access_token_); + request_->AddExtraRequestHeader("Authorization: Bearer " + access_token_); request_->Start(); }
diff --git a/components/autofill/core/common/autofill_pref_names.cc b/components/autofill/core/common/autofill_pref_names.cc index 62fe49b..b272a62 100644 --- a/components/autofill/core/common/autofill_pref_names.cc +++ b/components/autofill/core/common/autofill_pref_names.cc
@@ -38,8 +38,16 @@ // true, then kAutofillMacAddressBookQueried is expected to also be true. const char kAutofillUseMacAddressBook[] = "autofill.use_mac_address_book"; -// Boolean that's true when Wallet card and address import is enabled. +// Boolean that's true when Wallet card and address import is enabled by the +// user. This will only be available to the user if the overall feature is +// enabled. const char kAutofillWalletImportEnabled[] = "autofill.wallet_import_enabled"; +// Enables/disables the Wallet card and address feature. Set via sync +// experiment. Even if this is false, the feature can still be enabled via the +// command line flag flags::kEnableWalletCardImport. +const char kAutofillWalletSyncExperimentEnabled[] = + "autofill.wallet_import_sync_experiment_enabled"; + } // namespace prefs } // namespace autofill
diff --git a/components/autofill/core/common/autofill_pref_names.h b/components/autofill/core/common/autofill_pref_names.h index 087780e..fffafd9 100644 --- a/components/autofill/core/common/autofill_pref_names.h +++ b/components/autofill/core/common/autofill_pref_names.h
@@ -18,6 +18,7 @@ extern const char kAutofillPositiveUploadRate[]; extern const char kAutofillUseMacAddressBook[]; extern const char kAutofillWalletImportEnabled[]; +extern const char kAutofillWalletSyncExperimentEnabled[]; } // namespace prefs } // namespace autofill
diff --git a/components/autofill/core/common/password_form.cc b/components/autofill/core/common/password_form.cc index 73a2fd5..2b62766 100644 --- a/components/autofill/core/common/password_form.cc +++ b/components/autofill/core/common/password_form.cc
@@ -20,7 +20,7 @@ blacklisted_by_user(false), type(TYPE_MANUAL), times_used(0), - is_zero_click(false) { + skip_zero_click(false) { } PasswordForm::~PasswordForm() { @@ -55,7 +55,7 @@ display_name == form.display_name && avatar_url == form.avatar_url && federation_url == form.federation_url && - is_zero_click == form.is_zero_click; + skip_zero_click == form.skip_zero_click; } bool PasswordForm::operator!=(const PasswordForm& form) const { @@ -91,7 +91,7 @@ << " display_name: " << base::UTF16ToUTF8(form.display_name) << " avatar_url: " << form.avatar_url << " federation_url: " << form.federation_url - << " is_zero_click: " << form.is_zero_click; + << " skip_next_zero_click: " << form.skip_zero_click; } } // namespace autofill
diff --git a/components/autofill/core/common/password_form.h b/components/autofill/core/common/password_form.h index be85cd3e..29d369a7 100644 --- a/components/autofill/core/common/password_form.h +++ b/components/autofill/core/common/password_form.h
@@ -218,9 +218,10 @@ // The URL of identity provider used for federated login. GURL federation_url; - // If true, Chrome will sign the user in automatically using the credentials. - // This field isn't synced deliberately. - bool is_zero_click; + // If true, Chrome will not return this credential to a site in response to + // 'navigator.credentials.request()' without user interaction. + // Once user selects this credential the flag is reseted. + bool skip_zero_click; // Returns true if this match was found using public suffix matching. bool IsPublicSuffixMatch() const;
diff --git a/components/browser_watcher/watcher_client_win.cc b/components/browser_watcher/watcher_client_win.cc index e055278..dd6182a 100644 --- a/components/browser_watcher/watcher_client_win.cc +++ b/components/browser_watcher/watcher_client_win.cc
@@ -48,6 +48,8 @@ // Launch the child process inheriting only |self| on // Vista and better. to_inherit.push_back(self.Handle()); + to_inherit.insert(to_inherit.end(), inherited_handles_.begin(), + inherited_handles_.end()); options.handles_to_inherit = &to_inherit; } @@ -56,4 +58,8 @@ LOG(ERROR) << "Failed to launch browser watcher."; } +void WatcherClient::AddInheritedHandle(HANDLE handle) { + inherited_handles_.push_back(handle); +} + } // namespace browser_watcher
diff --git a/components/browser_watcher/watcher_client_win.h b/components/browser_watcher/watcher_client_win.h index 5ae3c96..9e8810799 100644 --- a/components/browser_watcher/watcher_client_win.h +++ b/components/browser_watcher/watcher_client_win.h
@@ -32,12 +32,19 @@ // a non-threadsafe legacy launch mode that's compatible with Windows XP. void LaunchWatcher(); + // Ensures that |handle| may be inherited by the watcher process. |handle| + // must still be inheritable, and it's the client's responsibility to + // communicate the value of |handle| to the launched process. + void AddInheritedHandle(HANDLE handle); + + // Returns the launched process. + const base::Process& process() const { return process_; } + // Accessors, exposed only for testing. bool use_legacy_launch() const { return use_legacy_launch_; } void set_use_legacy_launch(bool use_legacy_launch) { use_legacy_launch_ = use_legacy_launch; } - base::ProcessHandle process() const { return process_.Handle(); } private: // If true, the watcher process will be launched with XP legacy handle @@ -52,6 +59,8 @@ // LaunchWatcher() call. base::Process process_; + std::vector<HANDLE> inherited_handles_; + DISALLOW_COPY_AND_ASSIGN(WatcherClient); };
diff --git a/components/browser_watcher/watcher_client_win_unittest.cc b/components/browser_watcher/watcher_client_win_unittest.cc index 2e19f42..ca24e81 100644 --- a/components/browser_watcher/watcher_client_win_unittest.cc +++ b/components/browser_watcher/watcher_client_win_unittest.cc
@@ -137,25 +137,11 @@ base::Unretained(this), handle_policy); } - void AssertSuccessfulExitCode(base::ProcessHandle handle) { - ASSERT_NE(base::kNullProcessHandle, handle); - - // Duplicate the process handle to work around the fact that - // WaitForExitCode closes it(!!!). - base::ProcessHandle dupe = NULL; - ASSERT_TRUE(::DuplicateHandle(base::GetCurrentProcessHandle(), - handle, - base::GetCurrentProcessHandle(), - &dupe, - SYNCHRONIZE | PROCESS_QUERY_INFORMATION, - FALSE, - 0)); - ASSERT_NE(base::kNullProcessHandle, dupe); + void AssertSuccessfulExitCode(base::Process process) { + ASSERT_TRUE(process.IsValid()); int exit_code = 0; - if (!base::WaitForExitCode(dupe, &exit_code)) { - base::CloseProcessHandle(dupe); - FAIL() << "WaitForExitCode failed."; - } + if (!process.WaitForExit(&exit_code)) + FAIL() << "Process::WaitForExit failed."; ASSERT_EQ(0, exit_code); } @@ -177,7 +163,8 @@ client.LaunchWatcher(); - ASSERT_NO_FATAL_FAILURE(AssertSuccessfulExitCode(client.process())); + ASSERT_NO_FATAL_FAILURE( + AssertSuccessfulExitCode(client.process().Duplicate())); } TEST_F(WatcherClientTest, LaunchWatcherLegacyModeSucceeds) { @@ -190,7 +177,8 @@ client.LaunchWatcher(); - ASSERT_NO_FATAL_FAILURE(AssertSuccessfulExitCode(client.process())); + ASSERT_NO_FATAL_FAILURE( + AssertSuccessfulExitCode(client.process().Duplicate())); } TEST_F(WatcherClientTest, LegacyModeDetectedOnXP) { @@ -205,7 +193,8 @@ client.LaunchWatcher(); - ASSERT_NO_FATAL_FAILURE(AssertSuccessfulExitCode(client.process())); + ASSERT_NO_FATAL_FAILURE( + AssertSuccessfulExitCode(client.process().Duplicate())); } } // namespace browser_watcher
diff --git a/components/components.gyp b/components/components.gyp index e5714dd..c8b1e35 100644 --- a/components/components.gyp +++ b/components/components.gyp
@@ -72,7 +72,6 @@ 'includes': [ 'app_modal.gypi', 'cdm.gypi', - 'copresence_endpoints.gypi', 'navigation_interception.gypi', 'plugins.gypi', 'power.gypi',
diff --git a/components/components_browsertests.isolate b/components/components_browsertests.isolate index cb5b41c..aaa6d190 100644 --- a/components/components_browsertests.isolate +++ b/components/components_browsertests.isolate
@@ -28,6 +28,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -51,6 +53,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index c4ee483..23261b15 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -723,6 +723,7 @@ 'components.gyp:wifi_sync', 'components.gyp:pairing', + 'components.gyp:user_manager_test_support', '../chromeos/chromeos.gyp:chromeos_test_support', ], }],
diff --git a/components/components_unittests.isolate b/components/components_unittests.isolate index 84d0fd137..d94c567 100644 --- a/components/components_unittests.isolate +++ b/components/components_unittests.isolate
@@ -29,6 +29,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -47,6 +49,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.so', @@ -63,6 +67,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../chrome/test/data/policy/',
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index 715df59..386de0c 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -518,6 +518,7 @@ setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT; case CONTENT_SETTINGS_TYPE_GEOLOCATION: case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: + case CONTENT_SETTINGS_TYPE_FULLSCREEN: case CONTENT_SETTINGS_TYPE_MOUSELOCK: case CONTENT_SETTINGS_TYPE_MEDIASTREAM: case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
diff --git a/components/copresence_endpoints.gypi b/components/copresence_endpoints.gypi deleted file mode 100644 index 5cd7cc2..0000000 --- a/components/copresence_endpoints.gypi +++ /dev/null
@@ -1,28 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'targets': [ - { - 'target_name': 'copresence_endpoints', - 'type': 'static_library', - 'dependencies': [ - '../base/base.gyp:base', - '../device/bluetooth/bluetooth.gyp:device_bluetooth', - '../net/net.gyp:net', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - # GN version: //components/copresence_endpoints - 'copresence_endpoints/copresence_endpoint.cc', - 'copresence_endpoints/copresence_socket.h', - 'copresence_endpoints/public/copresence_endpoint.h', - 'copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.cc', - 'copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h', - ], - }, - ], -}
diff --git a/components/copresence_endpoints/BUILD.gn b/components/copresence_endpoints/BUILD.gn deleted file mode 100644 index 7d4ee0a7..0000000 --- a/components/copresence_endpoints/BUILD.gn +++ /dev/null
@@ -1,19 +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. - -static_library("copresence_endpoints") { - sources = [ - "copresence_endpoint.cc", - "copresence_socket.h", - "public/copresence_endpoint.h", - "transports/bluetooth/copresence_socket_bluetooth.cc", - "transports/bluetooth/copresence_socket_bluetooth.h", - ] - - deps = [ - "//base", - "//device/bluetooth", - "//net", - ] -}
diff --git a/components/copresence_endpoints/DEPS b/components/copresence_endpoints/DEPS deleted file mode 100644 index 338b701a..0000000 --- a/components/copresence_endpoints/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - "+base", - "+device/bluetooth", - "+net", -]
diff --git a/components/copresence_endpoints/OWNERS b/components/copresence_endpoints/OWNERS deleted file mode 100644 index 6a2cb03..0000000 --- a/components/copresence_endpoints/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -rkc@chromium.org
diff --git a/components/copresence_endpoints/copresence_endpoint.cc b/components/copresence_endpoints/copresence_endpoint.cc deleted file mode 100644 index c13fd33..0000000 --- a/components/copresence_endpoints/copresence_endpoint.cc +++ /dev/null
@@ -1,162 +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 "components/copresence_endpoints/public/copresence_endpoint.h" - -#include <stdint.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/format_macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/string_number_conversions.h" -#include "components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h" -#include "device/bluetooth/bluetooth_adapter.h" -#include "device/bluetooth/bluetooth_adapter_factory.h" -#include "device/bluetooth/bluetooth_device.h" -#include "device/bluetooth/bluetooth_socket.h" -#include "device/bluetooth/bluetooth_uuid.h" - -namespace { - -const char kAdapterError[] = "NOADAPTER"; -const char kSocketServiceUuid[] = "2491fb14-0077-4d4d-bd41-b18e9a570f56"; - -// This class will confirm pairing for a device that is expecting a pairing -// confirmation. -class DefaultApprovalDelegate - : public device::BluetoothDevice::PairingDelegate { - public: - DefaultApprovalDelegate() {} - ~DefaultApprovalDelegate() override {} - - // device::BluetoothDevice::PairingDelegate overrides: - void RequestPinCode(device::BluetoothDevice* device) override {} - void RequestPasskey(device::BluetoothDevice* device) override {} - void DisplayPinCode(device::BluetoothDevice* device, - const std::string& pincode) override {} - void DisplayPasskey(device::BluetoothDevice* device, - uint32 passkey) override {} - void KeysEntered(device::BluetoothDevice* device, uint32 entered) override {} - void ConfirmPasskey(device::BluetoothDevice* device, - uint32 passkey) override {} - void AuthorizePairing(device::BluetoothDevice* device) override { - if (device->ExpectingConfirmation()) - device->ConfirmPairing(); - } -}; - -} // namespace - -namespace copresence_endpoints { - -CopresenceEndpoint::CopresenceEndpoint( - int endpoint_id, - const CreateEndpointCallback& create_callback, - const base::Closure& accept_callback, - const CopresenceSocket::ReceiveCallback& receive_callback) - : endpoint_id_(endpoint_id), - create_callback_(create_callback), - accept_callback_(accept_callback), - receive_callback_(receive_callback), - delegate_(nullptr), - weak_ptr_factory_(this) { - CHECK(!create_callback.is_null()); - CHECK(!accept_callback.is_null()); - CHECK(!receive_callback.is_null()); - - if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { - create_callback_.Run(std::string()); - return; - } - - device::BluetoothAdapterFactory::GetAdapter(base::Bind( - &CopresenceEndpoint::OnGetAdapter, weak_ptr_factory_.GetWeakPtr())); -} - -CopresenceEndpoint::~CopresenceEndpoint() { - server_socket_->Disconnect(base::Bind(&base::DoNothing)); - server_socket_->Close(); - if (delegate_) - adapter_->RemovePairingDelegate(delegate_.get()); -} - -std::string CopresenceEndpoint::GetLocator() { - if (!adapter_.get()) - return kAdapterError; - return base::IntToString(endpoint_id_) + "." + adapter_->GetAddress() + "." + - kSocketServiceUuid; -} - -bool CopresenceEndpoint::Send(const scoped_refptr<net::IOBuffer>& buffer, - int buffer_size) { - if (!client_socket_) - return false; - - return client_socket_->Send(buffer, buffer_size); -} - -// Private methods. - -void CopresenceEndpoint::OnGetAdapter( - scoped_refptr<device::BluetoothAdapter> adapter) { - if (!adapter.get() || !adapter->IsPresent() || !adapter->IsPowered()) { - LOG(WARNING) << "Unable to use BT adapter"; - create_callback_.Run(std::string()); - return; - } - - adapter_ = adapter; - delegate_ = make_scoped_ptr(new DefaultApprovalDelegate()); - VLOG(2) << "Got Adapter, creating service with UUID: " << kSocketServiceUuid; - adapter_->AddPairingDelegate( - delegate_.get(), - device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH); - adapter_->CreateRfcommService( - device::BluetoothUUID(kSocketServiceUuid), - device::BluetoothAdapter::ServiceOptions(), - base::Bind(&CopresenceEndpoint::OnCreateService, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&CopresenceEndpoint::OnCreateServiceError, - weak_ptr_factory_.GetWeakPtr())); -} - -void CopresenceEndpoint::OnCreateService( - scoped_refptr<device::BluetoothSocket> socket) { - if (!socket.get()) { - LOG(WARNING) << "Couldn't create service!"; - create_callback_.Run(std::string()); - return; - } - - VLOG(3) << "Starting Accept Socket."; - server_socket_ = socket; - create_callback_.Run(GetLocator()); - server_socket_->Accept( - base::Bind(&CopresenceEndpoint::OnAccept, weak_ptr_factory_.GetWeakPtr()), - base::Bind(&CopresenceEndpoint::OnAcceptError, - weak_ptr_factory_.GetWeakPtr())); -} - -void CopresenceEndpoint::OnCreateServiceError(const std::string& message) { - LOG(WARNING) << "Couldn't create Bluetooth service: " << message; - create_callback_.Run(std::string()); -} - -void CopresenceEndpoint::OnAccept( - const device::BluetoothDevice* device, - scoped_refptr<device::BluetoothSocket> socket) { - if (!socket.get()) - return; - VLOG(3) << "Accepted Socket."; - client_socket_.reset(new CopresenceSocketBluetooth(socket)); - accept_callback_.Run(); - client_socket_->Receive(receive_callback_); -} - -void CopresenceEndpoint::OnAcceptError(const std::string& message) { - LOG(WARNING) << "Couldn't accept Bluetooth connection: " << message; -} - -} // namespace copresence_endpoints
diff --git a/components/copresence_endpoints/copresence_socket.h b/components/copresence_endpoints/copresence_socket.h deleted file mode 100644 index 115300e1..0000000 --- a/components/copresence_endpoints/copresence_socket.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_SOCKET_H_ -#define COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_SOCKET_H_ - -#include <string> - -#include "base/macros.h" - -namespace net { -class IOBuffer; -} - -namespace copresence_endpoints { - -// A CopresenceSocket is an object that is used to send receive data to and -// from CopresencePeers. -// TODO(rkc): Add the ability to connect to a remote CopresencePeer. -class CopresenceSocket { - public: - typedef base::Callback<void(const scoped_refptr<net::IOBuffer>& buffer, - int buffer_size)> ReceiveCallback; - - CopresenceSocket() {} - virtual ~CopresenceSocket() {} - - // Send data on this socket. If unable to send the data, return false. This - // operation only guarantees that if the return value is a success, the send - // was started. It does not make any guarantees about the completion of the - // operation. - // TODO(rkc): Expand the bool into more a more detailed failures enum. - virtual bool Send(const scoped_refptr<net::IOBuffer>& buffer, - int buffer_size) = 0; - virtual void Receive(const ReceiveCallback& callback) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(CopresenceSocket); -}; - -} // namespace copresence_endpoints - -#endif // COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_SOCKET_H_
diff --git a/components/copresence_endpoints/public/copresence_endpoint.h b/components/copresence_endpoints/public/copresence_endpoint.h deleted file mode 100644 index c0b7bc55..0000000 --- a/components/copresence_endpoints/public/copresence_endpoint.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINT_H_ -#define COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINT_H_ - -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "components/copresence_endpoints/copresence_socket.h" -#include "device/bluetooth/bluetooth_device.h" -#include "device/bluetooth/bluetooth_uuid.h" - -namespace device { -class BluetoothAdapter; -class BluetoothSocket; -} - -namespace copresence_endpoints { - -// A CopresenceEndpoint is an object that can be used for communication with -// remote endpoints. Creating this object will create a server that will listen -// on Bluetooth (currently) and accept connections. Once a connection is -// accepted, the endpoint continuously listens for data on the accepted -// connection(s). -class CopresenceEndpoint { - public: - // Callback with the locator data for the created peer. On a failed create, - // the locator string will be empty. - typedef base::Callback<void(const std::string&)> CreateEndpointCallback; - - // Create a CopresenceEndpoint and start listening for connections. Once the - // endpoint object is created, the locator data for the object is returned via - // create_callback. This locator data can be used to connect to this peer by - // a remote endpoint. - // endpoint_id is the id that this endpoint will use to identify itself. - // create_callback is called when the endpoint creation is complete. - // accept_callback is called when we receive an incoming connection. - // receive_callback is called when we receive data on this endpoint. - CopresenceEndpoint(int endpoint_id, - const CreateEndpointCallback& create_callback, - const base::Closure& accept_callback, - const CopresenceSocket::ReceiveCallback& receive_callback); - - virtual ~CopresenceEndpoint(); - - // Send's data to the remote device connected to this endpoint. - bool Send(const scoped_refptr<net::IOBuffer>& buffer, int buffer_size); - - // This will return a string containing the data needed for a remote endpoint - // to connect to this endpoint. - std::string GetLocator(); - - private: - void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter); - void OnCreateService(scoped_refptr<device::BluetoothSocket> socket); - void OnCreateServiceError(const std::string& message); - - void OnAccept(const device::BluetoothDevice* device, - scoped_refptr<device::BluetoothSocket> socket); - void OnAcceptError(const std::string& message); - - scoped_refptr<device::BluetoothAdapter> adapter_; - scoped_refptr<device::BluetoothSocket> server_socket_; - // TODO(rkc): Eventually an endpoint will be able to accept multiple - // connections. Whenever the API supports one-to-many connections, fix this - // code to do so too. - scoped_ptr<CopresenceSocket> client_socket_; - - int endpoint_id_; - CreateEndpointCallback create_callback_; - base::Closure accept_callback_; - CopresenceSocket::ReceiveCallback receive_callback_; - - scoped_ptr<device::BluetoothDevice::PairingDelegate> delegate_; - - base::WeakPtrFactory<CopresenceEndpoint> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CopresenceEndpoint); -}; - -} // namespace copresence_endpoints - -#endif // COMPONENTS_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINT_H_
diff --git a/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.cc b/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.cc deleted file mode 100644 index bfee046a..0000000 --- a/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.cc +++ /dev/null
@@ -1,94 +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 "components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h" - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/string_piece.h" -#include "device/bluetooth/bluetooth_socket.h" -#include "net/base/io_buffer.h" - -namespace { - -// TODO(rkc): This number is totally arbitrary. Figure out what this should be. -const int kMaxReceiveBytes = 4096; - -} // namespace - -namespace copresence_endpoints { - -CopresenceSocketBluetooth::CopresenceSocketBluetooth( - const scoped_refptr<device::BluetoothSocket>& socket) - : socket_(socket), receiving_(false), weak_ptr_factory_(this) { -} - -CopresenceSocketBluetooth::~CopresenceSocketBluetooth() { - receiving_ = false; -} - -bool CopresenceSocketBluetooth::Send(const scoped_refptr<net::IOBuffer>& buffer, - int buffer_size) { - VLOG(3) << "Starting sending of data with size = " << buffer_size; - socket_->Send(buffer, buffer_size, - base::Bind(&CopresenceSocketBluetooth::OnSendComplete, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&CopresenceSocketBluetooth::OnSendError, - weak_ptr_factory_.GetWeakPtr())); - return true; -} - -void CopresenceSocketBluetooth::Receive(const ReceiveCallback& callback) { - VLOG(3) << "Starting Receive."; - receiving_ = true; - receive_callback_ = callback; - socket_->Receive(kMaxReceiveBytes, - base::Bind(&CopresenceSocketBluetooth::OnReceive, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&CopresenceSocketBluetooth::OnReceiveError, - weak_ptr_factory_.GetWeakPtr())); -} - -void CopresenceSocketBluetooth::OnSendComplete(int status) { - VLOG(3) << "Send Completed. Status = " << status; -} - -void CopresenceSocketBluetooth::OnSendError(const std::string& message) { - LOG(ERROR) << "Bluetooth send error: " << message; -} - -void CopresenceSocketBluetooth::OnReceive( - int size, - scoped_refptr<net::IOBuffer> io_buffer) { - VLOG(3) << "Data received with size = " << size - << " and receiving_ = " << receiving_; - // Dispatch the data to the callback and go back to listening for more data. - receive_callback_.Run(io_buffer, size); - - // We cancelled receiving due to an error. Don't post more receive tasks. - if (!receiving_) - return; - - // Post a task to delay the read until the socket is available, as - // calling Receive again at this point would error with ERR_IO_PENDING. - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&device::BluetoothSocket::Receive, socket_, kMaxReceiveBytes, - base::Bind(&CopresenceSocketBluetooth::OnReceive, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&CopresenceSocketBluetooth::OnReceiveError, - weak_ptr_factory_.GetWeakPtr()))); -} - -void CopresenceSocketBluetooth::OnReceiveError( - device::BluetoothSocket::ErrorReason reason, - const std::string& message) { - LOG(ERROR) << "Bluetooth receive error: " << message; - if (reason == device::BluetoothSocket::kIOPending) - return; - - receiving_ = false; -} - -} // namespace copresence_endpoints
diff --git a/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h b/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h deleted file mode 100644 index 5af5557d..0000000 --- a/components/copresence_endpoints/transports/bluetooth/copresence_socket_bluetooth.h +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_COPRESENCE_SOCKETS_TRANSPORTS_COPRESENCE_SOCKET_BLUETOOTH_H_ -#define COMPONENTS_COPRESENCE_SOCKETS_TRANSPORTS_COPRESENCE_SOCKET_BLUETOOTH_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "components/copresence_endpoints/copresence_socket.h" -#include "device/bluetooth/bluetooth_socket.h" - -namespace net { -class IOBuffer; -} - -namespace copresence_endpoints { - -// A CopresenceSocketBluetooth is the Bluetooth implementation of a -// CopresenceSocket. This is currently a thin wrapper around BluetoothSocket. -class CopresenceSocketBluetooth : public CopresenceSocket { - public: - explicit CopresenceSocketBluetooth( - const scoped_refptr<device::BluetoothSocket>& socket); - ~CopresenceSocketBluetooth() override; - - // CopresenceSocket overrides: - bool Send(const scoped_refptr<net::IOBuffer>& buffer, - int buffer_size) override; - void Receive(const ReceiveCallback& callback) override; - - private: - void OnSendComplete(int status); - void OnSendError(const std::string& message); - - void OnReceive(int size, scoped_refptr<net::IOBuffer> io_buffer); - void OnReceiveError(device::BluetoothSocket::ErrorReason reason, - const std::string& message); - - scoped_refptr<device::BluetoothSocket> socket_; - ReceiveCallback receive_callback_; - - bool receiving_; - - base::WeakPtrFactory<CopresenceSocketBluetooth> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(CopresenceSocketBluetooth); -}; - -} // namespace copresence_endpoints - -#endif // COMPONENTS_COPRESENCE_SOCKETS_TRANSPORTS_COPRESENCE_SOCKET_BLUETOOTH_H_
diff --git a/components/data_reduction_proxy/OWNERS b/components/data_reduction_proxy/OWNERS index 6a63b53..6fe062f7 100644 --- a/components/data_reduction_proxy/OWNERS +++ b/components/data_reduction_proxy/OWNERS
@@ -1,3 +1,4 @@ bengr@chromium.org bolian@chromium.org marq@chromium.org +sclittle@chromium.org
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc index 7c1293b..f603265 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats.cc
@@ -128,8 +128,13 @@ DCHECK(thread_checker_.CalledOnValidThread()); DataReductionProxyTypeInfo proxy_info; + // Ignore requests that did not use the data reduction proxy. The check for + // LOAD_BYPASS_PROXY is necessary because the proxy_server() in the |request| + // might still be set to the data reduction proxy if |request| was retried + // over direct and a network error occurred while retrying it. if (data_reduction_proxy_params_->WasDataReductionProxyUsed(request, - &proxy_info)) { + &proxy_info) && + (request->load_flags() & net::LOAD_BYPASS_PROXY) == 0) { if (request->status().status() == net::URLRequestStatus::SUCCESS) { successful_requests_through_proxy_count_++; NotifyUnavailabilityIfChanged();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc index 7867884..dbd85d4 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc
@@ -448,22 +448,25 @@ struct TestCase { bool was_proxy_used; + bool is_load_bypass_proxy; bool is_fallback; bool is_main_frame; net::Error net_error; }; const TestCase test_cases[] = { - {false, false, true, net::OK}, - {false, false, false, net::ERR_TOO_MANY_REDIRECTS}, - {true, false, true, net::OK}, - {true, false, true, net::ERR_TOO_MANY_REDIRECTS}, - {true, false, false, net::OK}, - {true, false, false, net::ERR_TOO_MANY_REDIRECTS}, - {true, true, true, net::OK}, - {true, true, true, net::ERR_TOO_MANY_REDIRECTS}, - {true, true, false, net::OK}, - {true, true, false, net::ERR_TOO_MANY_REDIRECTS} + {false, true, false, true, net::OK}, + {false, true, false, false, net::ERR_TOO_MANY_REDIRECTS}, + {false, false, false, true, net::OK}, + {false, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, + {true, false, false, true, net::OK}, + {true, false, false, true, net::ERR_TOO_MANY_REDIRECTS}, + {true, false, false, false, net::OK}, + {true, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, + {true, false, true, true, net::OK}, + {true, false, true, true, net::ERR_TOO_MANY_REDIRECTS}, + {true, false, true, false, net::OK}, + {true, false, true, false, net::ERR_TOO_MANY_REDIRECTS} }; for (size_t i = 0; i < arraysize(test_cases); ++i) { @@ -478,6 +481,10 @@ scoped_ptr<net::URLRequest> fake_request( CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), raw_headers)); + if (test_cases[i].is_load_bypass_proxy) { + fake_request->SetLoadFlags(fake_request->load_flags() | + net::LOAD_BYPASS_PROXY); + } if (test_cases[i].is_main_frame) { fake_request->SetLoadFlags(fake_request->load_flags() | net::LOAD_MAIN_FRAME); @@ -497,27 +504,29 @@ usage_stats->OnUrlRequestCompleted(fake_request.get(), false); - if (test_cases[i].was_proxy_used && !test_cases[i].is_fallback) { + if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && + !test_cases[i].is_fallback) { histogram_tester.ExpectUniqueSample( kPrimaryHistogramName, -net_error_int, 1); } else { histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); } - if (test_cases[i].was_proxy_used && test_cases[i].is_fallback) { + if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && + test_cases[i].is_fallback) { histogram_tester.ExpectUniqueSample( kFallbackHistogramName, -net_error_int, 1); } else { histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); } - if (test_cases[i].was_proxy_used && !test_cases[i].is_fallback && - test_cases[i].is_main_frame) { + if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && + !test_cases[i].is_fallback && test_cases[i].is_main_frame) { histogram_tester.ExpectUniqueSample( kPrimaryMainFrameHistogramName, -net_error_int, 1); } else { histogram_tester.ExpectTotalCount(kPrimaryMainFrameHistogramName, 0); } - if (test_cases[i].was_proxy_used && test_cases[i].is_fallback && - test_cases[i].is_main_frame) { + if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && + test_cases[i].is_fallback && test_cases[i].is_main_frame) { histogram_tester.ExpectUniqueSample( kFallbackMainFrameHistogramName, -net_error_int, 1); } else {
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.cc b/components/enhanced_bookmarks/enhanced_bookmark_model.cc index f9d34782..f114c5a 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model.cc +++ b/components/enhanced_bookmarks/enhanced_bookmark_model.cc
@@ -226,6 +226,16 @@ return true; } +void EnhancedBookmarkModel::RemoveImageData(const BookmarkNode* node) { + DCHECK(node->is_url()); + image::collections::ImageData data; + data.set_user_removed_image(true); + + std::string encoded_data; + base::Base64Encode(data.SerializeAsString(), &encoded_data); + SetMetaInfo(node, kImageDataKey, encoded_data); +} + bool EnhancedBookmarkModel::GetOriginalImage(const BookmarkNode* node, GURL* url, int* width,
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model.h b/components/enhanced_bookmarks/enhanced_bookmark_model.h index 7eab266..1660237 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model.h +++ b/components/enhanced_bookmarks/enhanced_bookmark_model.h
@@ -86,6 +86,10 @@ int width, int height); + // Removes all image data for the node and sets the user_removed_image flag + // so the server won't try to fetch a new image for the node. + void RemoveImageData(const BookmarkNode* node); + // Returns the url and dimensions of the original scraped image of a // bookmark |node|. // Returns true if the out variables are populated, false otherwise.
diff --git a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc index db2c54f0..f760d0c 100644 --- a/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc +++ b/components/enhanced_bookmarks/enhanced_bookmark_model_unittest.cc
@@ -25,6 +25,7 @@ namespace { const std::string BOOKMARK_URL("http://example.com/index.html"); +const std::string IMAGE_URL("http://example.com/image.jpg"); } // namespace class EnhancedBookmarkModelTest @@ -773,3 +774,24 @@ bookmark_model_->non_cloned_keys(); EXPECT_TRUE(non_cloned_keys.find("stars.id") != non_cloned_keys.end()); } + +TEST_F(EnhancedBookmarkModelTest, RemoveImageData) { + const BookmarkNode* node = AddBookmark(); + model_->SetAllImages(node, GURL(IMAGE_URL), 64, 64, GURL(IMAGE_URL), 16, 16); + + GURL url; + int width, height; + EXPECT_TRUE(model_->GetOriginalImage(node, &url, &width, &height)); + EXPECT_TRUE(model_->GetThumbnailImage(node, &url, &width, &height)); + + model_->RemoveImageData(node); + EXPECT_FALSE(model_->GetOriginalImage(node, &url, &width, &height)); + EXPECT_FALSE(model_->GetThumbnailImage(node, &url, &width, &height)); + + std::string meta_info = GetMetaInfoField(node, "stars.imageData"); + std::string decoded; + ASSERT_TRUE(base::Base64Decode(meta_info, &decoded)); + image::collections::ImageData data; + ASSERT_TRUE(data.ParseFromString(decoded)); + EXPECT_TRUE(data.user_removed_image()); +}
diff --git a/components/enhanced_bookmarks/proto/metadata.proto b/components/enhanced_bookmarks/proto/metadata.proto index bf4f18c..4a5f2ecd 100644 --- a/components/enhanced_bookmarks/proto/metadata.proto +++ b/components/enhanced_bookmarks/proto/metadata.proto
@@ -26,6 +26,17 @@ // Information about the server hosted thumbnail. optional ImageInfo thumbnail_info = 3; + + // The expiration timestamp of the served thumbnail, in microseconds since + // epoch. The thumbnail is only guaranteed until this time, afterwards the + // URL may be broken. + // If expiration_timestamp is not present, then whoever set the thumbnail_info + // should guarantee that the thumbnail will not expire. + optional int64 expiration_timestamp = 5; + + // Represents an explicit user action to remove an image. This will prevent + // any additional backfilling once this is set. + optional bool user_removed_image = 6; } message PageData {
diff --git a/components/nacl.gyp b/components/nacl.gyp index f6d7e26..9d543d8 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp
@@ -77,11 +77,12 @@ 'dependencies': [ '../base/base.gyp:base', '../base/base.gyp:base_static', + '../crypto/crypto.gyp:crypto', '../ipc/ipc.gyp:ipc', '../mojo/mojo_nacl.gyp:monacl_syscall', - '../ppapi/ppapi_internal.gyp:ppapi_shared', - '../ppapi/ppapi_internal.gyp:ppapi_ipc', '../native_client/src/trusted/service_runtime/service_runtime.gyp:sel_main_chrome', + '../ppapi/ppapi_internal.gyp:ppapi_ipc', + '../ppapi/ppapi_internal.gyp:ppapi_shared', '../third_party/mojo/mojo_edk.gyp:mojo_system_impl', ], 'conditions': [ @@ -202,11 +203,14 @@ 'target_name': 'nacl_loader_unittests', 'type': '<(gtest_target_type)', 'sources': [ + 'nacl/loader/nacl_ipc_adapter_unittest.cc', + 'nacl/loader/nacl_validation_query_unittest.cc', 'nacl/loader/run_all_unittests.cc', ], 'dependencies': [ 'nacl', '../base/base.gyp:test_support_base', + '../ipc/ipc.gyp:test_support_ipc', '../testing/gtest.gyp:gtest', ], 'conditions': [ @@ -218,8 +222,8 @@ 'nacl/loader/nonsfi/irt_icache_unittest.cc', # TODO(hamaji): Currently, we build them twice. Stop building # them for components_unittests. See crbug.com/364751 - 'nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc', 'nacl/loader/nonsfi/nonsfi_sandbox_sigsys_unittest.cc', + 'nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc', ], 'dependencies': [ 'nacl_linux',
diff --git a/components/password_manager/core/browser/affiliation_utils.cc b/components/password_manager/core/browser/affiliation_utils.cc index 23de0888..4f57b861 100644 --- a/components/password_manager/core/browser/affiliation_utils.cc +++ b/components/password_manager/core/browser/affiliation_utils.cc
@@ -8,8 +8,11 @@ #include <ostream> #include "base/base64.h" +#include "base/command_line.h" +#include "base/metrics/field_trial.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" +#include "components/password_manager/core/common/password_manager_switches.h" #include "net/base/escape.h" #include "url/third_party/mozilla/url_parse.h" #include "url/url_canon_stdstring.h" @@ -285,4 +288,17 @@ return std::equal(a_sorted.begin(), a_sorted.end(), b_sorted.begin()); } +bool IsAffiliationBasedMatchingEnabled(const base::CommandLine& command_line) { + // Note: It is important to always query the field trial state, to ensure that + // UMA reports the correct group. + const std::string group_name = + base::FieldTrialList::FindFullName("AffiliationBasedMatching"); + + if (command_line.HasSwitch(switches::kDisableAffiliationBasedMatching)) + return false; + if (command_line.HasSwitch(switches::kEnableAffiliationBasedMatching)) + return true; + return StartsWithASCII(group_name, "Enabled", /*case_sensitive=*/false); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/affiliation_utils.h b/components/password_manager/core/browser/affiliation_utils.h index 5a25b53e..8054346 100644 --- a/components/password_manager/core/browser/affiliation_utils.h +++ b/components/password_manager/core/browser/affiliation_utils.h
@@ -53,6 +53,10 @@ #include "base/time/time.h" #include "url/url_parse.h" +namespace base { +class CommandLine; +} // namespace base + namespace password_manager { // Encapsulates a facet URI in canonical form. @@ -161,6 +165,11 @@ bool AreEquivalenceClassesEqual(const AffiliatedFacets& a, const AffiliatedFacets& b); +// Returns whether or not affiliation based matching is enabled, either via +// command line flags or field trials. The command line flag, if present, always +// takes precedence. +bool IsAffiliationBasedMatchingEnabled(const base::CommandLine& command_line); + // For logging use only. std::ostream& operator<<(std::ostream& os, const FacetURI& facet_uri);
diff --git a/components/password_manager/core/browser/affiliation_utils_unittest.cc b/components/password_manager/core/browser/affiliation_utils_unittest.cc index 540963d..c67ac8be 100644 --- a/components/password_manager/core/browser/affiliation_utils_unittest.cc +++ b/components/password_manager/core/browser/affiliation_utils_unittest.cc
@@ -4,6 +4,9 @@ #include "components/password_manager/core/browser/affiliation_utils.h" +#include "base/command_line.h" +#include "base/metrics/field_trial.h" +#include "components/password_manager/core/common/password_manager_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/url_constants.h" @@ -192,4 +195,44 @@ EXPECT_FALSE(AreEquivalenceClassesEqual(c, b)); } +TEST(AffiliationUtilsTest, IsAffiliationBasedMatchingEnabled) { + const char kFieldTrialName[] = "AffiliationBasedMatching"; + + struct { + const char* field_trial_group; + const char* command_line_switch; + bool expected_enabled; + } kTestCases[] = { + {"", "", false}, + {"", switches::kEnableAffiliationBasedMatching, true}, + {"", switches::kDisableAffiliationBasedMatching, false}, + {"garbage value", "", false}, + {"disabled", "", false}, + {"disabled2", "", false}, + {"Disabled", "", false}, + {"Disabled", switches::kDisableAffiliationBasedMatching, false}, + {"Disabled", switches::kEnableAffiliationBasedMatching, true}, + {"enabled", "", true}, + {"enabled2", "", true}, + {"Enabled", "", true}, + {"Enabled", switches::kDisableAffiliationBasedMatching, false}, + {"Enabled", switches::kEnableAffiliationBasedMatching, true}}; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(testing::Message("Command line = ") + << test_case.command_line_switch); + SCOPED_TRACE(testing::Message("Group name = ") + << test_case.field_trial_group); + + base::FieldTrialList field_trials(NULL); + base::FieldTrialList::CreateFieldTrial(kFieldTrialName, + test_case.field_trial_group); + + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitch(test_case.command_line_switch); + EXPECT_EQ(test_case.expected_enabled, + IsAffiliationBasedMatchingEnabled(command_line)); + } +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc index 31cbb61..44dff2a 100644 --- a/components/password_manager/core/browser/login_database.cc +++ b/components/password_manager/core/browser/login_database.cc
@@ -27,7 +27,7 @@ namespace password_manager { -const int kCurrentVersionNumber = 10; +const int kCurrentVersionNumber = 11; static const int kCompatibleVersionNumber = 1; Pickle SerializeVector(const std::vector<base::string16>& vec) { @@ -74,7 +74,7 @@ COLUMN_DISPLAY_NAME, COLUMN_AVATAR_URL, COLUMN_FEDERATION_URL, - COLUMN_IS_ZERO_CLICK, + COLUMN_SKIP_ZERO_CLICK, }; void BindAddStatement(const PasswordForm& form, @@ -109,7 +109,7 @@ s->BindString16(COLUMN_DISPLAY_NAME, form.display_name); s->BindString(COLUMN_AVATAR_URL, form.avatar_url.spec()); s->BindString(COLUMN_FEDERATION_URL, form.federation_url.spec()); - s->BindInt(COLUMN_IS_ZERO_CLICK, form.is_zero_click); + s->BindInt(COLUMN_SKIP_ZERO_CLICK, form.skip_zero_click); } void AddCallback(int err, sql::Statement* /*stmt*/) { @@ -150,6 +150,43 @@ LogDynamicUMAStat(name, sample, 0, 100, 10); } +// Creates a table named |table_name| using our current schema. +bool CreateNewTable(sql::Connection* db, const char* table_name) { + std::string query = base::StringPrintf( + "CREATE TABLE %s (" + "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," + "password_type INTEGER," + "possible_usernames BLOB," + "times_used INTEGER," + "form_data BLOB," + "date_synced INTEGER," + "display_name VARCHAR," + "avatar_url VARCHAR," + "federation_url VARCHAR," + "skip_zero_click INTEGER," + "UNIQUE (origin_url, username_element, username_value, " + "password_element, signon_realm))", table_name); + return db->Execute(query.c_str()); +} + +bool CreateIndexOnSignonRealm(sql::Connection* db, const char* table_name) { + std::string query = base::StringPrintf( + "CREATE INDEX logins_signon ON %s (signon_realm)", table_name); + return db->Execute(query.c_str()); +} + } // namespace LoginDatabase::LoginDatabase(const base::FilePath& db_path) @@ -300,11 +337,30 @@ ("CREATE TABLE logins(" + fields_to_copy + ")").c_str()) || !db_.Execute(copy_data_query("logins_data", "logins").c_str()) || !db_.Execute("DROP TABLE logins_data") || - !db_.Execute("CREATE INDEX logins_signon ON logins (signon_realm)")) + !CreateIndexOnSignonRealm(&db_, "logins")) return false; meta_table_.SetVersionNumber(10); } + case 10: { + // rename is_zero_click -> skip_zero_click and restore the unique key + // (origin_url, username_element, username_value, password_element, + // signon_realm). + const char copy_query[] = "INSERT OR REPLACE INTO logins_new SELECT " + "origin_url, action_url, username_element, username_value, " + "password_element, password_value, submit_element, signon_realm, " + "ssl_valid, preferred, date_created, blacklisted_by_user, scheme, " + "password_type, possible_usernames, times_used, form_data, " + "date_synced, display_name, avatar_url, federation_url, is_zero_click" + " FROM logins"; + if (!CreateNewTable(&db_, "logins_new") || + !db_.Execute(copy_query) || + !db_.Execute("DROP TABLE logins") || + !db_.Execute("ALTER TABLE logins_new RENAME TO logins") || + !CreateIndexOnSignonRealm(&db_, "logins")) + return false; + meta_table_.SetVersionNumber(11); + } case kCurrentVersionNumber: // Already up to date return true; @@ -316,39 +372,11 @@ bool LoginDatabase::InitLoginsTable() { if (!db_.DoesTableExist("logins")) { - if (!db_.Execute( - "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," - "password_type INTEGER," - "possible_usernames BLOB," - "times_used INTEGER," - "form_data BLOB," - "date_synced INTEGER," - "display_name VARCHAR," - "avatar_url VARCHAR," - "federation_url VARCHAR," - "is_zero_click INTEGER," - "UNIQUE " - "(origin_url, username_element, " - "username_value, password_element, " - "submit_element, signon_realm))")) { + if (!CreateNewTable(&db_, "logins")) { NOTREACHED(); return false; } - if (!db_.Execute("CREATE INDEX logins_signon ON " - "logins (signon_realm)")) { + if (!CreateIndexOnSignonRealm(&db_, "logins")) { NOTREACHED(); return false; } @@ -483,7 +511,7 @@ " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " " scheme, password_type, possible_usernames, times_used, form_data, " " date_synced, display_name, avatar_url," - " federation_url, is_zero_click) VALUES " + " federation_url, skip_zero_click) VALUES " "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); BindAddStatement(form, encrypted_password, &s); db_.set_error_callback(base::Bind(&AddCallback)); @@ -502,7 +530,7 @@ " signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " " scheme, password_type, possible_usernames, times_used, form_data, " " date_synced, display_name, avatar_url," - " federation_url, is_zero_click) VALUES " + " federation_url, skip_zero_click) VALUES " "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")); BindAddStatement(form, encrypted_password, &s); if (s.Run()) { @@ -537,7 +565,7 @@ "display_name = ?, " "avatar_url = ?, " "federation_url = ?, " - "is_zero_click = ? " + "skip_zero_click = ? " "WHERE origin_url = ? AND " "username_element = ? AND " "username_value = ? AND " @@ -560,7 +588,7 @@ s.BindString16(12, form.display_name); s.BindString(13, form.avatar_url.spec()); s.BindString(14, form.federation_url.spec()); - s.BindInt(15, form.is_zero_click); + s.BindInt(15, form.skip_zero_click); // WHERE starts here. s.BindString(16, form.origin.spec()); @@ -681,7 +709,7 @@ form->display_name = s.ColumnString16(COLUMN_DISPLAY_NAME); form->avatar_url = GURL(s.ColumnString(COLUMN_AVATAR_URL)); form->federation_url = GURL(s.ColumnString(COLUMN_FEDERATION_URL)); - form->is_zero_click = (s.ColumnInt(COLUMN_IS_ZERO_CLICK) > 0); + form->skip_zero_click = (s.ColumnInt(COLUMN_SKIP_ZERO_CLICK) > 0); return ENCRYPTION_RESULT_SUCCESS; } @@ -697,7 +725,8 @@ "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " "scheme, password_type, possible_usernames, times_used, form_data, " "date_synced, display_name, avatar_url, " - "federation_url, is_zero_click FROM logins WHERE signon_realm == ? "; + "federation_url, skip_zero_click " + "FROM logins WHERE signon_realm == ? "; sql::Statement s; const GURL signon_realm(form.signon_realm); std::string registered_domain = GetRegistryControlledDomain(signon_realm); @@ -794,7 +823,7 @@ "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " "scheme, password_type, possible_usernames, times_used, form_data, " "date_synced, display_name, avatar_url, " - "federation_url, is_zero_click FROM logins " + "federation_url, skip_zero_click FROM logins " "WHERE date_created >= ? AND date_created < ?" "ORDER BY origin_url")); s.BindInt64(0, begin.ToInternalValue()); @@ -826,7 +855,7 @@ "ssl_valid, preferred, date_created, blacklisted_by_user, " "scheme, password_type, possible_usernames, times_used, form_data, " "date_synced, display_name, avatar_url, " - "federation_url, is_zero_click FROM logins " + "federation_url, skip_zero_click FROM logins " "WHERE date_synced >= ? AND date_synced < ?" "ORDER BY origin_url")); s.BindInt64(0, begin.ToInternalValue()); @@ -870,7 +899,7 @@ "signon_realm, ssl_valid, preferred, date_created, blacklisted_by_user, " "scheme, password_type, possible_usernames, times_used, form_data, " "date_synced, display_name, avatar_url, " - "federation_url, is_zero_click FROM logins " + "federation_url, skip_zero_click FROM logins " "WHERE blacklisted_by_user == ? ORDER BY origin_url")); s.BindInt(0, blacklisted ? 1 : 0);
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc index 97c566c..e9b87329 100644 --- a/components/password_manager/core/browser/login_database_unittest.cc +++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -11,6 +11,7 @@ #include "base/memory/scoped_vector.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" #include "base/time/time.h" @@ -65,7 +66,7 @@ form->display_name = ASCIIToUTF16("Mr. Smith"); form->avatar_url = GURL("https://accounts.google.com/Avatar"); form->federation_url = GURL("https://accounts.google.com/federation"); - form->is_zero_click = true; + form->skip_zero_click = true; } } // namespace @@ -617,7 +618,7 @@ form.display_name = ASCIIToUTF16(unique_string); form.avatar_url = GURL("https://accounts.google.com/Avatar"); form.federation_url = GURL("https://accounts.google.com/federation"); - form.is_zero_click = true; + form.skip_zero_click = true; if (date_is_creation) form.date_created = time; @@ -741,7 +742,7 @@ form.display_name = ASCIIToUTF16("Mr. Smith"); form.avatar_url = GURL("https://accounts.google.com/Avatar"); form.federation_url = GURL("https://accounts.google.com/federation"); - form.is_zero_click = true; + form.skip_zero_click = true; EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); // Get all non-blacklisted logins (should be none). @@ -980,7 +981,7 @@ form.display_name = ASCIIToUTF16("Mr. Smith"); form.avatar_url = GURL("https://accounts.google.com/Avatar"); form.federation_url = GURL("https://accounts.google.com/federation"); - form.is_zero_click = true; + form.skip_zero_click = true; EXPECT_EQ(UpdateChangeForForm(form), db().UpdateLogin(form)); ScopedVector<autofill::PasswordForm> result; @@ -1116,7 +1117,8 @@ } #endif // defined(OS_POSIX) -class LoginDatabaseMigrationTest : public testing::Test { +// Test the migration from GetParam() version to kCurrentVersionNumber. +class LoginDatabaseMigrationTest : public testing::TestWithParam<int> { protected: void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); @@ -1127,12 +1129,12 @@ database_path_ = temp_dir_.path().AppendASCII("test.db"); } - // Creates database of specific |version|. - void CreateDatabase(std::string version) { + // Creates the databse from |sql_file|. + void CreateDatabase(base::StringPiece sql_file) { base::FilePath database_dump; - PathService::Get(base::DIR_SOURCE_ROOT, &database_dump); - database_dump = database_dump.Append(database_dump_location_) - .AppendASCII("login_db_v" + version + ".sql"); + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &database_dump)); + database_dump = + database_dump.Append(database_dump_location_).AppendASCII(sql_file); ASSERT_TRUE( sql::test::CreateDatabaseFromSQL(database_path_, database_dump)); } @@ -1152,8 +1154,8 @@ return results; sql::Statement s(db.GetCachedStatement( - SQL_FROM_HERE, - "SELECT date_created from logins order by username_value")); + SQL_FROM_HERE, "SELECT date_created FROM logins " + "ORDER BY username_value, date_created DESC")); if (!s.is_valid()) { db.Close(); return results; @@ -1167,6 +1169,12 @@ return results; } + // Returns the database version for the test. + int version() const { return GetParam(); } + + // Actual test body. + void MigrationToVCurrent(base::StringPiece sql_file); + base::FilePath database_path_; private: @@ -1174,63 +1182,85 @@ base::ScopedTempDir temp_dir_; }; -// Tests the migration of the login database from version 1 to version -// kCurrentVersionNumber. This test will fail when kCurrentVersionNumber -// will be changed to 10, because file login_db_v10.sql doesn't exist. -// It has to be added in order to fix test. -TEST_F(LoginDatabaseMigrationTest, MigrationV1ToVCurrent) { - std::vector<std::string> versions; - for (int version = 1; version < kCurrentVersionNumber; ++version) - versions.push_back(base::IntToString(version)); - versions.push_back("9_without_use_additional_auth_field"); +void LoginDatabaseMigrationTest::MigrationToVCurrent( + base::StringPiece sql_file) { + SCOPED_TRACE(testing::Message("Version file = ") << sql_file); + CreateDatabase(sql_file); + // Original date, in seconds since UTC epoch. + std::vector<int64_t> date_created(GetDateCreated()); + ASSERT_EQ(2U, date_created.size()); + // Migration to version 8 performs changes dates to the new format. + // So for versions less of equal to 8 create date should be in old + // format before migration and in new format after. + if (version() <= 8) { + ASSERT_EQ(1402955745, date_created[0]); + ASSERT_EQ(1402950000, date_created[1]); + } else { + ASSERT_EQ(13047429345000000, date_created[0]); + ASSERT_EQ(13047423600000000, date_created[1]); + } - for (const auto& version : versions) { - CreateDatabase(version); - SCOPED_TRACE(testing::Message("Version = ") << version); - // Original date, in seconds since UTC epoch. - std::vector<int64_t> date_created(GetDateCreated()); - int table_version; - base::StringToInt(version, &table_version); - // Migration to version 8 performs changes dates to the new format. - // So for versions less of equal to 8 create date should be in old - // format before migration and in new format after. - if (table_version <= 8) { - ASSERT_EQ(1402955745, date_created[0]); - ASSERT_EQ(1402950000, date_created[1]); - } else { - ASSERT_EQ(13047429345000000, date_created[0]); - ASSERT_EQ(13047423600000000, date_created[1]); - } + { + // Assert that the database was successfully opened and updated + // to current version. + LoginDatabase db(database_path_); + ASSERT_TRUE(db.Init()); + // Verifies that the final version can save all the appropriate fields. + PasswordForm form; + GenerateExamplePasswordForm(&form); + // Add the same form twice to test the constraints in the database. + EXPECT_EQ(AddChangeForForm(form), db.AddLogin(form)); + PasswordStoreChangeList list; + list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); + list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); + EXPECT_EQ(list, db.AddLogin(form)); - { - // Assert that the database was successfully opened and updated - // to current version. - LoginDatabase db(database_path_); - ASSERT_TRUE(db.Init()); - // Verifies that the final version can save all the appropriate fields. - ScopedVector<autofill::PasswordForm> result; - PasswordForm form; - GenerateExamplePasswordForm(&form); - db.AddLogin(form); - EXPECT_TRUE(db.GetLogins(form, &result)); - ASSERT_EQ(1U, result.size()); - FormsAreEqual(form, *result[0]); - EXPECT_TRUE(db.RemoveLogin(form)); - result.clear(); + ScopedVector<autofill::PasswordForm> result; + EXPECT_TRUE(db.GetLogins(form, &result)); + ASSERT_EQ(1U, result.size()); + FormsAreEqual(form, *result[0]); + EXPECT_TRUE(db.RemoveLogin(form)); + } + // New date, in microseconds since platform independent epoch. + std::vector<int64_t> new_date_created(GetDateCreated()); + if (version() <= 8) { + ASSERT_EQ(2U, new_date_created.size()); + // Check that the two dates match up. + for (size_t i = 0; i < date_created.size(); ++i) { + EXPECT_EQ(base::Time::FromInternalValue(new_date_created[i]), + base::Time::FromTimeT(date_created[i])); } - // New date, in microseconds since platform independent epoch. - std::vector<int64_t> new_date_created(GetDateCreated()); + } else if (version() == 10) { + // The test data is setup on this version to cause a unique key collision. + EXPECT_EQ(1U, new_date_created.size()); + } else { + ASSERT_EQ(2U, new_date_created.size()); ASSERT_EQ(13047429345000000, new_date_created[0]); ASSERT_EQ(13047423600000000, new_date_created[1]); - if (table_version <= 8) { - // Check that the two dates match up. - for (size_t i = 0; i < date_created.size(); ++i) { - EXPECT_EQ(base::Time::FromInternalValue(new_date_created[i]), - base::Time::FromTimeT(date_created[i])); - } - } - DestroyDatabase(); } + DestroyDatabase(); } +// Tests the migration of the login database from version() to +// kCurrentVersionNumber. +TEST_P(LoginDatabaseMigrationTest, MigrationToVCurrent) { + MigrationToVCurrent(base::StringPrintf("login_db_v%d.sql", version())); +} + +class LoginDatabaseMigrationTestV9 : public LoginDatabaseMigrationTest { +}; + +// Tests migration from the alternative version #9, see crbug.com/423716. +TEST_P(LoginDatabaseMigrationTestV9, V9WithoutUseAdditionalAuthField) { + ASSERT_EQ(9, version()); + MigrationToVCurrent("login_db_v9_without_use_additional_auth_field.sql"); +} + +INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, + LoginDatabaseMigrationTest, + testing::Range(1, kCurrentVersionNumber)); +INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, + LoginDatabaseMigrationTestV9, + testing::Values(9)); + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 276090a..164db452 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -160,10 +160,15 @@ void PasswordStore::ReportMetrics(const std::string& sync_username, bool custom_passphrase_sync_enabled) { - ScheduleTask(base::Bind(&PasswordStore::ReportMetricsImpl, - this, - sync_username, - custom_passphrase_sync_enabled)); + scoped_refptr<base::SingleThreadTaskRunner> task_runner( + GetBackgroundTaskRunner()); + if (task_runner) { + base::Closure task = + base::Bind(&PasswordStore::ReportMetricsImpl, this, sync_username, + custom_passphrase_sync_enabled); + task_runner->PostDelayedTask(FROM_HERE, task, + base::TimeDelta::FromSeconds(30)); + } } void PasswordStore::AddObserver(Observer* observer) {
diff --git a/components/password_manager/core/common/password_manager_switches.cc b/components/password_manager/core/common/password_manager_switches.cc index 3b71d82..f230891 100644 --- a/components/password_manager/core/common/password_manager_switches.cc +++ b/components/password_manager/core/common/password_manager_switches.cc
@@ -11,6 +11,12 @@ // Force the password manager to allow sync credentials to be autofilled. const char kAllowAutofillSyncCredential[] = "allow-autofill-sync-credential"; +// Disable affiliation based matching, so that credentials stored for an Android +// application will not be considered matches for, and will not be filled into +// corresponding Web applications. +const char kDisableAffiliationBasedMatching[] = + "disable-affiliation-based-matching"; + // Disable dropping the credential used to sync passwords. const char kDisableDropSyncCredential[] = "disable-drop-sync-credential"; @@ -30,6 +36,12 @@ const char kDisallowAutofillSyncCredentialForReauth[] = "disallow-autofill-sync-credential-for-reauth"; +// Enable affiliation based matching, so that credentials stored for an Android +// application will also be considered matches for, and be filled into +// corresponding Web applications. +const char kEnableAffiliationBasedMatching[] = + "enable-affiliation-based-matching"; + // Disables the save-password prompt. Passwords are then saved automatically, // without asking the user. const char kEnableAutomaticPasswordSaving[] =
diff --git a/components/password_manager/core/common/password_manager_switches.h b/components/password_manager/core/common/password_manager_switches.h index abd8628..9b09685 100644 --- a/components/password_manager/core/common/password_manager_switches.h +++ b/components/password_manager/core/common/password_manager_switches.h
@@ -13,11 +13,13 @@ // alongside the definition of their values in the .cc file. extern const char kAllowAutofillSyncCredential[]; +extern const char kDisableAffiliationBasedMatching[]; extern const char kDisableDropSyncCredential[]; extern const char kDisableManagerForSyncSignin[]; extern const char kDisablePasswordLink[]; extern const char kDisallowAutofillSyncCredential[]; extern const char kDisallowAutofillSyncCredentialForReauth[]; +extern const char kEnableAffiliationBasedMatching[]; extern const char kEnableAutomaticPasswordSaving[]; extern const char kEnableDropSyncCredential[]; extern const char kEnableManagerForSyncSignin[];
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_client.cc b/components/policy/core/common/cloud/mock_cloud_policy_client.cc index 9a1b5a4..df3a2c1 100644 --- a/components/policy/core/common/cloud/mock_cloud_policy_client.cc +++ b/components/policy/core/common/cloud/mock_cloud_policy_client.cc
@@ -35,6 +35,11 @@ response = new enterprise_management::PolicyFetchResponse(policy); } +void MockCloudPolicyClient::SetFetchedInvalidationVersion( + int64_t fetched_invalidation_version) { + fetched_invalidation_version_ = fetched_invalidation_version; +} + void MockCloudPolicyClient::SetStatus(DeviceManagementStatus status) { status_ = status; }
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_client.h b/components/policy/core/common/cloud/mock_cloud_policy_client.h index 14aaaae..f297221 100644 --- a/components/policy/core/common/cloud/mock_cloud_policy_client.h +++ b/components/policy/core/common/cloud/mock_cloud_policy_client.h
@@ -43,6 +43,10 @@ const std::string& settings_entity_id, const enterprise_management::PolicyFetchResponse& policy); + // Inject invalidation version. + void SetFetchedInvalidationVersion( + int64_t fetched_invalidation_version); + // Sets the status field. void SetStatus(DeviceManagementStatus status);
diff --git a/components/rappor/rappor_service.cc b/components/rappor/rappor_service.cc index 5b7b7537..7fc4fce 100644 --- a/components/rappor/rappor_service.cc +++ b/components/rappor/rappor_service.cc
@@ -126,7 +126,8 @@ } } - DVLOG(1) << "RapporService may_upload=" << may_upload; + DVLOG(1) << "RapporService recording_level=" << recording_level_ + << " may_upload=" << may_upload; if (may_upload) { uploader_->Start(); } else {
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index 3103479..b39062b 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -65,6 +65,7 @@ NULL), registered_with_token_service_(false), registered_with_merge_session_helper_(false), + registered_with_content_settings_(false), is_reconcile_started_(false), first_execution_(true), are_gaia_accounts_set_(false), @@ -144,11 +145,24 @@ } void AccountReconcilor::RegisterWithContentSettings() { + VLOG(1) << "AccountReconcilor::RegisterWithContentSettings"; + // During re-auth, the reconcilor will get a callback about successful signin + // even when the profile is already connected. Avoid re-registering + // with the token service since this will DCHECK. + if (registered_with_content_settings_) + return; + client_->AddContentSettingsObserver(this); + registered_with_content_settings_ = true; } void AccountReconcilor::UnregisterWithContentSettings() { + VLOG(1) << "AccountReconcilor::UnregisterWithContentSettings"; + if (!registered_with_content_settings_) + return; + client_->RemoveContentSettingsObserver(this); + registered_with_content_settings_ = false; } void AccountReconcilor::RegisterWithTokenService() {
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h index 1b903aa1..1d7adcf 100644 --- a/components/signin/core/browser/account_reconcilor.h +++ b/components/signin/core/browser/account_reconcilor.h
@@ -193,6 +193,7 @@ scoped_ptr<GaiaAuthFetcher> gaia_fetcher_; bool registered_with_token_service_; bool registered_with_merge_session_helper_; + bool registered_with_content_settings_; // True while the reconcilor is busy checking or managing the accounts in // this profile.
diff --git a/components/test/data/data_reduction_proxy/OWNERS b/components/test/data/data_reduction_proxy/OWNERS index f74e102..a33576ac 100644 --- a/components/test/data/data_reduction_proxy/OWNERS +++ b/components/test/data/data_reduction_proxy/OWNERS
@@ -1,3 +1,4 @@ bengr@chromium.org marq@chromium.org bolian@chromium.org +sclittle@chromium.org
diff --git a/components/test/data/password_manager/login_db_v10.sql b/components/test/data/password_manager/login_db_v10.sql new file mode 100644 index 0000000..33e464c3 --- /dev/null +++ b/components/test/data/password_manager/login_db_v10.sql
@@ -0,0 +1,79 @@ +PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR); +INSERT INTO "meta" VALUES('last_compatible_version','1'); +INSERT INTO "meta" VALUES('version','9'); +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, +password_type INTEGER, +possible_usernames BLOB, +times_used INTEGER, +form_data BLOB, +date_synced INTEGER, +display_name VARCHAR, +avatar_url VARCHAR, +federation_url VARCHAR, +is_zero_click INTEGER, +UNIQUE (origin_url, username_element, username_value, password_element, submit_element, signon_realm)); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +13047429345000000, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000', /* form_data */ +0, /* date_synced */ +'', /* display_name */ +'', /* avatar_url */ +'', /* federation_url */ +0 /* is_zero_click */ +); +INSERT INTO "logins" VALUES( +'https://accounts.google.com/ServiceLogin', /* origin_url */ +'https://accounts.google.com/ServiceLoginAuth', /* action_url */ +'Email', /* username_element */ +'theerikchen', /* username_value */ +'Passwd', /* password_element */ +X'', /* password_value */ +'non-empty', /* submit_element */ +'https://accounts.google.com/', /* signon_realm */ +1, /* ssl_valid */ +1, /* preferred */ +13047423600000000, /* date_created */ +0, /* blacklisted_by_user */ +0, /* scheme */ +0, /* password_type */ +X'00000000', /* possible_usernames */ +1, /* times_used */ +X'18000000020000000000000000000000000000000000000000000000', /* form_data */ +0, /* date_synced */ +'', /* display_name */ +'', /* avatar_url */ +'', /* federation_url */ +0 /* is_zero_click */ +); +CREATE INDEX logins_signon ON logins (signon_realm); +COMMIT;
diff --git a/components/ui/zoom/BUILD.gn b/components/ui/zoom/BUILD.gn index a3958b8..8774b0d 100644 --- a/components/ui/zoom/BUILD.gn +++ b/components/ui/zoom/BUILD.gn
@@ -12,6 +12,7 @@ "zoom_controller.h", "zoom_event_manager.cc", "zoom_event_manager.h", + "zoom_event_manager_observer.h", "zoom_observer.h", ]
diff --git a/components/ui/zoom/zoom_event_manager.cc b/components/ui/zoom/zoom_event_manager.cc index 72906271..f841123 100644 --- a/components/ui/zoom/zoom_event_manager.cc +++ b/components/ui/zoom/zoom_event_manager.cc
@@ -4,6 +4,7 @@ #include "components/ui/zoom/zoom_event_manager.h" +#include "components/ui/zoom/zoom_event_manager_observer.h" #include "content/public/browser/browser_context.h" namespace { @@ -37,4 +38,19 @@ return zoom_level_changed_callbacks_.Add(callback); } +void ZoomEventManager::OnDefaultZoomLevelChanged() { + FOR_EACH_OBSERVER(ZoomEventManagerObserver, observers_, + OnDefaultZoomLevelChanged()); +} + +void ZoomEventManager::AddZoomEventManagerObserver( + ZoomEventManagerObserver* observer) { + observers_.AddObserver(observer); +} + +void ZoomEventManager::RemoveZoomEventManagerObserver( + ZoomEventManagerObserver* observer) { + observers_.RemoveObserver(observer); +} + } // namespace ui_zoom
diff --git a/components/ui/zoom/zoom_event_manager.h b/components/ui/zoom/zoom_event_manager.h index 3f0fcf0..72d335d 100644 --- a/components/ui/zoom/zoom_event_manager.h +++ b/components/ui/zoom/zoom_event_manager.h
@@ -7,6 +7,7 @@ #include "base/callback_list.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "base/supports_user_data.h" #include "content/public/browser/host_zoom_map.h" @@ -16,6 +17,8 @@ namespace ui_zoom { +class ZoomEventManagerObserver; + // This class serves as a target for event notifications from all ZoomController // objects. Classes that need to know about browser-specific zoom events (e.g. // manual-mode zoom) should subscribe here. @@ -34,9 +37,19 @@ void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change); // Add and remove zoom level changed callbacks. + // TODO(wjmaclean): Convert this callback mechanism to use + // ZoomEventManagerObserver instead. scoped_ptr<content::HostZoomMap::Subscription> AddZoomLevelChangedCallback( const content::HostZoomMap::ZoomLevelChangedCallback& callback); + // Called by ZoomLevelDelegates when changes are made to the default zoom + // level for their associated HostZoomMap. + void OnDefaultZoomLevelChanged(); + + // Add and remove observers. + void AddZoomEventManagerObserver(ZoomEventManagerObserver* observer); + void RemoveZoomEventManagerObserver(ZoomEventManagerObserver* observer); + // Get a weak ptr to be used by clients who may themselves be UserData for // the context, since the order of destruction is undefined between the client // and this class. @@ -47,6 +60,7 @@ private: base::CallbackList<void(const content::HostZoomMap::ZoomLevelChange&)> zoom_level_changed_callbacks_; + ObserverList<ZoomEventManagerObserver> observers_; base::WeakPtrFactory<ZoomEventManager> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ZoomEventManager);
diff --git a/components/ui/zoom/zoom_event_manager_observer.h b/components/ui/zoom/zoom_event_manager_observer.h new file mode 100644 index 0000000..f3afedc --- /dev/null +++ b/components/ui/zoom/zoom_event_manager_observer.h
@@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_UI_ZOOM_ZOOM_EVENT_MANAGER_OBSERVER_H_ +#define COMPONENTS_UI_ZOOM_ZOOM_EVENT_MANAGER_OBSERVER_H_ + +namespace ui_zoom { + +class ZoomEventManagerObserver { + public: + // TODO(wjmaclean): convert existing ZoomLevelChangedCallbacks to be + // observers. + virtual void OnZoomLevelChanged() {} + virtual void OnDefaultZoomLevelChanged() {} + + protected: + virtual ~ZoomEventManagerObserver() {} +}; + +} // namespace ui_zoom + +#endif // COMPONENTS_UI_ZOOM_ZOOM_EVENT_MANAGER_OBSERVER_H_
diff --git a/components/ui_zoom.gypi b/components/ui_zoom.gypi index fc3ed76..15e988d 100644 --- a/components/ui_zoom.gypi +++ b/components/ui_zoom.gypi
@@ -27,6 +27,7 @@ 'ui/zoom/zoom_controller.h', 'ui/zoom/zoom_event_manager.cc', 'ui/zoom/zoom_event_manager.h', + 'ui/zoom/zoom_event_manager_observer.h', 'ui/zoom/zoom_observer.h' ], }
diff --git a/components/user_manager.gypi b/components/user_manager.gypi index 03aba1e..dac32c3b 100644 --- a/components/user_manager.gypi +++ b/components/user_manager.gypi
@@ -62,5 +62,25 @@ 'sources': [ '<@(user_manager_chromeos_sources)' ], }], ], - }], + }, + { + # GN version: //components/user_manager:test_support + 'target_name': 'user_manager_test_support', + 'type': 'static_library', + 'conditions': [ + ['chromeos == 1', { + 'dependencies': [ + '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/base/base.gyp:test_support_base', + '<(DEPTH)/testing/gmock.gyp:gmock', + '<(DEPTH)/testing/gtest.gyp:gtest', + 'user_manager', + ], + 'sources': [ + 'user_manager/fake_user_manager.cc', + 'user_manager/fake_user_manager.h', + ], + }], + ] + },], }
diff --git a/components/user_manager/BUILD.gn b/components/user_manager/BUILD.gn index 0150e27..b0755a6 100644 --- a/components/user_manager/BUILD.gn +++ b/components/user_manager/BUILD.gn
@@ -47,3 +47,18 @@ ] } } + +source_set("test_support") { + testonly = true + if (is_chromeos) { + sources = [ + "fake_user_manager.cc", + "fake_user_manager.h", + ] + deps = [ + ":user_manager", + "//base", + "//skia", + ] + } +}
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc new file mode 100644 index 0000000..5e8d561 --- /dev/null +++ b/components/user_manager/fake_user_manager.cc
@@ -0,0 +1,273 @@ +// 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 "components/user_manager/fake_user_manager.h" + +#include "base/callback.h" +#include "base/task_runner.h" +#include "components/user_manager/user_type.h" +#include "ui/base/resource/resource_bundle.h" + +namespace { + +class FakeTaskRunner : public base::TaskRunner { + public: + bool PostDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) override { + task.Run(); + return true; + } + bool RunsTasksOnCurrentThread() const override { return true; } + + protected: + ~FakeTaskRunner() override {} +}; + +} // namespace + +namespace user_manager { + +FakeUserManager::FakeUserManager() + : UserManagerBase(new FakeTaskRunner(), new FakeTaskRunner()), + primary_user_(NULL), + owner_email_(std::string()) { +} + +FakeUserManager::~FakeUserManager() { +} + +const user_manager::User* FakeUserManager::AddUser(const std::string& email) { + user_manager::User* user = user_manager::User::CreateRegularUser(email); + users_.push_back(user); + return user; +} + +void FakeUserManager::RemoveUserFromList(const std::string& email) { + user_manager::UserList::iterator it = users_.begin(); + while (it != users_.end() && (*it)->email() != email) + ++it; + if (it != users_.end()) { + delete *it; + users_.erase(it); + } +} + +const user_manager::UserList& FakeUserManager::GetUsers() const { + return users_; +} + +user_manager::UserList FakeUserManager::GetUsersAllowedForMultiProfile() const { + user_manager::UserList result; + for (user_manager::UserList::const_iterator it = users_.begin(); + it != users_.end(); ++it) { + if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR && + !(*it)->is_logged_in()) + result.push_back(*it); + } + return result; +} + +const user_manager::UserList& FakeUserManager::GetLoggedInUsers() const { + return logged_in_users_; +} + +void FakeUserManager::UserLoggedIn(const std::string& email, + const std::string& username_hash, + bool browser_restart) { + for (user_manager::UserList::const_iterator it = users_.begin(); + it != users_.end(); ++it) { + if ((*it)->username_hash() == username_hash) { + (*it)->set_is_logged_in(true); + (*it)->set_profile_is_created(); + logged_in_users_.push_back(*it); + + if (!primary_user_) + primary_user_ = *it; + break; + } + } +} + +user_manager::User* FakeUserManager::GetActiveUserInternal() const { + if (users_.size()) { + if (!active_user_id_.empty()) { + for (user_manager::UserList::const_iterator it = users_.begin(); + it != users_.end(); ++it) { + if ((*it)->email() == active_user_id_) + return *it; + } + } + return users_[0]; + } + return NULL; +} + +const user_manager::User* FakeUserManager::GetActiveUser() const { + return GetActiveUserInternal(); +} + +user_manager::User* FakeUserManager::GetActiveUser() { + return GetActiveUserInternal(); +} + +void FakeUserManager::SwitchActiveUser(const std::string& email) { +} + +void FakeUserManager::SaveUserDisplayName(const std::string& username, + const base::string16& display_name) { + for (user_manager::UserList::iterator it = users_.begin(); it != users_.end(); + ++it) { + if ((*it)->email() == username) { + (*it)->set_display_name(display_name); + return; + } + } +} + +const user_manager::UserList& FakeUserManager::GetLRULoggedInUsers() const { + return users_; +} + +user_manager::UserList FakeUserManager::GetUnlockUsers() const { + return users_; +} + +const std::string& FakeUserManager::GetOwnerEmail() const { + return owner_email_; +} + +bool FakeUserManager::IsKnownUser(const std::string& email) const { + return true; +} + +const user_manager::User* FakeUserManager::FindUser( + const std::string& email) const { + const user_manager::UserList& users = GetUsers(); + for (user_manager::UserList::const_iterator it = users.begin(); + it != users.end(); ++it) { + if ((*it)->email() == email) + return *it; + } + return NULL; +} + +user_manager::User* FakeUserManager::FindUserAndModify( + const std::string& email) { + return NULL; +} + +const user_manager::User* FakeUserManager::GetLoggedInUser() const { + return NULL; +} + +user_manager::User* FakeUserManager::GetLoggedInUser() { + return NULL; +} + +const user_manager::User* FakeUserManager::GetPrimaryUser() const { + return primary_user_; +} + +base::string16 FakeUserManager::GetUserDisplayName( + const std::string& username) const { + return base::string16(); +} + +std::string FakeUserManager::GetUserDisplayEmail( + const std::string& username) const { + return std::string(); +} + +bool FakeUserManager::IsCurrentUserOwner() const { + return false; +} + +bool FakeUserManager::IsCurrentUserNew() const { + return false; +} + +bool FakeUserManager::IsCurrentUserNonCryptohomeDataEphemeral() const { + return false; +} + +bool FakeUserManager::CanCurrentUserLock() const { + return false; +} + +bool FakeUserManager::IsUserLoggedIn() const { + return logged_in_users_.size() > 0; +} + +bool FakeUserManager::IsLoggedInAsUserWithGaiaAccount() const { + return true; +} + +bool FakeUserManager::IsLoggedInAsPublicAccount() const { + return false; +} + +bool FakeUserManager::IsLoggedInAsGuest() const { + return false; +} + +bool FakeUserManager::IsLoggedInAsSupervisedUser() const { + return false; +} + +bool FakeUserManager::IsLoggedInAsKioskApp() const { + const user_manager::User* active_user = GetActiveUser(); + return active_user + ? active_user->GetType() == user_manager::USER_TYPE_KIOSK_APP + : false; +} + +bool FakeUserManager::IsLoggedInAsStub() const { + return false; +} + +bool FakeUserManager::IsSessionStarted() const { + return false; +} + +bool FakeUserManager::IsUserNonCryptohomeDataEphemeral( + const std::string& email) const { + return false; +} + +bool FakeUserManager::AreSupervisedUsersAllowed() const { + return true; +} + +bool FakeUserManager::AreEphemeralUsersEnabled() const { + return false; +} + +const std::string& FakeUserManager::GetApplicationLocale() const { + static const std::string default_locale("en-US"); + return default_locale; +} + +PrefService* FakeUserManager::GetLocalState() const { + return NULL; +} + +bool FakeUserManager::IsEnterpriseManaged() const { + return false; +} + +bool FakeUserManager::IsDemoApp(const std::string& user_id) const { + return false; +} + +bool FakeUserManager::IsKioskApp(const std::string& user_id) const { + return false; +} + +bool FakeUserManager::IsPublicAccountMarkedForRemoval( + const std::string& user_id) const { + return false; +} + +} // namespace user_manager
diff --git a/chrome/browser/chromeos/login/users/fake_user_manager.h b/components/user_manager/fake_user_manager.h similarity index 74% rename from chrome/browser/chromeos/login/users/fake_user_manager.h rename to components/user_manager/fake_user_manager.h index c8397d4..c71df24e 100644 --- a/chrome/browser/chromeos/login/users/fake_user_manager.h +++ b/components/user_manager/fake_user_manager.h
@@ -2,55 +2,34 @@ // 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_USERS_FAKE_USER_MANAGER_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_USERS_FAKE_USER_MANAGER_H_ +#ifndef COMPONENTS_USER_MANAGER_FAKE_USER_MANAGER_H_ +#define COMPONENTS_USER_MANAGER_FAKE_USER_MANAGER_H_ #include <map> #include <string> #include "base/memory/scoped_ptr.h" -#include "chrome/browser/chromeos/login/user_flow.h" -#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "components/user_manager/user.h" -#include "components/user_manager/user_image/user_image.h" +#include "components/user_manager/user_manager_base.h" -namespace chromeos { - -class FakeSupervisedUserManager; +namespace user_manager { // Fake user manager with a barebones implementation. Users can be added // and set as logged in, and those users can be returned. -class FakeUserManager : public ChromeUserManager { +class USER_MANAGER_EXPORT FakeUserManager : public UserManagerBase { public: FakeUserManager(); ~FakeUserManager() override; // Create and add a new user. - const user_manager::User* AddUser(const std::string& email); - - // Create and add a kiosk app user. - void AddKioskAppUser(const std::string& kiosk_app_username); - - // Create and add a public account user. - const user_manager::User* AddPublicAccountUser(const std::string& email); + virtual const user_manager::User* AddUser(const std::string& email); // Calculates the user name hash and calls UserLoggedIn to login a user. void LoginUser(const std::string& email); - // ChromeUserManager overrides. - MultiProfileUserController* GetMultiProfileUserController() override; - UserImageManager* GetUserImageManager(const std::string& user_id) override; - SupervisedUserManager* GetSupervisedUserManager() override; - void SetUserFlow(const std::string& email, UserFlow* flow) override {} - UserFlow* GetCurrentUserFlow() const override; - UserFlow* GetUserFlow(const std::string& email) const override; - void ResetUserFlow(const std::string& email) override {} - // UserManager overrides. const user_manager::UserList& GetUsers() const override; user_manager::UserList GetUsersAllowedForMultiProfile() const override; - user_manager::UserList GetUsersAllowedForSupervisedUsersCreation() - const override; const user_manager::UserList& GetLoggedInUsers() const override; // Set the user as logged in. @@ -133,33 +112,23 @@ void PublicAccountUserLoggedIn(user_manager::User* user) override {} void SupervisedUserLoggedIn(const std::string& user_id) override {} - void set_owner_email(const std::string& owner_email) { - owner_email_ = owner_email; - } - - void set_multi_profile_user_controller( - MultiProfileUserController* controller) { - multi_profile_user_controller_ = controller; - } - - private: - // We use this internal function for const-correctness. - user_manager::User* GetActiveUserInternal() const; - - scoped_ptr<FakeSupervisedUserManager> supervised_user_manager_; - user_manager::UserList user_list_; - user_manager::UserList logged_in_users_; - std::string owner_email_; + protected: user_manager::User* primary_user_; // If set this is the active user. If empty, the first created user is the // active user. std::string active_user_id_; - MultiProfileUserController* multi_profile_user_controller_; + + private: + // We use this internal function for const-correctness. + user_manager::User* GetActiveUserInternal() const; + + // stub, always empty string. + std::string owner_email_; DISALLOW_COPY_AND_ASSIGN(FakeUserManager); }; -} // namespace chromeos +} // namespace user_manager -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_USERS_FAKE_USER_MANAGER_H_ +#endif // COMPONENTS_USER_MANAGER_FAKE_USER_MANAGER_H_
diff --git a/components/user_manager/user.h b/components/user_manager/user.h index e5a45f3..684a0035 100644 --- a/components/user_manager/user.h +++ b/components/user_manager/user.h
@@ -20,7 +20,7 @@ namespace chromeos { class ChromeUserManagerImpl; class FakeLoginUtils; -class FakeUserManager; +class FakeChromeUserManager; class MockUserManager; class SupervisedUserManagerImpl; class UserAddingScreenTest; @@ -31,6 +31,7 @@ namespace user_manager { class UserManagerBase; +class FakeUserManager; // A class representing information about a previously logged in user. // Each user has a canonical email (username), returned by |email()| and @@ -169,9 +170,10 @@ friend class chromeos::UserSessionManager; // For testing: + friend class FakeUserManager; + friend class chromeos::FakeChromeUserManager; friend class chromeos::MockUserManager; friend class chromeos::FakeLoginUtils; - friend class chromeos::FakeUserManager; friend class chromeos::UserAddingScreenTest; // Do not allow anyone else to create new User instances.
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h index 4253992..1ac1a7f 100644 --- a/components/user_manager/user_manager.h +++ b/components/user_manager/user_manager.h
@@ -117,11 +117,6 @@ // has a policy that prohibits it to be part of multi-profile session. virtual UserList GetUsersAllowedForMultiProfile() const = 0; - // Returns list of users allowed for supervised user creation. - // Returns an empty list in cases when supervised user creation or adding new - // users is restricted. - virtual UserList GetUsersAllowedForSupervisedUsersCreation() const = 0; - // Returns a list of users who are currently logged in. virtual const UserList& GetLoggedInUsers() const = 0;
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h index ba7cd793..9dc1c9ab 100644 --- a/components/user_manager/user_manager_base.h +++ b/components/user_manager/user_manager_base.h
@@ -136,7 +136,7 @@ // Loads |users_| from Local State if the list has not been loaded yet. // Subsequent calls have no effect. Must be called on the UI thread. - void EnsureUsersLoaded(); + virtual void EnsureUsersLoaded(); // Handle OAuth token |status| change for |user_id|. virtual void HandleUserOAuthTokenStatusChange( @@ -260,6 +260,15 @@ // |UpdateAndCleanUpPublicAccounts|. UserList users_; + // List of all users that are logged in current session. These point to User + // instances in |users_|. Only one of them could be marked as active. + UserList logged_in_users_; + + // A list of all users that are logged in the current session. In contrast to + // |logged_in_users|, the order of this list is least recently used so that + // the active user should always be the first one in the list. + UserList lru_logged_in_users_; + private: // Stages of loading user list from preferences. Some methods can have // different behavior depending on stage. @@ -316,15 +325,6 @@ // Indicates stage of loading user from prefs. UserLoadStage user_loading_stage_; - // List of all users that are logged in current session. These point to User - // instances in |users_|. Only one of them could be marked as active. - UserList logged_in_users_; - - // A list of all users that are logged in the current session. In contrast to - // |logged_in_users|, the order of this list is least recently used so that - // the active user should always be the first one in the list. - UserList lru_logged_in_users_; - // True if SessionStarted() has been called. bool session_started_;
diff --git a/components/web_resource/web_resource_service.cc b/components/web_resource/web_resource_service.cc index 6e9c589f..40225b8c 100644 --- a/components/web_resource/web_resource_service.cc +++ b/components/web_resource/web_resource_service.cc
@@ -107,9 +107,9 @@ GURL web_resource_server = application_locale_.empty() - ? google_util::AppendGoogleLocaleParam(web_resource_server_, - application_locale_) - : web_resource_server_; + ? web_resource_server_ + : google_util::AppendGoogleLocaleParam(web_resource_server_, + application_locale_); DVLOG(1) << "WebResourceService StartFetch " << web_resource_server; url_fetcher_.reset(
diff --git a/content/app/android/child_process_service.cc b/content/app/android/child_process_service.cc index 9d46e080..93c622ef 100644 --- a/content/app/android/child_process_service.cc +++ b/content/app/android/child_process_service.cc
@@ -12,7 +12,7 @@ #include "base/android/memory_pressure_listener_android.h" #include "base/logging.h" #include "base/posix/global_descriptors.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/android/surface_texture_manager.h" #include "content/common/android/surface_texture_peer.h" #include "content/common/gpu/gpu_surface_lookup.h" @@ -188,7 +188,7 @@ } void ShutdownMainThread(JNIEnv* env, jobject obj) { - ChildThread::ShutdownThread(); + ChildThreadImpl::ShutdownThread(); } } // namespace content
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 3e794f8..8bebd15d 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -350,6 +350,7 @@ } if (is_chromeos) { + sources -= [ "device_sensors/data_fetcher_shared_memory_default.cc" ] deps += [ "//chromeos", "//chromeos:power_manager_proto",
diff --git a/content/browser/accessibility/android_granularity_movement_browsertest.cc b/content/browser/accessibility/android_granularity_movement_browsertest.cc index 975da4c..b24fa757 100644 --- a/content/browser/accessibility/android_granularity_movement_browsertest.cc +++ b/content/browser/accessibility/android_granularity_movement_browsertest.cc
@@ -33,7 +33,7 @@ class AndroidGranularityMovementBrowserTest : public ContentBrowserTest { public: AndroidGranularityMovementBrowserTest() {} - virtual ~AndroidGranularityMovementBrowserTest() {} + ~AndroidGranularityMovementBrowserTest() override {} BrowserAccessibility* LoadUrlAndGetAccessibilityRoot(const GURL& url) { NavigateToURL(shell(), GURL(url::kAboutBlankURL));
diff --git a/content/browser/accessibility/android_hit_testing_browsertest.cc b/content/browser/accessibility/android_hit_testing_browsertest.cc index f483286..12817d1 100644 --- a/content/browser/accessibility/android_hit_testing_browsertest.cc +++ b/content/browser/accessibility/android_hit_testing_browsertest.cc
@@ -32,7 +32,7 @@ class AndroidHitTestingBrowserTest : public ContentBrowserTest { public: AndroidHitTestingBrowserTest() {} - virtual ~AndroidHitTestingBrowserTest() {} + ~AndroidHitTestingBrowserTest() override {} }; IN_PROC_BROWSER_TEST_F(AndroidHitTestingBrowserTest,
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 65d805b..13402f5 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -186,43 +186,7 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { gfx::Rect bounds = GetLocation(); - - // Walk up the parent chain. Every time we encounter a Web Area, offset - // based on the scroll bars and then offset based on the origin of that - // nested web area. - BrowserAccessibility* parent = GetParentForBoundsCalculation(); - bool need_to_offset_web_area = - (GetRole() == ui::AX_ROLE_WEB_AREA || - GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); - while (parent) { - if (need_to_offset_web_area && - parent->GetLocation().width() > 0 && - parent->GetLocation().height() > 0) { - bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); - need_to_offset_web_area = false; - } - - // On some platforms, we don't want to take the root scroll offsets - // into account. - if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && - !manager()->UseRootScrollOffsetsWhenComputingBounds()) { - break; - } - - if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || - parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { - int sx = 0; - int sy = 0; - if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && - parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { - bounds.Offset(-sx, -sy); - } - need_to_offset_web_area = true; - } - parent = parent->GetParentForBoundsCalculation(); - } - - return bounds; + return ElementBoundsToLocalBounds(bounds); } gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { @@ -252,7 +216,7 @@ } start -= child_len; } - return bounds; + return ElementBoundsToLocalBounds(bounds); } int end = start + len; @@ -329,7 +293,7 @@ bounds.Union(child_overlap_rect); } - return bounds; + return ElementBoundsToLocalBounds(bounds); } gfx::Rect BrowserAccessibility::GetGlobalBoundsForRange(int start, int len) @@ -711,4 +675,44 @@ return manager_->delegate()->AccessibilityGetParentFrame(); } +gfx::Rect BrowserAccessibility::ElementBoundsToLocalBounds(gfx::Rect bounds) + const { + // Walk up the parent chain. Every time we encounter a Web Area, offset + // based on the scroll bars and then offset based on the origin of that + // nested web area. + BrowserAccessibility* parent = GetParentForBoundsCalculation(); + bool need_to_offset_web_area = + (GetRole() == ui::AX_ROLE_WEB_AREA || + GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); + while (parent) { + if (need_to_offset_web_area && + parent->GetLocation().width() > 0 && + parent->GetLocation().height() > 0) { + bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); + need_to_offset_web_area = false; + } + + // On some platforms, we don't want to take the root scroll offsets + // into account. + if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && + !manager()->UseRootScrollOffsetsWhenComputingBounds()) { + break; + } + + if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || + parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { + int sx = 0; + int sy = 0; + if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && + parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { + bounds.Offset(-sx, -sy); + } + need_to_offset_web_area = true; + } + parent = parent->GetParentForBoundsCalculation(); + } + + return bounds; +} + } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 47f19b7c..844d3cc2 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -267,6 +267,11 @@ // bounds offsets. BrowserAccessibility* GetParentForBoundsCalculation() const; + // Convert the bounding rectangle of an element (which is relative to + // its nearest scrollable ancestor) to local bounds (which are relative + // to the top of the web accessibility tree). + gfx::Rect ElementBoundsToLocalBounds(gfx::Rect bounds) const; + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); };
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h index 70579ab..8ab81a3 100644 --- a/content/browser/accessibility/browser_accessibility_android.h +++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -13,11 +13,11 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility { public: // Overrides from BrowserAccessibility. - virtual void OnDataChanged() override; - virtual bool IsNative() const override; - virtual void OnLocationChanged() override; + void OnDataChanged() override; + bool IsNative() const override; + void OnLocationChanged() override; - virtual bool PlatformIsLeaf() const override; + bool PlatformIsLeaf() const override; bool CanScrollForward() const; bool CanScrollBackward() const;
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h index 3d96d5d4..6ab9ae8 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.h +++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -41,7 +41,7 @@ BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); - virtual ~BrowserAccessibilityManagerAndroid(); + ~BrowserAccessibilityManagerAndroid() override; static ui::AXTreeUpdate GetEmptyDocument(); @@ -49,8 +49,8 @@ base::android::ScopedJavaLocalRef<jobject> content_view_core); // Implementation of BrowserAccessibilityManager. - virtual void NotifyAccessibilityEvent( - ui::AXEvent event_type, BrowserAccessibility* node) override; + void NotifyAccessibilityEvent(ui::AXEvent event_type, + BrowserAccessibility* node) override; // -------------------------------------------------------------------------- // Methods called from Java via JNI @@ -127,7 +127,7 @@ bool root_changed, const std::vector<ui::AXTreeDelegate::Change>& changes) override; - virtual bool UseRootScrollOffsetsWhenComputingBounds() override; + bool UseRootScrollOffsetsWhenComputingBounds() override; private: // This gives BrowserAccessibilityManager::Create access to the class
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index d0ca4bb..1b831615 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -798,6 +798,54 @@ static_text_accessible->GetLocalBoundsForRange(2, 2).ToString()); } +TEST(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) { + ui::AXNodeData root; + root.id = 1; + root.role = ui::AX_ROLE_ROOT_WEB_AREA; + root.AddIntAttribute(ui::AX_ATTR_SCROLL_X, 25); + root.AddIntAttribute(ui::AX_ATTR_SCROLL_Y, 50); + + ui::AXNodeData static_text; + static_text.id = 2; + static_text.SetValue("ABC"); + static_text.role = ui::AX_ROLE_STATIC_TEXT; + static_text.location = gfx::Rect(100, 100, 16, 9); + root.child_ids.push_back(2); + + ui::AXNodeData inline_text; + inline_text.id = 3; + inline_text.SetValue("ABC"); + inline_text.role = ui::AX_ROLE_INLINE_TEXT_BOX; + inline_text.location = gfx::Rect(100, 100, 16, 9); + inline_text.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, + ui::AX_TEXT_DIRECTION_LR); + std::vector<int32> character_offsets1; + character_offsets1.push_back(6); // 0 + character_offsets1.push_back(11); // 1 + character_offsets1.push_back(16); // 2 + inline_text.AddIntListAttribute( + ui::AX_ATTR_CHARACTER_OFFSETS, character_offsets1); + static_text.child_ids.push_back(3); + + scoped_ptr<BrowserAccessibilityManager> manager( + BrowserAccessibilityManager::Create( + MakeAXTreeUpdate(root, static_text, inline_text), + NULL, + new CountedBrowserAccessibilityFactory())); + + BrowserAccessibility* root_accessible = manager->GetRoot(); + BrowserAccessibility* static_text_accessible = + root_accessible->PlatformGetChild(0); + + if (manager->UseRootScrollOffsetsWhenComputingBounds()) { + EXPECT_EQ(gfx::Rect(75, 50, 16, 9).ToString(), + static_text_accessible->GetLocalBoundsForRange(0, 3).ToString()); + } else { + EXPECT_EQ(gfx::Rect(100, 100, 16, 9).ToString(), + static_text_accessible->GetLocalBoundsForRange(0, 3).ToString()); + } +} + #if defined(OS_WIN) #define MAYBE_BoundsForRangeOnParentElement \ DISABLED_BoundsForRangeOnParentElement
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc index 597b13a..5d68c2c 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -31,7 +31,8 @@ BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl() : BrowserAccessibilityState(), - accessibility_mode_(AccessibilityModeOff) { + accessibility_mode_(AccessibilityModeOff), + disable_hot_tracking_(false) { ResetAccessibilityModeValue(); #if defined(OS_WIN) // On Windows, UpdateHistograms calls some system functions with unknown
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h index 4c888437..7724916 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.h +++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -60,6 +60,18 @@ // removed. void RemoveAccessibilityMode(AccessibilityMode mode); + // Accessibility objects can have the "hot tracked" state set when + // the mouse is hovering over them, but this makes tests flaky because + // the test behaves differently when the mouse happens to be over an + // element. This is a global switch to not use the "hot tracked" state + // in a test. + void set_disable_hot_tracking_for_testing(bool disable_hot_tracking) { + disable_hot_tracking_ = disable_hot_tracking; + } + bool disable_hot_tracking_for_testing() const { + return disable_hot_tracking_; + } + private: friend class base::RefCountedThreadSafe<BrowserAccessibilityStateImpl>; friend struct DefaultSingletonTraits<BrowserAccessibilityStateImpl>; @@ -84,6 +96,8 @@ std::vector<base::Closure> histogram_callbacks_; + bool disable_hot_tracking_; + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityStateImpl); };
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index e4d2f379..a550159 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -3568,8 +3568,6 @@ ia_state |= STATE_SYSTEM_FOCUSABLE; if (HasState(ui::AX_STATE_HASPOPUP)) ia_state |= STATE_SYSTEM_HASPOPUP; - if (HasState(ui::AX_STATE_HOVERED)) - ia_state |= STATE_SYSTEM_HOTTRACKED; if (HasState(ui::AX_STATE_INDETERMINATE)) ia_state |= STATE_SYSTEM_INDETERMINATE; if (HasIntAttribute(ui::AX_ATTR_INVALID_STATE) && @@ -3607,6 +3605,16 @@ if (HasState(ui::AX_STATE_VISITED)) ia_state |= STATE_SYSTEM_TRAVERSED; + // Expose whether or not the mouse is over an element, but suppress + // this for tests because it can make the test results flaky depending + // on the position of the mouse. + BrowserAccessibilityStateImpl* accessibility_state = + BrowserAccessibilityStateImpl::GetInstance(); + if (!accessibility_state->disable_hot_tracking_for_testing()) { + if (HasState(ui::AX_STATE_HOVERED)) + ia_state |= STATE_SYSTEM_HOTTRACKED; + } + // WebKit marks everything as readonly unless it's editable text, so if it's // not readonly, mark it as editable now. The final computation of the // READONLY state for MSAA is below, after the switch.
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index c30c2bb..d09b852 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -16,6 +16,7 @@ #include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" @@ -121,6 +122,11 @@ void DumpAccessibilityTestBase::RunTest( const base::FilePath file_path, const char* file_dir) { + // Disable the "hot tracked" state (set when the mouse is hovering over + // an object) because it makes test output change based on the mouse position. + BrowserAccessibilityStateImpl::GetInstance()-> + set_disable_hot_tracking_for_testing(true); + NavigateToURL(shell(), GURL(url::kAboutBlankURL)); // Output the test path to help anyone who encounters a failure and needs
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 621d710..6f83a6f 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -267,6 +267,18 @@ RunAriaTest(FILE_PATH_LITERAL("aria-grabbed.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaGrid) { + RunAriaTest(FILE_PATH_LITERAL("aria-grid.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaGridCell) { + RunAriaTest(FILE_PATH_LITERAL("aria-gridcell.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaGroup) { + RunAriaTest(FILE_PATH_LITERAL("aria-group.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaImg) { RunAriaTest(FILE_PATH_LITERAL("aria-img.html")); } @@ -502,6 +514,10 @@ RunAriaTest(FILE_PATH_LITERAL("aria-tablist.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaTabPanel) { + RunAriaTest(FILE_PATH_LITERAL("aria-tabpanel.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaTextbox) { RunAriaTest(FILE_PATH_LITERAL("aria-textbox.html")); } @@ -563,6 +579,14 @@ RunHtmlTest(FILE_PATH_LITERAL("a-with-img.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityB) { + RunHtmlTest(FILE_PATH_LITERAL("b.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBase) { + RunHtmlTest(FILE_PATH_LITERAL("base.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBdo) { RunHtmlTest(FILE_PATH_LITERAL("bdo.html")); } @@ -783,6 +807,10 @@ RunHtmlTest(FILE_PATH_LITERAL("input-file.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputHidden) { + RunHtmlTest(FILE_PATH_LITERAL("input-hidden.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputImage) { RunHtmlTest(FILE_PATH_LITERAL("input-image.html")); } @@ -804,6 +832,10 @@ } #endif +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputPassword) { + RunHtmlTest(FILE_PATH_LITERAL("input-password.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputRadio) { RunHtmlTest(FILE_PATH_LITERAL("input-radio.html")); } @@ -825,6 +857,10 @@ RunHtmlTest(FILE_PATH_LITERAL("input-search.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilitySmall) { + RunHtmlTest(FILE_PATH_LITERAL("small.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputSubmit) { RunHtmlTest(FILE_PATH_LITERAL("input-submit.html")); }
diff --git a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc index a10959e1..1893e0d 100644 --- a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc +++ b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -47,13 +47,11 @@ root->GetStringAttribute(ui::AX_ATTR_DOC_URL) != url::kAboutBlankURL); } -// TODO(nasko): try enabling this test on more platforms once -// SitePerProcessBrowserTest.CrossSiteIframe is enabled everywhere. -// http://crbug.com/399775 -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) -#define MAYBE_CrossSiteIframeAccessibility CrossSiteIframeAccessibility -#else +// Times out on Android, not clear if it's an actual bug or just slow. +#if defined(OS_ANDROID) #define MAYBE_CrossSiteIframeAccessibility DISABLED_CrossSiteIframeAccessibility +#else +#define MAYBE_CrossSiteIframeAccessibility CrossSiteIframeAccessibility #endif IN_PROC_BROWSER_TEST_F(SitePerProcessAccessibilityBrowserTest, MAYBE_CrossSiteIframeAccessibility) {
diff --git a/content/browser/android/in_process/DEPS b/content/browser/android/in_process/DEPS index a8ba3f4c..6954b5f 100644 --- a/content/browser/android/in_process/DEPS +++ b/content/browser/android/in_process/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+cc/blink", # Required for SynchronousCompositor (in --single-process mode only). "+content/public/renderer/android", "+content/renderer",
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc index 4767b83..e3148ec 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -18,9 +18,9 @@ #include "ui/gl/gl_surface_stub.h" #include "webkit/common/gpu/context_provider_in_process.h" +using cc_blink::ContextProviderWebContext; using gpu_blink::WebGraphicsContext3DImpl; using gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl; -using webkit::gpu::ContextProviderWebContext; namespace content {
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h index a3739bdb..169381c 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -6,11 +6,11 @@ #define CONTENT_BROWSER_ANDROID_IN_PROCESS_SYNCHRONOUS_COMPOSITOR_FACTORY_IMPL_H_ #include "base/synchronization/lock.h" +#include "cc/blink/context_provider_web_context.h" #include "content/browser/android/in_process/synchronous_input_event_filter.h" #include "content/renderer/android/synchronous_compositor_factory.h" #include "content/renderer/media/android/stream_texture_factory_synchronous_impl.h" #include "gpu/command_buffer/service/in_process_command_buffer.h" -#include "webkit/common/gpu/context_provider_web_context.h" namespace gpu { class GLInProcessContext; @@ -38,10 +38,10 @@ virtual InputHandlerManagerClient* GetInputHandlerManagerClient() override; virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource( int routing_id) override; - virtual scoped_refptr<webkit::gpu::ContextProviderWebContext> - CreateOffscreenContextProvider( - const blink::WebGraphicsContext3D::Attributes& attributes, - const std::string& debug_name) override; + virtual scoped_refptr<cc_blink::ContextProviderWebContext> + CreateOffscreenContextProvider( + const blink::WebGraphicsContext3D::Attributes& attributes, + const std::string& debug_name) override; virtual scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory( int view_id) override; virtual gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl*
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 39881a0..8159b0d 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -124,7 +124,8 @@ // to the guest that initiated the drag/drop operation. This will ensure that // the guest's RVH state is reset properly. if (guest_started_drag_) - guest_started_drag_->EndSystemDrag(); + guest_started_drag_->EmbedderSystemDragEnded(); + guest_dragging_over_.reset(); ClearGuestDragStateIfApplicable(); }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 543a63c7..3c412a0 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -91,6 +91,9 @@ last_input_flags_(0), last_can_compose_inline_(true), guest_proxy_routing_id_(MSG_ROUTING_NONE), + last_drag_status_(blink::WebDragStatusUnknown), + seen_embedder_system_drag_ended_(false), + seen_embedder_drag_source_ended_at_(false), delegate_(delegate), weak_ptr_factory_(this) { DCHECK(web_contents); @@ -417,12 +420,45 @@ int screen_x, int screen_y, blink::WebDragOperation operation) { web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y, screen_x, screen_y, operation); + seen_embedder_drag_source_ended_at_ = true; + EndSystemDragIfApplicable(); } -void BrowserPluginGuest::EndSystemDrag() { - RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( - GetWebContents()->GetRenderViewHost()); - guest_rvh->DragSourceSystemDragEnded(); +void BrowserPluginGuest::EndSystemDragIfApplicable() { + // Ideally we'd want either WebDragStatusDrop or WebDragStatusLeave... + // Call guest RVH->DragSourceSystemDragEnded() correctly on the guest where + // the drag was initiated. Calling DragSourceSystemDragEnded() correctly + // means we call it in all cases and also make sure we only call it once. + // This ensures that the input state of the guest stays correct, otherwise + // it will go stale and won't accept any further input events. + // + // The strategy used here to call DragSourceSystemDragEnded() on the RVH + // is when the following conditions are met: + // a. Embedder has seen SystemDragEnded() + // b. Embedder has seen DragSourceEndedAt() + // c. The guest has seen some drag status update other than + // WebDragStatusUnknown. Note that this step should ideally be done + // differently: The guest has seen at least one of + // {WebDragStatusOver, WebDragStatusDrop}. However, if a user drags + // a source quickly outside of <webview> bounds, then the + // BrowserPluginGuest never sees any of these drag status updates, + // there we just check whether we've seen any drag status update or + // not. + if (last_drag_status_ != blink::WebDragStatusOver && + seen_embedder_drag_source_ended_at_ && seen_embedder_system_drag_ended_) { + RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( + GetWebContents()->GetRenderViewHost()); + guest_rvh->DragSourceSystemDragEnded(); + + last_drag_status_ = blink::WebDragStatusUnknown; + seen_embedder_system_drag_ended_ = false; + seen_embedder_drag_source_ended_at_ = false; + } +} + +void BrowserPluginGuest::EmbedderSystemDragEnded() { + seen_embedder_system_drag_ended_ = true; + EndSystemDragIfApplicable(); } void BrowserPluginGuest::SendQueuedMessages() { @@ -649,11 +685,12 @@ break; case blink::WebDragStatusDrop: host->DragTargetDrop(location, location, 0); - EndSystemDrag(); break; case blink::WebDragStatusUnknown: NOTREACHED(); } + last_drag_status_ = drag_status; + EndSystemDragIfApplicable(); } void BrowserPluginGuest::OnExecuteEditCommand(int browser_plugin_instance_id, @@ -830,8 +867,8 @@ #endif void BrowserPluginGuest::OnShowWidget(int route_id, - const gfx::Rect& initial_pos) { - GetWebContents()->ShowCreatedWidget(route_id, initial_pos); + const gfx::Rect& initial_rect) { + GetWebContents()->ShowCreatedWidget(route_id, initial_rect); } void BrowserPluginGuest::OnTakeFocus(bool reverse) {
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index 09417820..fd859e7 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -198,7 +198,8 @@ int screen_y, blink::WebDragOperation operation); // Called when the drag started by this guest ends at an OS-level. - void EndSystemDrag(); + void EmbedderSystemDragEnded(); + void EndSystemDragIfApplicable(); void RespondToPermissionRequest(int request_id, bool should_allow, @@ -330,7 +331,7 @@ void OnShowPopup(RenderFrameHost* render_frame_host, const FrameHostMsg_ShowPopup_Params& params); #endif - void OnShowWidget(int route_id, const gfx::Rect& initial_pos); + void OnShowWidget(int route_id, const gfx::Rect& initial_rect); void OnTakeFocus(bool reverse); void OnUpdateFrameName(int frame_id, bool is_top_level, @@ -387,6 +388,12 @@ // The is the routing ID for a swapped out RenderView for the guest // WebContents in the embedder's process. int guest_proxy_routing_id_; + // Last seen state of drag status update. + blink::WebDragStatus last_drag_status_; + // Whether or not our embedder has seen a SystemDragEnded() call. + bool seen_embedder_system_drag_ended_; + // Whether or not our embedder has seen a DragSourceEndedAt() call. + bool seen_embedder_drag_source_ended_at_; // Guests generate frames and send a CompositorFrameSwapped (CFS) message // indicating the next frame is ready to be positioned and composited.
diff --git a/content/browser/device_sensors/data_fetcher_shared_memory.h b/content/browser/device_sensors/data_fetcher_shared_memory.h index a5d1f82..a0d9828 100644 --- a/content/browser/device_sensors/data_fetcher_shared_memory.h +++ b/content/browser/device_sensors/data_fetcher_shared_memory.h
@@ -22,7 +22,9 @@ namespace content { -#if defined(OS_MACOSX) +#if defined(OS_CHROMEOS) +class SensorManagerChromeOS; +#elif defined(OS_MACOSX) class AmbientLightSensor; #endif @@ -42,7 +44,10 @@ DeviceOrientationHardwareBuffer* orientation_buffer_; DeviceLightHardwareBuffer* light_buffer_; #endif -#if defined(OS_MACOSX) + +#if defined(OS_CHROMEOS) + scoped_ptr<SensorManagerChromeOS> sensor_manager_; +#elif defined(OS_MACOSX) void Fetch(unsigned consumer_bitmask) override; FetcherType GetType() const override;
diff --git a/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc b/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.cc new file mode 100644 index 0000000..6dc0336 --- /dev/null +++ b/content/browser/device_sensors/data_fetcher_shared_memory_chromeos.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/browser/device_sensors/data_fetcher_shared_memory.h" + +#include "content/browser/device_sensors/sensor_manager_chromeos.h" + +namespace content { + +DataFetcherSharedMemory::DataFetcherSharedMemory() { +} + +DataFetcherSharedMemory::~DataFetcherSharedMemory() { +} + +bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) { + DCHECK(buffer); + if (!sensor_manager_) + sensor_manager_.reset(new SensorManagerChromeOS); + + switch (consumer_type) { + case CONSUMER_TYPE_MOTION: + // TODO(jonross): Implement Device Motion API. (crbug.com/427662) + NOTIMPLEMENTED(); + return false; + case CONSUMER_TYPE_ORIENTATION: + return sensor_manager_->StartFetchingDeviceOrientationData( + static_cast<DeviceOrientationHardwareBuffer*>(buffer)); + case CONSUMER_TYPE_LIGHT: + NOTIMPLEMENTED(); + return false; + } + NOTREACHED(); + return false; +} + +bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { + switch (consumer_type) { + case CONSUMER_TYPE_MOTION: + NOTIMPLEMENTED(); + return false; + case CONSUMER_TYPE_ORIENTATION: + return sensor_manager_->StopFetchingDeviceOrientationData(); + case CONSUMER_TYPE_LIGHT: + NOTIMPLEMENTED(); + return false; + } + NOTREACHED(); + return false; +} + +} // namespace content
diff --git a/content/browser/device_sensors/sensor_manager_android_unittest.cc b/content/browser/device_sensors/sensor_manager_android_unittest.cc index b5f0c5fb9..5ce25fb 100644 --- a/content/browser/device_sensors/sensor_manager_android_unittest.cc +++ b/content/browser/device_sensors/sensor_manager_android_unittest.cc
@@ -17,9 +17,9 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid { public: FakeSensorManagerAndroid() { } - virtual ~FakeSensorManagerAndroid() { } + ~FakeSensorManagerAndroid() override {} - virtual int GetNumberActiveDeviceMotionSensors() override { + int GetNumberActiveDeviceMotionSensors() override { return number_active_sensors_; } @@ -28,12 +28,9 @@ } protected: - virtual bool Start(EventType event_type) override { - return true; - } + bool Start(EventType event_type) override { return true; } - virtual void Stop(EventType event_type) override { - } + void Stop(EventType event_type) override {} private: int number_active_sensors_;
diff --git a/content/browser/device_sensors/sensor_manager_chromeos.cc b/content/browser/device_sensors/sensor_manager_chromeos.cc new file mode 100644 index 0000000..2952ab63 --- /dev/null +++ b/content/browser/device_sensors/sensor_manager_chromeos.cc
@@ -0,0 +1,119 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/device_sensors/sensor_manager_chromeos.h" + +#include "base/logging.h" +#include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" +#include "ui/gfx/geometry/vector3d_f.h" + +namespace { +// Conversion ratio from radians to degrees. +const double kRad2deg = 180.0 / M_PI; +} + +namespace content { + +SensorManagerChromeOS::SensorManagerChromeOS() : orientation_buffer_(nullptr) { +} + +SensorManagerChromeOS::~SensorManagerChromeOS() { +} + +bool SensorManagerChromeOS::StartFetchingDeviceOrientationData( + DeviceOrientationHardwareBuffer* buffer) { + DCHECK(buffer); + { + base::AutoLock autolock(orientation_buffer_lock_); + if (orientation_buffer_) + return false; + orientation_buffer_ = buffer; + + // No compass information, so we cannot provide absolute orientation. + orientation_buffer_->seqlock.WriteBegin(); + orientation_buffer_->data.absolute = false; + orientation_buffer_->data.hasAbsolute = true; + orientation_buffer_->seqlock.WriteEnd(); + } + + StartObservingAccelerometer(); + return true; +} + +bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() { + { + base::AutoLock autolock(orientation_buffer_lock_); + if (!orientation_buffer_) + return false; + // Make sure to indicate that the sensor data is no longer available. + orientation_buffer_->seqlock.WriteBegin(); + orientation_buffer_->data.allAvailableSensorsAreActive = false; + orientation_buffer_->seqlock.WriteEnd(); + orientation_buffer_ = nullptr; + } + + StopObservingAccelerometer(); + return true; +} + +void SensorManagerChromeOS::OnAccelerometerUpdated( + const chromeos::AccelerometerUpdate& update) { + base::AutoLock autolock(orientation_buffer_lock_); + if (!orientation_buffer_) + return; + + chromeos::AccelerometerSource source; + if (update.has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) { + source = chromeos::ACCELEROMETER_SOURCE_SCREEN; + } else if (update.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) { + source = chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD; + } else { + return; + } + + double x = update.get(source).x; + double y = update.get(source).y; + double z = update.get(source).z; + + // Create a unit vector for trigonometry + // TODO(jonross): Stop reversing signs for vector components once + // accelerometer values have been fixed. crbug.com/431391 + // Ternaries are to remove -0.0f which gives incorrect trigonometrical + // results. + gfx::Vector3dF data(x, y ? -y : 0.0f, z ? -z : 0.0f); + data.Scale(1.0f / data.Length()); + + // Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix. + // x = sin(gamma) + // y = -cos(gamma) * sin(beta) + // z = cos(beta) * cos(gamma) + // With only accelerometer alpha cannot be provided. + double beta = kRad2deg * atan2(data.y(), data.z()); + double gamma = kRad2deg * asin(data.x()); + + // Convert beta and gamma to fit the intervals in the specification. Beta is + // [-180, 180) and gamma is [-90, 90). + if (beta >= 180.0f) + beta = -180.0f; + if (gamma >= 90.0f) + gamma = -90.0f; + orientation_buffer_->seqlock.WriteBegin(); + orientation_buffer_->data.beta = beta; + orientation_buffer_->data.hasBeta = true; + orientation_buffer_->data.gamma = gamma; + orientation_buffer_->data.hasGamma = true; + orientation_buffer_->data.allAvailableSensorsAreActive = true; + orientation_buffer_->seqlock.WriteEnd(); +} + +void SensorManagerChromeOS::StartObservingAccelerometer() { + chromeos::AccelerometerReader::GetInstance()->AddObserver(this); +} + +void SensorManagerChromeOS::StopObservingAccelerometer() { + chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this); +} + +} // namespace content
diff --git a/content/browser/device_sensors/sensor_manager_chromeos.h b/content/browser/device_sensors/sensor_manager_chromeos.h new file mode 100644 index 0000000..faeabeb7 --- /dev/null +++ b/content/browser/device_sensors/sensor_manager_chromeos.h
@@ -0,0 +1,55 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_ +#define CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_ + +#include "base/macros.h" +#include "base/synchronization/lock.h" +#include "chromeos/accelerometer/accelerometer_reader.h" +#include "chromeos/accelerometer/accelerometer_types.h" +#include "content/common/content_export.h" +#include "content/common/device_sensors/device_orientation_hardware_buffer.h" + +namespace content { + +// Observes Chrome OS accelerometer sensors, and provides updated device +// orientation information. +class CONTENT_EXPORT SensorManagerChromeOS + : public chromeos::AccelerometerReader::Observer { + public: + SensorManagerChromeOS(); + ~SensorManagerChromeOS() override; + + // Begins monitoring of orientation events, the shared memory of |buffer| will + // be updated upon subsequent events. + bool StartFetchingDeviceOrientationData( + DeviceOrientationHardwareBuffer* buffer); + + // Stops monitoring orientation events. Returns true if there is an active + // |orientation_buffer_| and fetching stops. Otherwise returns false. + bool StopFetchingDeviceOrientationData(); + + // chromeos::AccelerometerReader::Observer: + void OnAccelerometerUpdated( + const chromeos::AccelerometerUpdate& update) override; + + protected: + // Begins/ends the observation of accelerometer events. + virtual void StartObservingAccelerometer(); + virtual void StopObservingAccelerometer(); + + private: + // Shared memory to update. + DeviceOrientationHardwareBuffer* orientation_buffer_; + + // Synchronize orientation_buffer_ across threads. + base::Lock orientation_buffer_lock_; + + DISALLOW_COPY_AND_ASSIGN(SensorManagerChromeOS); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_
diff --git a/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc b/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc new file mode 100644 index 0000000..3e71839 --- /dev/null +++ b/content/browser/device_sensors/sensor_manager_chromeos_unittest.cc
@@ -0,0 +1,151 @@ +// 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/device_sensors/sensor_manager_chromeos.h" + +#include "base/memory/scoped_ptr.h" +#include "chromeos/accelerometer/accelerometer_types.h" +#include "content/common/device_sensors/device_orientation_hardware_buffer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const double kMeanGravity = 9.80665; + +// Isolated content::SensorManagerChromeOS from the active +// chromeos::AccelerometerReader. This allows for direct control over which +// accelerometer events are provided to the sensor manager. +class TestSensorManagerChromeOS : public content::SensorManagerChromeOS { + public: + TestSensorManagerChromeOS() {} + ~TestSensorManagerChromeOS() override {}; + + protected: + void StartObservingAccelerometer() override {} + void StopObservingAccelerometer() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(TestSensorManagerChromeOS); +}; + +} // namespace + +namespace content { + +class SensorManagerChromeOSTest : public testing::Test { + public: + SensorManagerChromeOSTest() { + orientation_buffer_.reset(new DeviceOrientationHardwareBuffer); + } + + ~SensorManagerChromeOSTest() override {} + + void OnAccelerationIncludingGravity(double x, double y, double z) { + chromeos::AccelerometerUpdate update; + update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, x, y, z); + sensor_manager_->OnAccelerometerUpdated(update); + } + + DeviceOrientationHardwareBuffer* orientation_buffer() { + return orientation_buffer_.get(); + } + + SensorManagerChromeOS* sensor_manager() { return sensor_manager_.get(); } + + // testing::Test: + void SetUp() override { + testing::Test::SetUp(); + sensor_manager_.reset(new TestSensorManagerChromeOS); + sensor_manager_->StartFetchingDeviceOrientationData( + orientation_buffer_.get()); + } + + void TearDown() override { + sensor_manager_->StopFetchingDeviceOrientationData(); + testing::Test::TearDown(); + } + + private: + scoped_ptr<TestSensorManagerChromeOS> sensor_manager_; + + scoped_ptr<DeviceOrientationHardwareBuffer> orientation_buffer_; + + DISALLOW_COPY_AND_ASSIGN(SensorManagerChromeOSTest); +}; + +// Tests that starting to process orientation data will update the associated +// buffer. +TEST_F(SensorManagerChromeOSTest, OrientationBuffer) { + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_TRUE(buffer->data.hasAbsolute); + EXPECT_FALSE(buffer->data.hasAlpha); + EXPECT_FALSE(buffer->data.hasBeta); + EXPECT_FALSE(buffer->data.hasGamma); + EXPECT_FALSE(buffer->data.allAvailableSensorsAreActive); + + OnAccelerationIncludingGravity(0.0f, 0.0f, 1.0f); + EXPECT_FLOAT_EQ(0.0f, buffer->data.alpha); + EXPECT_FALSE(buffer->data.hasAlpha); + EXPECT_TRUE(buffer->data.hasBeta); + EXPECT_TRUE(buffer->data.hasGamma); + EXPECT_TRUE(buffer->data.allAvailableSensorsAreActive); + + sensor_manager()->StopFetchingDeviceOrientationData(); + EXPECT_FALSE(buffer->data.allAvailableSensorsAreActive); +} + +// Tests a device resting flat. +TEST_F(SensorManagerChromeOSTest, NeutralOrientation) { + OnAccelerationIncludingGravity(0.0f, 0.0f, -kMeanGravity); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(0.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma); +} + +// Tests an upside-down device, such that the W3C boundary [-180,180) causes the +// beta value to become negative. +TEST_F(SensorManagerChromeOSTest, UpsideDown) { + OnAccelerationIncludingGravity(0.0f, 0.0f, kMeanGravity); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(-180.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma); +} + +// Tests for positive beta value before the device is completely upside-down +TEST_F(SensorManagerChromeOSTest, BeforeUpsideDownBoundary) { + OnAccelerationIncludingGravity(0.0f, -kMeanGravity / 2.0f, + kMeanGravity / 2.0f); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(135.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma); +} + +// Tests a device lying on its left-edge. +TEST_F(SensorManagerChromeOSTest, LeftEdge) { + OnAccelerationIncludingGravity(-kMeanGravity, 0.0f, 0.0f); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(0.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(-90.0f, buffer->data.gamma); +} + +// Tests a device lying on its right-edge, such that the W3C boundary [-90,90) +// causes the gamma value to become negative. +TEST_F(SensorManagerChromeOSTest, RightEdge) { + OnAccelerationIncludingGravity(kMeanGravity, 0.0f, 0.0f); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(0.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(-90.0f, buffer->data.gamma); +} + +// Tests for positive gamma value before the device is completely on its right +// side. +TEST_F(SensorManagerChromeOSTest, BeforeRightEdgeBoundary) { + OnAccelerationIncludingGravity(kMeanGravity / 2.0f, 0.0f, + -kMeanGravity / 2.0f); + DeviceOrientationHardwareBuffer* buffer = orientation_buffer(); + EXPECT_FLOAT_EQ(0.0f, buffer->data.beta); + EXPECT_FLOAT_EQ(45.0f, buffer->data.gamma); +} + +} // namespace content
diff --git a/content/browser/frame_host/frame_accessibility.cc b/content/browser/frame_host/frame_accessibility.cc index c0e86b29..39b1e0e6 100644 --- a/content/browser/frame_host/frame_accessibility.cc +++ b/content/browser/frame_host/frame_accessibility.cc
@@ -161,9 +161,15 @@ FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); if (child_node && child_node->current_frame_host() == child_frame_host) { - // We should have gotten a *direct* child of the parent frame. - if (child_node->parent() != - iter->parent_frame_host->frame_tree_node()) { + // Assert that the child node is a descendant of the parent frame in + // the frame tree. It may not be a direct descendant because the + // parent frame's accessibility tree may span multiple frames from the + // same origin. + FrameTreeNode* parent_node = iter->parent_frame_host->frame_tree_node(); + FrameTreeNode* child_node_ancestor = child_node->parent(); + while (child_node_ancestor && child_node_ancestor != parent_node) + child_node_ancestor = child_node_ancestor->parent(); + if (child_node_ancestor != parent_node) { NOTREACHED(); return false; } @@ -201,8 +207,15 @@ if (!child_node) return nullptr; - // We should have gotten a *direct* child of the parent frame. - if (child_node->parent() != parent_frame_host->frame_tree_node()) { + // Assert that the child node is a descendant of the parent frame in + // the frame tree. It may not be a direct descendant because the + // parent frame's accessibility tree may span multiple frames from the + // same origin. + FrameTreeNode* parent_node = parent_frame_host->frame_tree_node(); + FrameTreeNode* child_node_ancestor = child_node->parent(); + while (child_node_ancestor && child_node_ancestor != parent_node) + child_node_ancestor = child_node_ancestor->parent(); + if (child_node_ancestor != parent_node) { NOTREACHED(); return nullptr; }
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc index 96890f0..af15b99 100644 --- a/content/browser/frame_host/frame_tree.cc +++ b/content/browser/frame_host/frame_tree.cc
@@ -208,6 +208,9 @@ root()->render_manager()->CreateRenderFrame( site_instance, nullptr, MSG_ROUTING_NONE, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr); + } else { + root()->render_manager()->EnsureRenderViewInitialized( + source, render_view_host, site_instance); } }
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index 57cd7fd..c59075c5 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -740,13 +740,13 @@ void InterstitialPageImpl::ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { NOTREACHED() << "InterstitialPage does not support showing popups yet."; } void InterstitialPageImpl::ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) { + const gfx::Rect& initial_rect) { NOTREACHED() << "InterstitialPage does not support showing drop-downs yet."; }
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h index 9a99b47..ae41f77 100644 --- a/content/browser/frame_host/interstitial_page_impl.h +++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -130,9 +130,9 @@ void CreateNewFullscreenWidget(int render_process_id, int route_id) override; void ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; - void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos) override; + void ShowCreatedWidget(int route_id, const gfx::Rect& initial_rect) override; void ShowCreatedFullscreenWidget(int route_id) override; SessionStorageNamespace* GetSessionStorageNamespace(
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 3eca788..d9bdc38c 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -4,17 +4,29 @@ #include "base/bind.h" #include "base/strings/stringprintf.h" +#include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/navigation_controller_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" +#include "content/test/content_browser_test_utils_internal.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace content { class NavigationControllerBrowserTest : public ContentBrowserTest { + protected: + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + } }; IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, LoadDataWithBaseURL) { @@ -76,5 +88,111 @@ controller.GetLastCommittedEntry()->GetURL()); } -} // namespace content +struct FrameNavigateParamsCapturer : public WebContentsObserver { + public: + explicit FrameNavigateParamsCapturer(FrameTreeNode* node) + : WebContentsObserver( + node->current_frame_host()->delegate()->GetAsWebContents()), + frame_tree_node_id_(node->frame_tree_node_id()), + message_loop_runner_(new MessageLoopRunner) {} + void Wait() { + message_loop_runner_->Run(); + } + + const FrameNavigateParams& params() const { + return params_; + } + + const LoadCommittedDetails& details() const { + return details_; + } + + private: + void DidNavigateAnyFrame(RenderFrameHost* render_frame_host, + const LoadCommittedDetails& details, + const FrameNavigateParams& params) override { + RenderFrameHostImpl* rfh = + static_cast<RenderFrameHostImpl*>(render_frame_host); + if (rfh->frame_tree_node()->frame_tree_node_id() != frame_tree_node_id_) + return; + + params_ = params; + details_ = details; + message_loop_runner_->Quit(); + } + + // The id of the FrameTreeNode whose navigations to observe. + int frame_tree_node_id_; + + // The params of the last navigation. + FrameNavigateParams params_; + + // The details of the last navigation. + LoadCommittedDetails details_; + + // The MessageLoopRunner used to spin the message loop. + scoped_refptr<MessageLoopRunner> message_loop_runner_; +}; + +// Verify that the distinction between manual and auto subframes is properly set +// for subframe navigations. TODO(avi): It's rather bogus that the same info is +// in two different enums; http://crbug.com/453555. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + ManualAndAutoSubframeNavigationClassification) { + GURL main_url( + embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html")); + NavigateToURL(shell(), main_url); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = + static_cast<WebContentsImpl*>(shell()->web_contents())-> + GetFrameTree()->root(); + + ASSERT_EQ(1U, root->child_count()); + ASSERT_NE(nullptr, root->child_at(0)); + + { + // Navigate the iframe to a new URL; expect a manual subframe transition. + FrameNavigateParamsCapturer capturer(root->child_at(0)); + GURL frame_url( + embedded_test_server()->GetURL("/frame_tree/2-1.html")); + NavigateFrameToURL(root->child_at(0), frame_url); + capturer.Wait(); + EXPECT_EQ(ui::PAGE_TRANSITION_MANUAL_SUBFRAME, + capturer.params().transition); + EXPECT_EQ(NAVIGATION_TYPE_NEW_SUBFRAME, capturer.details().type); + } + + { + // History navigations should result in an auto subframe transition. + FrameNavigateParamsCapturer capturer(root->child_at(0)); + shell()->web_contents()->GetController().GoBack(); + capturer.Wait(); + EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition); + EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type); + } + + { + // History navigations should result in an auto subframe transition. + FrameNavigateParamsCapturer capturer(root->child_at(0)); + shell()->web_contents()->GetController().GoForward(); + capturer.Wait(); + EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition); + EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type); + } + + { + // Navigate the iframe to a new URL; expect a manual subframe transition. + FrameNavigateParamsCapturer capturer(root->child_at(0)); + GURL frame_url( + embedded_test_server()->GetURL("/frame_tree/2-3.html")); + NavigateFrameToURL(root->child_at(0), frame_url); + capturer.Wait(); + EXPECT_EQ(ui::PAGE_TRANSITION_MANUAL_SUBFRAME, + capturer.params().transition); + EXPECT_EQ(NAVIGATION_TYPE_NEW_SUBFRAME, capturer.details().type); + } +} + +} // namespace content
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 34647b9..f359f51 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -108,7 +108,12 @@ DCHECK(state_ == STARTED); state_ = FAILED; // TODO(davidben): Network failures should display a network error page. - NOTIMPLEMENTED(); + NOTIMPLEMENTED() << " where net_error=" << net_error; +} + +void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) { + frame_tree_node_->navigator()->LogResourceRequestTime(timestamp, + common_params_.url); } } // namespace content
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 649e6288..8e1d303 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -110,6 +110,7 @@ void OnResponseStarted(const scoped_refptr<ResourceResponse>& response, scoped_ptr<StreamHandle> body) override; void OnRequestFailed(int net_error) override; + void OnRequestStarted(base::TimeTicks timestamp) override; FrameTreeNode* frame_tree_node_;
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index 191a5836..e56335a 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -138,8 +138,12 @@ // |frame_tree_node| is destroyed. virtual void CancelNavigation(FrameTreeNode* frame_tree_node) {} - // Called when the first resource request for a given navigation is executed - // so that it can be tracked into an histogram. + // Called when the network stack started handling the navigation request + // so that the |timestamp| when it happened can be recorded into an histogram. + // The |url| is used to verify we're tracking the correct navigation. + // TODO(carlosk): once PlzNavigate is the only navigation implementation + // remove the URL parameter and rename this method to better suit its naming + // conventions. virtual void LogResourceRequestTime( base::TimeTicks timestamp, const GURL& url) {};
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index ebd10e97..8617d7e6 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -504,21 +504,6 @@ bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSitePerProcess); - if (use_site_per_process) { - // TODO(creis): Until we mirror the frame tree in the subframe's process, - // cross-process subframe navigations happen in a renderer's main frame. - // Correct the transition type here if we know it is for a subframe. - NavigationEntryImpl* pending_entry = - NavigationEntryImpl::FromNavigationEntry( - controller_->GetPendingEntry()); - if (!render_frame_host->frame_tree_node()->IsMainFrame() && - pending_entry && - pending_entry->frame_tree_node_id() == - render_frame_host->frame_tree_node()->frame_tree_node_id()) { - params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME; - } - } - if (ui::PageTransitionIsMainFrame(params.transition)) { if (delegate_) { // When overscroll navigation gesture is enabled, a screenshot of the page @@ -772,6 +757,9 @@ navigation_request = scoped_request.get(); navigation_request_map_.set( frame_tree_node->frame_tree_node_id(), scoped_request.Pass()); + + if (frame_tree_node->IsMainFrame()) + navigation_data_.reset(); } DCHECK(navigation_request); @@ -833,6 +821,8 @@ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBrowserSideNavigation)); navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); + if (frame_tree_node->IsMainFrame()) + navigation_data_.reset(); // TODO(carlosk): move this cleanup into the NavigationRequest destructor once // we properly cancel ongoing navigations. frame_tree_node->render_manager()->CleanUpNavigation(); @@ -944,6 +934,7 @@ RecordAction(base::UserMetricsAction("FrameLoad")); if (!details.is_main_frame || !navigation_data_ || + navigation_data_->url_job_start_time_.is_null() || navigation_data_->url_ != params.original_request_url) { return; }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 5878180..420275f0 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -278,6 +278,8 @@ } blink::WebPageVisibilityState RenderFrameHostImpl::GetVisibilityState() { + // TODO(mlamouri,kenrb): call GetRenderWidgetHost() directly when it stops + // returning nullptr in some cases. See https://crbug.com/455245. blink::WebPageVisibilityState visibility_state = RenderWidgetHostImpl::From(GetView()->GetRenderWidgetHost())->is_hidden() ? blink::WebPageVisibilityStateHidden @@ -568,6 +570,14 @@ rwhv->Hide(); } + if (proxy_routing_id != MSG_ROUTING_NONE) { + RenderFrameProxyHost* proxy = RenderFrameProxyHost::FromID( + GetProcess()->GetID(), proxy_routing_id); + // We have also created a RenderFrameProxy in FrameMsg_NewFrame above, so + // remember that. + proxy->set_render_frame_proxy_created(true); + } + // The renderer now has a RenderFrame for this RenderFrameHost. Note that // this path is only used for out-of-process iframes. Main frame RenderFrames // are created with their RenderView, and same-site iframes are created at the @@ -1594,7 +1604,10 @@ } bool RenderFrameHostImpl::IsFocused() { - return GetView()->HasFocus() && + // TODO(mlamouri,kenrb): call GetRenderWidgetHost() directly when it stops + // returning nullptr in some cases. See https://crbug.com/455245. + return RenderWidgetHostImpl::From( + GetView()->GetRenderWidgetHost())->is_focused() && frame_tree_->GetFocusedFrame() && (frame_tree_->GetFocusedFrame() == frame_tree_node() || frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node())); @@ -1610,7 +1623,8 @@ FrameTree* frame_tree = frame_tree_node()->frame_tree(); FrameTreeNode* child_frame_tree_node = frame_tree->FindByRoutingID( - GetProcess()->GetID(), frame_routing_id); + frame_routing_id, GetProcess()->GetID()); + if (child_frame_tree_node) { FrameAccessibility::GetInstance()->AddChildFrame( this, node_id, child_frame_tree_node->frame_tree_node_id());
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index f66411d2..e7f1de5 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -408,7 +408,7 @@ // Returns whether the frame is focused. A frame is considered focused when it // is the parent chain of the focused frame within the frame tree. In - // addition, its associated RenderWidgetHostView has to be focused. + // addition, its associated RenderWidgetHost has to be focused. bool IsFocused(); protected:
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index baefe87f..4a9034b5 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -502,11 +502,22 @@ // swap them back in while the process is exiting. Start by finding them, // since there could be more than one. std::list<int> ids_to_remove; + // Do not remove proxies in the dead process that still have active frame + // count though, we just reset them to be uninitialized. + std::list<int> ids_to_keep; for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); iter != proxy_hosts_.end(); ++iter) { - if (iter->second->GetProcess() == render_process_host) + RenderFrameProxyHost* proxy = iter->second; + if (proxy->GetProcess() != render_process_host) + continue; + + if (static_cast<SiteInstanceImpl*>(proxy->GetSiteInstance()) + ->active_frame_count() >= 1U) { + ids_to_keep.push_back(iter->first); + } else { ids_to_remove.push_back(iter->first); + } } // Now delete them. @@ -515,6 +526,14 @@ proxy_hosts_.erase(ids_to_remove.back()); ids_to_remove.pop_back(); } + + while (!ids_to_keep.empty()) { + frame_tree_node_->frame_tree()->ForEach( + base::Bind( + &RenderFrameHostManager::ResetProxiesInSiteInstance, + ids_to_keep.back())); + ids_to_keep.pop_back(); + } } void RenderFrameHostManager::SwapOutOldFrame( @@ -570,6 +589,9 @@ // Tell the old RenderFrameHost to swap out and be replaced by the proxy. old_render_frame_host->SwapOut(proxy, true); + // SwapOut creates a RenderFrameProxy, so set the proxy to be initialized. + proxy->set_render_frame_proxy_created(true); + bool is_main_frame = frame_tree_node_->IsMainFrame(); if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kSitePerProcess) && @@ -694,17 +716,6 @@ CleanUpNavigation(); navigation_rfh = render_frame_host_.get(); } else { - // If the current render_frame_host_ isn't live, we should create it so - // that we don't show a sad tab while the navigation is ongoing. - // (Bug 1145340) - if (!render_frame_host_->IsRenderFrameLive()) { - // Note: we don't call InitRenderView here because we are navigating away - // soon anyway, and we don't have the NavigationEntry for this host. - delegate_->CreateRenderViewForRenderManager( - render_frame_host_->render_view_host(), MSG_ROUTING_NONE, - MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame()); - } - // If the SiteInstance for the final URL doesn't match the one from the // speculatively created RenderFrameHost, create a new RenderFrameHost using // this new SiteInstance. @@ -719,6 +730,16 @@ } DCHECK(speculative_render_frame_host_); navigation_rfh = speculative_render_frame_host_.get(); + + // Check if our current RFH is live. + if (!render_frame_host_->IsRenderFrameLive()) { + // The current RFH is not live. There's no reason to sit around with a + // sad tab or a newly created RFH while we wait for the navigation to + // complete. Just switch to the speculative RFH now and go back to non + // cross-navigating (Note that we don't care about on{before}unload + // handlers if the current RFH isn't live.) + CommitPending(); + } } DCHECK(navigation_rfh && (navigation_rfh == render_frame_host_.get() || @@ -811,6 +832,17 @@ return true; } +// static. +bool RenderFrameHostManager::ResetProxiesInSiteInstance(int32 site_instance_id, + FrameTreeNode* node) { + RenderFrameProxyHostMap::iterator iter = + node->render_manager()->proxy_hosts_.find(site_instance_id); + if (iter != node->render_manager()->proxy_hosts_.end()) + iter->second->set_render_frame_proxy_created(false); + + return true; +} + bool RenderFrameHostManager::ShouldTransitionCrossSite() { // False in the single-process mode, as it makes RVHs to accumulate // in swapped_out_hosts_. @@ -1393,6 +1425,23 @@ return proxy->GetRoutingID(); } +void RenderFrameHostManager::EnsureRenderViewInitialized( + FrameTreeNode* source, + RenderViewHostImpl* render_view_host, + SiteInstance* instance) { + DCHECK(frame_tree_node_->IsMainFrame()); + + if (render_view_host->IsRenderViewLive()) + return; + + // Recreate the opener chain. + int opener_route_id = + delegate_->CreateOpenerRenderViewsForRenderManager(instance); + RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); + InitRenderView(render_view_host, opener_route_id, proxy->GetRoutingID(), + source->IsMainFrame()); +} + bool RenderFrameHostManager::InitRenderView( RenderViewHostImpl* render_view_host, int opener_route_id, @@ -1454,6 +1503,8 @@ if (existing_proxy) { proxy_routing_id = existing_proxy->GetRoutingID(); CHECK_NE(proxy_routing_id, MSG_ROUTING_NONE); + if (!existing_proxy->is_render_frame_proxy_live()) + existing_proxy->InitRenderFrameProxy(); } return delegate_->CreateRenderFrameForRenderManager(render_frame_host, parent_routing_id,
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index cc2e2d840..59b4d77 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -234,6 +234,13 @@ pending_and_current_web_ui_.get(); } + // PlzNavigate + // Returns the speculative WebUI for the navigation (a newly created one or + // the current one if it should be reused). If none is set returns nullptr. + WebUIImpl* speculative_web_ui_for_testing() const { + return should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); + } + // Called when we want to instruct the renderer to navigate to the given // navigation entry. It may create a new RenderFrameHost or re-use an existing // one. The RenderFrameHost to navigate will be returned. Returns NULL if one @@ -397,6 +404,10 @@ void OnDidStartLoading(); void OnDidStopLoading(); + void EnsureRenderViewInitialized(FrameTreeNode* source, + RenderViewHostImpl* render_view_host, + SiteInstance* instance); + private: friend class NavigatorTestWithBrowserSideNavigation; friend class RenderFrameHostManagerTest; @@ -409,6 +420,10 @@ // FrameTreeNode's RenderFrameHostManager. static bool ClearProxiesInSiteInstance(int32 site_instance_id, FrameTreeNode* node); + // Used with FrameTree::ForEach to reset initialized state of + // RenderFrameProxyHosts from a FrameTreeNode's RenderFrameHostManager. + static bool ResetProxiesInSiteInstance(int32 site_instance_id, + FrameTreeNode* node); // Returns whether this tab should transition to a new renderer for // cross-site URLs. Enabled unless we see the --process-per-tab command line
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 079c6c4a..52d99af 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -941,8 +941,11 @@ scoped_ptr<TestWebContents> web_contents( TestWebContents::Create(browser_context(), instance)); RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); + RenderFrameHostImpl* initial_rfh = manager->current_frame_host(); EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); + EXPECT_FALSE(manager->web_ui()); + EXPECT_TRUE(initial_rfh); const GURL kUrl("chrome://foo"); NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, @@ -955,6 +958,7 @@ // RenderFrameHost was not live. We test a case where it is live in // WebUIInNewTab. EXPECT_TRUE(host); + EXPECT_NE(initial_rfh, host); EXPECT_EQ(host, manager->current_frame_host()); EXPECT_FALSE(GetPendingFrameHost(manager)); @@ -967,7 +971,12 @@ // The Web UI is committed immediately because the RenderViewHost has not been // used yet. UpdateStateForNavigate() took the short cut path. - EXPECT_FALSE(manager->pending_web_ui()); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)) { + EXPECT_FALSE(manager->speculative_web_ui_for_testing()); + } else { + EXPECT_FALSE(manager->pending_web_ui()); + } EXPECT_TRUE(manager->web_ui()); // Commit. @@ -1410,15 +1419,25 @@ RenderProcessHost::RendererClosedDetails details( base::TERMINATION_STATUS_PROCESS_CRASHED, 0); + // TODO(nasko): Investigate whether this test can be made more realistic by + // not faking the notification and just doing the RenderProcessGone. This + // should also get rid of faking |set_render_view_created()| call below. NotificationService::current()->Notify( NOTIFICATION_RENDERER_PROCESS_CLOSED, Source<RenderProcessHost>(rvh1->GetProcess()), Details<RenderProcessHost::RendererClosedDetails>(&details)); rvh1->set_render_view_created(false); - // Ensure that the swapped out RenderViewHost has been deleted. - EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost( - rvh1->GetSiteInstance())); + // Ensure that the RenderFrameProxyHost stays around and the RenderFrameProxy + // is deleted. + RenderFrameProxyHost* render_frame_proxy_host = + opener1_manager->GetRenderFrameProxyHost(rvh1->GetSiteInstance()); + EXPECT_TRUE(render_frame_proxy_host); + EXPECT_FALSE(render_frame_proxy_host->is_render_frame_proxy_live()); + + // Expect the swapped out RVH to exist. + EXPECT_TRUE(opener1_manager->GetSwappedOutRenderViewHost( + rvh1->GetSiteInstance())); // Reload the initial tab. This should recreate the opener's swapped out RVH // in the original SiteInstance.
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index 7366da77..5b74b1e 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -44,7 +44,9 @@ FrameTreeNode* frame_tree_node) : routing_id_(site_instance->GetProcess()->GetNextRoutingID()), site_instance_(site_instance), - frame_tree_node_(frame_tree_node) { + process_(site_instance->GetProcess()), + frame_tree_node_(frame_tree_node), + render_frame_proxy_created_(false) { GetProcess()->AddRoute(routing_id_, this); CHECK(g_routing_id_frame_proxy_map.Get().insert( std::make_pair( @@ -121,11 +123,12 @@ } bool RenderFrameProxyHost::InitRenderFrameProxy() { + DCHECK(!render_frame_proxy_created_); // The process may (if we're sharing a process with another host that already // initialized it) or may not (we have our own process or the old process // crashed) have been initialized. Calling Init multiple times will be // ignored, so this is safe. - if (!site_instance_->GetProcess()->Init()) + if (!GetProcess()->Init()) return false; DCHECK(GetProcess()->HasConnection()); @@ -146,6 +149,7 @@ frame_tree_node_ ->current_replication_state())); + render_frame_proxy_created_ = true; return true; }
diff --git a/content/browser/frame_host/render_frame_proxy_host.h b/content/browser/frame_host/render_frame_proxy_host.h index ed3235c..9647506 100644 --- a/content/browser/frame_host/render_frame_proxy_host.h +++ b/content/browser/frame_host/render_frame_proxy_host.h
@@ -62,7 +62,7 @@ ~RenderFrameProxyHost() override; RenderProcessHost* GetProcess() { - return site_instance_->GetProcess(); + return process_; } // Initializes the object and creates the RenderFrameProxy in the process @@ -106,6 +106,13 @@ // action in another renderer process. void DisownOpener(); + void set_render_frame_proxy_created(bool created) { + render_frame_proxy_created_ = created; + } + + // Returns if the RenderFrameProxy for this host is alive. + bool is_render_frame_proxy_live() { return render_frame_proxy_created_; } + private: // IPC Message handlers. void OnOpenURL(const FrameHostMsg_OpenURL_Params& params); @@ -116,9 +123,18 @@ // The SiteInstance this proxy is associated with. scoped_refptr<SiteInstance> site_instance_; + // The renderer process this RenderFrameHostProxy is associated with. It is + // equivalent to the result of site_instance_->GetProcess(), but that + // method has the side effect of creating the process if it doesn't exist. + // Cache a pointer to avoid unnecessary process creation. + RenderProcessHost* process_; + // The node in the frame tree where this proxy is located. FrameTreeNode* frame_tree_node_; + // True if we have a live RenderFrameProxy for this host. + bool render_frame_proxy_created_; + // When a RenderFrameHost is in a different process from its parent in the // frame tree, this class connects its associated RenderWidgetHostView // to this RenderFrameProxyHost, which corresponds to the same frame in the
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 04d6663..ebbea17c 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -107,7 +107,7 @@ void RenderWidgetHostViewChildFrame::InitAsPopup( RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) { + const gfx::Rect& bounds) { NOTREACHED(); }
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index e063eb9..84835a8 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -57,7 +57,7 @@ // RenderWidgetHostViewBase implementation. void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) override; + const gfx::Rect& bounds) override; void InitAsFullscreen(RenderWidgetHostView* reference_host_view) override; void MovePluginWindows(const std::vector<WebPluginGeometry>& moves) override; void Blur() override; @@ -120,8 +120,8 @@ // RenderWidgetHostViewBase implementation. #if defined(OS_ANDROID) - virtual void LockCompositingSurface() override; - virtual void UnlockCompositingSurface() override; + void LockCompositingSurface() override; + void UnlockCompositingSurface() override; #endif // defined(OS_ANDROID) #if defined(OS_WIN)
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index 075d4ff..17d22b6 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -218,7 +218,7 @@ } void RenderWidgetHostViewGuest::InitAsPopup( - RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { + RenderWidgetHostView* parent_host_view, const gfx::Rect& bounds) { // This should never get called. NOTREACHED(); }
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h index be07e97b..c5a6e72 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.h +++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -67,7 +67,7 @@ // RenderWidgetHostViewBase implementation. void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) override; + const gfx::Rect& bounds) override; void InitAsFullscreen(RenderWidgetHostView* reference_host_view) override; void MovePluginWindows(const std::vector<WebPluginGeometry>& moves) override; void UpdateCursor(const WebCursor& cursor) override; @@ -124,8 +124,8 @@ #endif // defined(OS_ANDROID) || defined(TOOLKIT_VIEWS) #if defined(OS_ANDROID) - virtual void LockCompositingSurface() override; - virtual void UnlockCompositingSurface() override; + void LockCompositingSurface() override; + void UnlockCompositingSurface() override; #endif // defined(OS_ANDROID) #if defined(OS_WIN)
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_android.h b/content/browser/gamepad/gamepad_platform_data_fetcher_android.h index 989a467..4acdfb3b 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_android.h +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_android.h
@@ -21,12 +21,12 @@ class GamepadPlatformDataFetcherAndroid : public GamepadDataFetcher { public: GamepadPlatformDataFetcherAndroid(); - virtual ~GamepadPlatformDataFetcherAndroid(); + ~GamepadPlatformDataFetcherAndroid() override; - virtual void PauseHint(bool paused) override; + void PauseHint(bool paused) override; - virtual void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; + void GetGamepadData(blink::WebGamepads* pads, + bool devices_changed_hint) override; // Registers the JNI methods for GamepadsReader. static bool RegisterGamepadPlatformDataFetcherAndroid(JNIEnv* env);
diff --git a/content/browser/geolocation/location_provider_android.h b/content/browser/geolocation/location_provider_android.h index e24f67c..9e0ad5f 100644 --- a/content/browser/geolocation/location_provider_android.h +++ b/content/browser/geolocation/location_provider_android.h
@@ -17,17 +17,17 @@ class LocationProviderAndroid : public LocationProviderBase { public: LocationProviderAndroid(); - virtual ~LocationProviderAndroid(); + ~LocationProviderAndroid() override; // Called by the AndroidLocationApiAdapter. void NotifyNewGeoposition(const Geoposition& position); // LocationProvider. - virtual bool StartProvider(bool high_accuracy) override; - virtual void StopProvider() override; - virtual void GetPosition(Geoposition* position) override; - virtual void RequestRefresh() override; - virtual void OnPermissionGranted() override; + bool StartProvider(bool high_accuracy) override; + void StopProvider() override; + void GetPosition(Geoposition* position) override; + void RequestRefresh() override; + void OnPermissionGranted() override; private: Geoposition last_position_;
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 0f01ec8..9606eb5 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -292,6 +292,21 @@ return command_line.HasSwitch(switches::kForceGpuRasterization); } +bool IsThreadedGpuRasterizationEnabled() { + if (!IsImplSidePaintingEnabled()) + return false; + + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + if (command_line.HasSwitch(switches::kDisableThreadedGpuRasterization)) + return false; + if (command_line.HasSwitch(switches::kEnableThreadedGpuRasterization)) + return true; + + return false; +} + bool UseSurfacesEnabled() { #if defined(OS_ANDROID) return false;
diff --git a/content/browser/gpu/compositor_util.h b/content/browser/gpu/compositor_util.h index 6266f36e..16dca45c 100644 --- a/content/browser/gpu/compositor_util.h +++ b/content/browser/gpu/compositor_util.h
@@ -42,6 +42,10 @@ // Returns true if force-gpu-rasterization is on (via flags) for the renderer. CONTENT_EXPORT bool IsForceGpuRasterizationEnabled(); +// Returns true if threaded GPU rasterization is on (via flags) for the +// renderer. +CONTENT_EXPORT bool IsThreadedGpuRasterizationEnabled(); + // Returns the number of raster threads to use for compositing. CONTENT_EXPORT int NumberOfRendererRasterThreads();
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h index 199f48a..f558c754 100644 --- a/content/browser/loader/navigation_url_loader_delegate.h +++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -39,6 +39,12 @@ // network error code for the failure. virtual void OnRequestFailed(int net_error) = 0; + // Called after the network request has begun on the IO thread at time + // |timestamp|. This is just a thread hop but is used to compare timing + // against the pre-PlzNavigate codepath which didn't start the network request + // until after the renderer was initialized. + virtual void OnRequestStarted(base::TimeTicks timestamp) = 0; + protected: NavigationURLLoaderDelegate() {} virtual ~NavigationURLLoaderDelegate() {}
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index b6dbed0..949d630 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -73,4 +73,10 @@ delegate_->OnRequestFailed(net_error); } +void NavigationURLLoaderImpl::NotifyRequestStarted(base::TimeTicks timestamp) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + delegate_->OnRequestStarted(timestamp); +} + } // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index ecfd238..7dba1185 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -9,6 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "content/browser/loader/navigation_url_loader.h" namespace net { @@ -50,6 +51,10 @@ // Notifies the delegate the request failed to return a response. void NotifyRequestFailed(int net_error); + // Notifies the delegate the begin navigation request was handled and a + // potential first network request is about to be made. + void NotifyRequestStarted(base::TimeTicks timestamp); + NavigationURLLoaderDelegate* delegate_; // |core_| is deleted on the IO thread in a subsequent task when the
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc index 48845e8..c8e681e 100644 --- a/content/browser/loader/navigation_url_loader_impl_core.cc +++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/location.h" +#include "base/time/time.h" #include "content/browser/frame_host/navigation_request_info.h" #include "content/browser/loader/navigation_resource_handler.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" @@ -42,6 +43,11 @@ ResourceRequestBody* request_body) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&NavigationURLLoaderImpl::NotifyRequestStarted, loader_, + base::TimeTicks::Now())); + ResourceDispatcherHostImpl::Get()->BeginNavigationRequest( resource_context, frame_tree_node_id, common_params, *request_info, request_body,
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index 097035c..745afe82 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -62,8 +62,7 @@ class TestNavigationURLLoaderDelegate : public NavigationURLLoaderDelegate { public: TestNavigationURLLoaderDelegate() - : net_error_(0) { - } + : net_error_(0), on_request_handled_counter_(0) {} const net::RedirectInfo& redirect_info() const { return redirect_info_; } ResourceResponse* redirect_response() const { @@ -72,6 +71,7 @@ ResourceResponse* response() const { return response_.get(); } StreamHandle* body() const { return body_.get(); } int net_error() const { return net_error_; } + int on_request_handled_counter() const { return on_request_handled_counter_; } void WaitForRequestRedirected() { request_redirected_.reset(new base::RunLoop); @@ -119,12 +119,18 @@ request_failed_->Quit(); } + void OnRequestStarted(base::TimeTicks timestamp) override { + ASSERT_FALSE(timestamp.is_null()); + ++on_request_handled_counter_; + } + private: net::RedirectInfo redirect_info_; scoped_refptr<ResourceResponse> redirect_response_; scoped_refptr<ResourceResponse> response_; scoped_ptr<StreamHandle> body_; int net_error_; + int on_request_handled_counter_; scoped_ptr<base::RunLoop> request_redirected_; scoped_ptr<base::RunLoop> response_started_; @@ -222,6 +228,8 @@ // Check the body is correct. EXPECT_EQ(net::URLRequestTestJob::test_data_1(), FetchURL(delegate.body()->GetURL())); + + EXPECT_EQ(1, delegate.on_request_handled_counter()); } // Tests that request failures are propagated correctly. @@ -233,6 +241,7 @@ // Wait for the request to fail as expected. delegate.WaitForRequestFailed(); EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, delegate.net_error()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); } // Test that redirects are sent to the delegate. @@ -252,6 +261,7 @@ EXPECT_EQ(net::URLRequestTestJob::test_url_2(), delegate.redirect_info().new_first_party_for_cookies); EXPECT_EQ(302, delegate.redirect_response()->head.headers->response_code()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); // Wait for the response to complete. loader->FollowRedirect(); @@ -265,6 +275,8 @@ EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); EXPECT_EQ(net::URLRequestTestJob::test_data_2(), FetchURL(delegate.body()->GetURL())); + + EXPECT_EQ(1, delegate.on_request_handled_counter()); } // Tests that the destroying the loader cancels the request. @@ -325,6 +337,7 @@ // Wait for the request to now be aborted. delegate.WaitForRequestFailed(); EXPECT_EQ(net::ERR_ABORTED, delegate.net_error()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); } // Tests that, if the request is blocked by the ResourceDispatcherHostDelegate, @@ -340,6 +353,7 @@ // Wait for the request to fail as expected. delegate.WaitForRequestFailed(); EXPECT_EQ(net::ERR_ABORTED, delegate.net_error()); + EXPECT_EQ(1, delegate.on_request_handled_counter()); host_.SetDelegate(nullptr); }
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 332b7ec..ddb8a09 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -979,7 +979,9 @@ // When logging time-to-network only care about main frame and non-transfer // navigations. if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME && - request_data.transferred_request_request_id == -1) { + request_data.transferred_request_request_id == -1 && + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserSideNavigation)) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE,
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index 404831dd..b31d26a 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -281,4 +281,32 @@ EXPECT_EQ(6u, console_error_count()); } +// If a page has a manifest and the page is navigated to a page without a +// manifest, the page's manifest should be updated. +IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) { + { + GURL test_url = GetTestUrl("manifest", "dummy-manifest.html"); + + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + shell()->LoadURL(test_url); + navigation_observer.Wait(); + + GetManifestAndWait(); + EXPECT_FALSE(manifest().IsEmpty()); + EXPECT_EQ(0u, console_error_count()); + } + + { + GURL test_url = GetTestUrl("manifest", "no-manifest.html"); + + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + shell()->LoadURL(test_url); + navigation_observer.Wait(); + + GetManifestAndWait(); + EXPECT_TRUE(manifest().IsEmpty()); + EXPECT_EQ(0u, console_error_count()); + } +} + } // namespace content
diff --git a/content/browser/media/OWNERS b/content/browser/media/OWNERS index 00fcbc6..c64283a 100644 --- a/content/browser/media/OWNERS +++ b/content/browser/media/OWNERS
@@ -1,11 +1,12 @@ dalecurtis@chromium.org ddorwin@chromium.org -perkj@chromium.org scherkus@chromium.org -tommi@chromium.org -vrk@chromium.org xhwang@chromium.org +# WebRTC OWNERS. +perkj@chromium.org +tommi@chromium.org + per-file midi_*=toyoshim@chromium.org # For changes related to the tab media indicators.
diff --git a/content/browser/media/android/browser_demuxer_android.cc b/content/browser/media/android/browser_demuxer_android.cc index a0cf7f7d..ed46203 100644 --- a/content/browser/media/android/browser_demuxer_android.cc +++ b/content/browser/media/android/browser_demuxer_android.cc
@@ -15,26 +15,25 @@ : demuxer_(demuxer), demuxer_client_id_(demuxer_client_id) {} - virtual ~Internal() { + ~Internal() override { DCHECK(ClientIDExists()) << demuxer_client_id_; demuxer_->RemoveDemuxerClient(demuxer_client_id_); } // media::DemuxerAndroid implementation. - virtual void Initialize(media::DemuxerAndroidClient* client) override { + void Initialize(media::DemuxerAndroidClient* client) override { DCHECK(!ClientIDExists()) << demuxer_client_id_; demuxer_->AddDemuxerClient(demuxer_client_id_, client); } - virtual void RequestDemuxerData(media::DemuxerStream::Type type) override { + void RequestDemuxerData(media::DemuxerStream::Type type) override { DCHECK(ClientIDExists()) << demuxer_client_id_; demuxer_->Send(new MediaPlayerMsg_ReadFromDemuxer( demuxer_client_id_, type)); } - virtual void RequestDemuxerSeek( - const base::TimeDelta& time_to_seek, - bool is_browser_seek) override { + void RequestDemuxerSeek(const base::TimeDelta& time_to_seek, + bool is_browser_seek) override { DCHECK(ClientIDExists()) << demuxer_client_id_; demuxer_->Send(new MediaPlayerMsg_DemuxerSeekRequest( demuxer_client_id_, time_to_seek, is_browser_seek));
diff --git a/content/browser/media/android/browser_demuxer_android.h b/content/browser/media/android/browser_demuxer_android.h index 1e7f799..407e0b3 100644 --- a/content/browser/media/android/browser_demuxer_android.h +++ b/content/browser/media/android/browser_demuxer_android.h
@@ -21,9 +21,9 @@ BrowserDemuxerAndroid(); // BrowserMessageFilter overrides. - virtual void OverrideThreadForMessage(const IPC::Message& message, - BrowserThread::ID* thread) override; - virtual bool OnMessageReceived(const IPC::Message& message) override; + void OverrideThreadForMessage(const IPC::Message& message, + BrowserThread::ID* thread) override; + bool OnMessageReceived(const IPC::Message& message) override; // Returns an uninitialized demuxer implementation associated with // |demuxer_client_id|, which can be used to communicate with the real demuxer @@ -32,7 +32,7 @@ protected: friend class base::RefCountedThreadSafe<BrowserDemuxerAndroid>; - virtual ~BrowserDemuxerAndroid(); + ~BrowserDemuxerAndroid() override; private: class Internal;
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 7f00e6a..55fbf55 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -149,6 +149,12 @@ fullscreen_player_id_ = kInvalidMediaPlayerId; if (!player) return; + +#if defined(VIDEO_HOLE) + if (external_video_surface_container_) + external_video_surface_container_->OnFrameInfoUpdated(); +#endif // defined(VIDEO_HOLE) + if (release_media_player) ReleaseFullscreenPlayer(player); else @@ -318,6 +324,9 @@ } void BrowserMediaPlayerManager::OnFrameInfoUpdated() { + if (fullscreen_player_id_ != kInvalidMediaPlayerId) + return; + if (external_video_surface_container_) external_video_surface_container_->OnFrameInfoUpdated(); }
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index 3925eeb..e0a40132 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h
@@ -54,7 +54,7 @@ ContentViewCoreImpl* GetContentViewCore() const; - virtual ~BrowserMediaPlayerManager(); + ~BrowserMediaPlayerManager() override; // Fullscreen video playback controls. virtual void ExitFullscreen(bool release_media_player); @@ -68,32 +68,28 @@ void ReleaseAllMediaPlayers(); // media::MediaPlayerManager overrides. - virtual void OnTimeUpdate( - int player_id, - base::TimeDelta current_timestamp, - base::TimeTicks current_time_ticks) override; - virtual void OnMediaMetadataChanged( - int player_id, - base::TimeDelta duration, - int width, - int height, - bool success) override; - virtual void OnPlaybackComplete(int player_id) override; - virtual void OnMediaInterrupted(int player_id) override; - virtual void OnBufferingUpdate(int player_id, int percentage) override; - virtual void OnSeekComplete( - int player_id, - const base::TimeDelta& current_time) override; - virtual void OnError(int player_id, int error) override; - virtual void OnVideoSizeChanged( - int player_id, int width, int height) override; - virtual media::MediaResourceGetter* GetMediaResourceGetter() override; - virtual media::MediaUrlInterceptor* GetMediaUrlInterceptor() override; - virtual media::MediaPlayerAndroid* GetFullscreenPlayer() override; - virtual media::MediaPlayerAndroid* GetPlayer(int player_id) override; - virtual void RequestFullScreen(int player_id) override; + void OnTimeUpdate(int player_id, + base::TimeDelta current_timestamp, + base::TimeTicks current_time_ticks) override; + void OnMediaMetadataChanged(int player_id, + base::TimeDelta duration, + int width, + int height, + bool success) override; + void OnPlaybackComplete(int player_id) override; + void OnMediaInterrupted(int player_id) override; + void OnBufferingUpdate(int player_id, int percentage) override; + void OnSeekComplete(int player_id, + const base::TimeDelta& current_time) override; + void OnError(int player_id, int error) override; + void OnVideoSizeChanged(int player_id, int width, int height) override; + media::MediaResourceGetter* GetMediaResourceGetter() override; + media::MediaUrlInterceptor* GetMediaUrlInterceptor() override; + media::MediaPlayerAndroid* GetFullscreenPlayer() override; + media::MediaPlayerAndroid* GetPlayer(int player_id) override; + void RequestFullScreen(int player_id) override; #if defined(VIDEO_HOLE) - virtual bool ShouldUseVideoOverlayForEmbeddedEncryptedVideo() override; + bool ShouldUseVideoOverlayForEmbeddedEncryptedVideo() override; void AttachExternalVideoSurface(int player_id, jobject surface); void DetachExternalVideoSurface(int player_id);
diff --git a/content/browser/media/android/media_resource_getter_impl.h b/content/browser/media/android/media_resource_getter_impl.h index 4f0d2e8..9a55fcb7 100644 --- a/content/browser/media/android/media_resource_getter_impl.h +++ b/content/browser/media/android/media_resource_getter_impl.h
@@ -40,30 +40,25 @@ storage::FileSystemContext* file_system_context, int render_process_id, int render_frame_id); - virtual ~MediaResourceGetterImpl(); + ~MediaResourceGetterImpl() override; // media::MediaResourceGetter implementation. // Must be called on the UI thread. - virtual void GetAuthCredentials( - const GURL& url, - const GetAuthCredentialsCB& callback) override; - virtual void GetCookies( - const GURL& url, - const GURL& first_party_for_cookies, - const GetCookieCB& callback) override; - virtual void GetPlatformPathFromURL( - const GURL& url, - const GetPlatformPathCB& callback) override; - virtual void ExtractMediaMetadata( - const std::string& url, - const std::string& cookies, - const std::string& user_agent, - const ExtractMediaMetadataCB& callback) override; - virtual void ExtractMediaMetadata( - const int fd, - const int64 offset, - const int64 size, - const ExtractMediaMetadataCB& callback) override; + void GetAuthCredentials(const GURL& url, + const GetAuthCredentialsCB& callback) override; + void GetCookies(const GURL& url, + const GURL& first_party_for_cookies, + const GetCookieCB& callback) override; + void GetPlatformPathFromURL(const GURL& url, + const GetPlatformPathCB& callback) override; + void ExtractMediaMetadata(const std::string& url, + const std::string& cookies, + const std::string& user_agent, + const ExtractMediaMetadataCB& callback) override; + void ExtractMediaMetadata(const int fd, + const int64 offset, + const int64 size, + const ExtractMediaMetadataCB& callback) override; static bool RegisterMediaResourceGetter(JNIEnv* env);
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index 0ddcf269..bb546c2 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -451,7 +451,7 @@ void DesktopCaptureDevice::AllocateAndStart( const media::VideoCaptureParams& params, scoped_ptr<Client> client) { - thread_.message_loop_proxy()->PostTask( + thread_.task_runner()->PostTask( FROM_HERE, base::Bind(&Core::AllocateAndStart, base::Unretained(core_.get()), params, base::Passed(&client))); @@ -459,16 +459,20 @@ void DesktopCaptureDevice::StopAndDeAllocate() { if (core_) { - thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, core_.release()); + thread_.task_runner()->DeleteSoon(FROM_HERE, core_.release()); thread_.Stop(); } } void DesktopCaptureDevice::SetNotificationWindowId( gfx::NativeViewId window_id) { - thread_.message_loop_proxy()->PostTask( + // This may be called after the capturer has been stopped. + if (!core_) + return; + thread_.task_runner()->PostTask( FROM_HERE, - base::Bind(&Core::SetNotificationWindowId, base::Unretained(core_.get()), + base::Bind(&Core::SetNotificationWindowId, + base::Unretained(core_.get()), window_id)); } @@ -485,7 +489,7 @@ thread_.StartWithOptions(base::Thread::Options(thread_type, 0)); - core_.reset(new Core(thread_.message_loop_proxy(), capturer.Pass(), type)); + core_.reset(new Core(thread_.task_runner(), capturer.Pass(), type)); } } // namespace content
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc index 9e02339..7d58aca 100644 --- a/content/browser/media/encrypted_media_browsertest.cc +++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -129,7 +129,7 @@ } #if defined(OS_ANDROID) - virtual void SetUpCommandLine(base::CommandLine* command_line) override { + void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( switches::kDisableGestureRequirementForMediaPlayback); }
diff --git a/content/browser/media/media_source_browsertest.cc b/content/browser/media/media_source_browsertest.cc index 54c80d5..191ff66 100644 --- a/content/browser/media/media_source_browsertest.cc +++ b/content/browser/media/media_source_browsertest.cc
@@ -49,7 +49,7 @@ } #if defined(OS_ANDROID) - virtual void SetUpCommandLine(base::CommandLine* command_line) override { + void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( switches::kDisableGestureRequirementForMediaPlayback); }
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc index 617c66b..91e013b 100644 --- a/content/browser/notifications/notification_event_dispatcher_impl.cc +++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -46,6 +46,7 @@ case SERVICE_WORKER_ERROR_IPC_FAILED: case SERVICE_WORKER_ERROR_NETWORK: case SERVICE_WORKER_ERROR_SECURITY: + case SERVICE_WORKER_ERROR_STATE: status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR; break; } @@ -93,6 +94,7 @@ case SERVICE_WORKER_ERROR_NETWORK: case SERVICE_WORKER_ERROR_SECURITY: case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: + case SERVICE_WORKER_ERROR_STATE: status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR; break; case SERVICE_WORKER_OK:
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc index 8d69c5ce..bec7730 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.cc +++ b/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -412,6 +412,7 @@ case SERVICE_WORKER_ERROR_NETWORK: case SERVICE_WORKER_ERROR_SECURITY: case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: + case SERVICE_WORKER_ERROR_STATE: NOTREACHED() << "Got unexpected error code: " << service_worker_status << " " << ServiceWorkerStatusToString(service_worker_status); DidUnregister(request_id, PUSH_UNREGISTRATION_STATUS_UNKNOWN_ERROR); @@ -527,6 +528,7 @@ case SERVICE_WORKER_ERROR_NETWORK: case SERVICE_WORKER_ERROR_SECURITY: case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: + case SERVICE_WORKER_ERROR_STATE: NOTREACHED() << "Got unexpected error code: " << service_worker_status << " " << ServiceWorkerStatusToString(service_worker_status); get_status = PUSH_GETREGISTRATION_STATUS_SERVICE_WORKER_ERROR;
diff --git a/content/browser/push_messaging/push_messaging_router.cc b/content/browser/push_messaging/push_messaging_router.cc index 2fe0538..085ee7d21 100644 --- a/content/browser/push_messaging/push_messaging_router.cc +++ b/content/browser/push_messaging/push_messaging_router.cc
@@ -114,6 +114,7 @@ case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED: case SERVICE_WORKER_ERROR_NETWORK: case SERVICE_WORKER_ERROR_SECURITY: + case SERVICE_WORKER_ERROR_STATE: NOTREACHED() << "Got unexpected error code: " << service_worker_status << " " << ServiceWorkerStatusToString(service_worker_status); delivery_status = PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index c32fc32..8b2f7b9 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -80,7 +80,7 @@ main_thread_ = base::MessageLoopProxy::current(); } - virtual void SwapBuffers(cc::CompositorFrame* frame) override { + void SwapBuffers(cc::CompositorFrame* frame) override { GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info); DCHECK(frame->gl_frame_data->sub_buffer_rect == gfx::Rect(frame->gl_frame_data->size)); @@ -88,7 +88,7 @@ client_->DidSwapBuffers(); } - virtual bool BindToClient(cc::OutputSurfaceClient* client) override { + bool BindToClient(cc::OutputSurfaceClient* client) override { if (!OutputSurface::BindToClient(client)) return false;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 09c8b8a..dbcdc66 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -44,7 +44,7 @@ public ui::WindowAndroidCompositor { public: CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window); - virtual ~CompositorImpl(); + ~CompositorImpl() override; static bool IsInitialized(); @@ -52,53 +52,51 @@ private: // Compositor implementation. - virtual void SetRootLayer(scoped_refptr<cc::Layer> root) override; - virtual void SetSurface(jobject surface) override; - virtual void SetVisible(bool visible) override; - virtual void setDeviceScaleFactor(float factor) override; - virtual void SetWindowBounds(const gfx::Size& size) override; - virtual void SetHasTransparentBackground(bool flag) override; - virtual void SetNeedsComposite() override; - virtual ui::UIResourceProvider& GetUIResourceProvider() override; - virtual ui::ResourceManager& GetResourceManager() override; + void SetRootLayer(scoped_refptr<cc::Layer> root) override; + void SetSurface(jobject surface) override; + void SetVisible(bool visible) override; + void setDeviceScaleFactor(float factor) override; + void SetWindowBounds(const gfx::Size& size) override; + void SetHasTransparentBackground(bool flag) override; + void SetNeedsComposite() override; + ui::UIResourceProvider& GetUIResourceProvider() override; + ui::ResourceManager& GetResourceManager() override; // LayerTreeHostClient implementation. - virtual void WillBeginMainFrame(int frame_id) override {} - virtual void DidBeginMainFrame() override {} - virtual void BeginMainFrame(const cc::BeginFrameArgs& args) override {} - virtual void Layout() override; - virtual void ApplyViewportDeltas( - const gfx::Vector2d& inner_delta, - const gfx::Vector2d& outer_delta, - const gfx::Vector2dF& elastic_overscroll_delta, - float page_scale, - float top_controls_delta) override {} - virtual void ApplyViewportDeltas( - const gfx::Vector2d& scroll_delta, - float page_scale, - float top_controls_delta) override {} - virtual void RequestNewOutputSurface() override; - virtual void DidInitializeOutputSurface() override {} - virtual void DidFailToInitializeOutputSurface() override; - virtual void WillCommit() override {} - virtual void DidCommit() override; - virtual void DidCommitAndDrawFrame() override {} - virtual void DidCompleteSwapBuffers() override; - virtual void DidCompletePageScaleAnimation() override {} + void WillBeginMainFrame() override {} + void DidBeginMainFrame() override {} + void BeginMainFrame(const cc::BeginFrameArgs& args) override {} + void Layout() override; + void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, + const gfx::Vector2d& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) override {} + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float page_scale, + float top_controls_delta) override {} + void RequestNewOutputSurface() override; + void DidInitializeOutputSurface() override {} + void DidFailToInitializeOutputSurface() override; + void WillCommit() override {} + void DidCommit() override; + void DidCommitAndDrawFrame() override {} + void DidCompleteSwapBuffers() override; + void DidCompletePageScaleAnimation() override {} // LayerTreeHostSingleThreadClient implementation. - virtual void ScheduleComposite() override; - virtual void ScheduleAnimation() override; - virtual void DidPostSwapBuffers() override; - virtual void DidAbortSwapBuffers() override; + void ScheduleComposite() override; + void ScheduleAnimation() override; + void DidPostSwapBuffers() override; + void DidAbortSwapBuffers() override; // WindowAndroidCompositor implementation. - virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override; - virtual void RequestCopyOfOutputOnRootLayer( + void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override; + void RequestCopyOfOutputOnRootLayer( scoped_ptr<cc::CopyOutputRequest> request) override; - virtual void OnVSync(base::TimeTicks frame_time, - base::TimeDelta vsync_period) override; - virtual void SetNeedsAnimate() override; + void OnVSync(base::TimeTicks frame_time, + base::TimeDelta vsync_period) override; + void SetNeedsAnimate() override; void SetWindowSurface(ANativeWindow* window);
diff --git a/content/browser/renderer_host/input/input_router_config_helper.cc b/content/browser/renderer_host/input/input_router_config_helper.cc index 57ad49e..3ed530f 100644 --- a/content/browser/renderer_host/input/input_router_config_helper.cc +++ b/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -95,28 +95,12 @@ #endif -TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() { - std::string modeString = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kTouchScrollingMode); - if (modeString == switches::kTouchScrollingModeAsyncTouchmove) - return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE; - if (modeString == switches::kTouchScrollingModeSyncTouchmove) - return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE; - if (modeString == switches::kTouchScrollingModeTouchcancel) - return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL; - if (!modeString.empty()) - LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString; - return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT; -} - } // namespace InputRouterImpl::Config GetInputRouterConfigForPlatform() { InputRouterImpl::Config config; config.gesture_config = GetGestureEventQueueConfig(); config.touch_config = GetTouchEventQueueConfig(); - config.touch_config.touch_scrolling_mode = GetTouchScrollingMode(); return config; }
diff --git a/content/browser/renderer_host/input/motion_event_android.h b/content/browser/renderer_host/input/motion_event_android.h index 4af9f72..f4e8c94 100644 --- a/content/browser/renderer_host/input/motion_event_android.h +++ b/content/browser/renderer_host/input/motion_event_android.h
@@ -55,35 +55,35 @@ jfloat raw_offset_y_pixels, const Pointer& pointer0, const Pointer& pointer1); - virtual ~MotionEventAndroid(); + ~MotionEventAndroid() override; // ui::MotionEvent methods. - virtual int GetId() const override; - virtual Action GetAction() const override; - virtual int GetActionIndex() const override; - virtual size_t GetPointerCount() const override; - virtual int GetPointerId(size_t pointer_index) const override; - virtual float GetX(size_t pointer_index) const override; - virtual float GetY(size_t pointer_index) const override; - virtual float GetRawX(size_t pointer_index) const override; - virtual float GetRawY(size_t pointer_index) const override; - virtual float GetTouchMajor(size_t pointer_index) const override; - virtual float GetTouchMinor(size_t pointer_index) const override; - virtual float GetOrientation(size_t pointer_index) const override; - virtual float GetPressure(size_t pointer_index) const override; - virtual base::TimeTicks GetEventTime() const override; - virtual size_t GetHistorySize() const override; - virtual base::TimeTicks GetHistoricalEventTime( + int GetId() const override; + Action GetAction() const override; + int GetActionIndex() const override; + size_t GetPointerCount() const override; + int GetPointerId(size_t pointer_index) const override; + float GetX(size_t pointer_index) const override; + float GetY(size_t pointer_index) const override; + float GetRawX(size_t pointer_index) const override; + float GetRawY(size_t pointer_index) const override; + float GetTouchMajor(size_t pointer_index) const override; + float GetTouchMinor(size_t pointer_index) const override; + float GetOrientation(size_t pointer_index) const override; + float GetPressure(size_t pointer_index) const override; + base::TimeTicks GetEventTime() const override; + size_t GetHistorySize() const override; + base::TimeTicks GetHistoricalEventTime( size_t historical_index) const override; - virtual float GetHistoricalTouchMajor(size_t pointer_index, - size_t historical_index) const override; - virtual float GetHistoricalX(size_t pointer_index, - size_t historical_index) const override; - virtual float GetHistoricalY(size_t pointer_index, - size_t historical_index) const override; - virtual ToolType GetToolType(size_t pointer_index) const override; - virtual int GetButtonState() const override; - virtual int GetFlags() const override; + float GetHistoricalTouchMajor(size_t pointer_index, + size_t historical_index) const override; + float GetHistoricalX(size_t pointer_index, + size_t historical_index) const override; + float GetHistoricalY(size_t pointer_index, + size_t historical_index) const override; + ToolType GetToolType(size_t pointer_index) const override; + int GetButtonState() const override; + int GetFlags() const override; static bool RegisterMotionEventAndroid(JNIEnv* env);
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_android.h b/content/browser/renderer_host/input/synthetic_gesture_target_android.h index 571fcbd..afd124e5 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_android.h +++ b/content/browser/renderer_host/input/synthetic_gesture_target_android.h
@@ -18,28 +18,28 @@ SyntheticGestureTargetAndroid( RenderWidgetHostImpl* host, base::android::ScopedJavaLocalRef<jobject> touch_event_synthesizer); - virtual ~SyntheticGestureTargetAndroid(); + ~SyntheticGestureTargetAndroid() override; static bool RegisterTouchEventSynthesizer(JNIEnv* env); // SyntheticGestureTargetBase: - virtual void DispatchWebTouchEventToPlatform( + void DispatchWebTouchEventToPlatform( const blink::WebTouchEvent& web_touch, const ui::LatencyInfo& latency_info) override; - virtual void DispatchWebMouseWheelEventToPlatform( + void DispatchWebMouseWheelEventToPlatform( const blink::WebMouseWheelEvent& web_wheel, const ui::LatencyInfo& latency_info) override; - virtual void DispatchWebMouseEventToPlatform( + void DispatchWebMouseEventToPlatform( const blink::WebMouseEvent& web_mouse, const ui::LatencyInfo& latency_info) override; // SyntheticGestureTarget: - virtual SyntheticGestureParams::GestureSourceType - GetDefaultSyntheticGestureSourceType() const override; + SyntheticGestureParams::GestureSourceType + GetDefaultSyntheticGestureSourceType() const override; - virtual float GetTouchSlopInDips() const override; + float GetTouchSlopInDips() const override; - virtual float GetMinScalingSpanInDips() const override; + float GetMinScalingSpanInDips() const override; private: // Enum values below need to be kept in sync with TouchEventSynthesizer.java
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc index ea4649e..38718b3f 100644 --- a/content/browser/renderer_host/input/touch_action_browsertest.cc +++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -179,14 +179,8 @@ EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchstart")); EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchmove")); - if (TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT == - TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL) { - EXPECT_EQ(0, ExecuteScriptAndExtractInt("eventCounts.touchend")); - EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchcancel")); - } else { - EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchend")); - EXPECT_EQ(0, ExecuteScriptAndExtractInt("eventCounts.touchcancel")); - } + EXPECT_EQ(1, ExecuteScriptAndExtractInt("eventCounts.touchend")); + EXPECT_EQ(0, ExecuteScriptAndExtractInt("eventCounts.touchcancel")); } // Verify that touching a touch-action: none region disables scrolling and
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc index 013ddd0..6ac63ce 100644 --- a/content/browser/renderer_host/input/touch_event_queue.cc +++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -357,8 +357,7 @@ }; TouchEventQueue::Config::Config() - : touch_scrolling_mode(TOUCH_SCROLLING_MODE_DEFAULT), - touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)), + : touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)), touch_ack_timeout_supported(false) { } @@ -371,8 +370,7 @@ drop_remaining_touches_in_sequence_(false), touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), send_touch_events_async_(false), - last_sent_touch_timestamp_sec_(0), - touch_scrolling_mode_(config.touch_scrolling_mode) { + last_sent_touch_timestamp_sec_(0) { DCHECK(client); if (config.touch_ack_timeout_supported) { timeout_handler_.reset( @@ -541,8 +539,7 @@ DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) << "A touch handler should be offered a touchmove before scrolling."; } - if (touch_scrolling_mode_ == TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE && - !drop_remaining_touches_in_sequence_ && + if (!drop_remaining_touches_in_sequence_ && touch_consumer_states_.is_empty()) { // If no touch points have a consumer, prevent all subsequent touch events // received during the scroll from reaching the renderer. This ensures @@ -552,60 +549,26 @@ drop_remaining_touches_in_sequence_ = true; } - if (touch_scrolling_mode_ == TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE) - pending_async_touchmove_.reset(); + pending_async_touchmove_.reset(); return; } - if (gesture_event.event.type != blink::WebInputEvent::GestureScrollUpdate) - return; - - if (touch_scrolling_mode_ == TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE) + if (gesture_event.event.type == blink::WebInputEvent::GestureScrollUpdate) send_touch_events_async_ = true; - - if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_TOUCHCANCEL) - return; - - // We assume that scroll events are generated synchronously from - // dispatching a touch event ack. This allows us to generate a synthetic - // cancel event that has the same touch ids as the touch event that - // is being acked. Otherwise, we don't perform the touch-cancel optimization. - if (!dispatching_touch_ack_) - return; - - if (drop_remaining_touches_in_sequence_) - return; - - drop_remaining_touches_in_sequence_ = true; - - // Fake a TouchCancel to cancel the touch points of the touch event - // that is currently being acked. - // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we - // are in the scope of PopTouchEventToClient() and that no touch event - // in the queue is waiting for ack from renderer. So we can just insert - // the touch cancel at the beginning of the queue. - touch_queue_.push_front(new CoalescedWebTouchEvent( - ObtainCancelEventForTouchEvent( - dispatching_touch_ack_->coalesced_event()), true)); } void TouchEventQueue::OnGestureEventAck( const GestureEventWithLatencyInfo& event, InputEventAckState ack_result) { - if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE) - return; - - if (event.event.type != blink::WebInputEvent::GestureScrollUpdate) - return; - // Throttle sending touchmove events as long as the scroll events are handled. // Note that there's no guarantee that this ACK is for the most recent // gesture event (or even part of the current sequence). Worst case, the // delay in updating the absorption state will result in minor UI glitches. // A valid |pending_async_touchmove_| will be flushed when the next event is // forwarded. - send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); + if (event.event.type == blink::WebInputEvent::GestureScrollUpdate) + send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); } void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { @@ -774,10 +737,9 @@ touch_consumer_states_.clear_bit(point.id); } } else if (event.type == WebInputEvent::TouchStart) { - if (touch_scrolling_mode_ == TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE && - ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) { + if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) send_touch_events_async_ = false; - } + for (unsigned i = 0; i < event.touchesLength; ++i) { const WebTouchPoint& point = event.touches[i]; if (point.state == WebTouchPoint::StatePressed) {
diff --git a/content/browser/renderer_host/input/touch_event_queue.h b/content/browser/renderer_host/input/touch_event_queue.h index cdd5d29..584935f 100644 --- a/content/browser/renderer_host/input/touch_event_queue.h +++ b/content/browser/renderer_host/input/touch_event_queue.h
@@ -38,31 +38,9 @@ // A queue for throttling and coalescing touch-events. class CONTENT_EXPORT TouchEventQueue { public: - // Different ways of dealing with touch events during scrolling. - // TODO(rbyers): Remove this once we're confident that touch move absorption - // is OK. http://crbug.com/350430 - enum TouchScrollingMode { - // Send a touchcancel on scroll start and no further touch events for the - // duration of the scroll. Chrome Android's traditional behavior. - TOUCH_SCROLLING_MODE_TOUCHCANCEL, - // Send touchmove events throughout a scroll, blocking on each ACK and - // using the disposition to determine whether a scroll update should be - // sent. Mobile Safari's default overflow scroll behavior. - TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE, - // Send touchmove events throughout a scroll, but throttle sending and - // ignore the ACK as long as scrolling remains possible. Unconsumed scroll - // events return touchmove events to being dispatched synchronously. - TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE, - TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE - }; - struct CONTENT_EXPORT Config { Config(); - // Determines the type of touch scrolling. - // Defaults to TouchEventQueue:::TOUCH_SCROLLING_MODE_DEFAULT. - TouchEventQueue::TouchScrollingMode touch_scrolling_mode; - // Controls whether touch ack timeouts will trigger touch cancellation. // Defaults to 200ms. base::TimeDelta touch_ack_timeout_delay; @@ -212,8 +190,7 @@ // this is a stricter condition than an empty |touch_consumer_states_|, as it // also prevents forwarding of touchstart events for new pointers in the // current sequence. This is only used when the event is synthetically - // cancelled after a touch timeout, or after a scroll event when the - // mode is TOUCH_SCROLLING_MODE_TOUCHCANCEL. + // cancelled after a touch timeout. bool drop_remaining_touches_in_sequence_; // Optional handler for timed-out touch event acks. @@ -232,11 +209,6 @@ scoped_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_; double last_sent_touch_timestamp_sec_; - // How touch events are handled during scrolling. For now this is a global - // setting for experimentation, but we may evolve it into an app-controlled - // mode. - const TouchScrollingMode touch_scrolling_mode_; - // Event is saved to compare pointer positions for new touchmove events. scoped_ptr<blink::WebTouchEvent> last_sent_touchevent_;
diff --git a/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/content/browser/renderer_host/input/touch_event_queue_unittest.cc index afdc436..5af6743 100644 --- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
@@ -37,13 +37,14 @@ : sent_event_count_(0), acked_event_count_(0), last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN), - slop_length_dips_(0), - touch_scrolling_mode_(TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT) {} + slop_length_dips_(0) {} ~TouchEventQueueTest() override {} // testing::Test - void SetUp() override { ResetQueueWithConfig(CreateConfig()); } + void SetUp() override { + ResetQueueWithConfig(TouchEventQueue::Config()); + } void TearDown() override { queue_.reset(); } @@ -78,23 +79,12 @@ } protected: - TouchEventQueue::Config CreateConfig() { - TouchEventQueue::Config config; - config.touch_scrolling_mode = touch_scrolling_mode_; - return config; - } - - void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) { - touch_scrolling_mode_ = mode; - ResetQueueWithConfig(CreateConfig()); - } - void SetUpForTouchMoveSlopTesting(double slop_length_dips) { slop_length_dips_ = slop_length_dips; } void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) { - TouchEventQueue::Config config = CreateConfig(); + TouchEventQueue::Config config; config.touch_ack_timeout_delay = timeout_delay; config.touch_ack_timeout_supported = true; ResetQueueWithConfig(config); @@ -304,7 +294,6 @@ scoped_ptr<InputEventAckState> sync_ack_result_; double slop_length_dips_; gfx::PointF anchor_; - TouchEventQueue::TouchScrollingMode touch_scrolling_mode_; base::MessageLoopForUI message_loop_; }; @@ -988,140 +977,6 @@ EXPECT_EQ(1U, GetAndResetAckedEventCount()); } -// Tests that no TouchEvents are sent to renderer during scrolling. -TEST_F(TouchEventQueueTest, TouchCancelOnScroll) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL); - // Queue a TouchStart. - PressTouchPoint(0, 1); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - - MoveTouchPoint(0, 20, 5); - EXPECT_EQ(1U, queued_event_count()); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - - MoveTouchPoint(0, 30, 15); - EXPECT_EQ(2U, queued_event_count()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - - // Queue another TouchStart. - PressTouchPoint(20, 20); - EXPECT_EQ(3U, queued_event_count()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type); - - WebGestureEvent followup_scroll; - followup_scroll.type = WebInputEvent::GestureScrollBegin; - SetFollowupEvent(followup_scroll); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(2U, queued_event_count()); - EXPECT_TRUE(sent_event().cancelable); - EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type); - - // GestureScrollUpdate inserts a synthetic TouchCancel before the TouchStart. - followup_scroll.type = WebInputEvent::GestureScrollUpdate; - SetFollowupEvent(followup_scroll); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(2U, queued_event_count()); - EXPECT_EQ(WebInputEvent::TouchCancel, sent_event().type); - EXPECT_FALSE(sent_event().cancelable); - EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type); - - // Acking the TouchCancel will result in dispatch of the next TouchStart. - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // The synthetic TouchCancel should not reach client, only the TouchStart. - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type); - - // TouchMove should not be sent to the renderer. - MoveTouchPoint(0, 30, 5); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); - - // GestureScrollUpdates should not change affect touch forwarding. - SendGestureEvent(WebInputEvent::GestureScrollUpdate); - - // TouchEnd should not be sent to the renderer. - ReleaseTouchPoint(0); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); - - ReleaseTouchPoint(0); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); - - // Touch events from a new gesture sequence should be forwarded normally. - PressTouchPoint(80, 10); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - - MoveTouchPoint(0, 80, 20); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - - ReleaseTouchPoint(0); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); -} - -// Tests that a scroll event will not insert a synthetic TouchCancel if there -// was no consumer for the current touch sequence. -TEST_F(TouchEventQueueTest, NoTouchCancelOnScrollIfNoConsumer) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL); - - // Queue a TouchStart. - PressTouchPoint(0, 1); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type); - - // Queue a TouchMove that turns into a GestureScrollBegin. - WebGestureEvent followup_scroll; - followup_scroll.type = WebInputEvent::GestureScrollBegin; - SetFollowupEvent(followup_scroll); - MoveTouchPoint(0, 20, 5); - - // The TouchMove has no consumer, and should be ack'ed immediately. However, - // *no* synthetic TouchCancel should be inserted as the touch sequence - // had no consumer. - EXPECT_EQ(0U, queued_event_count()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, queued_event_count()); - EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type); - - // Subsequent TouchMove's should not be sent to the renderer. - MoveTouchPoint(0, 30, 5); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); - - // TouchEnd should not be sent to the renderer. - ReleaseTouchPoint(0); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); - - // Touch events from a new gesture sequence should be forwarded normally. - PressTouchPoint(80, 10); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); -} - // Tests that IsTouchStartPendingAck works correctly. TEST_F(TouchEventQueueTest, PendingStart) { @@ -1714,31 +1569,7 @@ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state()); } -TEST_F(TouchEventQueueTest, SyncTouchMoveDoesntCancelTouchOnScroll) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE); - // Queue a TouchStart. - PressTouchPoint(0, 1); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - - MoveTouchPoint(0, 20, 5); - EXPECT_EQ(1U, queued_event_count()); - EXPECT_EQ(1U, GetAndResetSentEventCount()); - - // GestureScrollBegin doesn't insert a synthetic TouchCancel. - WebGestureEvent followup_scroll; - followup_scroll.type = WebInputEvent::GestureScrollBegin; - SetFollowupEvent(followup_scroll); - SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - EXPECT_EQ(0U, GetAndResetSentEventCount()); - EXPECT_EQ(1U, GetAndResetAckedEventCount()); - EXPECT_EQ(0U, queued_event_count()); -} - TEST_F(TouchEventQueueTest, AsyncTouch) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - // Queue a TouchStart. PressTouchPoint(0, 1); EXPECT_EQ(1U, GetAndResetSentEventCount()); @@ -1770,8 +1601,6 @@ // Ensure that touchmove's are appropriately throttled during a typical // scroll sequences that transitions between scrolls consumed and unconsumed. TEST_F(TouchEventQueueTest, AsyncTouchThrottledAfterScroll) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - // Process a TouchStart PressTouchPoint(0, 1); EXPECT_EQ(1U, GetAndResetSentEventCount()); @@ -1967,8 +1796,6 @@ } TEST_F(TouchEventQueueTest, AsyncTouchFlushedByTouchEnd) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - PressTouchPoint(0, 0); SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(1U, GetAndResetSentEventCount()); @@ -2024,7 +1851,6 @@ // Ensure that async touch dispatch and touch ack timeout interactions work // appropriately. TEST_F(TouchEventQueueTest, AsyncTouchWithAckTimeout) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); SetUpForTimeoutTesting(DefaultTouchTimeoutDelay()); // The touchstart should start the timeout. @@ -2107,8 +1933,6 @@ // Ensure that if the touch ack for an async touchmove triggers a follow-up // touch event, that follow-up touch will be forwarded appropriately. TEST_F(TouchEventQueueTest, AsyncTouchWithTouchCancelAfterAck) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - PressTouchPoint(0, 0); EXPECT_EQ(1U, GetAndResetSentEventCount()); SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); @@ -2162,8 +1986,6 @@ // Ensure that the async touch is fully reset if the touch sequence restarts // without properly terminating. TEST_F(TouchEventQueueTest, AsyncTouchWithHardTouchStartReset) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - PressTouchPoint(0, 0); EXPECT_EQ(1U, GetAndResetSentEventCount()); SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); @@ -2201,8 +2023,6 @@ } TEST_F(TouchEventQueueTest, TouchAbsorptionWithConsumedFirstMove) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - // Queue a TouchStart. PressTouchPoint(0, 1); SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); @@ -2242,8 +2062,6 @@ } TEST_F(TouchEventQueueTest, TouchStartCancelableDuringScroll) { - SetTouchScrollingMode(TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE); - // Queue a touchstart and touchmove that go unconsumed, transitioning to an // active scroll sequence. PressTouchPoint(0, 1);
diff --git a/content/browser/renderer_host/media/OWNERS b/content/browser/renderer_host/media/OWNERS index 9fd1d61..848d5a5 100644 --- a/content/browser/renderer_host/media/OWNERS +++ b/content/browser/renderer_host/media/OWNERS
@@ -1,7 +1,8 @@ dalecurtis@chromium.org ddorwin@chromium.org -perkj@chromium.org scherkus@chromium.org -tommi@chromium.org -vrk@chromium.org xhwang@chromium.org + +# WebRTC OWNERS. +perkj@chromium.org +tommi@chromium.org
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc index f35ea575..8ff97bdf 100644 --- a/content/browser/renderer_host/media/video_capture_controller.cc +++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -469,23 +469,29 @@ NOTREACHED(); } - libyuv::ConvertToI420(data, - length, - yplane, - yplane_stride, - uplane, - uv_plane_stride, - vplane, - uv_plane_stride, - crop_x, - crop_y, - frame_format.frame_size.width(), - (flip ? -frame_format.frame_size.height() : + if (libyuv::ConvertToI420(data, + length, + yplane, + yplane_stride, + uplane, + uv_plane_stride, + vplane, + uv_plane_stride, + crop_x, + crop_y, + frame_format.frame_size.width(), + (flip ? -frame_format.frame_size.height() : frame_format.frame_size.height()), - new_unrotated_width, - new_unrotated_height, - rotation_mode, - origin_colorspace); + new_unrotated_width, + new_unrotated_height, + rotation_mode, + origin_colorspace) != 0) { + DLOG(WARNING) << "Failed to convert buffer from" + << media::VideoCaptureFormat::PixelFormatToString( + frame_format.pixel_format) + << "to I420."; + return; + } scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapExternalPackedMemory( media::VideoFrame::I420,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 37d745e3..3223ecb 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1075,6 +1075,9 @@ if (IsGpuRasterizationEnabled()) command_line->AppendSwitch(switches::kEnableGpuRasterization); + if (IsThreadedGpuRasterizationEnabled()) + command_line->AppendSwitch(switches::kEnableThreadedGpuRasterization); + int msaa_sample_count = GpuRasterizationMSAASampleCount(); if (msaa_sample_count > 0) { command_line->AppendSwitchASCII( @@ -2065,6 +2068,10 @@ #endif RemoveUserData(kSessionStorageHolderKey); + // RenderProcessGone handlers might navigate or perform other actions that + // require a connection. Ensure that there is one before calling them. + mojo_application_host_.reset(new MojoApplicationHost); + IDMap<IPC::Listener>::iterator iter(&listeners_); while (!iter.IsAtEnd()) { iter.GetCurrentValue()->OnMessageReceived( @@ -2074,8 +2081,6 @@ iter.Advance(); } - mojo_application_host_.reset(new MojoApplicationHost); - // It's possible that one of the calls out to the observers might have caused // this object to be no longer needed. if (delayed_cleanup_needed_)
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index 634cc81..e07f318 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -250,13 +250,13 @@ // the Windows function which is actually a #define. virtual void ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) {} // Show the newly created widget with the specified bounds. // The widget is identified by the route_id passed to CreateNewWidget. virtual void ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) {} + const gfx::Rect& initial_rect) {} // Show the newly created full screen widget. Similar to above. virtual void ShowCreatedFullscreenWidget(int route_id) {}
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 1626be711..2be0fc0 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -1001,19 +1001,19 @@ void RenderViewHostImpl::OnShowView(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { if (is_active_) { delegate_->ShowCreatedWindow( - route_id, disposition, initial_pos, user_gesture); + route_id, disposition, initial_rect, user_gesture); } Send(new ViewMsg_Move_ACK(route_id)); } void RenderViewHostImpl::OnShowWidget(int route_id, - const gfx::Rect& initial_pos) { + const gfx::Rect& initial_rect) { if (is_active_) - delegate_->ShowCreatedWidget(route_id, initial_pos); + delegate_->ShowCreatedWidget(route_id, initial_rect); Send(new ViewMsg_Move_ACK(route_id)); }
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index cc07184..430e34ad 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -171,10 +171,8 @@ void SelectWordAroundCaret() override; #if defined(OS_ANDROID) - virtual void ActivateNearestFindResult(int request_id, - float x, - float y) override; - virtual void RequestFindMatchRects(int current_version) override; + void ActivateNearestFindResult(int request_id, float x, float y) override; + void RequestFindMatchRects(int current_version) override; #endif void set_delegate(RenderViewHostDelegate* d) { @@ -334,9 +332,9 @@ // IPC message handlers. void OnShowView(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture); - void OnShowWidget(int route_id, const gfx::Rect& initial_pos); + void OnShowWidget(int route_id, const gfx::Rect& initial_rect); void OnShowFullscreenWidget(int route_id); void OnRunModal(int opener_id, IPC::Message* reply_msg); void OnRenderViewReady();
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 05ad072..5272547 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -186,6 +186,7 @@ has_touch_handler_(false), next_browser_snapshot_id_(1), owned_by_render_frame_host_(false), + is_focused_(false), weak_factory_(this) { CHECK(delegate_); if (routing_id_ == MSG_ROUTING_NONE) { @@ -663,10 +664,14 @@ } void RenderWidgetHostImpl::Focus() { + is_focused_ = true; + Send(new InputMsg_SetFocus(routing_id_, true)); } void RenderWidgetHostImpl::Blur() { + is_focused_ = false; + // If there is a pending mouse lock request, we don't want to reject it at // this point. The user can switch focus back to this view and approve the // request later.
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 99f2aa3..a5136ce 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -140,8 +140,8 @@ const SkColorType color_type) override; bool CanCopyFromBackingStore() override; #if defined(OS_ANDROID) - virtual void LockBackingStore() override; - virtual void UnlockBackingStore() override; + void LockBackingStore() override; + void UnlockBackingStore() override; #endif void ForwardMouseEvent(const blink::WebMouseEvent& mouse_event) override; void ForwardWheelEvent(const blink::WebMouseWheelEvent& wheel_event) override; @@ -228,6 +228,15 @@ virtual void GotFocus(); virtual void LostCapture(); + // Indicates whether the RenderWidgetHost thinks it is focused. + // This is different from RenderWidgetHostView::HasFocus() in the sense that + // it reflects what the renderer process knows: it saves the state that is + // sent/received. + // RenderWidgetHostView::HasFocus() is checking whether the view is focused so + // it is possible in some edge cases that a view was requested to be focused + // but it failed, thus HasFocus() returns false. + bool is_focused() const { return is_focused_; } + // Called to notify the RenderWidget that it has lost the mouse lock. virtual void LostMouseLock(); @@ -841,6 +850,12 @@ // object does not self destroy. bool owned_by_render_frame_host_; + // Indicates whether this RenderWidgetHost thinks is focused. This is trying + // to match what the renderer process knows. It is different from + // RenderWidgetHostView::HasFocus in that in that the focus request may fail, + // causing HasFocus to return false when is_focused_ is true. + bool is_focused_; + base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 11d2113a..0c6a5fc 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -89,115 +89,110 @@ public: RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget, ContentViewCoreImpl* content_view_core); - virtual ~RenderWidgetHostViewAndroid(); + ~RenderWidgetHostViewAndroid() override; // RenderWidgetHostView implementation. - virtual bool OnMessageReceived(const IPC::Message& msg) override; - virtual void InitAsChild(gfx::NativeView parent_view) override; - virtual void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) override; - virtual void InitAsFullscreen( - RenderWidgetHostView* reference_host_view) override; - virtual RenderWidgetHost* GetRenderWidgetHost() const override; - virtual void SetSize(const gfx::Size& size) override; - virtual void SetBounds(const gfx::Rect& rect) override; - virtual gfx::Vector2dF GetLastScrollOffset() const override; - virtual gfx::NativeView GetNativeView() const override; - virtual gfx::NativeViewId GetNativeViewId() const override; - virtual gfx::NativeViewAccessible GetNativeViewAccessible() override; - virtual void MovePluginWindows( - const std::vector<WebPluginGeometry>& moves) override; - virtual void Focus() override; - virtual void Blur() override; - virtual bool HasFocus() const override; - virtual bool IsSurfaceAvailableForCopy() const override; - virtual void Show() override; - virtual void Hide() override; - virtual bool IsShowing() override; - virtual gfx::Rect GetViewBounds() const override; - virtual gfx::Size GetPhysicalBackingSize() const override; - virtual bool DoTopControlsShrinkBlinkSize() const override; - virtual float GetTopControlsHeight() const override; - virtual void UpdateCursor(const WebCursor& cursor) override; - virtual void SetIsLoading(bool is_loading) override; - virtual void TextInputTypeChanged(ui::TextInputType type, - ui::TextInputMode input_mode, - bool can_compose_inline, - int flags) override; - virtual void ImeCancelComposition() override; - virtual void ImeCompositionRangeChanged( + bool OnMessageReceived(const IPC::Message& msg) override; + void InitAsChild(gfx::NativeView parent_view) override; + void InitAsPopup(RenderWidgetHostView* parent_host_view, + const gfx::Rect& pos) override; + void InitAsFullscreen(RenderWidgetHostView* reference_host_view) override; + RenderWidgetHost* GetRenderWidgetHost() const override; + void SetSize(const gfx::Size& size) override; + void SetBounds(const gfx::Rect& rect) override; + gfx::Vector2dF GetLastScrollOffset() const override; + gfx::NativeView GetNativeView() const override; + gfx::NativeViewId GetNativeViewId() const override; + gfx::NativeViewAccessible GetNativeViewAccessible() override; + void MovePluginWindows(const std::vector<WebPluginGeometry>& moves) override; + void Focus() override; + void Blur() override; + bool HasFocus() const override; + bool IsSurfaceAvailableForCopy() const override; + void Show() override; + void Hide() override; + bool IsShowing() override; + gfx::Rect GetViewBounds() const override; + gfx::Size GetPhysicalBackingSize() const override; + bool DoTopControlsShrinkBlinkSize() const override; + float GetTopControlsHeight() const override; + void UpdateCursor(const WebCursor& cursor) override; + void SetIsLoading(bool is_loading) override; + void TextInputTypeChanged(ui::TextInputType type, + ui::TextInputMode input_mode, + bool can_compose_inline, + int flags) override; + void ImeCancelComposition() override; + void ImeCompositionRangeChanged( const gfx::Range& range, const std::vector<gfx::Rect>& character_bounds) override; - virtual void FocusedNodeChanged(bool is_editable_node) override; - virtual void RenderProcessGone(base::TerminationStatus status, - int error_code) override; - virtual void Destroy() override; - virtual void SetTooltipText(const base::string16& tooltip_text) override; - virtual void SelectionChanged(const base::string16& text, - size_t offset, - const gfx::Range& range) override; - virtual void SelectionBoundsChanged( + void FocusedNodeChanged(bool is_editable_node) override; + void RenderProcessGone(base::TerminationStatus status, + int error_code) override; + void Destroy() override; + void SetTooltipText(const base::string16& tooltip_text) override; + void SelectionChanged(const base::string16& text, + size_t offset, + const gfx::Range& range) override; + void SelectionBoundsChanged( const ViewHostMsg_SelectionBounds_Params& params) override; - virtual void AcceleratedSurfaceInitialized(int route_id) override; - virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) override; - virtual void SetBackgroundColor(SkColor color) override; - virtual void CopyFromCompositingSurface( - const gfx::Rect& src_subrect, - const gfx::Size& dst_size, - ReadbackRequestCallback& callback, - const SkColorType color_type) override; - virtual void CopyFromCompositingSurfaceToVideoFrame( + void AcceleratedSurfaceInitialized(int route_id) override; + bool HasAcceleratedSurface(const gfx::Size& desired_size) override; + void SetBackgroundColor(SkColor color) override; + void CopyFromCompositingSurface(const gfx::Rect& src_subrect, + const gfx::Size& dst_size, + ReadbackRequestCallback& callback, + const SkColorType color_type) override; + void CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) override; - virtual bool CanCopyToVideoFrame() const override; - virtual void GetScreenInfo(blink::WebScreenInfo* results) override; - virtual gfx::Rect GetBoundsInRootWindow() override; - virtual gfx::GLSurfaceHandle GetCompositingSurface() override; - virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, - InputEventAckState ack_result) override; - virtual InputEventAckState FilterInputEvent( + bool CanCopyToVideoFrame() const override; + void GetScreenInfo(blink::WebScreenInfo* results) override; + gfx::Rect GetBoundsInRootWindow() override; + gfx::GLSurfaceHandle GetCompositingSurface() override; + void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, + InputEventAckState ack_result) override; + InputEventAckState FilterInputEvent( const blink::WebInputEvent& input_event) override; - virtual void OnSetNeedsFlushInput() override; - virtual void GestureEventAck(const blink::WebGestureEvent& event, - InputEventAckState ack_result) override; - virtual BrowserAccessibilityManager* CreateBrowserAccessibilityManager( + void OnSetNeedsFlushInput() override; + void GestureEventAck(const blink::WebGestureEvent& event, + InputEventAckState ack_result) override; + BrowserAccessibilityManager* CreateBrowserAccessibilityManager( BrowserAccessibilityDelegate* delegate) override; - virtual bool LockMouse() override; - virtual void UnlockMouse() override; - virtual void OnSwapCompositorFrame( - uint32 output_surface_id, - scoped_ptr<cc::CompositorFrame> frame) override; - virtual void DidOverscroll(const DidOverscrollParams& params) override; - virtual void DidStopFlinging() override; - virtual void ShowDisambiguationPopup(const gfx::Rect& rect_pixels, - const SkBitmap& zoomed_bitmap) override; - virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() - override; - virtual void LockCompositingSurface() override; - virtual void UnlockCompositingSurface() override; - virtual void OnTextSurroundingSelectionResponse(const base::string16& content, - size_t start_offset, - size_t end_offset) override; + bool LockMouse() override; + void UnlockMouse() override; + void OnSwapCompositorFrame(uint32 output_surface_id, + scoped_ptr<cc::CompositorFrame> frame) override; + void DidOverscroll(const DidOverscrollParams& params) override; + void DidStopFlinging() override; + void ShowDisambiguationPopup(const gfx::Rect& rect_pixels, + const SkBitmap& zoomed_bitmap) override; + scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() override; + void LockCompositingSurface() override; + void UnlockCompositingSurface() override; + void OnTextSurroundingSelectionResponse(const base::string16& content, + size_t start_offset, + size_t end_offset) override; // cc::DelegatedFrameResourceCollectionClient implementation. - virtual void UnusedResourcesAreAvailable() override; + void UnusedResourcesAreAvailable() override; // ui::GestureProviderClient implementation. - virtual void OnGestureEvent(const ui::GestureEventData& gesture) override; + void OnGestureEvent(const ui::GestureEventData& gesture) override; // ui::WindowAndroidObserver implementation. - virtual void OnCompositingDidCommit() override; - virtual void OnAttachCompositor() override; - virtual void OnDetachCompositor() override; - virtual void OnVSync(base::TimeTicks frame_time, - base::TimeDelta vsync_period) override; - virtual void OnAnimate(base::TimeTicks begin_frame_time) override; + void OnCompositingDidCommit() override; + void OnAttachCompositor() override; + void OnDetachCompositor() override; + void OnVSync(base::TimeTicks frame_time, + base::TimeDelta vsync_period) override; + void OnAnimate(base::TimeTicks begin_frame_time) override; // DelegatedFrameEvictor implementation - virtual void EvictDelegatedFrame() override; + void EvictDelegatedFrame() override; - virtual SkColorType PreferredReadbackFormat() override; + SkColorType PreferredReadbackFormat() override; // StylusTextSelectorClient implementation. void OnStylusSelectBegin(float x0, float y0, float x1, float y1) override; @@ -206,15 +201,15 @@ void OnStylusSelectTap(base::TimeTicks time, float x, float y) override; // ui::TouchSelectionControllerClient implementation. - virtual bool SupportsAnimation() const override; - virtual void SetNeedsAnimate() override; - virtual void MoveCaret(const gfx::PointF& position) override; - virtual void MoveRangeSelectionExtent(const gfx::PointF& extent) override; - virtual void SelectBetweenCoordinates(const gfx::PointF& base, - const gfx::PointF& extent) override; - virtual void OnSelectionEvent(ui::SelectionEventType event, - const gfx::PointF& anchor_position) override; - virtual scoped_ptr<ui::TouchHandleDrawable> CreateDrawable() override; + bool SupportsAnimation() const override; + void SetNeedsAnimate() override; + void MoveCaret(const gfx::PointF& position) override; + void MoveRangeSelectionExtent(const gfx::PointF& extent) override; + void SelectBetweenCoordinates(const gfx::PointF& base, + const gfx::PointF& extent) override; + void OnSelectionEvent(ui::SelectionEventType event, + const gfx::PointF& anchor_position) override; + scoped_ptr<ui::TouchHandleDrawable> CreateDrawable() override; // Non-virtual methods void SetContentViewCore(ContentViewCoreImpl* content_view_core);
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 3189f94..9f1450b 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -193,7 +193,7 @@ // Perform all the initialization steps necessary for this object to represent // a popup (such as a <select> dropdown), then shows the popup at |pos|. virtual void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) = 0; + const gfx::Rect& bounds) = 0; // Perform all the initialization steps necessary for this object to represent // a full screen window.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 57c9369..d1be2b8 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -148,6 +148,18 @@ // Event monitor for scroll wheel end event. id endWheelMonitor_; + // When a gesture starts, the system does not inform the view of which type + // of gesture is happening (magnify, rotate, etc), rather, it just informs + // the view that some as-yet-undefined gesture is starting. Capture the + // information about the gesture's beginning event here. It will be used to + // create a specific gesture begin event later. + scoped_ptr<blink::WebGestureEvent> gestureBeginEvent_; + + // This is set if a GesturePinchBegin event has been sent in the lifetime of + // |gestureBeginEvent_|. If set, a GesturePinchEnd will be sent when the + // gesture ends. + BOOL gestureBeginPinchSent_; + // If true then escape key down events are suppressed until the first escape // key up event. (The up event is suppressed as well). This is used by the // flash fullscreen code to avoid sending a key up event without a matching
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 01e60c5..b0150f8 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2239,19 +2239,37 @@ - (void)beginGestureWithEvent:(NSEvent*)event { [responderDelegate_ beginGestureWithEvent:event]; + gestureBeginEvent_.reset( + new WebGestureEvent(WebInputEventFactory::gestureEvent(event, self))); } + - (void)endGestureWithEvent:(NSEvent*)event { [responderDelegate_ endGestureWithEvent:event]; + gestureBeginEvent_.reset(); + + if (!renderWidgetHostView_->render_widget_host_) + return; + + if (gestureBeginPinchSent_) { + WebGestureEvent endEvent(WebInputEventFactory::gestureEvent(event, self)); + endEvent.type = WebInputEvent::GesturePinchEnd; + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(endEvent); + gestureBeginPinchSent_ = NO; + } } + - (void)touchesMovedWithEvent:(NSEvent*)event { [responderDelegate_ touchesMovedWithEvent:event]; } + - (void)touchesBeganWithEvent:(NSEvent*)event { [responderDelegate_ touchesBeganWithEvent:event]; } + - (void)touchesCancelledWithEvent:(NSEvent*)event { [responderDelegate_ touchesCancelledWithEvent:event]; } + - (void)touchesEndedWithEvent:(NSEvent*)event { [responderDelegate_ touchesEndedWithEvent:event]; } @@ -2330,16 +2348,27 @@ // Called repeatedly during a pinch gesture, with incremental change values. - (void)magnifyWithEvent:(NSEvent*)event { - if (renderWidgetHostView_->render_widget_host_) { - // Send a GesturePinchUpdate event. - // Note that we don't attempt to bracket these by GesturePinchBegin/End (or - // GestureSrollBegin/End) as is done for touchscreen. Keeping track of when - // a pinch is active would take a little more work here, and we don't need - // it for anything yet. - const WebGestureEvent& webEvent = - WebInputEventFactory::gestureEvent(event, self); - renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); + if (!renderWidgetHostView_->render_widget_host_) + return; + + // If, due to nesting of multiple gestures (e.g, from multiple touch + // devices), the beginning of the gesture has been lost, skip the remainder + // of the gesture. + if (!gestureBeginEvent_) + return; + + // Send a GesturePinchBegin event if none has been sent yet. + if (!gestureBeginPinchSent_) { + WebGestureEvent beginEvent(*gestureBeginEvent_); + beginEvent.type = WebInputEvent::GesturePinchBegin; + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(beginEvent); + gestureBeginPinchSent_ = YES; } + + // Send a GesturePinchUpdate event. + const WebGestureEvent& updateEvent = + WebInputEventFactory::gestureEvent(event, self); + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(updateEvent); } - (void)viewWillMoveToWindow:(NSWindow*)newWindow {
diff --git a/content/browser/resources/media/OWNERS b/content/browser/resources/media/OWNERS index a55b92f..ae057213 100644 --- a/content/browser/resources/media/OWNERS +++ b/content/browser/resources/media/OWNERS
@@ -2,5 +2,4 @@ ddorwin@chromium.org scherkus@chromium.org tommi@chromium.org -vrk@chromium.org xhwang@chromium.org
diff --git a/content/browser/screen_orientation/screen_orientation_delegate_android.h b/content/browser/screen_orientation/screen_orientation_delegate_android.h index efcdafe..063a569 100644 --- a/content/browser/screen_orientation/screen_orientation_delegate_android.h +++ b/content/browser/screen_orientation/screen_orientation_delegate_android.h
@@ -20,7 +20,7 @@ class ScreenOrientationDelegateAndroid : public ScreenOrientationDelegate { public: ScreenOrientationDelegateAndroid(); - virtual ~ScreenOrientationDelegateAndroid(); + ~ScreenOrientationDelegateAndroid() override; static bool Register(JNIEnv* env);
diff --git a/content/browser/screen_orientation/screen_orientation_message_filter_android.h b/content/browser/screen_orientation/screen_orientation_message_filter_android.h index 9a01ed4..9d85fe6 100644 --- a/content/browser/screen_orientation/screen_orientation_message_filter_android.h +++ b/content/browser/screen_orientation/screen_orientation_message_filter_android.h
@@ -14,10 +14,10 @@ ScreenOrientationMessageFilterAndroid(); // BrowserMessageFilter implementation. - virtual bool OnMessageReceived(const IPC::Message& message) override; + bool OnMessageReceived(const IPC::Message& message) override; private: - virtual ~ScreenOrientationMessageFilterAndroid(); + ~ScreenOrientationMessageFilterAndroid() override; void OnStartListening(); void OnStopListening();
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 4e357443..443c87d 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -21,11 +21,14 @@ #include "content/common/service_worker/service_worker_types.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "content/public/common/referrer.h" +#include "content/public/common/security_style.h" +#include "content/public/common/ssl_status.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -766,45 +769,110 @@ } IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, Reload) { - const std::string kPageUrl = "/service_worker/reload.html"; - const std::string kWorkerUrl = "/service_worker/fetch_event_reload.js"; - { - scoped_refptr<WorkerActivatedObserver> observer = - new WorkerActivatedObserver(wrapper()); - observer->Init(); - public_context()->RegisterServiceWorker( - embedded_test_server()->GetURL(kPageUrl), - embedded_test_server()->GetURL(kWorkerUrl), - base::Bind(&ExpectResultAndRun, true, base::Bind(&base::DoNothing))); - observer->Wait(); - } - { - const base::string16 title = base::ASCIIToUTF16("reload=false"); - TitleWatcher title_watcher(shell()->web_contents(), title); - NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl)); - EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); - } - { - const base::string16 title = base::ASCIIToUTF16("reload=true"); - TitleWatcher title_watcher(shell()->web_contents(), title); - ReloadBlockUntilNavigationsComplete(shell(), 1); - EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); - } + const char kPageUrl[] = "/service_worker/reload.html"; + const char kWorkerUrl[] = "/service_worker/fetch_event_reload.js"; + scoped_refptr<WorkerActivatedObserver> observer = + new WorkerActivatedObserver(wrapper()); + observer->Init(); + public_context()->RegisterServiceWorker( + embedded_test_server()->GetURL(kPageUrl), + embedded_test_server()->GetURL(kWorkerUrl), + base::Bind(&ExpectResultAndRun, true, base::Bind(&base::DoNothing))); + observer->Wait(); + + const base::string16 title1 = base::ASCIIToUTF16("reload=false"); + TitleWatcher title_watcher1(shell()->web_contents(), title1); + NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl)); + EXPECT_EQ(title1, title_watcher1.WaitAndGetTitle()); + + const base::string16 title2 = base::ASCIIToUTF16("reload=true"); + TitleWatcher title_watcher2(shell()->web_contents(), title2); + ReloadBlockUntilNavigationsComplete(shell(), 1); + EXPECT_EQ(title2, title_watcher2.WaitAndGetTitle()); + shell()->Close(); - { - base::RunLoop run_loop; - public_context()->UnregisterServiceWorker( - embedded_test_server()->GetURL(kPageUrl), - base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); - run_loop.Run(); - } + + base::RunLoop run_loop; + public_context()->UnregisterServiceWorker( + embedded_test_server()->GetURL(kPageUrl), + base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, + ResponseFromHTTPSServiceWorkerIsMarkedAsSecure) { + const char kPageUrl[] = "files/service_worker/fetch_event_blob.html"; + const char kWorkerUrl[] = "files/service_worker/fetch_event_blob.js"; + net::SpawnedTestServer https_server( + net::SpawnedTestServer::TYPE_HTTPS, + net::BaseTestServer::SSLOptions( + net::BaseTestServer::SSLOptions::CERT_OK), + base::FilePath(FILE_PATH_LITERAL("content/test/data/"))); + ASSERT_TRUE(https_server.Start()); + + scoped_refptr<WorkerActivatedObserver> observer = + new WorkerActivatedObserver(wrapper()); + observer->Init(); + public_context()->RegisterServiceWorker( + https_server.GetURL(kPageUrl), + https_server.GetURL(kWorkerUrl), + base::Bind(&ExpectResultAndRun, true, base::Bind(&base::DoNothing))); + observer->Wait(); + + const base::string16 title = base::ASCIIToUTF16("Title"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), https_server.GetURL(kPageUrl)); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + NavigationEntry* entry = + shell()->web_contents()->GetController().GetVisibleEntry(); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->GetSSL().security_style); + + shell()->Close(); + + base::RunLoop run_loop; + public_context()->UnregisterServiceWorker( + https_server.GetURL(kPageUrl), + base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); + run_loop.Run(); +} + +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, + ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure) { + const char kPageUrl[] = "/service_worker/fetch_event_blob.html"; + const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; + scoped_refptr<WorkerActivatedObserver> observer = + new WorkerActivatedObserver(wrapper()); + observer->Init(); + public_context()->RegisterServiceWorker( + embedded_test_server()->GetURL(kPageUrl), + embedded_test_server()->GetURL(kWorkerUrl), + base::Bind(&ExpectResultAndRun, true, base::Bind(&base::DoNothing))); + observer->Wait(); + + const base::string16 title = base::ASCIIToUTF16("Title"); + TitleWatcher title_watcher(shell()->web_contents(), title); + NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl)); + EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); + EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + NavigationEntry* entry = + shell()->web_contents()->GetController().GetVisibleEntry(); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->GetSSL().security_style); + + shell()->Close(); + + base::RunLoop run_loop; + public_context()->UnregisterServiceWorker( + embedded_test_server()->GetURL(kPageUrl), + base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); + run_loop.Run(); } IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ImportsBustMemcache) { - const std::string kScopeUrl = "/service_worker/imports_bust_memcache_scope/"; - const std::string kPageUrl = "/service_worker/imports_bust_memcache.html"; - const std::string kScriptUrl = "/service_worker/worker_with_one_import.js"; - const std::string kImportUrl = "/service_worker/long_lived_import.js"; + const char kScopeUrl[] = "/service_worker/imports_bust_memcache_scope/"; + const char kPageUrl[] = "/service_worker/imports_bust_memcache.html"; + const char kScriptUrl[] = "/service_worker/worker_with_one_import.js"; + const char kImportUrl[] = "/service_worker/long_lived_import.js"; const base::string16 kOKTitle(base::ASCIIToUTF16("OK")); const base::string16 kFailTitle(base::ASCIIToUTF16("FAIL")); @@ -878,8 +946,8 @@ shell()->Close(); EXPECT_EQ(0, CountRenderProcessHosts()); - const std::string kWorkerUrl = "/service_worker/fetch_event.js"; - const std::string kScope = "/service_worker/"; + const char kWorkerUrl[] = "/service_worker/fetch_event.js"; + const char kScope[] = "/service_worker/"; // Unregistering nothing should return false. { @@ -953,7 +1021,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, CrossSiteTransfer) { // The first page registers a service worker. - const std::string kRegisterPageUrl = "/service_worker/cross_site_xfer.html"; + const char kRegisterPageUrl[] = "/service_worker/cross_site_xfer.html"; const base::string16 kOKTitle1(base::ASCIIToUTF16("OK_1")); const base::string16 kFailTitle1(base::ASCIIToUTF16("FAIL_1")); content::TitleWatcher title_watcher1(shell()->web_contents(), kOKTitle1); @@ -966,7 +1034,7 @@ ShellContentBrowserClient::SetSwapProcessesForRedirect(true); // The second pages loads via the serviceworker including a subresource. - const std::string kConfirmPageUrl = + const char kConfirmPageUrl[] = "/service_worker/cross_site_xfer_scope/" "cross_site_xfer_confirm_via_serviceworker.html"; const base::string16 kOKTitle2(base::ASCIIToUTF16("OK_2"));
diff --git a/content/browser/service_worker/service_worker_context_request_handler.cc b/content/browser/service_worker/service_worker_context_request_handler.cc index 3bd8418..dad2c75 100644 --- a/content/browser/service_worker/service_worker_context_request_handler.cc +++ b/content/browser/service_worker/service_worker_context_request_handler.cc
@@ -83,7 +83,7 @@ int64 response_id = kInvalidServiceWorkerResponseId; if (ShouldReadFromScriptCache(request->url(), &response_id)) { return new ServiceWorkerReadFromCacheJob( - request, network_delegate, context_, response_id); + request, network_delegate, context_, version_, response_id); } // NULL means use the network.
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index c5f9b16..46f9074 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -57,7 +57,8 @@ provider_id_(provider_id), context_(context), dispatcher_host_(dispatcher_host), - allow_association_(true) { + allow_association_(true), + is_claiming_(false) { DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); if (render_frame_id == MSG_ROUTING_NONE) { // Actual thread id is set when the worker context gets started. @@ -124,7 +125,7 @@ return; // Could be NULL in some tests. bool should_notify_controllerchange = - previous_version && version && version->skip_waiting(); + is_claiming_ || (previous_version && version && version->skip_waiting()); // SetController message should be sent only for the document context. DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); @@ -159,10 +160,7 @@ void ServiceWorkerProviderHost::AssociateRegistration( ServiceWorkerRegistration* registration) { DCHECK(CanAssociateRegistration(registration)); - if (associated_registration_.get()) - DecreaseProcessReference(associated_registration_->pattern()); IncreaseProcessReference(registration->pattern()); - associated_registration_ = registration; associated_registration_->AddListener(this); SendAssociateRegistrationMessage(); @@ -282,6 +280,19 @@ IncreaseProcessReference(pattern); } +void ServiceWorkerProviderHost::ClaimedByRegistration( + ServiceWorkerRegistration* registration) { + DCHECK(registration->active_version()); + is_claiming_ = true; + if (registration == associated_registration_) { + SetControllerVersionAttribute(registration->active_version()); + } else if (allow_association_) { + DisassociateRegistration(); + AssociateRegistration(registration); + } + is_claiming_ = false; +} + void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_);
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 99898a9..b3e60c1 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -152,6 +152,9 @@ // be removed in destructor. void AddScopedProcessReferenceToPattern(const GURL& pattern); + // |registration| claims the document to be controlled. + void ClaimedByRegistration(ServiceWorkerRegistration* registration); + // Methods to support cross site navigations. void PrepareForCrossSiteTransfer(); void CompleteCrossSiteTransfer( @@ -220,6 +223,7 @@ base::WeakPtr<ServiceWorkerContextCore> context_; ServiceWorkerDispatcherHost* dispatcher_host_; bool allow_association_; + bool is_claiming_; std::vector<base::Closure> queued_events_;
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.cc b/content/browser/service_worker/service_worker_read_from_cache_job.cc index 84b7988..135c5898 100644 --- a/content/browser/service_worker/service_worker_read_from_cache_job.cc +++ b/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -26,9 +26,11 @@ net::URLRequest* request, net::NetworkDelegate* network_delegate, base::WeakPtr<ServiceWorkerContextCore> context, + const scoped_refptr<ServiceWorkerVersion>& version, int64 response_id) : net::URLRequestJob(request, network_delegate), context_(context), + version_(version), response_id_(response_id), has_been_killed_(false), weak_factory_(this) { @@ -164,6 +166,8 @@ if (is_range_request()) SetupRangeResponse(http_info_io_buffer_->response_data_size); http_info_io_buffer_ = NULL; + if (request_->url() == version_->script_url()) + version_->SetMainScriptHttpResponseInfo(*http_info_); TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerReadFromCacheJob::ReadInfo", this,
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.h b/content/browser/service_worker/service_worker_read_from_cache_job.h index 2a290d3..48c2aa5 100644 --- a/content/browser/service_worker/service_worker_read_from_cache_job.h +++ b/content/browser/service_worker/service_worker_read_from_cache_job.h
@@ -18,6 +18,7 @@ class ServiceWorkerContextCore; class ServiceWorkerResponseReader; +class ServiceWorkerVersion; // A URLRequestJob derivative used to retrieve script resources // from the service workers script cache. It uses a response reader @@ -29,6 +30,7 @@ net::URLRequest* request, net::NetworkDelegate* network_delegate, base::WeakPtr<ServiceWorkerContextCore> context, + const scoped_refptr<ServiceWorkerVersion>& version, int64 response_id); private: @@ -55,6 +57,7 @@ void SetupRangeResponse(int response_data_size); base::WeakPtr<ServiceWorkerContextCore> context_; + scoped_refptr<ServiceWorkerVersion> version_; int64 response_id_; scoped_ptr<ServiceWorkerResponseReader> reader_; scoped_refptr<HttpResponseInfoIOBuffer> http_info_io_buffer_;
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc index a4fac5c..2640e5e 100644 --- a/content/browser/service_worker/service_worker_registration.cc +++ b/content/browser/service_worker/service_worker_registration.cc
@@ -161,6 +161,16 @@ ActivateWaitingVersion(); } +void ServiceWorkerRegistration::ClaimClients(const StatusCallback& callback) { + DCHECK(context_); + DCHECK(active_version()); + // TODO(xiang): Should better not hit the database http://crbug.com/454250. + context_->storage()->GetRegistrationsForOrigin( + pattern_.GetOrigin(), + base::Bind(&ServiceWorkerRegistration::DidGetRegistrationsForClaimClients, + this, callback, active_version_)); +} + void ServiceWorkerRegistration::ClearWhenReady() { DCHECK(context_); if (is_uninstalling_) @@ -360,4 +370,48 @@ callback.Run(status); } +void ServiceWorkerRegistration::DidGetRegistrationsForClaimClients( + const StatusCallback& callback, + scoped_refptr<ServiceWorkerVersion> version, + const std::vector<ServiceWorkerRegistrationInfo>& registrations) { + if (!context_) { + callback.Run(SERVICE_WORKER_ERROR_ABORT); + return; + } + if (!active_version() || version != active_version()) { + callback.Run(SERVICE_WORKER_ERROR_STATE); + return; + } + + for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = + context_->GetProviderHostIterator(); + !it->IsAtEnd(); it->Advance()) { + ServiceWorkerProviderHost* host = it->GetProviderHost(); + if (ShouldClaim(host, registrations)) + host->ClaimedByRegistration(this); + } + callback.Run(SERVICE_WORKER_OK); +} + +bool ServiceWorkerRegistration::ShouldClaim( + ServiceWorkerProviderHost* provider_host, + const std::vector<ServiceWorkerRegistrationInfo>& registrations) { + if (provider_host->controlling_version() == active_version()) + return false; + + LongestScopeMatcher matcher(provider_host->document_url()); + if (!matcher.MatchLongest(pattern_)) + return false; + for (const ServiceWorkerRegistrationInfo& info : registrations) { + ServiceWorkerRegistration* registration = + context_->GetLiveRegistration(info.registration_id); + if (registration && + (registration->is_uninstalling() || registration->is_uninstalled())) + continue; + if (matcher.MatchLongest(info.pattern)) + return false; + } + return true; +} + } // namespace content
diff --git a/content/browser/service_worker/service_worker_registration.h b/content/browser/service_worker/service_worker_registration.h index 6a8d11fc..2618483 100644 --- a/content/browser/service_worker/service_worker_registration.h +++ b/content/browser/service_worker/service_worker_registration.h
@@ -109,6 +109,10 @@ // initiated immediately. void ActivateWaitingVersionWhenReady(); + // Takes over control of provider hosts which are currently not controlled or + // controlled by other registrations. + void ClaimClients(const StatusCallback& callback); + // Triggers the [[ClearRegistration]] algorithm when the currently // active version has no controllees. Deletes this registration // from storage immediately. @@ -163,6 +167,14 @@ scoped_refptr<ServiceWorkerVersion> version, ServiceWorkerStatusCode status); + void DidGetRegistrationsForClaimClients( + const StatusCallback& callback, + scoped_refptr<ServiceWorkerVersion> version, + const std::vector<ServiceWorkerRegistrationInfo>& registrations); + bool ShouldClaim( + ServiceWorkerProviderHost* provider_host, + const std::vector<ServiceWorkerRegistrationInfo>& registration_infos); + const GURL pattern_; const int64 registration_id_; bool is_deleted_;
diff --git a/content/browser/service_worker/service_worker_registration_status.cc b/content/browser/service_worker/service_worker_registration_status.cc index 548ec5f3..84f293e 100644 --- a/content/browser/service_worker/service_worker_registration_status.cc +++ b/content/browser/service_worker/service_worker_registration_status.cc
@@ -53,6 +53,7 @@ case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND: case SERVICE_WORKER_ERROR_EXISTS: case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: + case SERVICE_WORKER_ERROR_STATE: // Unexpected, or should have bailed out before calling this, or we don't // have a corresponding blink error code yet. break; // Fall through to NOTREACHED().
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc index ecac9528..4c6c59d 100644 --- a/content/browser/service_worker/service_worker_url_request_job.cc +++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -112,7 +112,9 @@ void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { if (!http_info()) return; + const base::Time request_time = info->request_time; *info = *http_info(); + info->request_time = request_time; info->response_time = response_time_; } @@ -538,6 +540,16 @@ fetch_end_time_ = base::TimeTicks::Now(); load_timing_info_.send_end = fetch_end_time_; + // Creates a new HttpResponseInfo using the the ServiceWorker script's + // HttpResponseInfo to show HTTPS padlock. + // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a + // ServiceWorker, we have to check the security level of the responses. + DCHECK(!http_response_info_); + const net::HttpResponseInfo* main_script_http_info = + provider_host_->active_version()->GetMainScriptHttpResponseInfo(); + DCHECK(main_script_http_info); + http_response_info_.reset(new net::HttpResponseInfo(*main_script_http_info)); + // Set up a request for reading the stream. if (response.stream_url.is_valid()) { DCHECK(response.blob_uuid.empty()); @@ -610,8 +622,11 @@ } void ServiceWorkerURLRequestJob::CommitResponseHeader() { - http_response_info_.reset(new net::HttpResponseInfo()); + if (!http_response_info_) + http_response_info_.reset(new net::HttpResponseInfo()); http_response_info_->headers.swap(http_response_headers_); + http_response_info_->vary_data = net::HttpVaryData(); + http_response_info_->metadata = nullptr; NotifyHeadersComplete(); }
diff --git a/content/browser/service_worker/service_worker_url_request_job.h b/content/browser/service_worker/service_worker_url_request_job.h index 7ce8007..0081740 100644 --- a/content/browser/service_worker/service_worker_url_request_job.h +++ b/content/browser/service_worker/service_worker_url_request_job.h
@@ -108,8 +108,6 @@ // StreamRegisterObserver override: void OnStreamRegistered(Stream* stream) override; - const net::HttpResponseInfo* http_info() const; - void GetExtraResponseInfo( bool* was_fetched_via_service_worker, bool* was_fallback_required_by_service_worker, @@ -163,6 +161,8 @@ // Releases the resources for streaming. void ClearStream(); + const net::HttpResponseInfo* http_info() const; + base::WeakPtr<ServiceWorkerProviderHost> provider_host_; // Timing info to show on the popup in Devtools' Network tab.
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc index 28986de..8103b8f4 100644 --- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc +++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -31,8 +31,11 @@ #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/io_buffer.h" +#include "net/base/test_data_directory.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "net/ssl/ssl_info.h" +#include "net/test/cert_test_util.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job_factory_impl.h" @@ -125,6 +128,15 @@ GURL("http://example.com/service_worker.js"), 1L, helper_->context()->AsWeakPtr()); + net::HttpResponseInfo http_info; + http_info.ssl_info.cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), + "ok_cert.pem"); + EXPECT_TRUE(http_info.ssl_info.is_valid()); + http_info.ssl_info.security_bits = 0x100; + // SSL3 TLS_DHE_RSA_WITH_AES_256_CBC_SHA + http_info.ssl_info.connection_status = 0x300039; + version_->SetMainScriptHttpResponseInfo(http_info); scoped_ptr<ServiceWorkerProviderHost> provider_host( new ServiceWorkerProviderHost( @@ -180,6 +192,10 @@ EXPECT_EQ(expected_status_text, request_->response_headers()->GetStatusText()); EXPECT_EQ(expected_response, url_request_delegate_.response_data()); + const net::SSLInfo& ssl_info = request_->response_info().ssl_info; + EXPECT_TRUE(ssl_info.is_valid()); + EXPECT_EQ(ssl_info.security_bits, 0x100); + EXPECT_EQ(ssl_info.connection_status, 0x300039); } bool HasInflightRequests() {
diff --git a/content/browser/service_worker/service_worker_utils_unittest.cc b/content/browser/service_worker/service_worker_utils_unittest.cc index 766b59c..d7895a43b 100644 --- a/content/browser/service_worker/service_worker_utils_unittest.cc +++ b/content/browser/service_worker/service_worker_utils_unittest.cc
@@ -102,6 +102,9 @@ // "/xxx" should be matched longer than "/xx". ASSERT_TRUE(matcher.MatchLongest(GURL("http://www.example.com/xxx"))); + // The second call with the same URL should return false. + ASSERT_FALSE(matcher.MatchLongest(GURL("http://www.example.com/xxx"))); + ASSERT_FALSE(matcher.MatchLongest(GURL("http://www.example.com/xxxx"))); }
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 94dce9a..8776f0e 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/stl_util.h" #include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" #include "content/browser/message_port_message_filter.h" #include "content/browser/message_port_service.h" #include "content/browser/service_worker/embedded_worker_instance.h" @@ -18,6 +19,7 @@ #include "content/common/service_worker/service_worker_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" +#include "net/http/http_response_info.h" namespace content { @@ -71,6 +73,12 @@ // Default delay for scheduled update. const int kUpdateDelaySeconds = 1; +const char kClaimClientsStateErrorMesage[] = + "Only the active worker can claim clients."; + +const char kClaimClientsShutdownErrorMesage[] = + "Failed to claim clients due to Service Worker system shutdown."; + void RunSoon(const base::Closure& callback) { if (!callback.is_null()) base::MessageLoop::current()->PostTask(FROM_HERE, callback); @@ -669,6 +677,16 @@ } } +void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( + const net::HttpResponseInfo& http_info) { + main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); +} + +const net::HttpResponseInfo* +ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { + return main_script_http_info_.get(); +} + void ServiceWorkerVersion::OnStarted() { DCHECK_EQ(RUNNING, running_status()); DCHECK(cache_listener_.get()); @@ -800,6 +818,8 @@ OnGetClientInfoError) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, OnSkipWaiting) + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, + OnClaimClients) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -1105,6 +1125,45 @@ embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); } +void ServiceWorkerVersion::OnClaimClients(int request_id) { + StatusCallback callback = base::Bind(&ServiceWorkerVersion::DidClaimClients, + weak_factory_.GetWeakPtr(), request_id); + if (status_ != ACTIVATING && status_ != ACTIVATED) { + callback.Run(SERVICE_WORKER_ERROR_STATE); + return; + } + if (!context_) { + callback.Run(SERVICE_WORKER_ERROR_ABORT); + return; + } + + ServiceWorkerRegistration* registration = + context_->GetLiveRegistration(registration_id_); + if (!registration) { + callback.Run(SERVICE_WORKER_ERROR_ABORT); + return; + } + registration->ClaimClients(callback); +} + +void ServiceWorkerVersion::DidClaimClients( + int request_id, ServiceWorkerStatusCode status) { + if (status == SERVICE_WORKER_ERROR_STATE) { + embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( + request_id, blink::WebServiceWorkerError::ErrorTypeState, + base::ASCIIToUTF16(kClaimClientsStateErrorMesage))); + return; + } + if (status == SERVICE_WORKER_ERROR_ABORT) { + embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( + request_id, blink::WebServiceWorkerError::ErrorTypeAbort, + base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage))); + return; + } + DCHECK(status == SERVICE_WORKER_OK); + embedded_worker_->SendMessage(ServiceWorkerMsg_DidClaimClients(request_id)); +} + void ServiceWorkerVersion::DidGetClientInfo( int client_id, scoped_refptr<GetClientDocumentsCallback> callback,
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 6954a420..015fc9d 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -33,6 +33,10 @@ struct WebCircularGeofencingRegion; } +namespace net { +class HttpResponseInfo; +} + namespace content { class EmbeddedWorkerRegistry; @@ -292,6 +296,13 @@ void SetDevToolsAttached(bool attached); + // Sets the HttpResponseInfo used to load the main script. + // This HttpResponseInfo will be used for all responses sent back from the + // service worker, as the effective security of these responses is equivalent + // to that of the ServiceWorker. + void SetMainScriptHttpResponseInfo(const net::HttpResponseInfo& http_info); + const net::HttpResponseInfo* GetMainScriptHttpResponseInfo(); + private: class GetClientDocumentsCallback; @@ -357,9 +368,11 @@ const std::vector<int>& sent_message_port_ids); void OnFocusClient(int request_id, int client_id); void OnSkipWaiting(int request_id); + void OnClaimClients(int request_id); void OnFocusClientFinished(int request_id, bool result); void DidSkipWaiting(int request_id); + void DidClaimClients(int request_id, ServiceWorkerStatusCode status); void DidGetClientInfo(int client_id, scoped_refptr<GetClientDocumentsCallback> callback, ServiceWorkerStatusCode status, @@ -409,6 +422,7 @@ bool is_doomed_; std::vector<int> pending_skip_waiting_requests_; bool skip_waiting_; + scoped_ptr<net::HttpResponseInfo> main_script_http_info_; base::WeakPtrFactory<ServiceWorkerVersion> weak_factory_;
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc index a6a8cfb..0138c90 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job.cc +++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -418,6 +418,8 @@ if (!CheckPathRestriction(request)) return; + + version_->SetMainScriptHttpResponseInfo(net_request_->response_info()); } WriteHeadersToCache();
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 61b8111..f5b509a 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -337,25 +337,79 @@ child->current_frame_host()->GetSiteInstance()); } -// In A-embed-B-embed-C scenario, verify that killing process B clears proxies -// of C from the tree. +// This test checks that killing a renderer process of a remote frame +// and then navigating some other frame to the same SiteInstance of the killed +// process works properly. +// This can be illustrated as follows, +// where 1/2/3 are FrameTreeNode-s and A/B are processes and B* is the killed +// B process: // -// 1 A A -// / \ / \ / \ . -// 2 3 -> B A -> Kill B -> B* A +// 1 A A A +// / \ -> / \ -> Kill B -> / \ -> Navigate 3 to B -> / \ . +// 2 3 B A B* A B* B +// +// Initially, node1.proxy_hosts_ = {B} +// After we kill B, we make sure B stays in node1.proxy_hosts_, then we navigate +// 3 to B and we expect that to complete normally. +// See http://crbug.com/432107. +// +// Note that due to http://crbug.com/450681, node2 cannot be re-navigated to +// site B and stays in not rendered state. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + NavigateRemoteFrameToKilledProcess) { + GURL main_url(embedded_test_server()->GetURL( + "/frame_tree/page_with_two_frames.html")); + NavigateToURL(shell(), main_url); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = + static_cast<WebContentsImpl*>(shell()->web_contents())-> + GetFrameTree()->root(); + + TestNavigationObserver observer(shell()->web_contents()); + ASSERT_EQ(2U, root->child_count()); + + // Make sure node2 points to the correct cross-site page. + GURL site_b_url = embedded_test_server()->GetURL("bar.com", "/title1.html"); + FrameTreeNode* node2 = root->child_at(0); + EXPECT_EQ(site_b_url, node2->current_url()); + + // Kill that cross-site renderer. + RenderProcessHost* child_process = + node2->current_frame_host()->GetProcess(); + RenderProcessHostWatcher crash_observer( + child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + child_process->Shutdown(0, false); + crash_observer.Wait(); + + // Now navigate the second iframe (node3) to the same site as the node2. + FrameTreeNode* node3 = root->child_at(1); + NavigateFrameToURL(node3, site_b_url); + EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_EQ(site_b_url, observer.last_navigation_url()); +} + +// This test is similar to +// SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcess with +// addition that node2 also has a cross-origin frame to site C. +// +// 1 A A A +// / \ / \ / \ / \ . +// 2 3 -> B A -> Kill B -> B* A -> Navigate 3 -> B* B // / / // 4 C // -// node1 is the root. -// Initially, both node1.proxy_hosts_ and node3.proxy_hosts_ contain C. -// After we kill B, make sure proxies for C are cleared. +// Initially, node1.proxy_hosts_ = {B, C} +// After we kill B, we make sure B stays in node1.proxy_hosts_, but +// C gets cleared from node1.proxy_hosts_. // -// TODO(lazyboy): Once http://crbug.com/432107 is fixed, we should also make -// sure that proxies for B are not cleared when we kill B. +// Note that due to http://crbug.com/450681, node2 cannot be re-navigated to +// site B and stays in not rendered state. IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - KillingRendererClearsDescendantProxies) { + NavigateRemoteFrameToKilledProcessWithSubtree) { GURL main_url( - embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html")); + embedded_test_server()->GetURL( + "/frame_tree/page_with_two_frames_nested.html")); NavigateToURL(shell(), main_url); // It is safe to obtain the root frame tree node here, as it doesn't change. @@ -366,24 +420,9 @@ ASSERT_EQ(2U, root->child_count()); - // Navigate the second subframe (node3) to a local frame. - GURL site_a_url(embedded_test_server()->GetURL("/title1.html")); - NavigateFrameToURL(root->child_at(1), site_a_url); - - // Navigate the first subframe (node2) to a cross-site page with two - // subframes. - // NavigateFrameToURL can't be used here because it doesn't guarantee that - // FrameTreeNodes will have been created for child frames when it returns. - RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 3); GURL site_b_url( embedded_test_server()->GetURL( "bar.com", "/frame_tree/page_with_one_frame.html")); - NavigationController::LoadURLParams params_b(site_b_url); - params_b.transition_type = ui::PAGE_TRANSITION_LINK; - params_b.frame_tree_node_id = root->child_at(0)->frame_tree_node_id(); - root->child_at(0)->navigator()->GetController()->LoadURLWithParams(params_b); - frame_observer.Wait(); - // We can't use a TestNavigationObserver to verify the URL here, // since the frame has children that may have clobbered it in the observer. EXPECT_EQ(site_b_url, root->child_at(0)->current_url()); @@ -397,12 +436,107 @@ ASSERT_EQ(1U, root->child_at(0)->child_count()); - // Navigate node4 to cross-site-page. + // Make sure node4 points to the correct cross-site page. FrameTreeNode* node4 = root->child_at(0)->child_at(0); - GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title2.html")); - NavigateFrameToURL(node4, site_c_url); + GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title1.html")); + EXPECT_EQ(site_c_url, node4->current_url()); + + // |site_instance_c| is expected to go away once we kill |child_process_b| + // below, so create a local scope so we can extend the lifetime of + // |site_instance_c| with a refptr. + { + SiteInstance* site_instance_b = + root->child_at(0)->current_frame_host()->GetSiteInstance(); + // |site_c| will go away, so extend its lifetime with a refptr. + scoped_refptr<SiteInstanceImpl> site_instance_c = + node4->current_frame_host()->GetSiteInstance(); + + // Initially proxies for both B and C will be present in the root and node3. + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost( + site_instance_c.get())); + FrameTreeNode* node3 = root->child_at(1); + EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); + EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost( + site_instance_c.get())); + + // Kill that cross-site renderer/process B. + RenderProcessHost* child_process_b = + root->child_at(0)->current_frame_host()->GetProcess(); + RenderProcessHostWatcher crash_observer( + child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + child_process_b->Shutdown(0, false); + crash_observer.Wait(); + + // Make sure proxy B stays around in root and node3. + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); + EXPECT_TRUE(node3->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); + // Make sure proxy C goes away from root and node3. + EXPECT_FALSE(root->render_manager()->GetRenderFrameProxyHost( + site_instance_c.get())); + EXPECT_FALSE(node3->render_manager()->GetRenderFrameProxyHost( + site_instance_c.get())); + } + + // Now navigate the second iframe (node3) to the same site as the node2. + FrameTreeNode* node3 = root->child_at(1); + GURL url = embedded_test_server()->GetURL("bar.com", "/title1.html"); + NavigateFrameToURL(node3, url); EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(site_c_url, observer.last_navigation_url()); + EXPECT_EQ(url, observer.last_navigation_url()); +} + +// In A-embed-B-embed-C scenario, verify that killing process B clears proxies +// of C from the tree. +// +// 1 A A +// / \ / \ / \ . +// 2 3 -> B A -> Kill B -> B* A +// / / +// 4 C +// +// node1 is the root. +// Initially, both node1.proxy_hosts_ and node3.proxy_hosts_ contain C. +// After we kill B, make sure proxies for C are cleared. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + KillingRendererClearsDescendantProxies) { + GURL main_url( + embedded_test_server()->GetURL( + "/frame_tree/page_with_two_frames_nested.html")); + NavigateToURL(shell(), main_url); + + // It is safe to obtain the root frame tree node here, as it doesn't change. + FrameTreeNode* root = + static_cast<WebContentsImpl*>(shell()->web_contents())-> + GetFrameTree()->root(); + TestNavigationObserver observer(shell()->web_contents()); + + ASSERT_EQ(2U, root->child_count()); + + GURL site_b_url( + embedded_test_server()->GetURL( + "bar.com", "/frame_tree/page_with_one_frame.html")); + // We can't use a TestNavigationObserver to verify the URL here, + // since the frame has children that may have clobbered it in the observer. + EXPECT_EQ(site_b_url, root->child_at(0)->current_url()); + + // Ensure that a new process is created for node2. + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), + root->child_at(0)->current_frame_host()->GetSiteInstance()); + // Ensure that a new process is *not* created for node3. + EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), + root->child_at(1)->current_frame_host()->GetSiteInstance()); + + ASSERT_EQ(1U, root->child_at(0)->child_count()); + + // Make sure node4 points to the correct cross-site-page. + FrameTreeNode* node4 = root->child_at(0)->child_at(0); + GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title1.html")); + EXPECT_EQ(site_c_url, node4->current_url()); // |site_instance_c| is expected to go away once we kill |child_process_b| // below, so create a local scope so we can extend the lifetime of @@ -433,8 +567,11 @@ // Make sure proxy C has gone from node3 as well. EXPECT_FALSE(root->child_at(1)->render_manager()->GetRenderFrameProxyHost( site_instance_c.get())); - // TODO(lazyboy): Once http://crbug.com/432107 is fixed, we should also - // check that proxy B exists in both root and node3. + // Make sure proxy B stays around in root and node3. + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); + EXPECT_TRUE(root->child_at(1)->render_manager()->GetRenderFrameProxyHost( + site_instance_b)); } }
diff --git a/content/browser/speech/speech_recognizer_impl_android.h b/content/browser/speech/speech_recognizer_impl_android.h index cdf0b4db..11895c4 100644 --- a/content/browser/speech/speech_recognizer_impl_android.h +++ b/content/browser/speech/speech_recognizer_impl_android.h
@@ -24,11 +24,11 @@ int session_id); // SpeechRecognizer methods. - virtual void StartRecognition(const std::string& device_id) override; - virtual void AbortRecognition() override; - virtual void StopAudioCapture() override; - virtual bool IsActive() const override; - virtual bool IsCapturingAudio() const override; + void StartRecognition(const std::string& device_id) override; + void AbortRecognition() override; + void StopAudioCapture() override; + bool IsActive() const override; + bool IsCapturingAudio() const override; // Called from Java methods via JNI. void OnAudioStart(JNIEnv* env, jobject obj); @@ -53,7 +53,7 @@ std::string language, bool continuous, bool interim_results); void OnRecognitionResultsOnIOThread(SpeechRecognitionResults const &results); - virtual ~SpeechRecognizerImplAndroid(); + ~SpeechRecognizerImplAndroid() override; base::android::ScopedJavaGlobalRef<jobject> j_recognition_; State state_;
diff --git a/content/browser/time_zone_monitor_android.h b/content/browser/time_zone_monitor_android.h index a462eb5..cb3cb9f21 100644 --- a/content/browser/time_zone_monitor_android.h +++ b/content/browser/time_zone_monitor_android.h
@@ -17,7 +17,7 @@ class TimeZoneMonitorAndroid : public TimeZoneMonitor { public: TimeZoneMonitorAndroid(); - virtual ~TimeZoneMonitorAndroid(); + ~TimeZoneMonitorAndroid() override; // Must be called at startup. static bool Register(JNIEnv* env);
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index 12bb8da..5e2b128 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc
@@ -480,19 +480,4 @@ ConvertJavaStringToUTF8(env, message))); } -void WebContentsAndroid::OpenURL(JNIEnv* env, - jobject obj, - jstring url, - jboolean user_gesture, - jboolean is_renderer_initiated) { - GURL gurl(base::android::ConvertJavaStringToUTF8(env, url)); - OpenURLParams open_params(gurl, - Referrer(), - CURRENT_TAB, - ui::PAGE_TRANSITION_LINK, - is_renderer_initiated); - open_params.user_gesture = user_gesture; - web_contents_->OpenURL(open_params); -} - } // namespace content
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index 219872b..4379e3d 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -32,7 +32,7 @@ static bool Register(JNIEnv* env); explicit WebContentsAndroid(WebContents* web_contents); - virtual ~WebContentsAndroid(); + ~WebContentsAndroid() override; WebContents* web_contents() const { return web_contents_; } @@ -109,12 +109,6 @@ jint level, jstring message); - void OpenURL(JNIEnv* env, - jobject jobj, - jstring url, - jboolean user_gesture, - jboolean is_renderer_initiated); - private: RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid();
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 507ebbe..094361d 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1644,9 +1644,9 @@ // new window. As a result, we need to show and navigate the window here. bool was_blocked = false; if (delegate_) { - gfx::Rect initial_pos; + gfx::Rect initial_rect; delegate_->AddNewContents( - this, new_contents, params.disposition, initial_pos, + this, new_contents, params.disposition, initial_rect, params.user_gesture, &was_blocked); } if (!was_blocked) { @@ -1716,21 +1716,21 @@ void WebContentsImpl::ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { WebContentsImpl* contents = GetCreatedWindow(route_id); if (contents) { WebContentsDelegate* delegate = GetDelegate(); if (delegate) { delegate->AddNewContents( - this, contents, disposition, initial_pos, user_gesture, NULL); + this, contents, disposition, initial_rect, user_gesture, NULL); } } } void WebContentsImpl::ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) { - ShowCreatedWidget(route_id, false, initial_pos); + const gfx::Rect& initial_rect) { + ShowCreatedWidget(route_id, false, initial_rect); } void WebContentsImpl::ShowCreatedFullscreenWidget(int route_id) { @@ -1739,7 +1739,7 @@ void WebContentsImpl::ShowCreatedWidget(int route_id, bool is_fullscreen, - const gfx::Rect& initial_pos) { + const gfx::Rect& initial_rect) { RenderWidgetHostViewBase* widget_host_view = static_cast<RenderWidgetHostViewBase*>(GetCreatedWidget(route_id)); if (!widget_host_view) @@ -1769,7 +1769,7 @@ if (!widget_host_view->HasFocus()) widget_host_view->Focus(); } else { - widget_host_view->InitAsPopup(view, initial_pos); + widget_host_view->InitAsPopup(view, initial_rect); } RenderWidgetHostImpl* render_widget_host_impl =
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index afec265..c76a40a79 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -341,8 +341,7 @@ void GetManifest(const GetManifestCallback&) override; void ExitFullscreen() override; #if defined(OS_ANDROID) - virtual base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() - override; + base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() override; virtual WebContentsAndroid* GetWebContentsAndroid(); #elif defined(OS_MACOSX) void SetAllowOtherViews(bool allow) override; @@ -473,9 +472,9 @@ void CreateNewFullscreenWidget(int render_process_id, int route_id) override; void ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; - void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos) override; + void ShowCreatedWidget(int route_id, const gfx::Rect& initial_rect) override; void ShowCreatedFullscreenWidget(int route_id) override; void RequestMediaAccessPermission( const MediaStreamRequest& request, @@ -887,7 +886,7 @@ // Helper for ShowCreatedWidget/ShowCreatedFullscreenWidget. void ShowCreatedWidget(int route_id, bool is_fullscreen, - const gfx::Rect& initial_pos); + const gfx::Rect& initial_rect); // Finds the new RenderWidgetHost and returns it. Note that this can only be // called once as this call also removes it from the internal map.
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index e82a5daa..ded5a4b 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2909,7 +2909,7 @@ // Commit the navigation in the child frame and send the DidStopLoading // message. contents()->TestDidNavigate( - subframe, 3, bar_url, ui::PAGE_TRANSITION_TYPED); + subframe, 3, bar_url, ui::PAGE_TRANSITION_MANUAL_SUBFRAME); subframe->OnMessageReceived( FrameHostMsg_DidStopLoading(subframe->GetRoutingID())); }
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h index a63bb88..9f7216f 100644 --- a/content/browser/web_contents/web_contents_view_android.h +++ b/content/browser/web_contents/web_contents_view_android.h
@@ -22,7 +22,7 @@ public: WebContentsViewAndroid(WebContentsImpl* web_contents, WebContentsViewDelegate* delegate); - virtual ~WebContentsViewAndroid(); + ~WebContentsViewAndroid() override; // Sets the interface to the view system. ContentViewCoreImpl is owned // by its Java ContentViewCore counterpart, whose lifetime is managed @@ -30,48 +30,49 @@ void SetContentViewCore(ContentViewCoreImpl* content_view_core); // WebContentsView implementation -------------------------------------------- - virtual gfx::NativeView GetNativeView() const override; - virtual gfx::NativeView GetContentNativeView() const override; - virtual gfx::NativeWindow GetTopLevelNativeWindow() const override; - virtual void GetContainerBounds(gfx::Rect* out) const override; - virtual void SizeContents(const gfx::Size& size) override; - virtual void Focus() override; - virtual void SetInitialFocus() override; - virtual void StoreFocus() override; - virtual void RestoreFocus() override; - virtual DropData* GetDropData() const override; - virtual gfx::Rect GetViewBounds() const override; - virtual void CreateView( - const gfx::Size& initial_size, gfx::NativeView context) override; - virtual RenderWidgetHostViewBase* CreateViewForWidget( - RenderWidgetHost* render_widget_host, bool is_guest_view_hack) override; - virtual RenderWidgetHostViewBase* CreateViewForPopupWidget( + gfx::NativeView GetNativeView() const override; + gfx::NativeView GetContentNativeView() const override; + gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetContainerBounds(gfx::Rect* out) const override; + void SizeContents(const gfx::Size& size) override; + void Focus() override; + void SetInitialFocus() override; + void StoreFocus() override; + void RestoreFocus() override; + DropData* GetDropData() const override; + gfx::Rect GetViewBounds() const override; + void CreateView(const gfx::Size& initial_size, + gfx::NativeView context) override; + RenderWidgetHostViewBase* CreateViewForWidget( + RenderWidgetHost* render_widget_host, + bool is_guest_view_hack) override; + RenderWidgetHostViewBase* CreateViewForPopupWidget( RenderWidgetHost* render_widget_host) override; - virtual void SetPageTitle(const base::string16& title) override; - virtual void RenderViewCreated(RenderViewHost* host) override; - virtual void RenderViewSwappedIn(RenderViewHost* host) override; - virtual void SetOverscrollControllerEnabled(bool enabled) override; + void SetPageTitle(const base::string16& title) override; + void RenderViewCreated(RenderViewHost* host) override; + void RenderViewSwappedIn(RenderViewHost* host) override; + void SetOverscrollControllerEnabled(bool enabled) override; // Backend implementation of RenderViewHostDelegateView. - virtual void ShowContextMenu(RenderFrameHost* render_frame_host, - const ContextMenuParams& params) override; - virtual void ShowPopupMenu(RenderFrameHost* render_frame_host, - const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<MenuItem>& items, - bool right_aligned, - bool allow_multiple_selection) override; - virtual void HidePopupMenu() override; - virtual void StartDragging(const DropData& drop_data, - blink::WebDragOperationsMask allowed_ops, - const gfx::ImageSkia& image, - const gfx::Vector2d& image_offset, - const DragEventSourceInfo& event_info) override; - virtual void UpdateDragCursor(blink::WebDragOperation operation) override; - virtual void GotFocus() override; - virtual void TakeFocus(bool reverse) override; + void ShowContextMenu(RenderFrameHost* render_frame_host, + const ContextMenuParams& params) override; + void ShowPopupMenu(RenderFrameHost* render_frame_host, + const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<MenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) override; + void HidePopupMenu() override; + void StartDragging(const DropData& drop_data, + blink::WebDragOperationsMask allowed_ops, + const gfx::ImageSkia& image, + const gfx::Vector2d& image_offset, + const DragEventSourceInfo& event_info) override; + void UpdateDragCursor(blink::WebDragOperation operation) override; + void GotFocus() override; + void TakeFocus(bool reverse) override; private: // The WebContents whose contents we display.
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index d5b5367..a8d488a 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -31,7 +31,7 @@ #include "content/app/resources/grit/content_resources.h" #include "content/app/strings/grit/content_strings.h" #include "content/child/bluetooth/web_bluetooth_impl.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/content_child_helpers.h" #include "content/child/geofencing/web_geofencing_provider_impl.h" #include "content/child/navigator_connect/navigator_connect_provider.h" @@ -436,15 +436,15 @@ void BlinkPlatformImpl::InternalInit() { // ChildThread may not exist in some tests. - if (ChildThread::current()) { + if (ChildThreadImpl::current()) { geofencing_provider_.reset(new WebGeofencingProviderImpl( - ChildThread::current()->thread_safe_sender())); + ChildThreadImpl::current()->thread_safe_sender())); bluetooth_.reset( - new WebBluetoothImpl(ChildThread::current()->thread_safe_sender())); - thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); + new WebBluetoothImpl(ChildThreadImpl::current()->thread_safe_sender())); + thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender(); notification_dispatcher_ = - ChildThread::current()->notification_dispatcher(); - push_dispatcher_ = ChildThread::current()->push_dispatcher(); + ChildThreadImpl::current()->notification_dispatcher(); + push_dispatcher_ = ChildThreadImpl::current()->push_dispatcher(); } if (main_thread_task_runner_.get()) { @@ -456,7 +456,7 @@ } WebURLLoader* BlinkPlatformImpl::createURLLoader() { - ChildThread* child_thread = ChildThread::current(); + ChildThreadImpl* child_thread = ChildThreadImpl::current(); // There may be no child thread in RenderViewTests. These tests can still use // data URLs to bypass the ResourceDispatcher. return new WebURLLoaderImpl(
diff --git a/content/child/bluetooth/bluetooth_message_filter.cc b/content/child/bluetooth/bluetooth_message_filter.cc index b339674..554e3c3 100644 --- a/content/child/bluetooth/bluetooth_message_filter.cc +++ b/content/child/bluetooth/bluetooth_message_filter.cc
@@ -4,40 +4,34 @@ #include "content/child/bluetooth/bluetooth_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/bluetooth/bluetooth_dispatcher.h" #include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "ipc/ipc_message_macros.h" namespace content { BluetoothMessageFilter::BluetoothMessageFilter(ThreadSafeSender* sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(sender) { + : WorkerThreadMessageFilter(sender) { } BluetoothMessageFilter::~BluetoothMessageFilter() { } -base::TaskRunner* BluetoothMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != BluetoothMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool BluetoothMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == BluetoothMsgStart; } -bool BluetoothMessageFilter::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != BluetoothMsgStart) - return false; - BluetoothDispatcher::GetOrCreateThreadSpecificInstance( - thread_safe_sender_.get())->OnMessageReceived(msg); - return true; +void BluetoothMessageFilter::OnFilteredMessageReceived( + const IPC::Message& msg) { + BluetoothDispatcher::GetOrCreateThreadSpecificInstance(thread_safe_sender()) + ->OnMessageReceived(msg); +} + +bool BluetoothMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } } // namespace content
diff --git a/content/child/bluetooth/bluetooth_message_filter.h b/content/child/bluetooth/bluetooth_message_filter.h index db183806..5692dcce 100644 --- a/content/child/bluetooth/bluetooth_message_filter.h +++ b/content/child/bluetooth/bluetooth_message_filter.h
@@ -5,30 +5,22 @@ #ifndef CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_ #define CONTENT_CHILD_BLUETOOTH_BLUETOOTH_MESSAGE_FILTER_H_ -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - -class BluetoothMessageFilter : public ChildMessageFilter { +class BluetoothMessageFilter : public WorkerThreadMessageFilter { public: explicit BluetoothMessageFilter(ThreadSafeSender* thread_safe_sender); private: ~BluetoothMessageFilter() override; - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; - - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; DISALLOW_COPY_AND_ASSIGN(BluetoothMessageFilter); };
diff --git a/content/child/child_discardable_shared_memory_manager.cc b/content/child/child_discardable_shared_memory_manager.cc index 7d07e327..83d29d6 100644 --- a/content/child/child_discardable_shared_memory_manager.cc +++ b/content/child/child_discardable_shared_memory_manager.cc
@@ -6,7 +6,6 @@ #include "base/memory/discardable_shared_memory.h" #include "base/process/process_metrics.h" -#include "content/child/child_thread.h" #include "content/common/child_process_messages.h" namespace content {
diff --git a/content/child/child_gpu_memory_buffer_manager.cc b/content/child/child_gpu_memory_buffer_manager.cc index 7cb793d..0e1c312ad 100644 --- a/content/child/child_gpu_memory_buffer_manager.cc +++ b/content/child/child_gpu_memory_buffer_manager.cc
@@ -4,7 +4,6 @@ #include "content/child/child_gpu_memory_buffer_manager.h" -#include "content/child/child_thread.h" #include "content/common/child_process_messages.h" #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
diff --git a/content/child/child_histogram_message_filter.cc b/content/child/child_histogram_message_filter.cc index 3e895fc..3e778d5 100644 --- a/content/child/child_histogram_message_filter.cc +++ b/content/child/child_histogram_message_filter.cc
@@ -10,7 +10,6 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_delta_serialization.h" #include "content/child/child_process.h" -#include "content/child/child_thread.h" #include "content/common/child_process_messages.h" #include "ipc/ipc_sender.h"
diff --git a/content/child/child_message_filter.cc b/content/child/child_message_filter.cc index 9e5ff63..66b7555 100644 --- a/content/child/child_message_filter.cc +++ b/content/child/child_message_filter.cc
@@ -8,7 +8,7 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/task_runner.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/thread_safe_sender.h" #include "ipc/message_filter.h" @@ -52,7 +52,7 @@ ChildMessageFilter::ChildMessageFilter() : internal_(NULL), - thread_safe_sender_(ChildThread::current()->thread_safe_sender()) {} + thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {} ChildMessageFilter::~ChildMessageFilter() {}
diff --git a/content/child/child_message_filter.h b/content/child/child_message_filter.h index a79ceec..e3dbdf8 100644 --- a/content/child/child_message_filter.h +++ b/content/child/child_message_filter.h
@@ -51,7 +51,7 @@ private: class Internal; - friend class ChildThread; + friend class ChildThreadImpl; friend class RenderThreadImpl; friend class WorkerThread;
diff --git a/content/child/child_process.cc b/content/child/child_process.cc index 42eff930..db73ea3 100644 --- a/content/child/child_process.cc +++ b/content/child/child_process.cc
@@ -16,7 +16,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" #include "base/threading/thread_local.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #if defined(OS_ANDROID) #include "base/debug/debugger.h" @@ -72,11 +72,11 @@ io_thread_.Stop(); } -ChildThread* ChildProcess::main_thread() { +ChildThreadImpl* ChildProcess::main_thread() { return main_thread_.get(); } -void ChildProcess::set_main_thread(ChildThread* thread) { +void ChildProcess::set_main_thread(ChildThreadImpl* thread) { main_thread_.reset(thread); }
diff --git a/content/child/child_process.h b/content/child/child_process.h index 1aedcb6..cf3173f7 100644 --- a/content/child/child_process.h +++ b/content/child/child_process.h
@@ -12,7 +12,7 @@ #include "content/common/content_export.h" namespace content { -class ChildThread; +class ChildThreadImpl; // Base class for child processes of the browser process (i.e. renderer and // plugin host). This is a singleton object for each child process. @@ -22,12 +22,12 @@ // // 1. ChildProcess::~ChildProcess() is called. // 2. Shutdown event is fired. Background threads should stop. -// 3. ChildThread::Shutdown() is called. ChildThread is also deleted. +// 3. ChildThreadImpl::Shutdown() is called. ChildThread is also deleted. // 4. IO thread is stopped. // 5. Main message loop exits. // 6. Child process is now fully stopped. // -// Note: IO thread outlives the ChildThread object. +// Note: IO thread outlives the ChildThreadImpl object. class CONTENT_EXPORT ChildProcess { public: // Child processes should have an object that derives from this class. @@ -36,11 +36,11 @@ virtual ~ChildProcess(); // May be NULL if the main thread hasn't been set explicitly. - ChildThread* main_thread(); + ChildThreadImpl* main_thread(); // Sets the object associated with the main thread of this process. // Takes ownership of the pointer. - void set_main_thread(ChildThread* thread); + void set_main_thread(ChildThreadImpl* thread); base::MessageLoop* io_message_loop() { return io_thread_.message_loop(); } base::MessageLoopProxy* io_message_loop_proxy() { @@ -81,7 +81,7 @@ // NOTE: make sure that main_thread_ is listed after shutdown_event_, since // it depends on it (indirectly through IPC::SyncChannel). Same for // io_thread_. - scoped_ptr<ChildThread> main_thread_; + scoped_ptr<ChildThreadImpl> main_thread_; DISALLOW_COPY_AND_ASSIGN(ChildProcess); };
diff --git a/content/child/child_shared_bitmap_manager.cc b/content/child/child_shared_bitmap_manager.cc index 5cccb6d36..73395da 100644 --- a/content/child/child_shared_bitmap_manager.cc +++ b/content/child/child_shared_bitmap_manager.cc
@@ -6,7 +6,7 @@ #include "base/debug/alias.h" #include "base/process/process_metrics.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/child_process_messages.h" #include "ui/gfx/geometry/size.h" @@ -111,7 +111,7 @@ if (!memory->Map(memory_size)) CHECK(false); #else - memory = ChildThread::AllocateSharedMemory(memory_size, sender_.get()); + memory = ChildThreadImpl::AllocateSharedMemory(memory_size, sender_.get()); #if defined(OS_WIN) if (!memory) CollectMemoryUsageAndDie(size);
diff --git a/content/child/child_thread.cc b/content/child/child_thread_impl.cc similarity index 89% rename from content/child/child_thread.cc rename to content/child/child_thread_impl.cc index 82caa77..4db2e27c 100644 --- a/content/child/child_thread.cc +++ b/content/child/child_thread_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include <signal.h> @@ -71,7 +71,7 @@ // How long to wait for a connection to the browser process before giving up. const int kConnectionTimeoutS = 15; -base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls = +base::LazyInstance<base::ThreadLocalPointer<ChildThreadImpl> > g_lazy_tls = LAZY_INSTANCE_INITIALIZER; // This isn't needed on Windows because there the sandbox's job object @@ -162,7 +162,7 @@ #endif // OS(POSIX) #if defined(OS_ANDROID) -ChildThread* g_child_thread = NULL; +ChildThreadImpl* g_child_thread = NULL; // A lock protects g_child_thread. base::LazyInstance<base::Lock> g_lazy_child_thread_lock = @@ -199,50 +199,54 @@ } // namespace -ChildThread::Options::Options() +ChildThread* ChildThread::Get() { + return ChildThreadImpl::current(); +} + +ChildThreadImpl::Options::Options() : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kProcessChannelID)), use_mojo_channel(false), in_browser_process(false) { } -ChildThread::Options::Options(bool mojo) +ChildThreadImpl::Options::Options(bool mojo) : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kProcessChannelID)), use_mojo_channel(mojo), in_browser_process(true) { } -ChildThread::Options::Options(std::string name, bool mojo) +ChildThreadImpl::Options::Options(std::string name, bool mojo) : channel_name(name), use_mojo_channel(mojo), in_browser_process(true) { } -ChildThread::Options::~Options() { +ChildThreadImpl::Options::~Options() { } -ChildThread::ChildThreadMessageRouter::ChildThreadMessageRouter( +ChildThreadImpl::ChildThreadMessageRouter::ChildThreadMessageRouter( IPC::Sender* sender) : sender_(sender) {} -bool ChildThread::ChildThreadMessageRouter::Send(IPC::Message* msg) { +bool ChildThreadImpl::ChildThreadMessageRouter::Send(IPC::Message* msg) { return sender_->Send(msg); } -ChildThread::ChildThread() +ChildThreadImpl::ChildThreadImpl() : router_(this), in_browser_process_(false), channel_connected_factory_(this) { Init(Options()); } -ChildThread::ChildThread(const Options& options) +ChildThreadImpl::ChildThreadImpl(const Options& options) : router_(this), in_browser_process_(options.in_browser_process), channel_connected_factory_(this) { Init(options); } -void ChildThread::ConnectChannel(bool use_mojo_channel) { +void ChildThreadImpl::ConnectChannel(bool use_mojo_channel) { bool create_pipe_now = true; if (use_mojo_channel) { VLOG(1) << "Mojo is enabled on child"; @@ -255,7 +259,7 @@ channel_->Init(channel_name_, IPC::Channel::MODE_CLIENT, create_pipe_now); } -void ChildThread::Init(const Options& options) { +void ChildThreadImpl::Init(const Options& options) { channel_name_ = options.channel_name; g_lazy_tls.Pointer()->Set(this); @@ -363,7 +367,7 @@ base::MessageLoop::current()->PostDelayedTask( FROM_HERE, - base::Bind(&ChildThread::EnsureConnected, + base::Bind(&ChildThreadImpl::EnsureConnected, channel_connected_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(connection_timeout)); @@ -395,7 +399,7 @@ new ChildDiscardableSharedMemoryManager(thread_safe_sender())); } -ChildThread::~ChildThread() { +ChildThreadImpl::~ChildThreadImpl() { #ifdef IPC_MESSAGE_LOG_ENABLED IPC::Logging::GetInstance()->SetIPCSender(NULL); #endif @@ -415,7 +419,7 @@ g_lazy_tls.Pointer()->Set(NULL); } -void ChildThread::Shutdown() { +void ChildThreadImpl::Shutdown() { // Delete objects that hold references to blink so derived classes can // safely shutdown blink in their Shutdown implementation. file_system_dispatcher_.reset(); @@ -423,16 +427,16 @@ WebFileSystemImpl::DeleteThreadSpecificInstance(); } -void ChildThread::OnChannelConnected(int32 peer_pid) { +void ChildThreadImpl::OnChannelConnected(int32 peer_pid) { channel_connected_factory_.InvalidateWeakPtrs(); } -void ChildThread::OnChannelError() { +void ChildThreadImpl::OnChannelError() { set_on_channel_error_called(true); base::MessageLoop::current()->Quit(); } -bool ChildThread::Send(IPC::Message* msg) { +bool ChildThreadImpl::Send(IPC::Message* msg) { DCHECK(base::MessageLoop::current() == message_loop()); if (!channel_) { delete msg; @@ -442,19 +446,29 @@ return channel_->Send(msg); } -MessageRouter* ChildThread::GetRouter() { +#if defined(OS_WIN) +void ChildThreadImpl::PreCacheFont(const LOGFONT& log_font) { + Send(new ChildProcessHostMsg_PreCacheFont(log_font)); +} + +void ChildThreadImpl::ReleaseCachedFonts() { + Send(new ChildProcessHostMsg_ReleaseCachedFonts()); +} +#endif + +MessageRouter* ChildThreadImpl::GetRouter() { DCHECK(base::MessageLoop::current() == message_loop()); return &router_; } -scoped_ptr<base::SharedMemory> ChildThread::AllocateSharedMemory( +scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory( size_t buf_size) { DCHECK(base::MessageLoop::current() == message_loop()); return AllocateSharedMemory(buf_size, this); } // static -scoped_ptr<base::SharedMemory> ChildThread::AllocateSharedMemory( +scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory( size_t buf_size, IPC::Sender* sender) { scoped_ptr<base::SharedMemory> shared_buf; @@ -484,7 +498,7 @@ return shared_buf; } -bool ChildThread::OnMessageReceived(const IPC::Message& msg) { +bool ChildThreadImpl::OnMessageReceived(const IPC::Message& msg) { if (mojo_application_->OnMessageReceived(msg)) return true; @@ -497,7 +511,7 @@ return true; bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ChildThread, msg) + IPC_BEGIN_MESSAGE_MAP(ChildThreadImpl, msg) IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown) #if defined(IPC_MESSAGE_LOG_ENABLED) IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled, @@ -525,16 +539,16 @@ return router_.OnMessageReceived(msg); } -bool ChildThread::OnControlMessageReceived(const IPC::Message& msg) { +bool ChildThreadImpl::OnControlMessageReceived(const IPC::Message& msg) { return false; } -void ChildThread::OnShutdown() { +void ChildThreadImpl::OnShutdown() { base::MessageLoop::current()->Quit(); } #if defined(IPC_MESSAGE_LOG_ENABLED) -void ChildThread::OnSetIPCLoggingEnabled(bool enable) { +void ChildThreadImpl::OnSetIPCLoggingEnabled(bool enable) { if (enable) IPC::Logging::GetInstance()->Enable(); else @@ -542,11 +556,11 @@ } #endif // IPC_MESSAGE_LOG_ENABLED -void ChildThread::OnSetProfilerStatus(ThreadData::Status status) { +void ChildThreadImpl::OnSetProfilerStatus(ThreadData::Status status) { ThreadData::InitializeAndSetTrackingStatus(status); } -void ChildThread::OnGetChildProfilerData(int sequence_number) { +void ChildThreadImpl::OnGetChildProfilerData(int sequence_number) { tracked_objects::ProcessDataSnapshot process_data; ThreadData::Snapshot(false, &process_data); @@ -554,7 +568,7 @@ process_data)); } -void ChildThread::OnDumpHandles() { +void ChildThreadImpl::OnDumpHandles() { #if defined(OS_WIN) scoped_refptr<HandleEnumerator> handle_enum( new HandleEnumerator( @@ -568,7 +582,7 @@ } #if defined(USE_TCMALLOC) -void ChildThread::OnGetTcmallocStats() { +void ChildThreadImpl::OnGetTcmallocStats() { std::string result; char buffer[1024 * 32]; base::allocator::GetStats(buffer, sizeof(buffer)); @@ -577,15 +591,15 @@ } #endif -ChildThread* ChildThread::current() { +ChildThreadImpl* ChildThreadImpl::current() { return g_lazy_tls.Pointer()->Get(); } #if defined(OS_ANDROID) // The method must NOT be called on the child thread itself. // It may block the child thread if so. -void ChildThread::ShutdownThread() { - DCHECK(!ChildThread::current()) << +void ChildThreadImpl::ShutdownThread() { + DCHECK(!ChildThreadImpl::current()) << "this method should NOT be called from child thread itself"; { base::AutoLock lock(g_lazy_child_thread_lock.Get()); @@ -598,7 +612,7 @@ } #endif -void ChildThread::OnProcessFinalRelease() { +void ChildThreadImpl::OnProcessFinalRelease() { if (on_channel_error_called_) { base::MessageLoop::current()->Quit(); return; @@ -613,12 +627,12 @@ Send(new ChildProcessHostMsg_ShutdownRequest); } -void ChildThread::EnsureConnected() { - VLOG(0) << "ChildThread::EnsureConnected()"; +void ChildThreadImpl::EnsureConnected() { + VLOG(0) << "ChildThreadImpl::EnsureConnected()"; base::KillProcess(base::GetCurrentProcessHandle(), 0, false); } -void ChildThread::OnProcessBackgrounded(bool background) { +void ChildThreadImpl::OnProcessBackgrounded(bool background) { // Set timer slack to maximum on main thread when in background. base::TimerSlack timer_slack = base::TIMER_SLACK_NONE; if (background)
diff --git a/content/child/child_thread.h b/content/child/child_thread_impl.h similarity index 90% rename from content/child/child_thread.h rename to content/child/child_thread_impl.h index 24cfc61..20decd40 100644 --- a/content/child/child_thread.h +++ b/content/child/child_thread_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_CHILD_CHILD_THREAD_H_ -#define CONTENT_CHILD_CHILD_THREAD_H_ +#ifndef CONTENT_CHILD_CHILD_THREAD_IMPL_H_ +#define CONTENT_CHILD_CHILD_THREAD_IMPL_H_ #include <string> @@ -16,6 +16,7 @@ #include "content/child/mojo/mojo_application.h" #include "content/common/content_export.h" #include "content/common/message_router.h" +#include "content/public/child/child_thread.h" #include "ipc/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED. namespace base { @@ -37,14 +38,13 @@ } // namespace blink namespace content { -class BluetoothMessageFilter; +class ChildMessageFilter; class ChildDiscardableSharedMemoryManager; class ChildGpuMemoryBufferManager; class ChildHistogramMessageFilter; class ChildResourceMessageFilter; class ChildSharedBitmapManager; class FileSystemDispatcher; -class GeofencingMessageFilter; class NavigatorConnectDispatcher; class NotificationDispatcher; class PushDispatcher; @@ -57,7 +57,9 @@ struct RequestInfo; // The main thread of a child process derives from this class. -class CONTENT_EXPORT ChildThread : public IPC::Listener, public IPC::Sender { +class CONTENT_EXPORT ChildThreadImpl + : public IPC::Listener, + virtual public ChildThread { public: struct CONTENT_EXPORT Options { Options(); @@ -72,21 +74,27 @@ }; // Creates the thread. - ChildThread(); + ChildThreadImpl(); // Allow to be used for single-process mode and for in process gpu mode via // options. - explicit ChildThread(const Options& options); + explicit ChildThreadImpl(const Options& options); // ChildProcess::main_thread() is reset after Shutdown(), and before the // destructor, so any subsystem that relies on ChildProcess::main_thread() // must be terminated before Shutdown returns. In particular, if a subsystem // has a thread that post tasks to ChildProcess::main_thread(), that thread // should be joined in Shutdown(). - ~ChildThread() override; + ~ChildThreadImpl() override; virtual void Shutdown(); // IPC::Sender implementation: bool Send(IPC::Message* msg) override; + // ChildThread implementation: +#if defined(OS_WIN) + void PreCacheFont(const LOGFONT& log_font) override; + void ReleaseCachedFonts() override; +#endif + IPC::SyncChannel* channel() { return channel_.get(); } MessageRouter* GetRouter(); @@ -170,7 +178,7 @@ base::MessageLoop* message_loop() const { return message_loop_; } // Returns the one child thread. Can only be called on the main thread. - static ChildThread* current(); + static ChildThreadImpl* current(); #if defined(OS_ANDROID) // Called on Android's service thread to shutdown the main thread of this @@ -241,7 +249,8 @@ scoped_refptr<ThreadSafeSender> thread_safe_sender_; - // Implements message routing functionality to the consumers of ChildThread. + // Implements message routing functionality to the consumers of + // ChildThreadImpl. ChildThreadMessageRouter router_; // Handles resource loads for this process. @@ -284,19 +293,18 @@ scoped_ptr<base::PowerMonitor> power_monitor_; - scoped_refptr<GeofencingMessageFilter> geofencing_message_filter_; - - scoped_refptr<BluetoothMessageFilter> bluetooth_message_filter_; + scoped_refptr<ChildMessageFilter> geofencing_message_filter_; + scoped_refptr<ChildMessageFilter> bluetooth_message_filter_; scoped_refptr<NavigatorConnectDispatcher> navigator_connect_dispatcher_; bool in_browser_process_; - base::WeakPtrFactory<ChildThread> channel_connected_factory_; + base::WeakPtrFactory<ChildThreadImpl> channel_connected_factory_; - DISALLOW_COPY_AND_ASSIGN(ChildThread); + DISALLOW_COPY_AND_ASSIGN(ChildThreadImpl); }; } // namespace content -#endif // CONTENT_CHILD_CHILD_THREAD_H_ +#endif // CONTENT_CHILD_CHILD_THREAD_IMPL_H_
diff --git a/content/child/fileapi/file_system_dispatcher.cc b/content/child/fileapi/file_system_dispatcher.cc index 8ba8764e..1a742db2 100644 --- a/content/child/fileapi/file_system_dispatcher.cc +++ b/content/child/fileapi/file_system_dispatcher.cc
@@ -8,7 +8,7 @@ #include "base/files/file_util.h" #include "base/message_loop/message_loop_proxy.h" #include "base/process/process.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/fileapi/file_system_messages.h" #include "storage/common/fileapi/file_system_info.h" @@ -171,7 +171,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send(new FileSystemHostMsg_OpenFileSystem( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_OpenFileSystem( request_id, origin_url, type)); } @@ -181,7 +181,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send(new FileSystemHostMsg_ResolveURL( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_ResolveURL( request_id, filesystem_url)); } @@ -189,7 +189,7 @@ storage::FileSystemType type, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_DeleteFileSystem( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_DeleteFileSystem( request_id, origin_url, type)); } @@ -198,7 +198,7 @@ const GURL& dest_path, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_Move( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_Move( request_id, src_path, dest_path)); } @@ -207,7 +207,7 @@ const GURL& dest_path, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_Copy( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_Copy( request_id, src_path, dest_path)); } @@ -216,7 +216,7 @@ bool recursive, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_Remove(request_id, path, recursive)); } @@ -226,7 +226,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_ReadMetadata(request_id, path)); } @@ -235,7 +235,7 @@ bool exclusive, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_Create( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_Create( request_id, path, exclusive, false /* is_directory */, false /* recursive */)); } @@ -246,7 +246,7 @@ bool recursive, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_Create( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_Create( request_id, path, exclusive, true /* is_directory */, recursive)); } @@ -255,7 +255,7 @@ bool is_directory, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_Exists(request_id, path, is_directory)); } @@ -265,7 +265,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_ReadDirectory(request_id, path)); } @@ -275,7 +275,7 @@ int* request_id_out, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_Truncate(request_id, path, offset)); if (request_id_out) @@ -291,7 +291,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_Write(request_id, path, blob_id, offset)); if (request_id_out) @@ -302,7 +302,7 @@ int request_id_to_cancel, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send(new FileSystemHostMsg_CancelWrite( + ChildThreadImpl::current()->Send(new FileSystemHostMsg_CancelWrite( request_id, request_id_to_cancel)); } @@ -312,7 +312,7 @@ const base::Time& last_modified_time, const StatusCallback& callback) { int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_TouchFile( request_id, path, last_access_time, last_modified_time)); } @@ -323,7 +323,7 @@ const StatusCallback& error_callback) { int request_id = dispatchers_.Add( CallbackDispatcher::Create(success_callback, error_callback)); - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new FileSystemHostMsg_CreateSnapshotFile( request_id, file_path)); }
diff --git a/content/child/fileapi/webfilesystem_impl.cc b/content/child/fileapi/webfilesystem_impl.cc index 8fe0243..c791e8d 100644 --- a/content/child/fileapi/webfilesystem_impl.cc +++ b/content/child/fileapi/webfilesystem_impl.cc
@@ -10,12 +10,12 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/thread_task_runner_handle.h" #include "base/threading/thread_local.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/file_info_util.h" #include "content/child/fileapi/file_system_dispatcher.h" #include "content/child/fileapi/webfilewriter_impl.h" -#include "content/child/worker_task_runner.h" #include "content/common/fileapi/file_system_messages.h" #include "storage/common/fileapi/directory_entry.h" #include "storage/common/fileapi/file_system_util.h" @@ -86,15 +86,11 @@ g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; void DidReceiveSnapshotFile(int request_id) { - if (ChildThread::current()) - ChildThread::current()->Send( + if (ChildThreadImpl::current()) + ChildThreadImpl::current()->Send( new FileSystemHostMsg_DidReceiveSnapshotFile(request_id)); } -int CurrentWorkerId() { - return WorkerTaskRunner::Instance()->CurrentWorkerId(); -} - template <typename Method, typename Params> void CallDispatcherOnMainThread( const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner, @@ -110,12 +106,12 @@ return; waitable_results->WaitAndRun(); } - if (!ChildThread::current() || - !ChildThread::current()->file_system_dispatcher()) + if (!ChildThreadImpl::current() || + !ChildThreadImpl::current()->file_system_dispatcher()) return; DCHECK(!waitable_results); - DispatchToMethod(ChildThread::current()->file_system_dispatcher(), + DispatchToMethod(ChildThreadImpl::current()->file_system_dispatcher(), method, params); } @@ -191,35 +187,37 @@ callback.Run(&callbacks); } -void DispatchResultsClosure(int thread_id, int callbacks_id, - WaitableCallbackResults* waitable_results, - const base::Closure& results_closure) { - if (thread_id != CurrentWorkerId()) { - if (waitable_results) { - // If someone is waiting, this should result in running the closure. - waitable_results->AddResultsAndSignal(results_closure); - // In case no one is waiting, post a task to run the closure. - WorkerTaskRunner::Instance()->PostTask( - thread_id, - base::Bind(&WaitableCallbackResults::Run, - make_scoped_refptr(waitable_results))); - return; - } - WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure); +void DispatchResultsClosure( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, + WaitableCallbackResults* waitable_results, + const base::Closure& results_closure) { + if (task_runner->BelongsToCurrentThread()) { + results_closure.Run(); return; } - results_closure.Run(); + + if (waitable_results) { + // If someone is waiting, this should result in running the closure. + waitable_results->AddResultsAndSignal(results_closure); + // In case no one is waiting, post a task to run the closure. + task_runner->PostTask(FROM_HERE, + base::Bind(&WaitableCallbackResults::Run, + make_scoped_refptr(waitable_results))); + return; + } + task_runner->PostTask(FROM_HERE, results_closure); } void CallbackFileSystemCallbacks( - int thread_id, int callbacks_id, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, WaitableCallbackResults* waitable_results, const base::Callback<void(WebFileSystemCallbacks*)>& callback, CallbacksUnregisterMode callbacksunregister_mode) { - DispatchResultsClosure( - thread_id, callbacks_id, waitable_results, - base::Bind(&RunCallbacks, callbacks_id, callback, - callbacksunregister_mode)); + DispatchResultsClosure(task_runner, callbacks_id, waitable_results, + base::Bind(&RunCallbacks, callbacks_id, callback, + callbacksunregister_mode)); } //----------------------------------------------------------------------------- @@ -228,64 +226,67 @@ // if necessary. void OpenFileSystemCallbackAdapter( - int thread_id, int callbacks_id, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, WaitableCallbackResults* waitable_results, - const std::string& name, const GURL& root) { + const std::string& name, + const GURL& root) { CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, + task_runner, callbacks_id, waitable_results, base::Bind(&DidOpenFileSystem, base::UTF8ToUTF16(name), root), UNREGISTER_CALLBACKS); } -void ResolveURLCallbackAdapter(int thread_id, - int callbacks_id, - WaitableCallbackResults* waitable_results, - const storage::FileSystemInfo& info, - const base::FilePath& file_path, - bool is_directory) { +void ResolveURLCallbackAdapter( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, + WaitableCallbackResults* waitable_results, + const storage::FileSystemInfo& info, + const base::FilePath& file_path, + bool is_directory) { base::FilePath normalized_path( storage::VirtualPath::GetNormalizedFilePath(file_path)); CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, + task_runner, callbacks_id, waitable_results, base::Bind(&DidResolveURL, base::UTF8ToUTF16(info.name), info.root_url, - info.mount_type, - normalized_path.AsUTF16Unsafe(), is_directory), + info.mount_type, normalized_path.AsUTF16Unsafe(), + is_directory), UNREGISTER_CALLBACKS); } -void StatusCallbackAdapter(int thread_id, int callbacks_id, - WaitableCallbackResults* waitable_results, - base::File::Error error) { +void StatusCallbackAdapter( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, + WaitableCallbackResults* waitable_results, + base::File::Error error) { if (error == base::File::FILE_OK) { - CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, - base::Bind(&DidSucceed), - UNREGISTER_CALLBACKS); + CallbackFileSystemCallbacks(task_runner, callbacks_id, waitable_results, + base::Bind(&DidSucceed), UNREGISTER_CALLBACKS); } else { - CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, - base::Bind(&DidFail, error), - UNREGISTER_CALLBACKS); + CallbackFileSystemCallbacks(task_runner, callbacks_id, waitable_results, + base::Bind(&DidFail, error), + UNREGISTER_CALLBACKS); } } -void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id, - WaitableCallbackResults* waitable_results, - const base::File::Info& file_info) { - CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, - base::Bind(&DidReadMetadata, file_info), - UNREGISTER_CALLBACKS); +void ReadMetadataCallbackAdapter( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, + WaitableCallbackResults* waitable_results, + const base::File::Info& file_info) { + CallbackFileSystemCallbacks(task_runner, callbacks_id, waitable_results, + base::Bind(&DidReadMetadata, file_info), + UNREGISTER_CALLBACKS); } void ReadDirectoryCallbackAdapter( - int thread_id, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, int callbacks_id, WaitableCallbackResults* waitable_results, const std::vector<storage::DirectoryEntry>& entries, bool has_more) { CallbackFileSystemCallbacks( - thread_id, callbacks_id, waitable_results, + task_runner, callbacks_id, waitable_results, base::Bind(&DidReadDirectory, entries, has_more), has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS); } @@ -317,14 +318,15 @@ } void CreateFileWriterCallbackAdapter( - int thread_id, int callbacks_id, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, WaitableCallbackResults* waitable_results, const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner, const GURL& path, blink::WebFileWriterClient* client, const base::File::Info& file_info) { DispatchResultsClosure( - thread_id, callbacks_id, waitable_results, + task_runner, callbacks_id, waitable_results, base::Bind(&DidCreateFileWriter, callbacks_id, path, client, main_thread_task_runner, file_info)); } @@ -355,14 +357,15 @@ } void CreateSnapshotFileCallbackAdapter( - int thread_id, int callbacks_id, + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + int callbacks_id, WaitableCallbackResults* waitable_results, const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner, const base::File::Info& file_info, const base::FilePath& platform_path, int request_id) { DispatchResultsClosure( - thread_id, callbacks_id, waitable_results, + task_runner, callbacks_id, waitable_results, base::Bind(&DidCreateSnapshotFile, callbacks_id, main_thread_task_runner, file_info, platform_path, request_id)); } @@ -413,17 +416,14 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::OpenFileSystem, + main_thread_task_runner_, &FileSystemDispatcher::OpenFileSystem, MakeTuple(GURL(storage_partition), static_cast<storage::FileSystemType>(type), base::Bind(&OpenFileSystemCallbackAdapter, - CurrentWorkerId(), - callbacks_id, + base::ThreadTaskRunnerHandle::Get(), callbacks_id, waitable_results), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), - callbacks_id, + base::ThreadTaskRunnerHandle::Get(), callbacks_id, waitable_results)), waitable_results.get()); } @@ -435,13 +435,14 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::ResolveURL, + main_thread_task_runner_, &FileSystemDispatcher::ResolveURL, MakeTuple(GURL(filesystem_url), base::Bind(&ResolveURLCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -453,13 +454,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::DeleteFileSystem, + main_thread_task_runner_, &FileSystemDispatcher::DeleteFileSystem, MakeTuple(GURL(storage_partition), static_cast<storage::FileSystemType>(type), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), - callbacks_id, + base::ThreadTaskRunnerHandle::Get(), callbacks_id, waitable_results)), waitable_results.get()); } @@ -472,11 +471,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Move, + main_thread_task_runner_, &FileSystemDispatcher::Move, MakeTuple(GURL(src_path), GURL(dest_path), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -488,11 +487,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Copy, + main_thread_task_runner_, &FileSystemDispatcher::Copy, MakeTuple(GURL(src_path), GURL(dest_path), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -503,11 +502,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Remove, + main_thread_task_runner_, &FileSystemDispatcher::Remove, MakeTuple(GURL(path), false /* recursive */, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -518,11 +517,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Remove, + main_thread_task_runner_, &FileSystemDispatcher::Remove, MakeTuple(GURL(path), true /* recursive */, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -533,13 +532,13 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::ReadMetadata, - MakeTuple(GURL(path), - base::Bind(&ReadMetadataCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results), + main_thread_task_runner_, &FileSystemDispatcher::ReadMetadata, + MakeTuple(GURL(path), base::Bind(&ReadMetadataCallbackAdapter, + base::ThreadTaskRunnerHandle::Get(), + callbacks_id, waitable_results), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -551,11 +550,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::CreateFile, + main_thread_task_runner_, &FileSystemDispatcher::CreateFile, MakeTuple(GURL(path), exclusive, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -567,11 +566,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::CreateDirectory, + main_thread_task_runner_, &FileSystemDispatcher::CreateDirectory, MakeTuple(GURL(path), exclusive, false /* recursive */, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -582,11 +581,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Exists, + main_thread_task_runner_, &FileSystemDispatcher::Exists, MakeTuple(GURL(path), false /* directory */, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -597,11 +596,11 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::Exists, + main_thread_task_runner_, &FileSystemDispatcher::Exists, MakeTuple(GURL(path), true /* directory */, base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -612,13 +611,13 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::ReadDirectory, - MakeTuple(GURL(path), - base::Bind(&ReadDirectoryCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results), + main_thread_task_runner_, &FileSystemDispatcher::ReadDirectory, + MakeTuple(GURL(path), base::Bind(&ReadDirectoryCallbackAdapter, + base::ThreadTaskRunnerHandle::Get(), + callbacks_id, waitable_results), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); return callbacks_id; } @@ -631,14 +630,15 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::ReadMetadata, + main_thread_task_runner_, &FileSystemDispatcher::ReadMetadata, MakeTuple(GURL(path), base::Bind(&CreateFileWriterCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results, - main_thread_task_runner_, GURL(path), client), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results, main_thread_task_runner_, + GURL(path), client), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); } @@ -649,14 +649,14 @@ scoped_refptr<WaitableCallbackResults> waitable_results = MaybeCreateWaitableResults(callbacks, callbacks_id); CallDispatcherOnMainThread( - main_thread_task_runner_, - &FileSystemDispatcher::CreateSnapshotFile, + main_thread_task_runner_, &FileSystemDispatcher::CreateSnapshotFile, MakeTuple(GURL(path), base::Bind(&CreateSnapshotFileCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results, - main_thread_task_runner_), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results, main_thread_task_runner_), base::Bind(&StatusCallbackAdapter, - CurrentWorkerId(), callbacks_id, waitable_results)), + base::ThreadTaskRunnerHandle::Get(), callbacks_id, + waitable_results)), waitable_results.get()); }
diff --git a/content/child/fileapi/webfilewriter_impl.cc b/content/child/fileapi/webfilewriter_impl.cc index a8fd3ea..ef16def1 100644 --- a/content/child/fileapi/webfilewriter_impl.cc +++ b/content/child/fileapi/webfilewriter_impl.cc
@@ -6,7 +6,8 @@ #include "base/bind.h" #include "base/synchronization/waitable_event.h" -#include "content/child/child_thread.h" +#include "base/thread_task_runner_handle.h" +#include "content/child/child_thread_impl.h" #include "content/child/fileapi/file_system_dispatcher.h" #include "content/child/worker_task_runner.h" @@ -15,8 +16,8 @@ namespace { FileSystemDispatcher* GetFileSystemDispatcher() { - return ChildThread::current() ? - ChildThread::current()->file_system_dispatcher() : NULL; + return ChildThreadImpl::current() ? + ChildThreadImpl::current()->file_system_dispatcher() : NULL; } } // namespace @@ -31,7 +32,9 @@ public: WriterBridge(WebFileWriterImpl::Type type) : request_id_(0), - thread_id_(WorkerTaskRunner::Instance()->CurrentWorkerId()), + running_on_worker_(WorkerTaskRunner::Instance()->CurrentWorkerId() > 0), + task_runner_(running_on_worker_ ? base::ThreadTaskRunnerHandle::Get() + : nullptr), written_bytes_(0) { if (type == WebFileWriterImpl::TYPE_SYNC) waitable_event_.reset(new base::WaitableEvent(false, false)); @@ -42,7 +45,7 @@ status_callback_ = status_callback; if (!GetFileSystemDispatcher()) return; - ChildThread::current()->file_system_dispatcher()->Truncate( + ChildThreadImpl::current()->file_system_dispatcher()->Truncate( path, offset, &request_id_, base::Bind(&WriterBridge::DidFinish, this)); } @@ -54,7 +57,7 @@ status_callback_ = error_callback; if (!GetFileSystemDispatcher()) return; - ChildThread::current()->file_system_dispatcher()->Write( + ChildThreadImpl::current()->file_system_dispatcher()->Write( path, id, offset, &request_id_, base::Bind(&WriterBridge::DidWrite, this), base::Bind(&WriterBridge::DidFinish, this)); @@ -64,7 +67,7 @@ status_callback_ = status_callback; if (!GetFileSystemDispatcher()) return; - ChildThread::current()->file_system_dispatcher()->Cancel( + ChildThreadImpl::current()->file_system_dispatcher()->Cancel( request_id_, base::Bind(&WriterBridge::DidFinish, this)); } @@ -96,23 +99,25 @@ void PostTaskToWorker(const base::Closure& closure) { written_bytes_ = 0; - if (!thread_id_) { + if (!running_on_worker_) { DCHECK(!waitable_event_); closure.Run(); return; } + DCHECK(task_runner_); if (waitable_event_) { results_closure_ = closure; waitable_event_->Signal(); return; } - WorkerTaskRunner::Instance()->PostTask(thread_id_, closure); + task_runner_->PostTask(FROM_HERE, closure); } StatusCallback status_callback_; WriteCallback write_callback_; int request_id_; - int thread_id_; + const bool running_on_worker_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; int written_bytes_; scoped_ptr<base::WaitableEvent> waitable_event_; base::Closure results_closure_;
diff --git a/content/child/geofencing/geofencing_message_filter.cc b/content/child/geofencing/geofencing_message_filter.cc index a833457..a866b37 100644 --- a/content/child/geofencing/geofencing_message_filter.cc +++ b/content/child/geofencing/geofencing_message_filter.cc
@@ -4,40 +4,33 @@ #include "content/child/geofencing/geofencing_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/geofencing/geofencing_dispatcher.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "ipc/ipc_message_macros.h" namespace content { GeofencingMessageFilter::GeofencingMessageFilter(ThreadSafeSender* sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(sender) { + : WorkerThreadMessageFilter(sender) { } GeofencingMessageFilter::~GeofencingMessageFilter() { } -base::TaskRunner* GeofencingMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != GeofencingMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool GeofencingMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == GeofencingMsgStart; } -bool GeofencingMessageFilter::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != GeofencingMsgStart) - return false; - GeofencingDispatcher::GetOrCreateThreadSpecificInstance( - thread_safe_sender_.get())->OnMessageReceived(msg); - return true; +void GeofencingMessageFilter::OnFilteredMessageReceived( + const IPC::Message& msg) { + GeofencingDispatcher::GetOrCreateThreadSpecificInstance(thread_safe_sender()) + ->OnMessageReceived(msg); +} + +bool GeofencingMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } } // namespace content
diff --git a/content/child/geofencing/geofencing_message_filter.h b/content/child/geofencing/geofencing_message_filter.h index 3a95d42..34a05c2 100644 --- a/content/child/geofencing/geofencing_message_filter.h +++ b/content/child/geofencing/geofencing_message_filter.h
@@ -5,30 +5,22 @@ #ifndef CONTENT_CHILD_GEOFENCING_GEOFENCING_MESSAGE_FILTER_H_ #define CONTENT_CHILD_GEOFENCING_GEOFENCING_MESSAGE_FILTER_H_ -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - -class GeofencingMessageFilter : public ChildMessageFilter { +class GeofencingMessageFilter : public WorkerThreadMessageFilter { public: explicit GeofencingMessageFilter(ThreadSafeSender* thread_safe_sender); private: ~GeofencingMessageFilter() override; - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; - - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; DISALLOW_COPY_AND_ASSIGN(GeofencingMessageFilter); };
diff --git a/content/child/indexed_db/indexed_db_message_filter.cc b/content/child/indexed_db/indexed_db_message_filter.cc index bce3817..60c1bea 100644 --- a/content/child/indexed_db/indexed_db_message_filter.cc +++ b/content/child/indexed_db/indexed_db_message_filter.cc
@@ -4,10 +4,8 @@ #include "content/child/indexed_db/indexed_db_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/indexed_db/indexed_db_dispatcher.h" #include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/indexed_db/indexed_db_constants.h" #include "content/common/indexed_db/indexed_db_messages.h" @@ -15,29 +13,26 @@ IndexedDBMessageFilter::IndexedDBMessageFilter( ThreadSafeSender* thread_safe_sender) - : main_thread_loop_(base::MessageLoopProxy::current()), - thread_safe_sender_(thread_safe_sender) {} + : WorkerThreadMessageFilter(thread_safe_sender) { +} IndexedDBMessageFilter::~IndexedDBMessageFilter() {} -base::TaskRunner* IndexedDBMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != IndexedDBMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool IndexedDBMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == IndexedDBMsgStart; } -bool IndexedDBMessageFilter::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != IndexedDBMsgStart) - return false; - IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get()) +void IndexedDBMessageFilter::OnFilteredMessageReceived( + const IPC::Message& msg) { + IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender()) ->OnMessageReceived(msg); - return true; +} + +bool IndexedDBMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } void IndexedDBMessageFilter::OnStaleMessageReceived(const IPC::Message& msg) { @@ -57,13 +52,13 @@ const IndexedDBDatabaseMetadata& idb_metadata) { if (ipc_database_id == kNoDatabase) return; - thread_safe_sender_->Send( + thread_safe_sender()->Send( new IndexedDBHostMsg_DatabaseClose(ipc_database_id)); } void IndexedDBMessageFilter::OnStaleUpgradeNeeded( const IndexedDBMsg_CallbacksUpgradeNeeded_Params& p) { - thread_safe_sender_->Send( + thread_safe_sender()->Send( new IndexedDBHostMsg_DatabaseClose(p.ipc_database_id)); }
diff --git a/content/child/indexed_db/indexed_db_message_filter.h b/content/child/indexed_db/indexed_db_message_filter.h index e2d1ed5..08e39982 100644 --- a/content/child/indexed_db/indexed_db_message_filter.h +++ b/content/child/indexed_db/indexed_db_message_filter.h
@@ -6,7 +6,7 @@ #define CONTENT_CHILD_INDEXED_DB_INDEXED_DB_MESSAGE_FILTER_H_ #include "base/memory/ref_counted.h" -#include "content/child/child_message_filter.h" +#include "content/child/worker_thread_message_filter.h" struct IndexedDBDatabaseMetadata; struct IndexedDBMsg_CallbacksUpgradeNeeded_Params; @@ -15,15 +15,9 @@ class MessageLoopProxy; } -namespace IPC { -class Message; -} - namespace content { -class ThreadSafeSender; - -class IndexedDBMessageFilter : public ChildMessageFilter { +class IndexedDBMessageFilter : public WorkerThreadMessageFilter { public: explicit IndexedDBMessageFilter(ThreadSafeSender* thread_safe_sender); @@ -31,10 +25,13 @@ ~IndexedDBMessageFilter() override; private: - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; + + // ChildMessageFilter: void OnStaleMessageReceived(const IPC::Message& msg) override; void OnStaleSuccessIDBDatabase(int32 ipc_thread_id, @@ -44,9 +41,6 @@ const IndexedDBDatabaseMetadata&); void OnStaleUpgradeNeeded(const IndexedDBMsg_CallbacksUpgradeNeeded_Params&); - scoped_refptr<base::MessageLoopProxy> main_thread_loop_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; - DISALLOW_COPY_AND_ASSIGN(IndexedDBMessageFilter); };
diff --git a/content/child/navigator_connect/navigator_connect_dispatcher.cc b/content/child/navigator_connect/navigator_connect_dispatcher.cc index d2f7119a..1a30433 100644 --- a/content/child/navigator_connect/navigator_connect_dispatcher.cc +++ b/content/child/navigator_connect/navigator_connect_dispatcher.cc
@@ -4,41 +4,33 @@ #include "content/child/navigator_connect/navigator_connect_dispatcher.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/navigator_connect/navigator_connect_provider.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/navigator_connect_messages.h" namespace content { NavigatorConnectDispatcher::NavigatorConnectDispatcher(ThreadSafeSender* sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(sender) { + : WorkerThreadMessageFilter(sender) { } NavigatorConnectDispatcher::~NavigatorConnectDispatcher() { } -base::TaskRunner* NavigatorConnectDispatcher::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != NavigatorConnectMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool NavigatorConnectDispatcher::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == NavigatorConnectMsgStart; } -bool NavigatorConnectDispatcher::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != NavigatorConnectMsgStart) - return false; - NavigatorConnectProvider::ThreadSpecificInstance(thread_safe_sender_.get(), - main_thread_loop_proxy_) - ->OnMessageReceived(msg); - return true; +void NavigatorConnectDispatcher::OnFilteredMessageReceived( + const IPC::Message& msg) { + NavigatorConnectProvider::ThreadSpecificInstance( + thread_safe_sender(), main_thread_task_runner())->OnMessageReceived(msg); +} + +bool NavigatorConnectDispatcher::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } } // namespace content
diff --git a/content/child/navigator_connect/navigator_connect_dispatcher.h b/content/child/navigator_connect/navigator_connect_dispatcher.h index 3455912..0044b51 100644 --- a/content/child/navigator_connect/navigator_connect_dispatcher.h +++ b/content/child/navigator_connect/navigator_connect_dispatcher.h
@@ -5,32 +5,24 @@ #ifndef CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_DISPATCHER_H_ #define CONTENT_CHILD_NAVIGATOR_CONNECT_NAVIGATOR_CONNECT_DISPATCHER_H_ -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - // Receives IPC messages from the browser process and dispatches them to the // correct thread specific NavigatorConnectProvider. -class NavigatorConnectDispatcher : public ChildMessageFilter { +class NavigatorConnectDispatcher : public WorkerThreadMessageFilter { public: explicit NavigatorConnectDispatcher(ThreadSafeSender* thread_safe_sender); private: ~NavigatorConnectDispatcher() override; - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; - - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; DISALLOW_COPY_AND_ASSIGN(NavigatorConnectDispatcher); };
diff --git a/content/child/notifications/notification_dispatcher.cc b/content/child/notifications/notification_dispatcher.cc index a9a5daa..5949972 100644 --- a/content/child/notifications/notification_dispatcher.cc +++ b/content/child/notifications/notification_dispatcher.cc
@@ -4,19 +4,14 @@ #include "content/child/notifications/notification_dispatcher.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/notifications/notification_manager.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/platform_notification_messages.h" namespace content { NotificationDispatcher::NotificationDispatcher( ThreadSafeSender* thread_safe_sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(thread_safe_sender), - next_notification_id_(0) { + : WorkerThreadMessageFilter(thread_safe_sender), next_notification_id_(0) { } NotificationDispatcher::~NotificationDispatcher() {} @@ -27,43 +22,32 @@ return next_notification_id_++; } -base::TaskRunner* NotificationDispatcher::OverrideTaskRunnerForMessage( +bool NotificationDispatcher::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == PlatformNotificationMsgStart; +} + +void NotificationDispatcher::OnFilteredMessageReceived( const IPC::Message& msg) { - if (!ShouldHandleMessage(msg)) - return NULL; + NotificationManager::ThreadSpecificInstance(thread_safe_sender(), + main_thread_task_runner(), + this)->OnMessageReceived(msg); +} - int notification_id = -1, - thread_id = 0; - +bool NotificationDispatcher::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + int notification_id = -1; const bool success = PickleIterator(msg).ReadInt(¬ification_id); DCHECK(success); - { - base::AutoLock lock(notification_id_map_lock_); - auto iterator = notification_id_map_.find(notification_id); - if (iterator != notification_id_map_.end()) - thread_id = iterator->second; + base::AutoLock lock(notification_id_map_lock_); + auto iterator = notification_id_map_.find(notification_id); + if (iterator != notification_id_map_.end()) { + *ipc_thread_id = iterator->second; + return true; } - - if (!thread_id) - return main_thread_loop_proxy_.get(); - - return new WorkerThreadTaskRunner(thread_id); -} - -bool NotificationDispatcher::OnMessageReceived(const IPC::Message& msg) { - if (!ShouldHandleMessage(msg)) - return false; - - NotificationManager::ThreadSpecificInstance( - thread_safe_sender_.get(), - main_thread_loop_proxy_.get(), - this)->OnMessageReceived(msg); - return true; -} - -bool NotificationDispatcher::ShouldHandleMessage(const IPC::Message& msg) { - return IPC_MESSAGE_CLASS(msg) == PlatformNotificationMsgStart; + return false; } } // namespace content
diff --git a/content/child/notifications/notification_dispatcher.h b/content/child/notifications/notification_dispatcher.h index be4ada9..824cde3b 100644 --- a/content/child/notifications/notification_dispatcher.h +++ b/content/child/notifications/notification_dispatcher.h
@@ -7,19 +7,12 @@ #include <map> -#include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - -class NotificationDispatcher : public ChildMessageFilter { +class NotificationDispatcher : public WorkerThreadMessageFilter { public: explicit NotificationDispatcher(ThreadSafeSender* thread_safe_sender); @@ -31,15 +24,11 @@ ~NotificationDispatcher() override; private: - bool ShouldHandleMessage(const IPC::Message& msg); - - // ChildMessageFilter implementation. - base::TaskRunner* OverrideTaskRunnerForMessage(const IPC::Message& msg) - override; - bool OnMessageReceived(const IPC::Message& msg) override; - - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; using NotificationIdToThreadId = std::map<int, int>;
diff --git a/content/child/notifications/notification_image_loader.cc b/content/child/notifications/notification_image_loader.cc index b2eb23eb..c194b024 100644 --- a/content/child/notifications/notification_image_loader.cc +++ b/content/child/notifications/notification_image_loader.cc
@@ -5,7 +5,7 @@ #include "content/child/notifications/notification_image_loader.h" #include "base/logging.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/image_decoder.h" #include "content/child/worker_task_runner.h" #include "third_party/WebKit/public/platform/Platform.h" @@ -29,7 +29,7 @@ void NotificationImageLoader::StartOnMainThread(const WebURL& image_url, int worker_thread_id) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); DCHECK(!url_loader_); worker_thread_id_ = worker_thread_id;
diff --git a/content/child/npapi/plugin_url_fetcher.cc b/content/child/npapi/plugin_url_fetcher.cc index c7db56c..15bd602 100644 --- a/content/child/npapi/plugin_url_fetcher.cc +++ b/content/child/npapi/plugin_url_fetcher.cc
@@ -5,7 +5,7 @@ #include "content/child/npapi/plugin_url_fetcher.h" #include "base/memory/scoped_ptr.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/multipart_response_delegate.h" #include "content/child/npapi/plugin_host.h" #include "content/child/npapi/plugin_instance.h" @@ -146,7 +146,7 @@ request_info.headers = std::string("Range: ") + range; } - bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge( + bridge_.reset(ChildThreadImpl::current()->resource_dispatcher()->CreateBridge( request_info)); if (!body.empty()) { scoped_refptr<ResourceRequestBody> request_body =
diff --git a/content/child/push_messaging/push_dispatcher.cc b/content/child/push_messaging/push_dispatcher.cc index 4bd1705..8cc33fc0 100644 --- a/content/child/push_messaging/push_dispatcher.cc +++ b/content/child/push_messaging/push_dispatcher.cc
@@ -4,19 +4,13 @@ #include "content/child/push_messaging/push_dispatcher.h" -#include "base/message_loop/message_loop_proxy.h" -#include "base/pickle.h" #include "content/child/push_messaging/push_provider.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/push_messaging_messages.h" namespace content { PushDispatcher::PushDispatcher(ThreadSafeSender* thread_safe_sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(thread_safe_sender), - next_request_id_(0) { + : WorkerThreadMessageFilter(thread_safe_sender), next_request_id_(0) { } PushDispatcher::~PushDispatcher() { @@ -28,43 +22,7 @@ return next_request_id_++; } -base::TaskRunner* PushDispatcher::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (!ShouldHandleMessage(msg)) - return nullptr; - - int request_id = -1; - int thread_id = 0; - - const bool success = PickleIterator(msg).ReadInt(&request_id); - DCHECK(success); - - { - base::AutoLock lock(request_id_map_lock_); - auto it = request_id_map_.find(request_id); - if (it != request_id_map_.end()) { - thread_id = it->second; - request_id_map_.erase(it); - } - } - - if (!thread_id) - return main_thread_loop_proxy_.get(); - - return new WorkerThreadTaskRunner(thread_id); -} - -bool PushDispatcher::OnMessageReceived(const IPC::Message& msg) { - if (!ShouldHandleMessage(msg)) - return false; - - bool handled = PushProvider::ThreadSpecificInstance( - thread_safe_sender_.get(), this)->OnMessageReceived(msg); - DCHECK(handled); - return handled; -} - -bool PushDispatcher::ShouldHandleMessage(const IPC::Message& msg) { +bool PushDispatcher::ShouldHandleMessage(const IPC::Message& msg) const { // Note that not all Push API IPC messages flow through this class. A subset // of the API functionality requires a direct association with a document and // a frame, and for those cases the IPC messages are handled by a @@ -79,4 +37,27 @@ msg.type() == PushMessagingMsg_UnregisterError::ID; } +void PushDispatcher::OnFilteredMessageReceived(const IPC::Message& msg) { + bool handled = PushProvider::ThreadSpecificInstance( + thread_safe_sender(), this)->OnMessageReceived(msg); + DCHECK(handled); +} + +bool PushDispatcher::GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) { + int request_id = -1; + + const bool success = PickleIterator(msg).ReadInt(&request_id); + DCHECK(success); + + base::AutoLock lock(request_id_map_lock_); + auto it = request_id_map_.find(request_id); + if (it != request_id_map_.end()) { + *ipc_thread_id = it->second; + request_id_map_.erase(it); + return true; + } + return false; +} + } // namespace content
diff --git a/content/child/push_messaging/push_dispatcher.h b/content/child/push_messaging/push_dispatcher.h index db598fb..5eaf550 100644 --- a/content/child/push_messaging/push_dispatcher.h +++ b/content/child/push_messaging/push_dispatcher.h
@@ -7,20 +7,12 @@ #include <map> -#include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "content/child/child_message_filter.h" -#include "content/public/common/push_messaging_status.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - -class PushDispatcher : public ChildMessageFilter { +class PushDispatcher : public WorkerThreadMessageFilter { public: explicit PushDispatcher(ThreadSafeSender* thread_safe_sender); @@ -34,15 +26,11 @@ ~PushDispatcher() override; private: - bool ShouldHandleMessage(const IPC::Message& msg); - - // ChildMessageFilter implementation. - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; - - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; base::Lock request_id_map_lock_; std::map<int, int> request_id_map_; // Maps request id to thread id.
diff --git a/content/child/push_messaging/push_provider.h b/content/child/push_messaging/push_provider.h index 3a0eec9..3a243c78 100644 --- a/content/child/push_messaging/push_provider.h +++ b/content/child/push_messaging/push_provider.h
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "content/child/push_messaging/push_dispatcher.h" #include "content/child/worker_task_runner.h" +#include "content/public/common/push_messaging_status.h" #include "third_party/WebKit/public/platform/WebPushError.h" #include "third_party/WebKit/public/platform/WebPushProvider.h"
diff --git a/content/child/quota_dispatcher.cc b/content/child/quota_dispatcher.cc index 1a1577a..fa766dba 100644 --- a/content/child/quota_dispatcher.cc +++ b/content/child/quota_dispatcher.cc
@@ -7,7 +7,6 @@ #include "base/basictypes.h" #include "base/lazy_instance.h" #include "base/threading/thread_local.h" -#include "content/child/child_thread.h" #include "content/child/quota_message_filter.h" #include "content/child/thread_safe_sender.h" #include "content/common/quota_messages.h"
diff --git a/content/child/quota_message_filter.cc b/content/child/quota_message_filter.cc index 139be25..e9290e48 100644 --- a/content/child/quota_message_filter.cc +++ b/content/child/quota_message_filter.cc
@@ -4,19 +4,13 @@ #include "content/child/quota_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/quota_dispatcher.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/quota_messages.h" namespace content { -QuotaMessageFilter::QuotaMessageFilter( - ThreadSafeSender* thread_safe_sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(thread_safe_sender), - next_request_id_(0) { +QuotaMessageFilter::QuotaMessageFilter(ThreadSafeSender* thread_safe_sender) + : WorkerThreadMessageFilter(thread_safe_sender), next_request_id_(0) { } QuotaMessageFilter::~QuotaMessageFilter() {} @@ -38,35 +32,29 @@ } } -base::TaskRunner* QuotaMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != QuotaMsgStart) - return NULL; +bool QuotaMessageFilter::ShouldHandleMessage(const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == QuotaMsgStart; +} - int request_id = -1, thread_id = 0; +void QuotaMessageFilter::OnFilteredMessageReceived(const IPC::Message& msg) { + QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender(), this) + ->OnMessageReceived(msg); +} + +bool QuotaMessageFilter::GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) { + int request_id = -1; const bool success = PickleIterator(msg).ReadInt(&request_id); DCHECK(success); - { - base::AutoLock lock(request_id_map_lock_); - RequestIdToThreadId::iterator found = request_id_map_.find(request_id); - if (found != request_id_map_.end()) { - thread_id = found->second; - request_id_map_.erase(found); - } + base::AutoLock lock(request_id_map_lock_); + RequestIdToThreadId::iterator found = request_id_map_.find(request_id); + if (found != request_id_map_.end()) { + *ipc_thread_id = found->second; + request_id_map_.erase(found); + return true; } - - if (!thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(thread_id); -} - -bool QuotaMessageFilter::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != QuotaMsgStart) - return false; - QuotaDispatcher::ThreadSpecificInstance(thread_safe_sender_.get(), this) - ->OnMessageReceived(msg); - return true; + return false; } } // namespace content
diff --git a/content/child/quota_message_filter.h b/content/child/quota_message_filter.h index b13e705..d6135849 100644 --- a/content/child/quota_message_filter.h +++ b/content/child/quota_message_filter.h
@@ -7,19 +7,12 @@ #include <map> -#include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class ThreadSafeSender; - -class QuotaMessageFilter : public ChildMessageFilter { +class QuotaMessageFilter : public WorkerThreadMessageFilter { public: explicit QuotaMessageFilter(ThreadSafeSender* thread_safe_sender); @@ -35,16 +28,14 @@ ~QuotaMessageFilter() override; private: - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; typedef std::map<int, int> RequestIdToThreadId; - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; - base::Lock request_id_map_lock_; RequestIdToThreadId request_id_map_; int next_request_id_;
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index ba7fe6f..bccff3b 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -16,7 +16,6 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/strings/string_util.h" -#include "content/child/child_thread.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_loader_bridge.h"
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index fce8783..73b9a29 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -8,7 +8,7 @@ #include "base/stl_util.h" #include "base/threading/thread_local.h" #include "base/trace_event/trace_event.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_provider_context.h" #include "content/child/service_worker/service_worker_registration_handle_reference.h" @@ -346,11 +346,11 @@ ProviderContextMap::iterator provider = provider_contexts_.find(provider_id); if (provider == provider_contexts_.end()) return; - provider->second->OnDisassociateRegistration(); worker_to_provider_.erase(provider->second->installing_handle_id()); worker_to_provider_.erase(provider->second->waiting_handle_id()); worker_to_provider_.erase(provider->second->active_handle_id()); worker_to_provider_.erase(provider->second->controller_handle_id()); + provider->second->OnDisassociateRegistration(); } void ServiceWorkerDispatcher::OnRegistered( @@ -638,7 +638,7 @@ const std::vector<int>& new_routing_ids) { // Make sure we're on the main document thread. (That must be the only // thread we get this message) - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); TRACE_EVENT1("ServiceWorker", "ServiceWorkerDispatcher::OnPostMessage", "Thread ID", thread_id);
diff --git a/content/child/service_worker/service_worker_message_filter.cc b/content/child/service_worker/service_worker_message_filter.cc index b0554c0..3568ad7 100644 --- a/content/child/service_worker/service_worker_message_filter.cc +++ b/content/child/service_worker/service_worker_message_filter.cc
@@ -4,10 +4,8 @@ #include "content/child/service_worker/service_worker_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" #include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" #include "ipc/ipc_message_macros.h" @@ -39,29 +37,26 @@ } // namespace ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender) - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(sender) {} + : WorkerThreadMessageFilter(sender) { +} ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {} -base::TaskRunner* ServiceWorkerMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != ServiceWorkerMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool ServiceWorkerMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == ServiceWorkerMsgStart; } -bool ServiceWorkerMessageFilter::OnMessageReceived(const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != ServiceWorkerMsgStart) - return false; +void ServiceWorkerMessageFilter::OnFilteredMessageReceived( + const IPC::Message& msg) { ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( - thread_safe_sender_.get())->OnMessageReceived(msg); - return true; + thread_safe_sender())->OnMessageReceived(msg); +} + +bool ServiceWorkerMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } void ServiceWorkerMessageFilter::OnStaleMessageReceived( @@ -83,13 +78,13 @@ int request_id, const ServiceWorkerRegistrationObjectInfo& info, const ServiceWorkerVersionAttributes& attrs) { - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.installing.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.waiting.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.active.handle_id); - SendRegistrationObjectDestroyed(thread_safe_sender_.get(), info.handle_id); + SendRegistrationObjectDestroyed(thread_safe_sender(), info.handle_id); } void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( @@ -98,11 +93,11 @@ int registration_handle_id, int changed_mask, const ServiceWorkerVersionAttributes& attrs) { - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.installing.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.waiting.handle_id); - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), + SendServiceWorkerObjectDestroyed(thread_safe_sender(), attrs.active.handle_id); // Don't have to decrement registration refcount because the sender of the // SetVersionAttributes message doesn't increment it. @@ -113,7 +108,7 @@ int provider_id, const ServiceWorkerObjectInfo& info, bool should_notify_controllerchange) { - SendServiceWorkerObjectDestroyed(thread_safe_sender_.get(), info.handle_id); + SendServiceWorkerObjectDestroyed(thread_safe_sender(), info.handle_id); } } // namespace content
diff --git a/content/child/service_worker/service_worker_message_filter.h b/content/child/service_worker/service_worker_message_filter.h index dca7e7d..d6fdeb9 100644 --- a/content/child/service_worker/service_worker_message_filter.h +++ b/content/child/service_worker/service_worker_message_filter.h
@@ -5,22 +5,17 @@ #ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_ #define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_ -#include "content/child/child_message_filter.h" +#include "content/child/worker_thread_message_filter.h" #include "content/common/content_export.h" -namespace base { -class MessageLoopProxy; -} - namespace content { -class ThreadSafeSender; struct ServiceWorkerObjectInfo; struct ServiceWorkerRegistrationObjectInfo; struct ServiceWorkerVersionAttributes; class CONTENT_EXPORT ServiceWorkerMessageFilter - : public NON_EXPORTED_BASE(ChildMessageFilter) { + : public NON_EXPORTED_BASE(WorkerThreadMessageFilter) { public: explicit ServiceWorkerMessageFilter(ThreadSafeSender* thread_safe_sender); @@ -28,10 +23,13 @@ ~ServiceWorkerMessageFilter() override; private: - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; + + // ChildMessageFilter: void OnStaleMessageReceived(const IPC::Message& msg) override; // Message handlers for stale messages. @@ -52,9 +50,6 @@ const ServiceWorkerObjectInfo& info, bool should_notify_controllerchange); - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMessageFilter); };
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc index db09351..915a1c96 100644 --- a/content/child/service_worker/service_worker_network_provider.cc +++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -5,7 +5,7 @@ #include "content/child/service_worker/service_worker_network_provider.h" #include "base/atomic_sequence_num.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/service_worker/service_worker_provider_context.h" #include "content/common/service_worker/service_worker_messages.h" @@ -38,24 +38,24 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(int render_frame_id) : provider_id_(GetNextProviderId()), context_(new ServiceWorkerProviderContext(provider_id_)) { - if (!ChildThread::current()) + if (!ChildThreadImpl::current()) return; // May be null in some tests. - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new ServiceWorkerHostMsg_ProviderCreated(provider_id_, render_frame_id)); } ServiceWorkerNetworkProvider::~ServiceWorkerNetworkProvider() { - if (!ChildThread::current()) + if (!ChildThreadImpl::current()) return; // May be null in some tests. - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new ServiceWorkerHostMsg_ProviderDestroyed(provider_id_)); } void ServiceWorkerNetworkProvider::SetServiceWorkerVersionId( int64 version_id) { - if (!ChildThread::current()) + if (!ChildThreadImpl::current()) return; // May be null in some tests. - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new ServiceWorkerHostMsg_SetVersionId(provider_id_, version_id)); }
diff --git a/content/child/service_worker/service_worker_provider_context.cc b/content/child/service_worker/service_worker_provider_context.cc index 129d557..d8273aa 100644 --- a/content/child/service_worker/service_worker_provider_context.cc +++ b/content/child/service_worker/service_worker_provider_context.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop_proxy.h" #include "base/stl_util.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_registration_handle_reference.h" @@ -20,9 +20,9 @@ ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id) : provider_id_(provider_id), main_thread_loop_proxy_(base::MessageLoopProxy::current()) { - if (!ChildThread::current()) + if (!ChildThreadImpl::current()) return; // May be null in some tests. - thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); + thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender(); ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( thread_safe_sender_.get());
diff --git a/content/child/service_worker/web_service_worker_provider_impl.cc b/content/child/service_worker/web_service_worker_provider_impl.cc index 52b6656..5b7d7406c 100644 --- a/content/child/service_worker/web_service_worker_provider_impl.cc +++ b/content/child/service_worker/web_service_worker_provider_impl.cc
@@ -6,7 +6,6 @@ #include "base/atomic_sequence_num.h" #include "base/logging.h" -#include "content/child/child_thread.h" #include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_provider_context.h"
diff --git a/content/child/shared_worker_devtools_agent.cc b/content/child/shared_worker_devtools_agent.cc index 3a9b3509..26a51ed 100644 --- a/content/child/shared_worker_devtools_agent.cc +++ b/content/child/shared_worker_devtools_agent.cc
@@ -4,7 +4,7 @@ #include "content/child/shared_worker_devtools_agent.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/devtools_messages.h" #include "ipc/ipc_channel.h" #include "third_party/WebKit/public/platform/WebCString.h" @@ -95,7 +95,7 @@ } bool SharedWorkerDevToolsAgent::Send(IPC::Message* message) { - return ChildThread::current()->Send(message); + return ChildThreadImpl::current()->Send(message); } } // namespace content
diff --git a/content/child/thread_safe_sender.cc b/content/child/thread_safe_sender.cc index d9ecfd1c..b8aef12 100644 --- a/content/child/thread_safe_sender.cc +++ b/content/child/thread_safe_sender.cc
@@ -5,7 +5,7 @@ #include "content/child/thread_safe_sender.h" #include "base/message_loop/message_loop_proxy.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "ipc/ipc_sync_message_filter.h" namespace content { @@ -21,7 +21,7 @@ bool ThreadSafeSender::Send(IPC::Message* msg) { if (main_loop_->BelongsToCurrentThread()) - return ChildThread::current()->Send(msg); + return ChildThreadImpl::current()->Send(msg); return sync_filter_->Send(msg); }
diff --git a/content/child/thread_safe_sender.h b/content/child/thread_safe_sender.h index 443e20a..37ad96b 100644 --- a/content/child/thread_safe_sender.h +++ b/content/child/thread_safe_sender.h
@@ -19,9 +19,9 @@ } namespace content { -class ChildThread; +class ChildThreadImpl; -// The class of Sender returned by ChildThread::thread_safe_sender(). +// The class of Sender returned by ChildThreadImpl::thread_safe_sender(). class CONTENT_EXPORT ThreadSafeSender : public IPC::Sender, public base::RefCountedThreadSafe<ThreadSafeSender> { @@ -29,7 +29,7 @@ bool Send(IPC::Message* msg) override; private: - friend class ChildThread; // for construction + friend class ChildThreadImpl; // for construction friend class IndexedDBDispatcherTest; friend class WebIDBCursorImplTest; friend class base::RefCountedThreadSafe<ThreadSafeSender>;
diff --git a/content/child/threaded_data_provider.cc b/content/child/threaded_data_provider.cc index ccfe891..69ed34b 100644 --- a/content/child/threaded_data_provider.cc +++ b/content/child/threaded_data_provider.cc
@@ -5,7 +5,7 @@ #include "content/child/threaded_data_provider.h" #include "content/child/child_process.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/resource_dispatcher.h" #include "content/child/thread_safe_sender.h" #include "content/child/webthread_impl.h" @@ -127,12 +127,12 @@ shm_size_(shm_size), background_thread_(static_cast<WebThreadImpl&>( *threaded_data_receiver->backgroundThread())), - ipc_channel_(ChildThread::current()->channel()), + ipc_channel_(ChildThreadImpl::current()->channel()), threaded_data_receiver_(threaded_data_receiver), resource_filter_active_(false), main_thread_task_runner_(main_thread_task_runner), main_thread_weak_factory_(this) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); DCHECK(ipc_channel_); DCHECK(threaded_data_receiver_); DCHECK(main_thread_task_runner_.get()); @@ -146,19 +146,19 @@ background_thread_weak_factory_->GetWeakPtr(), main_thread_weak_factory_.GetWeakPtr(), request_id); - ChildThread::current()->channel()->AddFilter(filter_.get()); + ChildThreadImpl::current()->channel()->AddFilter(filter_.get()); } ThreadedDataProvider::~ThreadedDataProvider() { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); - ChildThread::current()->channel()->RemoveFilter(filter_.get()); + ChildThreadImpl::current()->channel()->RemoveFilter(filter_.get()); delete threaded_data_receiver_; } void DestructOnMainThread(ThreadedDataProvider* data_provider) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); // The ThreadedDataProvider must be destructed on the main thread to // be threadsafe when removing the message filter and releasing the shared @@ -167,7 +167,7 @@ } void ThreadedDataProvider::Stop() { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); // Make sure we don't get called by on the main thread anymore via weak // pointers we've passed to the filter. @@ -207,7 +207,7 @@ } void ThreadedDataProvider::OnResourceMessageFilterAddedMainThread() { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); DCHECK(background_thread_weak_factory_); // We bounce this message from the I/O thread via the main thread and then @@ -264,7 +264,7 @@ void ThreadedDataProvider::OnReceivedDataOnForegroundThread( const char* data, int data_length, int encoded_data_length) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); background_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(&ThreadedDataProvider::ForwardAndACKData,
diff --git a/content/child/webblobregistry_impl.cc b/content/child/webblobregistry_impl.cc index 81a1f4b6..7b4ec42 100644 --- a/content/child/webblobregistry_impl.cc +++ b/content/child/webblobregistry_impl.cc
@@ -9,7 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/shared_memory.h" #include "base/message_loop/message_loop.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/thread_safe_sender.h" #include "content/common/fileapi/webblob_messages.h" #include "storage/common/data_element.h" @@ -158,7 +158,7 @@ // writing it directly to the IPC channel. size_t shared_memory_size = std::min(data.size(), kMaxSharedMemoryBytes); scoped_ptr<base::SharedMemory> shared_memory( - ChildThread::AllocateSharedMemory(shared_memory_size, sender_.get())); + ChildThreadImpl::AllocateSharedMemory(shared_memory_size, sender_.get())); CHECK(shared_memory.get()); if (!shared_memory->Map(shared_memory_size)) CHECK(false); @@ -179,19 +179,19 @@ void WebBlobRegistryImpl::registerStreamURL( const WebURL& url, const WebString& content_type) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_StartBuilding(url, content_type.utf8())); } void WebBlobRegistryImpl::registerStreamURL( const WebURL& url, const WebURL& src_url) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_Clone(url, src_url)); } void WebBlobRegistryImpl::addDataToStream(const WebURL& url, const char* data, size_t length) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); if (length == 0) return; if (length < kLargeThresholdBytes) { @@ -204,8 +204,8 @@ size_t shared_memory_size = std::min( length, kMaxSharedMemoryBytes); scoped_ptr<base::SharedMemory> shared_memory( - ChildThread::AllocateSharedMemory(shared_memory_size, - sender_.get())); + ChildThreadImpl::AllocateSharedMemory(shared_memory_size, + sender_.get())); CHECK(shared_memory.get()); if (!shared_memory->Map(shared_memory_size)) CHECK(false); @@ -224,22 +224,22 @@ } void WebBlobRegistryImpl::flushStream(const WebURL& url) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_Flush(url)); } void WebBlobRegistryImpl::finalizeStream(const WebURL& url) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_FinishBuilding(url)); } void WebBlobRegistryImpl::abortStream(const WebURL& url) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_AbortBuilding(url)); } void WebBlobRegistryImpl::unregisterStreamURL(const WebURL& url) { - DCHECK(ChildThread::current()); + DCHECK(ChildThreadImpl::current()); sender_->Send(new StreamHostMsg_Remove(url)); }
diff --git a/content/child/webcrypto/webcrypto_impl.cc b/content/child/webcrypto/webcrypto_impl.cc index 9a3924b..3270fbc0 100644 --- a/content/child/webcrypto/webcrypto_impl.cc +++ b/content/child/webcrypto/webcrypto_impl.cc
@@ -20,7 +20,6 @@ #include "content/child/webcrypto/generate_key_result.h" #include "content/child/webcrypto/status.h" #include "content/child/webcrypto/webcrypto_util.h" -#include "content/child/worker_thread_task_runner.h" #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -135,19 +134,10 @@ } } -// Gets a task runner for the current thread. The current thread is either: -// -// * The main Blink thread -// * A Blink web worker thread -// -// A different mechanism is needed for posting to these threads. The main -// thread has an associated message loop and can simply use -// base::ThreadTaskRunnerHandle. Whereas the web worker threads are managed by -// Blink and need to be indirected through WorkerThreadTaskRunner. +// Gets a task runner for the current thread. scoped_refptr<base::TaskRunner> GetCurrentBlinkThread() { - if (base::ThreadTaskRunnerHandle::IsSet()) - return base::ThreadTaskRunnerHandle::Get(); - return WorkerThreadTaskRunner::current(); + DCHECK(base::ThreadTaskRunnerHandle::IsSet()); + return base::ThreadTaskRunnerHandle::Get(); } // --------------------------------------------------------------------
diff --git a/content/child/webmessageportchannel_impl.cc b/content/child/webmessageportchannel_impl.cc index c3de36fb..725e5956 100644 --- a/content/child/webmessageportchannel_impl.cc +++ b/content/child/webmessageportchannel_impl.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop_proxy.h" #include "content/child/child_process.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/message_port_messages.h" #include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -56,7 +56,7 @@ Send(new MessagePortHostMsg_DestroyMessagePort(message_port_id_)); if (route_id_ != MSG_ROUTING_NONE) - ChildThread::current()->GetRouter()->RemoveRoute(route_id_); + ChildThreadImpl::current()->GetRouter()->RemoveRoute(route_id_); } // static @@ -169,7 +169,7 @@ Send(new MessagePortHostMsg_ReleaseMessages(message_port_id_)); } - ChildThread::current()->GetRouter()->AddRoute(route_id_, this); + ChildThreadImpl::current()->GetRouter()->AddRoute(route_id_, this); } void WebMessagePortChannelImpl::Entangle( @@ -216,7 +216,7 @@ return; } - ChildThread::current()->GetRouter()->Send(message); + ChildThreadImpl::current()->GetRouter()->Send(message); } bool WebMessagePortChannelImpl::OnMessageReceived(const IPC::Message& message) {
diff --git a/content/child/websocket_bridge.cc b/content/child/websocket_bridge.cc index 5b32702..e091023 100644 --- a/content/child/websocket_bridge.cc +++ b/content/child/websocket_bridge.cc
@@ -11,7 +11,7 @@ #include "base/logging.h" #include "base/strings/string_util.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/websocket_dispatcher.h" #include "content/common/websocket.h" #include "content/common/websocket_messages.h" @@ -52,7 +52,7 @@ if (channel_id_ != kInvalidChannelId) { // The connection is abruptly disconnected by the renderer without // closing handshake. - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new WebSocketMsg_DropChannel(channel_id_, false, kAbnormalShutdownOpCode, @@ -214,7 +214,7 @@ WebSocketHandleClient* client) { DCHECK_EQ(kInvalidChannelId, channel_id_); WebSocketDispatcher* dispatcher = - ChildThread::current()->websocket_dispatcher(); + ChildThreadImpl::current()->websocket_dispatcher(); channel_id_ = dispatcher->AddBridge(this); client_ = client; @@ -227,7 +227,7 @@ << JoinString(protocols_to_pass, ", ") << "), " << origin_to_pass.string() << ")"; - ChildThread::current()->Send(new WebSocketHostMsg_AddChannelRequest( + ChildThreadImpl::current()->Send(new WebSocketHostMsg_AddChannelRequest( channel_id_, url, protocols_to_pass, origin_to_pass, render_frame_id_)); } @@ -255,7 +255,7 @@ << fin << ", " << type_to_pass << ", " << "(data size = " << size << "))"; - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new WebSocketMsg_SendFrame(channel_id_, fin, type_to_pass, @@ -268,7 +268,7 @@ DVLOG(1) << "Bridge #" << channel_id_ << " FlowControl(" << quota << ")"; - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new WebSocketMsg_FlowControl(channel_id_, quota)); } @@ -281,7 +281,7 @@ DVLOG(1) << "Bridge #" << channel_id_ << " Close(" << code << ", " << reason_to_pass << ")"; // This method is for closing handshake and hence |was_clean| shall be true. - ChildThread::current()->Send( + ChildThreadImpl::current()->Send( new WebSocketMsg_DropChannel(channel_id_, true, code, reason_to_pass)); } @@ -289,7 +289,7 @@ if (channel_id_ == kInvalidChannelId) return; WebSocketDispatcher* dispatcher = - ChildThread::current()->websocket_dispatcher(); + ChildThreadImpl::current()->websocket_dispatcher(); dispatcher->RemoveBridge(channel_id_); channel_id_ = kInvalidChannelId;
diff --git a/content/child/worker_task_runner.cc b/content/child/worker_task_runner.cc index 45b3619..4fc5bde 100644 --- a/content/child/worker_task_runner.cc +++ b/content/child/worker_task_runner.cc
@@ -30,8 +30,7 @@ } // namespace struct WorkerTaskRunner::ThreadLocalState { - explicit ThreadLocalState(int id) : id_(id) {} - int id_; + ThreadLocalState() {} ObserverList<WorkerTaskRunner::Observer> stop_observers_; }; @@ -59,7 +58,7 @@ int WorkerTaskRunner::CurrentWorkerId() { if (!current_tls_.Get()) return 0; - return current_tls_.Get()->id_; + return base::PlatformThread::CurrentId(); } WorkerTaskRunner* WorkerTaskRunner::Instance() { @@ -84,9 +83,9 @@ void WorkerTaskRunner::OnWorkerRunLoopStarted(const WebWorkerRunLoop& loop) { DCHECK(!current_tls_.Get()); DCHECK(!base::PlatformThread::CurrentRef().is_null()); - int id = base::PlatformThread::CurrentId(); - current_tls_.Set(new ThreadLocalState(id)); + current_tls_.Set(new ThreadLocalState()); + int id = base::PlatformThread::CurrentId(); base::AutoLock locker_(loop_map_lock_); loop_map_[id] = loop; }
diff --git a/content/child/worker_thread_message_filter.cc b/content/child/worker_thread_message_filter.cc new file mode 100644 index 0000000..ac11a3dbd --- /dev/null +++ b/content/child/worker_thread_message_filter.cc
@@ -0,0 +1,42 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/worker_thread_message_filter.h" + +#include "base/thread_task_runner_handle.h" +#include "content/child/thread_safe_sender.h" +#include "content/child/worker_thread_task_runner.h" +#include "ipc/ipc_message_macros.h" + +namespace content { + +WorkerThreadMessageFilter::WorkerThreadMessageFilter( + ThreadSafeSender* thread_safe_sender) + : main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), + thread_safe_sender_(thread_safe_sender) { +} + +WorkerThreadMessageFilter::~WorkerThreadMessageFilter() { +} + +base::TaskRunner* WorkerThreadMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& msg) { + if (!ShouldHandleMessage(msg)) + return nullptr; + int ipc_thread_id = 0; + const bool success = GetWorkerThreadIdForMessage(msg, &ipc_thread_id); + DCHECK(success); + if (!ipc_thread_id) + return main_thread_task_runner_.get(); + return new WorkerThreadTaskRunner(ipc_thread_id); +} + +bool WorkerThreadMessageFilter::OnMessageReceived(const IPC::Message& msg) { + if (!ShouldHandleMessage(msg)) + return false; + OnFilteredMessageReceived(msg); + return true; +} + +} // namespace content
diff --git a/content/child/worker_thread_message_filter.h b/content/child/worker_thread_message_filter.h new file mode 100644 index 0000000..56db521b --- /dev/null +++ b/content/child/worker_thread_message_filter.h
@@ -0,0 +1,58 @@ +// 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_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_ +#define CONTENT_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_ + +#include "content/child/child_message_filter.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace content { + +class ThreadSafeSender; + +// A base class for filtering IPC messages targeted for worker threads. +class WorkerThreadMessageFilter : public ChildMessageFilter { + public: + explicit WorkerThreadMessageFilter(ThreadSafeSender* thread_safe_sender); + + protected: + ~WorkerThreadMessageFilter() override; + + base::SingleThreadTaskRunner* main_thread_task_runner() { + return main_thread_task_runner_.get(); + } + ThreadSafeSender* thread_safe_sender() { return thread_safe_sender_.get(); } + + private: + // Returns whether this filter should process |msg|. + virtual bool ShouldHandleMessage(const IPC::Message& msg) const = 0; + + // Processes the IPC message in the worker thread, if the filter could extract + // its thread id. Otherwise, runs in the main thread. It only receives a + // message if ShouldHandleMessage() returns true for it. + virtual void OnFilteredMessageReceived(const IPC::Message& msg) = 0; + + // Attempts to extract the thread-id of the worker-thread that should process + // the IPC message. Returns whether the thread-id could be determined and set + // in |ipc_thread_id|. + virtual bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) = 0; + + // ChildMessageFilter implementation: + base::TaskRunner* OverrideTaskRunnerForMessage(const IPC::Message& msg) final; + bool OnMessageReceived(const IPC::Message& msg) final; + + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + scoped_refptr<ThreadSafeSender> thread_safe_sender_; + + DISALLOW_COPY_AND_ASSIGN(WorkerThreadMessageFilter); +}; + +} // namespace content + +#endif // CONTENT_CHILD_WORKER_THREAD_MESSAGE_FILTER_H_
diff --git a/content/child/worker_thread_task_runner.cc b/content/child/worker_thread_task_runner.cc index 8e5b2e7..da7bc91 100644 --- a/content/child/worker_thread_task_runner.cc +++ b/content/child/worker_thread_task_runner.cc
@@ -13,13 +13,6 @@ : worker_thread_id_(worker_thread_id) { } -scoped_refptr<WorkerThreadTaskRunner> WorkerThreadTaskRunner::current() { - int worker_thread_id = WorkerTaskRunner::Instance()->CurrentWorkerId(); - if (!worker_thread_id) - return scoped_refptr<WorkerThreadTaskRunner>(); - return make_scoped_refptr(new WorkerThreadTaskRunner(worker_thread_id)); -} - bool WorkerThreadTaskRunner::PostDelayedTask( const tracked_objects::Location& /* from_here */, const base::Closure& task,
diff --git a/content/child/worker_thread_task_runner.h b/content/child/worker_thread_task_runner.h index 5acafbd8..8e70128 100644 --- a/content/child/worker_thread_task_runner.h +++ b/content/child/worker_thread_task_runner.h
@@ -17,10 +17,6 @@ public: explicit WorkerThreadTaskRunner(int worker_thread_id); - // Gets the WorkerThreadTaskRunner for the current worker thread. - // This returns non-null value only when it is called on a worker thread. - static scoped_refptr<WorkerThreadTaskRunner> current(); - // TaskRunner overrides. bool PostDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index baf65ce..1760a33 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -49,6 +49,42 @@ } } +if (is_chromeos && use_v4lplugin) { + action("libv4l2_generate_stubs") { + extra_header = "gpu/media/v4l2_stub_header.fragment" + + script = "../../tools/generate_stubs/generate_stubs.py" + sources = [ + "gpu/media/v4l2.sig", + ] + inputs = [ + extra_header, + ] + stubs_filename_root = "v4l2_stubs" + + outputs = [ + "$target_gen_dir/gpu/media/$stubs_filename_root.cc", + "$target_gen_dir/gpu/media/$stubs_filename_root.h", + ] + args = [ + "-i", + rebase_path("$target_gen_dir/gpu/media", root_build_dir), + "-o", + rebase_path("$target_gen_dir/gpu/media", root_build_dir), + "-t", + "posix_stubs", + "-e", + rebase_path(extra_header, root_build_dir), + "-s", + stubs_filename_root, + "-p", + "content/common/gpu/media", + ] + + args += rebase_path(sources, root_build_dir) + } +} + if (is_mac) { action("libvt_generate_stubs") { extra_header = "gpu/media/vt_stubs_header.fragment" @@ -280,32 +316,46 @@ } if (is_chromeos) { + if (use_v4lplugin) { + defines += [ "USE_LIBV4L2" ] + sources += get_target_outputs(":libv4l2_generate_stubs") + deps += [ ":libv4l2_generate_stubs" ] + } if (use_v4l2_codec) { defines += [ "USE_V4L2_CODEC" ] - } - if (cpu_arch == "arm" || (use_ozone && use_v4l2_codec)) { sources += [ + "gpu/media/accelerated_video_decoder.h", "gpu/media/generic_v4l2_video_device.cc", "gpu/media/generic_v4l2_video_device.h", + "gpu/media/h264_decoder.cc", + "gpu/media/h264_decoder.h", + "gpu/media/h264_dpb.cc", + "gpu/media/h264_dpb.h", "gpu/media/v4l2_image_processor.cc", "gpu/media/v4l2_image_processor.h", + "gpu/media/v4l2_slice_video_decode_accelerator.cc", + "gpu/media/v4l2_slice_video_decode_accelerator.h", "gpu/media/v4l2_video_decode_accelerator.cc", "gpu/media/v4l2_video_decode_accelerator.h", "gpu/media/v4l2_video_device.cc", "gpu/media/v4l2_video_device.h", "gpu/media/v4l2_video_encode_accelerator.cc", "gpu/media/v4l2_video_encode_accelerator.h", + "gpu/media/vp8_decoder.cc", + "gpu/media/vp8_decoder.h", + "gpu/media/vp8_picture.cc", + "gpu/media/vp8_picture.h", ] libs = [ "EGL", "GLESv2", ] - if (cpu_arch == "arm") { - sources += [ - "gpu/media/tegra_v4l2_video_device.cc", - "gpu/media/tegra_v4l2_video_device.h", - ] - } + } + if (cpu_arch == "arm") { + sources += [ + "gpu/media/tegra_v4l2_video_device.cc", + "gpu/media/tegra_v4l2_video_device.h", + ] } if (cpu_arch != "arm") { sources += [
diff --git a/content/common/common.gni b/content/common/common.gni index e192ae2..597cd1b5 100644 --- a/content/common/common.gni +++ b/content/common/common.gni
@@ -13,9 +13,10 @@ [ "../content_common.gypi" ]) declare_args() { - # TODO(henryhsu): This flag should be removed after the linux header of - # trybot is updated. - # Indicates if Video4Linux2 codec is used. This is used for x86 CrOS - # platform which has v4l2 hardware encoder / decoder. + # Indicates if V4L plugin is used. + use_v4lplugin = false + + # Indicates if Video4Linux2 codec is used. This is used for all CrOS + # platforms which have v4l2 hardware encoder / decoder. use_v4l2_codec = false }
diff --git a/content/common/gpu/client/DEPS b/content/common/gpu/client/DEPS index 2e15de34..1aea663 100644 --- a/content/common/gpu/client/DEPS +++ b/content/common/gpu/client/DEPS
@@ -1,3 +1,7 @@ +include_rules = [ + "+cc/blink", +] + specific_include_rules = { # Tests can make use of content/browser/ infrastructure. ".*browsertest\.cc": [
diff --git a/content/common/gpu/client/context_provider_command_buffer.h b/content/common/gpu/client/context_provider_command_buffer.h index 39c7fef..5be1e423 100644 --- a/content/common/gpu/client/context_provider_command_buffer.h +++ b/content/common/gpu/client/context_provider_command_buffer.h
@@ -9,10 +9,10 @@ #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" +#include "cc/blink/context_provider_web_context.h" #include "cc/output/context_provider.h" #include "content/common/content_export.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" -#include "webkit/common/gpu/context_provider_web_context.h" namespace webkit { namespace gpu { @@ -25,7 +25,7 @@ // Implementation of cc::ContextProvider that provides a // WebGraphicsContext3DCommandBufferImpl context and a GrContext. class CONTENT_EXPORT ContextProviderCommandBuffer - : NON_EXPORTED_BASE(public webkit::gpu::ContextProviderWebContext) { + : NON_EXPORTED_BASE(public cc_blink::ContextProviderWebContext) { public: static scoped_refptr<ContextProviderCommandBuffer> Create( scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d, @@ -33,7 +33,7 @@ CommandBufferProxyImpl* GetCommandBufferProxy(); - // ContextProviderWebContext implementation. + // cc_blink::ContextProviderWebContext implementation. WebGraphicsContext3DCommandBufferImpl* WebContext3D() override; // cc::ContextProvider implementation.
diff --git a/content/common/gpu/media/OWNERS b/content/common/gpu/media/OWNERS index dbb1145..29eb0cd 100644 --- a/content/common/gpu/media/OWNERS +++ b/content/common/gpu/media/OWNERS
@@ -2,5 +2,4 @@ posciak@chromium.org sandersd@chromium.org scherkus@chromium.org -vrk@chromium.org wuchengli@chromium.org
diff --git a/content/common/gpu/media/fake_video_decode_accelerator.cc b/content/common/gpu/media/fake_video_decode_accelerator.cc new file mode 100644 index 0000000..84a40eb --- /dev/null +++ b/content/common/gpu/media/fake_video_decode_accelerator.cc
@@ -0,0 +1,178 @@ +// 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 "content/common/gpu/media/fake_video_decode_accelerator.h" + +#include "base/bind.h" +#include "base/location.h" +#include "media/base/bitstream_buffer.h" +#include "media/base/limits.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_implementation.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_surface_glx.h" + +namespace content { + +static const uint32 kDefaultTextureTarget = GL_TEXTURE_2D; +// Must be at least 2 since the rendering helper will switch between textures +// and if there is only one, it will wait for the next one that will never come. +// Must also be an even number as otherwise there won't be the same amount of +// white and black frames. +static const unsigned int kNumBuffers = media::limits::kMaxVideoFrames + + (media::limits::kMaxVideoFrames & 1u); + +FakeVideoDecodeAccelerator::FakeVideoDecodeAccelerator( + gfx::GLContext* gl, + gfx::Size size, + const base::Callback<bool(void)>& make_context_current) + : child_message_loop_proxy_(base::MessageLoopProxy::current()), + client_(NULL), + make_context_current_(make_context_current), + gl_(gl), + frame_buffer_size_(size), + flushing_(false), + weak_this_factory_(this) { +} + +FakeVideoDecodeAccelerator::~FakeVideoDecodeAccelerator() { +} + +bool FakeVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, + Client* client) { + DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); + if (profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) { + LOG(ERROR) << "unknown codec profile"; + return false; + } + // V4L2VideoDecodeAccelerator waits until first decode call to ask for buffers + // This class asks for it on initialization instead. + client_ = client; + client_->ProvidePictureBuffers(kNumBuffers, + frame_buffer_size_, + kDefaultTextureTarget); + return true; +} + +void FakeVideoDecodeAccelerator::Decode( + const media::BitstreamBuffer& bitstream_buffer) { + int bitstream_buffer_id = bitstream_buffer.id(); + queued_bitstream_ids_.push(bitstream_buffer_id); + child_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, + weak_this_factory_.GetWeakPtr())); +} + +// Similar to UseOutputBitstreamBuffer for the encode accelerator. +void FakeVideoDecodeAccelerator::AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) { + DCHECK(buffers.size() == kNumBuffers); + DCHECK(!(buffers.size()%2)); + + // Save buffers and mark all buffers as ready for use. + scoped_ptr<uint8[]> white_data( + new uint8[frame_buffer_size_.width() * frame_buffer_size_.height() * 4]); + memset(white_data.get(), + UINT8_MAX, + frame_buffer_size_.width() * frame_buffer_size_.height() * 4); + scoped_ptr<uint8[]> black_data( + new uint8[frame_buffer_size_.width() * frame_buffer_size_.height() * 4]); + memset(black_data.get(), + 0, + frame_buffer_size_.width() * frame_buffer_size_.height() * 4); + if (!make_context_current_.Run()) { + LOG(ERROR) << "ReusePictureBuffer(): could not make context current"; + return; + } + for (size_t index = 0; index < buffers.size(); ++index) { + glBindTexture(GL_TEXTURE_2D, buffers[index].texture_id()); + // Every other frame white and the rest black. + uint8* data = index%2 ? white_data.get():black_data.get(); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + frame_buffer_size_.width(), + frame_buffer_size_.height(), + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + free_output_buffers_.push(buffers[index].id()); + } + child_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, + weak_this_factory_.GetWeakPtr())); +} + +void FakeVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { + free_output_buffers_.push(picture_buffer_id); + child_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, + weak_this_factory_.GetWeakPtr())); +} + +void FakeVideoDecodeAccelerator::Flush() { + flushing_ = true; + child_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&FakeVideoDecodeAccelerator::DoPictureReady, + weak_this_factory_.GetWeakPtr())); +} + +void FakeVideoDecodeAccelerator::Reset() { + while (!queued_bitstream_ids_.empty()) { + client_->NotifyEndOfBitstreamBuffer(queued_bitstream_ids_.front()); + queued_bitstream_ids_.pop(); + } + client_->NotifyResetDone(); +} + +void FakeVideoDecodeAccelerator::Destroy() { + while (!queued_bitstream_ids_.empty()) { + client_->NotifyEndOfBitstreamBuffer(queued_bitstream_ids_.front()); + queued_bitstream_ids_.pop(); + } + delete this; +} + +bool FakeVideoDecodeAccelerator::CanDecodeOnIOThread() { + return true; +} + +void FakeVideoDecodeAccelerator::DoPictureReady() { + if (flushing_ && queued_bitstream_ids_.empty()) { + flushing_ = false; + client_->NotifyFlushDone(); + } + while (!free_output_buffers_.empty() && !queued_bitstream_ids_.empty()) { + int bitstream_id = queued_bitstream_ids_.front(); + queued_bitstream_ids_.pop(); + int buffer_id = free_output_buffers_.front(); + free_output_buffers_.pop(); + + const media::Picture picture = + media::Picture(buffer_id, + bitstream_id, + gfx::Rect(frame_buffer_size_), + false); + client_->PictureReady(picture); + // Bitstream no longer needed. + client_->NotifyEndOfBitstreamBuffer(bitstream_id); + if (flushing_ && queued_bitstream_ids_.empty()) { + flushing_ = false; + client_->NotifyFlushDone(); + } + } +} + +} // namespace content
diff --git a/content/common/gpu/media/fake_video_decode_accelerator.h b/content/common/gpu/media/fake_video_decode_accelerator.h new file mode 100644 index 0000000..de7df4ae --- /dev/null +++ b/content/common/gpu/media/fake_video_decode_accelerator.h
@@ -0,0 +1,72 @@ +// 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 CONTENT_COMMON_GPU_MEDIA_FAKE_VIDEO_DECODE_ACCELERATOR_H_ +#define CONTENT_COMMON_GPU_MEDIA_FAKE_VIDEO_DECODE_ACCELERATOR_H_ + +#include <queue> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop_proxy.h" +#include "content/common/content_export.h" +#include "media/video/video_decode_accelerator.h" +#include "ui/gfx/geometry/size_f.h" +#include "ui/gl/gl_context.h" + +namespace content { + +class CONTENT_EXPORT FakeVideoDecodeAccelerator + : public media::VideoDecodeAccelerator { + public: + FakeVideoDecodeAccelerator( + gfx::GLContext* gl, + gfx::Size size, + const base::Callback<bool(void)>& make_context_current); + ~FakeVideoDecodeAccelerator() override; + + bool Initialize(media::VideoCodecProfile profile, + Client* client) override; + void Decode(const media::BitstreamBuffer& bitstream_buffer) override; + void AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) override; + void ReusePictureBuffer(int32 picture_buffer_id) override; + void Flush() override; + void Reset() override; + void Destroy() override; + bool CanDecodeOnIOThread() override; + + private: + void DoPictureReady(); + + // The message loop that created the class. Used for all callbacks. This + // class expects all calls to this class to be on this message loop (not + // checked). + const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; + + Client* client_; + + // Make our context current before running any GL entry points. + base::Callback<bool(void)> make_context_current_; + gfx::GLContext* gl_; + + // Output picture size. + gfx::Size frame_buffer_size_; + + // Picture buffer ids that are available for putting fake frames in. + std::queue<int> free_output_buffers_; + // BitstreamBuffer ids for buffers that contain new data to decode. + std::queue<int> queued_bitstream_ids_; + + bool flushing_; + + // The WeakPtrFactory for |weak_this_|. + base::WeakPtrFactory<FakeVideoDecodeAccelerator> weak_this_factory_; + + DISALLOW_COPY_AND_ASSIGN(FakeVideoDecodeAccelerator); +}; + +} // namespace content + +#endif // CONTENT_COMMON_GPU_MEDIA_FAKE_VIDEO_DECODE_ACCELERATOR_H_
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 8042690..4ab02c0 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -22,6 +22,7 @@ #include "ipc/message_filter.h" #include "media/base/limits.h" #include "ui/gl/gl_context.h" +#include "ui/gl/gl_image.h" #include "ui/gl/gl_surface_egl.h" #if defined(OS_WIN) @@ -30,18 +31,15 @@ #elif defined(OS_MACOSX) #include "content/common/gpu/media/vt_video_decode_accelerator.h" #elif defined(OS_CHROMEOS) -#if defined(ARCH_CPU_ARMEL) && defined(USE_LIBV4L2) +#if defined(USE_V4L2_CODEC) #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" -#endif // defined(ARCH_CPU_ARMEL) -#if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" #include "content/common/gpu/media/v4l2_video_device.h" -// defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) #endif #if defined(ARCH_CPU_X86_FAMILY) #include "content/common/gpu/media/vaapi_video_decode_accelerator.h" #include "ui/gl/gl_implementation.h" -#endif // defined(ARCH_CPU_X86_FAMILY) +#endif #elif defined(USE_OZONE) #include "media/ozone/media_ozone_platform.h" #elif defined(OS_ANDROID) @@ -302,8 +300,7 @@ scoped_ptr<media::VideoDecodeAccelerator> GpuVideoDecodeAccelerator::CreateV4L2VDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; -#if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ - (defined(USE_OZONE) && defined(USE_V4L2_CODEC))) +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); if (device.get()) { decoder.reset(new V4L2VideoDecodeAccelerator( @@ -321,7 +318,7 @@ scoped_ptr<media::VideoDecodeAccelerator> GpuVideoDecodeAccelerator::CreateV4L2SliceVDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_LIBV4L2) +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); if (device.get()) { decoder.reset(new V4L2SliceVideoDecodeAccelerator( @@ -336,11 +333,24 @@ return decoder.Pass(); } +void GpuVideoDecodeAccelerator::BindImage(uint32 client_texture_id, + uint32 texture_target, + scoped_refptr<gfx::GLImage> image) { + gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); + gpu::gles2::TextureManager* texture_manager = + command_decoder->GetContextGroup()->texture_manager(); + gpu::gles2::TextureRef* ref = texture_manager->GetTexture(client_texture_id); + if (ref) + texture_manager->SetLevelImage(ref, texture_target, 0, image.get()); +} + scoped_ptr<media::VideoDecodeAccelerator> GpuVideoDecodeAccelerator::CreateVaapiVDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) - decoder.reset(new VaapiVideoDecodeAccelerator(make_context_current_)); + decoder.reset(new VaapiVideoDecodeAccelerator( + make_context_current_, base::Bind(&GpuVideoDecodeAccelerator::BindImage, + base::Unretained(this)))); #endif return decoder.Pass(); } @@ -467,15 +477,9 @@ width, height, 1, 0, format, 0, false); } } - uint32 service_texture_id; - if (!command_decoder->GetServiceTextureId( - texture_ids[i], &service_texture_id)) { - DLOG(ERROR) << "Failed to translate texture!"; - NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); - return; - } - buffers.push_back(media::PictureBuffer( - buffer_ids[i], texture_dimensions_, service_texture_id)); + buffers.push_back(media::PictureBuffer(buffer_ids[i], texture_dimensions_, + texture_ref->service_id(), + texture_ids[i])); textures.push_back(texture_ref); } video_decode_accelerator_->AssignPictureBuffers(buffers);
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index 562b4c0..f147138c 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -104,6 +104,11 @@ // Helper for replying to the creation request. void SendCreateDecoderReply(IPC::Message* message, bool succeeded); + // Helper to bind |image| to the texture specified by |client_texture_id|. + void BindImage(uint32 client_texture_id, + uint32 texture_target, + scoped_refptr<gfx::GLImage> image); + // Route ID to communicate with the host. int32 host_route_id_;
diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc index df16d97..a2c3365c 100644 --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc
@@ -18,13 +18,12 @@ #include "media/base/video_frame.h" #if defined(OS_CHROMEOS) -#if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) +#if defined(USE_V4L2_CODEC) #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" -// defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) #endif #if defined(ARCH_CPU_X86_FAMILY) #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" -#endif // defined(ARCH_CPU_X86_FAMILY) +#endif #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) #include "content/common/gpu/media/android_video_encode_accelerator.h" #endif @@ -212,8 +211,7 @@ scoped_ptr<media::VideoEncodeAccelerator> GpuVideoEncodeAccelerator::CreateV4L2VEA() { scoped_ptr<media::VideoEncodeAccelerator> encoder; -#if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ - (defined(USE_OZONE) && defined(USE_V4L2_CODEC))) +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); if (device) encoder.reset(new V4L2VideoEncodeAccelerator(device));
diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc index 82e16ec..628b4c8 100644 --- a/content/common/gpu/media/vaapi_drm_picture.cc +++ b/content/common/gpu/media/vaapi_drm_picture.cc
@@ -13,6 +13,7 @@ #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image_linux_dma_buffer.h" #include "ui/gl/scoped_binders.h" +#include "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h" #include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" @@ -101,17 +102,14 @@ if (!make_context_current_.Run()) return false; - // Create an EGLImage out of the same buffer. - gl_image_ = new gfx::GLImageLinuxDMABuffer(size(), GL_RGBA); - if (!gl_image_->Initialize(base::FileDescriptor(dmabuf_fd, false), - gfx::GpuMemoryBuffer::BGRA_8888, dmabuf_pitch)) { - LOG(ERROR) << "Failed to create a GLImageLinuxDMABuffer for a NativePixmap"; - return false; - } - - // Bind the EGLImage to the given GL texture. gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, texture_id()); + gl_image_ = ui::GpuMemoryBufferFactoryOzoneNativeBuffer::CreateImageForPixmap( + pixmap_, size(), gfx::GpuMemoryBuffer::RGBA_8888, GL_RGBA); + if (!gl_image_) { + LOG(ERROR) << "Failed to create GLImage"; + return false; + } if (!gl_image_->BindTexImage(GL_TEXTURE_EXTERNAL_OES)) { LOG(ERROR) << "Failed to bind texture to GLImage"; return false; @@ -126,4 +124,12 @@ va_surface_->id(), va_surface_->size()); } +scoped_refptr<gfx::GLImage> VaapiDrmPicture::GetImageToBind() { + return gl_image_; +} + +bool VaapiDrmPicture::AllowOverlay() const { + return true; +} + } // namespace
diff --git a/content/common/gpu/media/vaapi_drm_picture.h b/content/common/gpu/media/vaapi_drm_picture.h index 46c7304..e982b59 100644 --- a/content/common/gpu/media/vaapi_drm_picture.h +++ b/content/common/gpu/media/vaapi_drm_picture.h
@@ -15,7 +15,7 @@ #include "ui/gfx/geometry/size.h" namespace gfx { -class GLImageLinuxDMABuffer; +class GLImage; } namespace ui { @@ -41,6 +41,10 @@ bool DownloadFromSurface(const scoped_refptr<VASurface>& va_surface) override; + scoped_refptr<gfx::GLImage> GetImageToBind() override; + + bool AllowOverlay() const override; + private: VaapiWrapper* vaapi_wrapper_; // Not owned. base::Callback<bool(void)> make_context_current_; @@ -49,7 +53,7 @@ scoped_refptr<ui::NativePixmap> pixmap_; // EGLImage bound to the GL textures used by the VDA client. - scoped_refptr<gfx::GLImageLinuxDMABuffer> gl_image_; + scoped_refptr<gfx::GLImage> gl_image_; // VASurface used to transfer from the decoder's pixel format. scoped_refptr<VASurface> va_surface_;
diff --git a/content/common/gpu/media/vaapi_picture.cc b/content/common/gpu/media/vaapi_picture.cc index 782971c6..cd886c06 100644 --- a/content/common/gpu/media/vaapi_picture.cc +++ b/content/common/gpu/media/vaapi_picture.cc
@@ -37,6 +37,10 @@ return picture; } +bool VaapiPicture::AllowOverlay() const { + return false; +} + // static uint32 VaapiPicture::GetGLTextureTarget() { #if defined(USE_OZONE)
diff --git a/content/common/gpu/media/vaapi_picture.h b/content/common/gpu/media/vaapi_picture.h index 44d9db7..ad43dfa3 100644 --- a/content/common/gpu/media/vaapi_picture.h +++ b/content/common/gpu/media/vaapi_picture.h
@@ -16,6 +16,10 @@ #include "base/threading/non_thread_safe.h" #include "ui/gfx/geometry/size.h" +namespace gfx { +class GLImage; +} + namespace content { class VASurface; @@ -33,6 +37,11 @@ uint32 texture_id() const { return texture_id_; } const gfx::Size& size() const { return size_; } + virtual bool AllowOverlay() const; + + // Returns the |GLImage|, if any, to bind to the texture. + virtual scoped_refptr<gfx::GLImage> GetImageToBind() = 0; + // Downloads the |va_surface| into the picture, potentially scaling // it if needed. virtual bool DownloadFromSurface(
diff --git a/content/common/gpu/media/vaapi_tfp_picture.cc b/content/common/gpu/media/vaapi_tfp_picture.cc index 7f0122f..ee03742 100644 --- a/content/common/gpu/media/vaapi_tfp_picture.cc +++ b/content/common/gpu/media/vaapi_tfp_picture.cc
@@ -74,4 +74,8 @@ va_surface->size()); } +scoped_refptr<gfx::GLImage> VaapiTFPPicture::GetImageToBind() { + return nullptr; +} + } // namespace content
diff --git a/content/common/gpu/media/vaapi_tfp_picture.h b/content/common/gpu/media/vaapi_tfp_picture.h index 02a1a23..3261791 100644 --- a/content/common/gpu/media/vaapi_tfp_picture.h +++ b/content/common/gpu/media/vaapi_tfp_picture.h
@@ -39,6 +39,8 @@ bool DownloadFromSurface(const scoped_refptr<VASurface>& va_surface) override; + scoped_refptr<gfx::GLImage> GetImageToBind() override; + private: VaapiWrapper* vaapi_wrapper_; // Not owned.
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 90c0cdda7..d24744d71 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -15,6 +15,7 @@ #include "media/base/bind_to_current_loop.h" #include "media/video/picture.h" #include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_image.h" static void ReportToUMA( content::VaapiH264Decoder::VAVDAH264DecoderFailure failure) { @@ -72,7 +73,9 @@ } VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( - const base::Callback<bool(void)>& make_context_current) + const base::Callback<bool(void)>& make_context_current, + const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& + bind_image) : make_context_current_(make_context_current), state_(kUninitialized), input_ready_(&lock_), @@ -84,6 +87,7 @@ finish_flush_pending_(false), awaiting_va_surfaces_recycle_(false), requested_num_pics_(0), + bind_image_(bind_image), weak_this_factory_(this) { weak_this_ = weak_this_factory_.GetWeakPtr(); va_surface_release_cb_ = media::BindToCurrentLoop( @@ -186,8 +190,9 @@ // TODO(posciak): Use visible size from decoder here instead // (crbug.com/402760). if (client_) - client_->PictureReady( - media::Picture(output_id, input_id, gfx::Rect(picture->size()), false)); + client_->PictureReady(media::Picture(output_id, input_id, + gfx::Rect(picture->size()), + picture->AllowOverlay())); } void VaapiVideoDecodeAccelerator::TryOutputSurface() { @@ -525,6 +530,12 @@ vaapi_wrapper_.get(), make_context_current_, buffers[i].id(), buffers[i].texture_id(), requested_pic_size_)); + scoped_refptr<gfx::GLImage> image = picture->GetImageToBind(); + if (image) { + bind_image_.Run(buffers[i].internal_texture_id(), + VaapiPicture::GetGLTextureTarget(), image); + } + RETURN_AND_NOTIFY_ON_FAILURE( picture.get(), "Failed assigning picture buffer to a texture.", PLATFORM_FAILURE, );
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index 9e98a6b7..0ef25c55 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h
@@ -28,6 +28,10 @@ #include "media/video/picture.h" #include "media/video/video_decode_accelerator.h" +namespace gfx { +class GLImage; +} + namespace content { class VaapiPicture; @@ -44,7 +48,9 @@ : public media::VideoDecodeAccelerator { public: VaapiVideoDecodeAccelerator( - const base::Callback<bool(void)>& make_context_current); + const base::Callback<bool(void)>& make_context_current, + const base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)>& + bind_image); ~VaapiVideoDecodeAccelerator() override; // media::VideoDecodeAccelerator implementation. @@ -264,6 +270,10 @@ size_t requested_num_pics_; gfx::Size requested_pic_size_; + // Binds the provided GLImage to a givenr client texture ID & texture target + // combination in GLES. + base::Callback<void(uint32, uint32, scoped_refptr<gfx::GLImage>)> bind_image_; + // The WeakPtrFactory for |weak_this_|. base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index a028f98..6c8d68c2 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -47,20 +47,20 @@ #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" +#include "content/common/gpu/media/fake_video_decode_accelerator.h" #include "content/common/gpu/media/rendering_helper.h" #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" #include "content/public/common/content_switches.h" #include "media/filters/h264_parser.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gl/gl_image.h" #if defined(OS_WIN) #include "base/win/windows_version.h" #include "content/common/gpu/media/dxva_video_decode_accelerator.h" #elif defined(OS_CHROMEOS) -#if defined(ARCH_CPU_ARMEL) && defined(USE_LIBV4L2) +#if defined(USE_V4L2_CODEC) #include "content/common/gpu/media/v4l2_slice_video_decode_accelerator.h" -#endif // defined(ARCH_CPU_ARMEL) -#if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) #include "content/common/gpu/media/v4l2_video_decode_accelerator.h" #include "content/common/gpu/media/v4l2_video_device.h" #endif @@ -118,6 +118,8 @@ // values for |num_play_throughs|. This setting will override the value. A // special value "0" means no override. int g_num_play_throughs = 0; +// Fake decode +int g_fake_decoder = 0; // Environment to store rendering thread. class VideoDecodeAcceleratorTestEnvironment; @@ -294,6 +296,7 @@ int frame_width, int frame_height, media::VideoCodecProfile profile, + int fake_decoder, bool suppress_rendering, int delay_reuse_after_frame_num, int decode_calls_per_second, @@ -329,11 +332,16 @@ private: typedef std::map<int32, scoped_refptr<TextureRef>> TextureRefMap; + scoped_ptr<media::VideoDecodeAccelerator> CreateFakeVDA(); scoped_ptr<media::VideoDecodeAccelerator> CreateDXVAVDA(); scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2VDA(); scoped_ptr<media::VideoDecodeAccelerator> CreateV4L2SliceVDA(); scoped_ptr<media::VideoDecodeAccelerator> CreateVaapiVDA(); + void BindImage(uint32 client_texture_id, + uint32 texture_target, + scoped_refptr<gfx::GLImage> image); + void SetState(ClientState new_state); void FinishInitialization(); void ReturnPicture(int32 picture_buffer_id); @@ -378,6 +386,7 @@ int num_done_bitstream_buffers_; base::TimeTicks initialize_done_ticks_; media::VideoCodecProfile profile_; + int fake_decoder_; GLenum texture_target_; bool suppress_rendering_; std::vector<base::TimeTicks> frame_delivery_times_; @@ -419,6 +428,7 @@ int frame_width, int frame_height, media::VideoCodecProfile profile, + int fake_decoder, bool suppress_rendering, int delay_reuse_after_frame_num, int decode_calls_per_second, @@ -440,6 +450,7 @@ num_queued_fragments_(0), num_decoded_frames_(0), num_done_bitstream_buffers_(0), + fake_decoder_(fake_decoder), texture_target_(0), suppress_rendering_(suppress_rendering), delay_reuse_after_frame_num_(delay_reuse_after_frame_num), @@ -467,6 +478,18 @@ static bool DoNothingReturnTrue() { return true; } scoped_ptr<media::VideoDecodeAccelerator> +GLRenderingVDAClient::CreateFakeVDA() { + scoped_ptr<media::VideoDecodeAccelerator> decoder; + if (fake_decoder_) { + decoder.reset(new FakeVideoDecodeAccelerator( + static_cast<gfx::GLContext*> (rendering_helper_->GetGLContextHandle()), + frame_size_, + base::Bind(&DoNothingReturnTrue))); + } + return decoder.Pass(); +} + +scoped_ptr<media::VideoDecodeAccelerator> GLRenderingVDAClient::CreateDXVAVDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; #if defined(OS_WIN) @@ -480,8 +503,7 @@ scoped_ptr<media::VideoDecodeAccelerator> GLRenderingVDAClient::CreateV4L2VDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; -#if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ - (defined(USE_OZONE) && defined(USE_V4L2_CODEC))) +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); if (device.get()) { base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); @@ -500,7 +522,7 @@ scoped_ptr<media::VideoDecodeAccelerator> GLRenderingVDAClient::CreateV4L2SliceVDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; -#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_LIBV4L2) +#if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); if (device.get()) { base::WeakPtr<VideoDecodeAccelerator::Client> weak_client = AsWeakPtr(); @@ -515,16 +537,23 @@ #endif return decoder.Pass(); } + scoped_ptr<media::VideoDecodeAccelerator> GLRenderingVDAClient::CreateVaapiVDA() { scoped_ptr<media::VideoDecodeAccelerator> decoder; #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) - decoder.reset( - new VaapiVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue))); + decoder.reset(new VaapiVideoDecodeAccelerator( + base::Bind(&DoNothingReturnTrue), + base::Bind(&GLRenderingVDAClient::BindImage, base::Unretained(this)))); #endif return decoder.Pass(); } +void GLRenderingVDAClient::BindImage(uint32 client_texture_id, + uint32 texture_target, + scoped_refptr<gfx::GLImage> image) { +} + void GLRenderingVDAClient::CreateAndStartDecoder() { CHECK(decoder_deleted()); CHECK(!decoder_.get()); @@ -532,6 +561,7 @@ VideoDecodeAccelerator::Client* client = this; scoped_ptr<media::VideoDecodeAccelerator> decoders[] = { + CreateFakeVDA(), CreateDXVAVDA(), CreateV4L2VDA(), CreateV4L2SliceVDA(), @@ -1222,6 +1252,7 @@ video_file->width, video_file->height, video_file->profile, + g_fake_decoder, suppress_rendering, delay_after_frame_num, 0, @@ -1475,6 +1506,7 @@ test_video_files_[0]->width, test_video_files_[0]->height, test_video_files_[0]->profile, + g_fake_decoder, true, std::numeric_limits<int>::max(), kWebRtcDecodeCallsPerSecond, @@ -1553,6 +1585,9 @@ if (it->first == "num_play_throughs") { std::string input(it->second.begin(), it->second.end()); CHECK(base::StringToInt(input, &content::g_num_play_throughs)); + } + if (it->first == "fake_decoder") { + content::g_fake_decoder = 1; continue; } if (it->first == "v" || it->first == "vmodule")
diff --git a/content/common/media/OWNERS b/content/common/media/OWNERS index bbbdeff..2ba40a0 100644 --- a/content/common/media/OWNERS +++ b/content/common/media/OWNERS
@@ -4,7 +4,6 @@ sandersd@chromium.org scherkus@chromium.org tommi@chromium.org -vrk@chromium.org xhwang@chromium.org # For security review of IPC message files.
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc index d89679bd..c401d873 100644 --- a/content/common/sandbox_win.cc +++ b/content/common/sandbox_win.cc
@@ -343,7 +343,8 @@ return true; } -bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) { +bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy, + std::string& type_str) { sandbox::ResultCode result; // Renderers need to share events with plugins. result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, @@ -353,8 +354,11 @@ return false; // Win8+ adds a device DeviceApi that we don't need. - if (base::win::GetVersion() > base::win::VERSION_WIN7) + // Only close this handle on renderer processes. See crbug.com/452613. + if (base::win::GetVersion() > base::win::VERSION_WIN7 && + type_str == switches::kRendererProcess) { result = policy->AddKernelObjectToClose(L"File", L"\\Device\\DeviceApi"); + } if (result != sandbox::SBOX_ALL_OK) return false; @@ -649,7 +653,8 @@ if (delegate) delegate->PreSandbox(&disable_default_policy, &exposed_dir); - if (!disable_default_policy && !AddPolicyForSandboxedProcess(policy)) + if (!disable_default_policy && + !AddPolicyForSandboxedProcess(policy, type_str)) return base::Process(); if (type_str == switches::kRendererProcess) {
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h index 20b13ec..5aee688 100644 --- a/content/common/service_worker/service_worker_messages.h +++ b/content/common/service_worker/service_worker_messages.h
@@ -240,6 +240,11 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_SkipWaiting, int /* request_id */) +// Asks the browser to have this worker take control of pages that match +// its scope. +IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_ClaimClients, + int /* request_id */) + // CacheStorage operations in the browser. IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_CacheStorageHas, int /* request_id */, @@ -442,6 +447,12 @@ std::vector<int> /* new_routing_ids */) IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_DidSkipWaiting, int /* request_id */) +IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_DidClaimClients, + int /* request_id */) +IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ClaimClientsError, + int /* request_id */, + blink::WebServiceWorkerError::ErrorType /* code */, + base::string16 /* message */) // Sent via EmbeddedWorker as a response of GetClientDocuments. IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidGetClientDocuments,
diff --git a/content/common/service_worker/service_worker_status_code.cc b/content/common/service_worker/service_worker_status_code.cc index f5c1e02..35aaa86 100644 --- a/content/common/service_worker/service_worker_status_code.cc +++ b/content/common/service_worker/service_worker_status_code.cc
@@ -37,6 +37,8 @@ case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: return "ServiceWorker failed to handle event (event.waitUntil " "Promise rejected)"; + case SERVICE_WORKER_ERROR_STATE: + return "The ServiceWorker state was not valid"; } NOTREACHED(); return "";
diff --git a/content/common/service_worker/service_worker_status_code.h b/content/common/service_worker/service_worker_status_code.h index e87e5c3..1e9cdd5 100644 --- a/content/common/service_worker/service_worker_status_code.h +++ b/content/common/service_worker/service_worker_status_code.h
@@ -51,6 +51,9 @@ // Event handling failed (event.waitUntil Promise rejected). SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, + + // An error triggered by invalid worker state. + SERVICE_WORKER_ERROR_STATE, }; CONTENT_EXPORT const char* ServiceWorkerStatusToString(
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index e0914db0..968c228e 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -1043,19 +1043,19 @@ // page/widget that was created by // CreateWindow/CreateWidget/CreateFullscreenWidget. routing_id // refers to the id that was returned from the Create message above. -// The initial_position parameter is a rectangle in screen coordinates. +// The initial_rect parameter is in screen coordinates. // // FUTURE: there will probably be flags here to control if the result is // in a new window. IPC_MESSAGE_ROUTED4(ViewHostMsg_ShowView, int /* route_id */, WindowOpenDisposition /* disposition */, - gfx::Rect /* initial_pos */, + gfx::Rect /* initial_rect */, bool /* opened_by_user_gesture */) IPC_MESSAGE_ROUTED2(ViewHostMsg_ShowWidget, int /* route_id */, - gfx::Rect /* initial_pos */) + gfx::Rect /* initial_rect */) // Message to show a full screen widget. IPC_MESSAGE_ROUTED1(ViewHostMsg_ShowFullscreenWidget,
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 21f668d..071dce7 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -514,6 +514,7 @@ 'browser/device_sensors/data_fetcher_shared_memory_android.cc', 'browser/device_sensors/data_fetcher_shared_memory_base.cc', 'browser/device_sensors/data_fetcher_shared_memory_base.h', + 'browser/device_sensors/data_fetcher_shared_memory_chromeos.cc', 'browser/device_sensors/data_fetcher_shared_memory_default.cc', 'browser/device_sensors/data_fetcher_shared_memory_mac.cc', 'browser/device_sensors/data_fetcher_shared_memory_win.cc', @@ -528,6 +529,8 @@ 'browser/device_sensors/inertial_sensor_consts.h', 'browser/device_sensors/sensor_manager_android.cc', 'browser/device_sensors/sensor_manager_android.h', + 'browser/device_sensors/sensor_manager_chromeos.cc', + 'browser/device_sensors/sensor_manager_chromeos.h', 'browser/dom_storage/dom_storage_area.cc', 'browser/dom_storage/dom_storage_area.h', 'browser/dom_storage/dom_storage_context_impl.cc', @@ -1891,6 +1894,7 @@ '../chromeos/chromeos.gyp:power_manager_proto', ], 'sources!': [ + 'browser/device_sensors/data_fetcher_shared_memory_default.cc', 'browser/geolocation/wifi_data_provider_linux.cc', 'browser/power_save_blocker_ozone.cc', 'browser/power_save_blocker_x11.cc',
diff --git a/content/content_browsertests.isolate b/content/content_browsertests.isolate index 53a53fc..9701675 100644 --- a/content/content_browsertests.isolate +++ b/content/content_browsertests.isolate
@@ -42,6 +42,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -92,6 +94,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/content/content_child.gypi b/content/content_child.gypi index 013d2e5..fedf374a 100644 --- a/content/content_child.gypi +++ b/content/content_child.gypi
@@ -23,6 +23,7 @@ ], 'variables': { 'public_child_sources': [ + 'public/child/child_thread.h', 'public/child/image_decoder_utils.h', 'public/child/request_peer.h', 'public/child/resource_dispatcher_delegate.h', @@ -61,8 +62,8 @@ 'child/child_resource_message_filter.h', 'child/child_shared_bitmap_manager.cc', 'child/child_shared_bitmap_manager.h', - 'child/child_thread.cc', - 'child/child_thread.h', + 'child/child_thread_impl.cc', + 'child/child_thread_impl.h', 'child/content_child_helpers.cc', 'child/content_child_helpers.h', 'child/database_util.cc', @@ -272,6 +273,8 @@ 'child/weburlresponse_extradata_impl.h', 'child/worker_task_runner.cc', 'child/worker_task_runner.h', + 'child/worker_thread_message_filter.cc', + 'child/worker_thread_message_filter.h', 'child/worker_thread_task_runner.cc', 'child/worker_thread_task_runner.h', ],
diff --git a/content/content_common.gypi b/content/content_common.gypi index 8a8dea2..31f3ea7 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -330,6 +330,8 @@ 'common/gpu/image_transport_surface_linux.cc', 'common/gpu/image_transport_surface_mac.mm', 'common/gpu/image_transport_surface_win.cc', + 'common/gpu/media/fake_video_decode_accelerator.cc', + 'common/gpu/media/fake_video_decode_accelerator.h', 'common/gpu/media/gpu_video_decode_accelerator.cc', 'common/gpu/media/gpu_video_decode_accelerator.h', 'common/gpu/media/gpu_video_encode_accelerator.cc', @@ -766,7 +768,7 @@ }], ['use_v4lplugin==1 and chromeos==1', { 'defines': [ - 'USE_LIBV4L2', + 'USE_LIBV4L2' ], 'variables': { 'generate_stubs_script': '../tools/generate_stubs/generate_stubs.py', @@ -817,50 +819,40 @@ 'defines': [ 'USE_V4L2_CODEC' ], - }], - ['chromeos==1 and (target_arch=="arm" or (use_ozone==1 and use_v4l2_codec==1))', { 'dependencies': [ '../media/media.gyp:media', ], 'sources': [ + 'common/gpu/media/accelerated_video_decoder.h', 'common/gpu/media/generic_v4l2_video_device.cc', 'common/gpu/media/generic_v4l2_video_device.h', + 'common/gpu/media/h264_decoder.cc', + 'common/gpu/media/h264_decoder.h', + 'common/gpu/media/h264_dpb.cc', + 'common/gpu/media/h264_dpb.h', 'common/gpu/media/v4l2_image_processor.cc', 'common/gpu/media/v4l2_image_processor.h', + 'common/gpu/media/v4l2_slice_video_decode_accelerator.cc', + 'common/gpu/media/v4l2_slice_video_decode_accelerator.h', 'common/gpu/media/v4l2_video_decode_accelerator.cc', 'common/gpu/media/v4l2_video_decode_accelerator.h', 'common/gpu/media/v4l2_video_device.cc', 'common/gpu/media/v4l2_video_device.h', 'common/gpu/media/v4l2_video_encode_accelerator.cc', 'common/gpu/media/v4l2_video_encode_accelerator.h', + 'common/gpu/media/vp8_decoder.cc', + 'common/gpu/media/vp8_decoder.h', + 'common/gpu/media/vp8_picture.cc', + 'common/gpu/media/vp8_picture.h', ], 'include_dirs': [ '<(DEPTH)/third_party/khronos', ], - 'conditions': [ - ['target_arch == "arm"', { - 'sources': [ - 'common/gpu/media/tegra_v4l2_video_device.cc', - 'common/gpu/media/tegra_v4l2_video_device.h', - ], - 'conditions': [ - ['use_v4lplugin==1', { - 'sources': [ - 'common/gpu/media/accelerated_video_decoder.h', - 'common/gpu/media/h264_decoder.cc', - 'common/gpu/media/h264_decoder.h', - 'common/gpu/media/h264_dpb.cc', - 'common/gpu/media/h264_dpb.h', - 'common/gpu/media/v4l2_slice_video_decode_accelerator.cc', - 'common/gpu/media/v4l2_slice_video_decode_accelerator.h', - 'common/gpu/media/vp8_decoder.cc', - 'common/gpu/media/vp8_decoder.h', - 'common/gpu/media/vp8_picture.cc', - 'common/gpu/media/vp8_picture.h', - ], - }], - ], - }], + }], + ['target_arch == "arm" and chromeos == 1', { + 'sources': [ + 'common/gpu/media/tegra_v4l2_video_device.cc', + 'common/gpu/media/tegra_v4l2_video_device.h', ], }], ['target_arch != "arm" and chromeos == 1', { @@ -1031,6 +1023,7 @@ ['use_ozone==1', { 'dependencies': [ '../ui/ozone/ozone.gyp:ozone', + '../ui/ozone/ozone.gyp:ozone_base', '../ui/ozone/gpu/ozone_gpu.gyp:ozone_gpu', ], 'sources!': [
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 13ac6c02..6cdd46b 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -4,7 +4,6 @@ { 'variables': { - 'use_v4lplugin%': 0, 'layouttest_support_content_sources': [ 'public/test/layouttest_support.h', 'public/test/nested_message_pump_android.cc', @@ -346,6 +345,7 @@ 'browser/database_util_unittest.cc', 'browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc', 'browser/device_sensors/sensor_manager_android_unittest.cc', + 'browser/device_sensors/sensor_manager_chromeos_unittest.cc', 'browser/devtools/devtools_http_handler_unittest.cc', 'browser/devtools/devtools_manager_unittest.cc', 'browser/devtools/shared_worker_devtools_manager_unittest.cc', @@ -1617,9 +1617,6 @@ '../ui/ozone/ozone.gyp:ozone', # Used by rendering_helper.cc ], }], - ['use_v4lplugin==1', { - 'defines': ['USE_LIBV4L2'], - }], ], # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. 'msvs_disabled_warnings': [ 4267, ],
diff --git a/content/content_unittests.isolate b/content/content_unittests.isolate index bc982e2..b72dcee 100644 --- a/content/content_unittests.isolate +++ b/content/content_unittests.isolate
@@ -6,6 +6,7 @@ ['OS=="android" or OS=="linux" or OS=="mac" or OS=="win"', { 'variables': { 'files': [ + '../net/data/ssl/certificates/', '../media/test/data/', 'test/data/', ], @@ -43,6 +44,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -67,6 +70,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.so', @@ -83,6 +88,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.dll',
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index b7846f4..1064a70 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc
@@ -44,8 +44,8 @@ return false; } -ChildThread::Options GetOptions() { - ChildThread::Options options; +ChildThreadImpl::Options GetOptions() { + ChildThreadImpl::Options options; #if defined(USE_OZONE) IPC::MessageFilter* message_filter = ui::OzonePlatform::GetInstance() @@ -64,7 +64,7 @@ bool dead_on_arrival, const gpu::GPUInfo& gpu_info, const DeferredMessages& deferred_messages) - : ChildThread(GetOptions()), + : ChildThreadImpl(GetOptions()), dead_on_arrival_(dead_on_arrival), gpu_info_(gpu_info), deferred_messages_(deferred_messages), @@ -77,7 +77,7 @@ } GpuChildThread::GpuChildThread(const std::string& channel_id) - : ChildThread(Options(channel_id, false)), + : ChildThreadImpl(Options(channel_id, false)), dead_on_arrival_(false), in_browser_process_(true) { #if defined(OS_WIN) @@ -102,7 +102,7 @@ } void GpuChildThread::Shutdown() { - ChildThread::Shutdown(); + ChildThreadImpl::Shutdown(); logging::SetLogMessageHandler(NULL); } @@ -115,7 +115,7 @@ // process. This could result in deadlock. DCHECK(!msg->is_sync()); - return ChildThread::Send(msg); + return ChildThreadImpl::Send(msg); } bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) {
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h index b5c312d..7103cd3 100644 --- a/content/gpu/gpu_child_thread.h +++ b/content/gpu/gpu_child_thread.h
@@ -14,7 +14,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "build/build_config.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/gpu_config.h" @@ -33,7 +33,7 @@ // these per process. It does process initialization and shutdown. It forwards // IPC messages to GpuChannelManager, which is responsible for issuing rendering // commands to the GPU. -class GpuChildThread : public ChildThread { +class GpuChildThread : public ChildThreadImpl { public: typedef std::queue<IPC::Message*> DeferredMessages;
diff --git a/content/plugin/plugin_thread.cc b/content/plugin/plugin_thread.cc index 720a77b..a688902 100644 --- a/content/plugin/plugin_thread.cc +++ b/content/plugin/plugin_thread.cc
@@ -106,7 +106,7 @@ } void PluginThread::Shutdown() { - ChildThread::Shutdown(); + ChildThreadImpl::Shutdown(); if (preloaded_plugin_module_) { base::UnloadNativeLibrary(preloaded_plugin_module_);
diff --git a/content/plugin/plugin_thread.h b/content/plugin/plugin_thread.h index 11acafc7..8ad115e2 100644 --- a/content/plugin/plugin_thread.h +++ b/content/plugin/plugin_thread.h
@@ -8,7 +8,7 @@ #include "base/files/file_path.h" #include "base/native_library.h" #include "build/build_config.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/npapi/plugin_lib.h" #include "content/plugin/plugin_channel.h" @@ -22,7 +22,7 @@ // The PluginThread class represents a background thread where plugin instances // live. Communication occurs between WebPluginDelegateProxy in the renderer // process and WebPluginDelegateStub in this thread through IPC messages. -class PluginThread : public ChildThread { +class PluginThread : public ChildThreadImpl { public: PluginThread(); ~PluginThread() override;
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc index ad84196..793f6d6 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -10,7 +10,7 @@ #include "base/strings/string16.h" #include "base/threading/platform_thread.h" #include "build/build_config.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/child_process_messages.h" #include "ppapi/proxy/plugin_globals.h" #include "ppapi/shared_impl/proxy_lock.h"
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 6d77afe..103a7b8 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -42,12 +42,10 @@ #include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/resource_reply_thread_registrar.h" -#include "ppapi/shared_impl/proxy_lock.h" #include "third_party/WebKit/public/web/WebKit.h" #include "ui/base/ui_base_switches.h" #if defined(OS_WIN) -#include "base/win/iat_patch_function.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "sandbox/win/src/sandbox.h" @@ -94,54 +92,6 @@ } } -// TODO(scottmg): http://crbug.com/448473. This code should be removed from the -// renderer once PDF is always OOP and/or PDF is made to use Skia instead of GDI -// directly. -const wchar_t kPdfFileName[] = L"pdf.dll"; - -static base::win::IATPatchFunction g_iat_patch_createdca; -HDC WINAPI CreateDCAPatch(LPCSTR driver_name, - LPCSTR device_name, - LPCSTR output, - const void* init_data) { - DCHECK(std::string("DISPLAY") == std::string(driver_name)); - DCHECK(!device_name); - DCHECK(!output); - DCHECK(!init_data); - - // CreateDC fails behind the sandbox, but not CreateCompatibleDC. - return CreateCompatibleDC(NULL); -} - -static base::win::IATPatchFunction g_iat_patch_get_font_data; -DWORD WINAPI GetFontDataPatch(HDC hdc, - DWORD table, - DWORD offset, - LPVOID buffer, - DWORD length) { - int rv = GetFontData(hdc, table, offset, buffer, length); - if (rv == GDI_ERROR && hdc) { - HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); - - LOGFONT logfont; - if (GetObject(font, sizeof(LOGFONT), &logfont)) { - std::vector<char> font_data; - { - ppapi::ProxyAutoLock lock; - // In the sandbox, font loading will fail. We ask the browser to load it - // which causes it to be loaded by the kernel, which then makes the - // subsequent call succeed. - ppapi::proxy::PluginGlobals::Get()->PreCacheFontForFlash( - reinterpret_cast<const void*>(&logfont)); - } - rv = GetFontData(hdc, table, offset, buffer, length); - } - } - return rv; -} - -#else -extern void* g_target_services; #endif namespace content { @@ -173,7 +123,7 @@ } void PpapiThread::Shutdown() { - ChildThread::Shutdown(); + ChildThreadImpl::Shutdown(); ppapi::proxy::PluginGlobals::Get()->ResetPluginProxyDelegate(); if (plugin_entry_points_.shutdown_module) @@ -185,7 +135,7 @@ bool PpapiThread::Send(IPC::Message* msg) { // Allow access from multiple threads. if (base::MessageLoop::current() == message_loop()) - return ChildThread::Send(msg); + return ChildThreadImpl::Send(msg); return sync_message_filter()->Send(msg); } @@ -207,7 +157,7 @@ } void PpapiThread::OnChannelConnected(int32 peer_pid) { - ChildThread::OnChannelConnected(peer_pid); + ChildThreadImpl::OnChannelConnected(peer_pid); #if defined(OS_WIN) if (is_broker_) peer_handle_.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, peer_pid)); @@ -253,8 +203,7 @@ void PpapiThread::PreCacheFont(const void* logfontw) { #if defined(OS_WIN) - Send(new ChildProcessHostMsg_PreCacheFont( - *static_cast<const LOGFONTW*>(logfontw))); + ChildThreadImpl::PreCacheFont(*static_cast<const LOGFONTW*>(logfontw)); #endif } @@ -374,15 +323,6 @@ // otherwise these would be silent terminations and fly under the radar). base::win::SetAbortBehaviorForCrashReporting(); - // Need to patch a few functions for font loading to work correctly. This can - // be removed once we switch PDF to use Skia. - if (GetModuleHandle(kPdfFileName)) { - g_iat_patch_createdca.Patch(kPdfFileName, "gdi32.dll", "CreateDCA", - CreateDCAPatch); - g_iat_patch_get_font_data.Patch(kPdfFileName, "gdi32.dll", "GetFontData", - GetFontDataPatch); - } - // Once we lower the token the sandbox is locked down and no new modules // can be loaded. TODO(cpu): consider changing to the loading style of // regular plugins.
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h index 3d80e49..8b4f522 100644 --- a/content/ppapi_plugin/ppapi_thread.h +++ b/content/ppapi_plugin/ppapi_thread.h
@@ -14,7 +14,7 @@ #include "base/process/process.h" #include "base/scoped_native_library.h" #include "build/build_config.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/public/common/pepper_plugin_info.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/trusted/ppp_broker.h" @@ -40,7 +40,13 @@ class PpapiBlinkPlatformImpl; -class PpapiThread : public ChildThread, +#if defined(COMPILER_MSVC) +// See explanation for other RenderViewHostImpl which is the same issue. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + +class PpapiThread : public ChildThreadImpl, public ppapi::proxy::PluginDispatcher::PluginDelegate, public ppapi::proxy::PluginProxyDelegate { public: @@ -158,6 +164,10 @@ DISALLOW_IMPLICIT_CONSTRUCTORS(PpapiThread); }; +#if defined(COMPILER_MSVC) +#pragma warning(pop) +#endif + } // namespace content #endif // CONTENT_PPAPI_PLUGIN_PPAPI_THREAD_H_
diff --git a/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png b/content/public/android/java/res/drawable-hdpi/ic_search.png similarity index 100% rename from content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png rename to content/public/android/java/res/drawable-hdpi/ic_search.png Binary files differ
diff --git a/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png b/content/public/android/java/res/drawable-mdpi/ic_search.png similarity index 100% rename from content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png rename to content/public/android/java/res/drawable-mdpi/ic_search.png Binary files differ
diff --git a/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png b/content/public/android/java/res/drawable-xhdpi/ic_search.png similarity index 100% rename from content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png rename to content/public/android/java/res/drawable-xhdpi/ic_search.png Binary files differ
diff --git a/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png b/content/public/android/java/res/drawable-xxhdpi/ic_search.png similarity index 100% rename from content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png rename to content/public/android/java/res/drawable-xxhdpi/ic_search.png Binary files differ
diff --git a/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png b/content/public/android/java/res/drawable-xxxhdpi/ic_search.png similarity index 100% rename from content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png rename to content/public/android/java/res/drawable-xxxhdpi/ic_search.png Binary files differ
diff --git a/content/public/android/java/res/values-v17/styles.xml b/content/public/android/java/res/values-v17/styles.xml index dbdc8b1..58d8ed4 100644 --- a/content/public/android/java/res/values-v17/styles.xml +++ b/content/public/android/java/res/values-v17/styles.xml
@@ -14,6 +14,6 @@ <item name="android:icon">@drawable/ic_menu_share_holo_light</item> </style> <style name="SelectActionMenuWebSearch"> - <item name="android:icon">@drawable/ic_menu_search_holo_light</item> + <item name="android:icon">@drawable/ic_search</item> </style> </resources>
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 00f974a6..d6cb714 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -296,11 +296,6 @@ nativeAddMessageToDevToolsConsole(mNativeWebContentsAndroid, level, message); } - @Override - public void openUrl(String url, boolean userGesture, boolean isRendererInitiated) { - nativeOpenURL(mNativeWebContentsAndroid, url, userGesture, isRendererInitiated); - } - @CalledByNative private static void onEvaluateJavaScriptResult( String jsonResult, JavaScriptCallback callback) { @@ -352,6 +347,4 @@ String script, JavaScriptCallback callback); private native void nativeAddMessageToDevToolsConsole( long nativeWebContentsAndroid, int level, String message); - private native void nativeOpenURL(long nativeWebContentsAndroid, String url, - boolean userGesture, boolean isRendererInitiated); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java index 3e56e61f..1902161 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -213,13 +213,4 @@ * org.chromium.content_public.common.ConsoleMessageLevel. */ public void addMessageToDevToolsConsole(int level, String message); - - /** - * Opens a URL on web contents. - * @param url The URL to open. - * @param userGesture Whether navigation is triggered during a user gesture. - * @param isRendererInitiated Whether the navigation was started in the renderer (e.g. - * clicking on a link). - */ - public void openUrl(String url, boolean userGesture, boolean isRendererInitiated); }
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 13d1c1d..33450ac 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -94,14 +94,14 @@ // Creates a new tab with the already-created WebContents 'new_contents'. // The window for the added contents should be reparented correctly when this - // method returns. If |disposition| is NEW_POPUP, |initial_pos| should hold - // the initial position. If |was_blocked| is non-nullptr, then |*was_blocked| - // will be set to true if the popup gets blocked, and left unchanged - // otherwise. + // method returns. If |disposition| is NEW_POPUP, |initial_rect| should hold + // the initial position and size. If |was_blocked| is non-nullptr, then + // |*was_blocked| will be set to true if the popup gets blocked, and left + // unchanged otherwise. virtual void AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) {}
diff --git a/content/public/child/child_thread.h b/content/public/child/child_thread.h new file mode 100644 index 0000000..e3df72ca --- /dev/null +++ b/content/public/child/child_thread.h
@@ -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. + +#ifndef CONTENT_PUBLIC_CHILD_THREAD_H_ +#define CONTENT_PUBLIC_CHILD_THREAD_H_ + +#include "content/common/content_export.h" +#include "ipc/ipc_sender.h" + +#if defined(OS_WIN) +#include <windows.h> +#endif + +namespace content { + +class CONTENT_EXPORT ChildThread : public IPC::Sender { + public: + // Returns the one child thread for this process. Note that this can only be + // accessed when running on the child thread itself. + static ChildThread* Get(); + + ~ChildThread() override {} + +#if defined(OS_WIN) + // Request that the given font be loaded by the browser so it's cached by the + // OS. Please see ChildProcessHost::PreCacheFont for details. + virtual void PreCacheFont(const LOGFONT& log_font) = 0; + + // Release cached font. + virtual void ReleaseCachedFonts() = 0; +#endif +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_CHILD_THREAD_H_
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index de9eb49d..85083ae 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -494,6 +494,14 @@ const char kGpuRasterizationMSAASampleCount[] = "gpu-rasterization-msaa-sample-count"; +// Enable threaded GPU rasterization. +const char kEnableThreadedGpuRasterization[] = + "enable-threaded-gpu-rasterization"; + +// Disable threaded GPU rasterization. Overrides enable. +const char kDisableThreadedGpuRasterization[] = + "disable-threaded-gpu-rasterization"; + // Force renderer accessibility to be on instead of enabling it on demand when // a screen reader is detected. The disable-renderer-accessibility switch // overrides this if present. @@ -744,11 +752,6 @@ // Type of the current test harness ("browser" or "ui"). const char kTestType[] = "test-type"; -const char kTouchScrollingMode[] = "touch-scrolling-mode"; -const char kTouchScrollingModeAsyncTouchmove[] = "async-touchmove"; -const char kTouchScrollingModeSyncTouchmove[] = "sync-touchmove"; -const char kTouchScrollingModeTouchcancel[] = "touchcancel"; - // Causes TRACE_EVENT flags to be recorded beginning with shutdown. Optionally, // can specify the specific trace categories to include (e.g. // --trace-shutdown=base,net) otherwise, all events are recorded.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index a8ad442..fd66188 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -144,6 +144,8 @@ CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kForceFieldTrials[]; CONTENT_EXPORT extern const char kForceGpuRasterization[]; +CONTENT_EXPORT extern const char kEnableThreadedGpuRasterization[]; +CONTENT_EXPORT extern const char kDisableThreadedGpuRasterization[]; CONTENT_EXPORT extern const char kForceRendererAccessibility[]; CONTENT_EXPORT extern const char kForceTextBlobs[]; extern const char kGpuDeviceID[]; @@ -210,10 +212,6 @@ CONTENT_EXPORT extern const char kTestingFixedHttpPort[]; CONTENT_EXPORT extern const char kTestingFixedHttpsPort[]; CONTENT_EXPORT extern const char kTestType[]; -CONTENT_EXPORT extern const char kTouchScrollingMode[]; -CONTENT_EXPORT extern const char kTouchScrollingModeAsyncTouchmove[]; -CONTENT_EXPORT extern const char kTouchScrollingModeSyncTouchmove[]; -CONTENT_EXPORT extern const char kTouchScrollingModeTouchcancel[]; CONTENT_EXPORT extern const char kTraceShutdown[]; extern const char kTraceShutdownFile[]; extern const char kTraceStartup[];
diff --git a/content/public/renderer/DEPS b/content/public/renderer/DEPS index 36c27b9..f78d4a39 100644 --- a/content/public/renderer/DEPS +++ b/content/public/renderer/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+content/public/child", "+media/base", "+media/filters", "+media/video",
diff --git a/content/public/renderer/render_thread.h b/content/public/renderer/render_thread.h index 002f45d..407128b 100644 --- a/content/public/renderer/render_thread.h +++ b/content/public/renderer/render_thread.h
@@ -10,12 +10,8 @@ #include "base/memory/shared_memory.h" #include "base/metrics/user_metrics_action.h" #include "content/common/content_export.h" +#include "content/public/child/child_thread.h" #include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_sender.h" - -#if defined(OS_WIN) -#include <windows.h> -#endif class GURL; @@ -45,7 +41,7 @@ class ResourceDispatcherDelegate; class ServiceRegistry; -class CONTENT_EXPORT RenderThread : public IPC::Sender { +class CONTENT_EXPORT RenderThread : virtual public ChildThread { public: // Returns the one render thread for this process. Note that this can only // be accessed when running on the render thread itself. @@ -135,15 +131,6 @@ // Gets the shutdown event for the process. virtual base::WaitableEvent* GetShutdownEvent() = 0; -#if defined(OS_WIN) - // Request that the given font be loaded by the browser so it's cached by the - // OS. Please see ChildProcessHost::PreCacheFont for details. - virtual void PreCacheFont(const LOGFONT& log_font) = 0; - - // Release cached font. - virtual void ReleaseCachedFonts() = 0; -#endif - // Returns the ServiceRegistry for this thread. virtual ServiceRegistry* GetServiceRegistry() = 0; };
diff --git a/content/public/utility/DEPS b/content/public/utility/DEPS new file mode 100644 index 0000000..ad94e88 --- /dev/null +++ b/content/public/utility/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+content/public/child", +]
diff --git a/content/public/utility/utility_thread.h b/content/public/utility/utility_thread.h index 6e7cbd10..42bf10c 100644 --- a/content/public/utility/utility_thread.h +++ b/content/public/utility/utility_thread.h
@@ -6,16 +6,11 @@ #define CONTENT_PUBLIC_UTILITY_UTILITY_THREAD_H_ #include "base/basictypes.h" -#include "content/common/content_export.h" -#include "ipc/ipc_sender.h" - -#if defined(OS_WIN) -#include <windows.h> -#endif +#include "content/public/child/child_thread.h" namespace content { -class CONTENT_EXPORT UtilityThread : public IPC::Sender { +class CONTENT_EXPORT UtilityThread : virtual public ChildThread { public: // Returns the one utility thread for this process. Note that this can only // be accessed when running on the utility thread itself. @@ -26,15 +21,6 @@ // Releases the process if we are not (or no longer) in batch mode. virtual void ReleaseProcessIfNeeded() = 0; - -#if defined(OS_WIN) - // Request that the given font be loaded by the browser so it's cached by the - // OS. Please see ChildProcessHost::PreCacheFont for details. - virtual void PreCacheFont(const LOGFONT& log_font) = 0; - - // Release cached font. - virtual void ReleaseCachedFonts() = 0; -#endif }; } // namespace content
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc index b6b93c6..44616e5 100644 --- a/content/renderer/accessibility/blink_ax_tree_source.cc +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -438,8 +438,7 @@ src.minValueForRange()); } - if (dst->role == ui::AX_ROLE_DOCUMENT || - dst->role == ui::AX_ROLE_WEB_AREA) { + if (dst->role == ui::AX_ROLE_WEB_AREA) { dst->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "#document"); const WebDocument& document = src.document(); if (name.empty())
diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h index 3ee74a09..7906f5f 100644 --- a/content/renderer/android/synchronous_compositor_factory.h +++ b/content/renderer/android/synchronous_compositor_factory.h
@@ -19,14 +19,12 @@ class OutputSurface; } -namespace gpu_blink { -class WebGraphicsContext3DInProcessCommandBufferImpl; -} - -namespace webkit { -namespace gpu { +namespace cc_blink { class ContextProviderWebContext; } + +namespace gpu_blink { +class WebGraphicsContext3DInProcessCommandBufferImpl; } namespace content { @@ -59,10 +57,10 @@ virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource( int routing_id) = 0; - virtual scoped_refptr<webkit::gpu::ContextProviderWebContext> - CreateOffscreenContextProvider( - const blink::WebGraphicsContext3D::Attributes& attributes, - const std::string& debug_name) = 0; + virtual scoped_refptr<cc_blink::ContextProviderWebContext> + CreateOffscreenContextProvider( + const blink::WebGraphicsContext3D::Attributes& attributes, + const std::string& debug_name) = 0; virtual scoped_refptr<StreamTextureFactory> CreateStreamTextureFactory( int frame_id) = 0; virtual gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl*
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 410e20b..08293fd 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -61,7 +61,10 @@ render_frame_proxy_(render_frame_proxy), frame_(frame) {} -ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {} +ChildFrameCompositingHelper::~ChildFrameCompositingHelper() { + if (resource_collection_.get()) + resource_collection_->SetClient(NULL); +} BrowserPluginManager* ChildFrameCompositingHelper::GetBrowserPluginManager() { if (!browser_plugin_)
diff --git a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc index 5b88d66..9b66ea0 100644 --- a/content/renderer/device_sensors/device_motion_event_pump_unittest.cc +++ b/content/renderer/device_sensors/device_motion_event_pump_unittest.cc
@@ -16,7 +16,8 @@ class MockDeviceMotionListener : public blink::WebDeviceMotionListener { public: - MockDeviceMotionListener() : did_change_device_motion_(false) { + MockDeviceMotionListener() + : did_change_device_motion_(false), number_of_events_(0) { memset(&data_, 0, sizeof(data_)); } virtual ~MockDeviceMotionListener() { } @@ -25,17 +26,22 @@ const blink::WebDeviceMotionData& data) override { memcpy(&data_, &data, sizeof(data)); did_change_device_motion_ = true; + ++number_of_events_; } bool did_change_device_motion() const { return did_change_device_motion_; } + + int number_of_events() const { return number_of_events_; } + const blink::WebDeviceMotionData& data() const { return data_; } private: bool did_change_device_motion_; + int number_of_events_; blink::WebDeviceMotionData data_; DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionListener); @@ -44,9 +50,17 @@ class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { public: DeviceMotionEventPumpForTesting() - : DeviceMotionEventPump(0) { } + : DeviceMotionEventPump(0), stop_on_fire_event_(true) {} ~DeviceMotionEventPumpForTesting() override {} + void set_stop_on_fire_event(bool stop_on_fire_event) { + stop_on_fire_event_ = stop_on_fire_event; + } + + bool stop_on_fire_event() { return stop_on_fire_event_; } + + int pump_delay_microseconds() const { return pump_delay_microseconds_; } + void OnDidStart(base::SharedMemoryHandle renderer_handle) { DeviceMotionEventPump::OnDidStart(renderer_handle); } @@ -54,11 +68,15 @@ void SendStopMessage() override {} void FireEvent() override { DeviceMotionEventPump::FireEvent(); - Stop(); - base::MessageLoop::current()->QuitWhenIdle(); + if (stop_on_fire_event_) { + Stop(); + base::MessageLoop::current()->QuitWhenIdle(); + } } private: + bool stop_on_fire_event_; + DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); }; @@ -158,4 +176,31 @@ EXPECT_FALSE(received_data.hasRotationRateGamma); } +// Confirm that the frequency of pumping events is not greater than 60Hz. A rate +// above 60Hz would allow for the detection of keystrokes (crbug.com/421691) +TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) { + // Confirm that the delay for pumping events is 60 Hz. + EXPECT_GE(60, base::Time::kMicrosecondsPerSecond / + motion_pump()->pump_delay_microseconds()); + + base::MessageLoopForUI loop; + + InitBuffer(true); + + motion_pump()->set_stop_on_fire_event(false); + motion_pump()->Start(listener()); + motion_pump()->OnDidStart(handle()); + + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, base::MessageLoop::QuitClosure(), + base::TimeDelta::FromMilliseconds(100)); + base::MessageLoop::current()->Run(); + motion_pump()->Stop(); + + // Check that the blink::WebDeviceMotionListener does not receive excess + // events. + EXPECT_TRUE(listener()->did_change_device_motion()); + EXPECT_GE(6, listener()->number_of_events()); +} + } // namespace content
diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc index ce56f8e..65b85a1 100644 --- a/content/renderer/geolocation_dispatcher.cc +++ b/content/renderer/geolocation_dispatcher.cc
@@ -4,7 +4,6 @@ #include "content/renderer/geolocation_dispatcher.h" -#include "content/child/child_thread.h" #include "content/public/common/geoposition.h" #include "content/renderer/render_view_impl.h" #include "third_party/WebKit/public/platform/WebString.h"
diff --git a/content/renderer/gpu/compositor_dependencies.h b/content/renderer/gpu/compositor_dependencies.h index 26dff9d8..9aae19f 100644 --- a/content/renderer/gpu/compositor_dependencies.h +++ b/content/renderer/gpu/compositor_dependencies.h
@@ -30,6 +30,7 @@ virtual bool IsImplSidePaintingEnabled() = 0; virtual bool IsGpuRasterizationForced() = 0; virtual bool IsGpuRasterizationEnabled() = 0; + virtual bool IsThreadedGpuRasterizationEnabled() = 0; virtual int GetGpuRasterizationMSAASampleCount() = 0; virtual bool IsLcdTextEnabled() = 0; virtual bool IsDistanceFieldTextEnabled() = 0;
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index f623cb1..a4e8627 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -239,6 +239,8 @@ compositor_deps_->IsGpuRasterizationForced(); settings.gpu_rasterization_enabled = compositor_deps_->IsGpuRasterizationEnabled(); + settings.threaded_gpu_rasterization_enabled = + compositor_deps_->IsThreadedGpuRasterizationEnabled(); settings.can_use_lcd_text = compositor_deps_->IsLcdTextEnabled(); settings.use_distance_field_text = compositor_deps_->IsDistanceFieldTextEnabled(); @@ -751,13 +753,11 @@ layer_tree_host_->SetTopControlsContentOffset(offset); } -void RenderWidgetCompositor::WillBeginMainFrame(int frame_id) { - widget_->InstrumentWillBeginFrame(frame_id); +void RenderWidgetCompositor::WillBeginMainFrame() { widget_->willBeginCompositorFrame(); } void RenderWidgetCompositor::DidBeginMainFrame() { - widget_->InstrumentDidBeginFrame(); } void RenderWidgetCompositor::BeginMainFrame(const cc::BeginFrameArgs& args) { @@ -840,7 +840,6 @@ } void RenderWidgetCompositor::WillCommit() { - widget_->InstrumentWillComposite(); } void RenderWidgetCompositor::DidCommit() {
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 20ce38e..117cffaa 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -132,7 +132,7 @@ virtual void setTopControlsContentOffset(float); // cc::LayerTreeHostClient implementation. - void WillBeginMainFrame(int frame_id) override; + void WillBeginMainFrame() override; void DidBeginMainFrame() override; void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override;
diff --git a/content/renderer/manifest/manifest_manager.cc b/content/renderer/manifest/manifest_manager.cc index 5c620c0d..a5ee94cf 100644 --- a/content/renderer/manifest/manifest_manager.cc +++ b/content/renderer/manifest/manifest_manager.cc
@@ -101,6 +101,11 @@ manifest_dirty_ = true; } +void ManifestManager::DidCommitProvisionalLoad(bool is_new_navigation) { + may_have_manifest_ = false; + manifest_dirty_ = true; +} + void ManifestManager::FetchManifest() { GURL url(render_frame()->GetWebFrame()->document().manifestURL());
diff --git a/content/renderer/manifest/manifest_manager.h b/content/renderer/manifest/manifest_manager.h index 5874724..e6529f2 100644 --- a/content/renderer/manifest/manifest_manager.h +++ b/content/renderer/manifest/manifest_manager.h
@@ -42,6 +42,7 @@ // RenderFrameObserver implementation. bool OnMessageReceived(const IPC::Message& message) override; void DidChangeManifest() override; + void DidCommitProvisionalLoad(bool is_new_navigation) override; private: enum ResolveState {
diff --git a/content/renderer/media/OWNERS b/content/renderer/media/OWNERS index b5ef0db..dbaad20 100644 --- a/content/renderer/media/OWNERS +++ b/content/renderer/media/OWNERS
@@ -1,14 +1,15 @@ dalecurtis@chromium.org ddorwin@chromium.org jrummell@chromium.org -perkj@chromium.org sandersd@chromium.org scherkus@chromium.org -tommi@chromium.org -vrk@chromium.org wolenetz@chromium.org xhwang@chromium.org +# WebRTC OWNERS. +perkj@chromium.org +tommi@chromium.org + per-file cast_*=hclam@chromium.org per-file cast_*=hubbe@chromium.org per-file cast_*=mikhal@chromium.org
diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc index 9c24682..66f3d28 100644 --- a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc +++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
@@ -8,7 +8,7 @@ #include <GLES2/gl2ext.h> #include "base/bind.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/common/gpu/client/gl_helper.h" #include "content/common/gpu/client/gpu_channel_host.h" @@ -48,7 +48,7 @@ : task_runner_(task_runner), gpu_channel_host_(gpu_channel_host), context_provider_(context_provider), - thread_safe_sender_(ChildThread::current()->thread_safe_sender()) {} + thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {} RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {} @@ -239,7 +239,7 @@ RendererGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) { DCHECK(task_runner_->BelongsToCurrentThread()); scoped_ptr<base::SharedMemory> mem( - ChildThread::AllocateSharedMemory(size, thread_safe_sender_.get())); + ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender_.get())); if (mem && !mem->Map(size)) return nullptr; return mem;
diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc index ffa2536c..0bfc9d87 100644 --- a/content/renderer/media/rtc_video_decoder.cc +++ b/content/renderer/media/rtc_video_decoder.cc
@@ -13,7 +13,6 @@ #include "base/stl_util.h" #include "base/synchronization/waitable_event.h" #include "base/task_runner_util.h" -#include "content/child/child_thread.h" #include "content/renderer/media/native_handle_impl.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/bind_to_current_loop.h"
diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc index 3b739eb..4c689d6d 100644 --- a/content/renderer/media/webmediaplayer_ms.cc +++ b/content/renderer/media/webmediaplayer_ms.cc
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" +#include "cc/blink/context_provider_web_context.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/video_layer.h" #include "content/public/renderer/render_view.h" @@ -32,7 +33,6 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebView.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "webkit/common/gpu/context_provider_web_context.h" using blink::WebCanvas; using blink::WebMediaPlayer;
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc index 32cac5d..66bc3627 100644 --- a/content/renderer/npapi/webplugin_delegate_proxy.cc +++ b/content/renderer/npapi/webplugin_delegate_proxy.cc
@@ -640,7 +640,7 @@ bool WebPluginDelegateProxy::CreateSharedBitmap( scoped_ptr<SharedMemoryBitmap>* memory, scoped_ptr<skia::PlatformCanvas>* canvas) { - *memory = ChildThread::current() + *memory = ChildThreadImpl::current() ->shared_bitmap_manager() ->AllocateSharedMemoryBitmap(plugin_rect_.size()); if (!memory->get())
diff --git a/content/renderer/pepper/pepper_compositor_host.cc b/content/renderer/pepper/pepper_compositor_host.cc index c5f5e98..eec292a 100644 --- a/content/renderer/pepper/pepper_compositor_host.cc +++ b/content/renderer/pepper/pepper_compositor_host.cc
@@ -12,7 +12,7 @@ #include "cc/resources/texture_mailbox.h" #include "cc/trees/layer_tree_host.h" #include "content/child/child_shared_bitmap_manager.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/gfx_conversion.h" #include "content/renderer/pepper/host_globals.h" @@ -288,7 +288,7 @@ DCHECK_EQ(desc.stride, desc.size.width * 4); DCHECK_EQ(desc.format, PP_IMAGEDATAFORMAT_RGBA_PREMUL); scoped_ptr<cc::SharedBitmap> bitmap = - ChildThread::current() + ChildThreadImpl::current() ->shared_bitmap_manager() ->GetBitmapForSharedMemory(image_shm.get());
diff --git a/content/renderer/pepper/pepper_file_system_host.cc b/content/renderer/pepper/pepper_file_system_host.cc index 69945341..bce63a2 100644 --- a/content/renderer/pepper/pepper_file_system_host.cc +++ b/content/renderer/pepper/pepper_file_system_host.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/callback.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/child/fileapi/file_system_dispatcher.h" #include "content/common/pepper_file_util.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" @@ -102,7 +102,7 @@ return PP_ERROR_FAILED; FileSystemDispatcher* file_system_dispatcher = - ChildThread::current()->file_system_dispatcher(); + ChildThreadImpl::current()->file_system_dispatcher(); reply_context_ = context->MakeReplyMessageContext(); file_system_dispatcher->OpenFileSystem( document_url.GetOrigin(),
diff --git a/content/renderer/pepper/ppb_broker_impl.cc b/content/renderer/pepper/ppb_broker_impl.cc index 33181a25..ead54a0 100644 --- a/content/renderer/pepper/ppb_broker_impl.cc +++ b/content/renderer/pepper/ppb_broker_impl.cc
@@ -32,7 +32,7 @@ connect_callback_(), pipe_handle_(PlatformFileToInt(base::SyncSocket::kInvalidHandle)), routing_id_(RenderThreadImpl::current()->GenerateRoutingID()) { - ChildThread::current()->GetRouter()->AddRoute(routing_id_, this); + ChildThreadImpl::current()->GetRouter()->AddRoute(routing_id_, this); } PPB_Broker_Impl::~PPB_Broker_Impl() { @@ -43,7 +43,7 @@ // The plugin owns the handle. pipe_handle_ = PlatformFileToInt(base::SyncSocket::kInvalidHandle); - ChildThread::current()->GetRouter()->RemoveRoute(routing_id_); + ChildThreadImpl::current()->GetRouter()->RemoveRoute(routing_id_); } PPB_Broker_API* PPB_Broker_Impl::AsPPB_Broker_API() { return this; }
diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc index 14123ac..da84db9 100644 --- a/content/renderer/pepper/video_decoder_shim.cc +++ b/content/renderer/pepper/video_decoder_shim.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/numerics/safe_conversions.h" #include "base/single_thread_task_runner.h" +#include "cc/blink/context_provider_web_context.h" #include "content/public/renderer/render_thread.h" #include "content/renderer/pepper/pepper_video_decoder_host.h" #include "content/renderer/render_thread_impl.h" @@ -24,7 +25,6 @@ #include "media/video/picture.h" #include "media/video/video_decode_accelerator.h" #include "ppapi/c/pp_errors.h" -#include "webkit/common/gpu/context_provider_web_context.h" namespace content {
diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h index 42335c1f..3a0f32a 100644 --- a/content/renderer/pepper/video_decoder_shim.h +++ b/content/renderer/pepper/video_decoder_shim.h
@@ -23,6 +23,10 @@ class SingleThreadTaskRunner; } +namespace cc_blink { +class ContextProviderWebContext; +} + namespace gpu { namespace gles2 { class GLES2Interface; @@ -33,12 +37,6 @@ class DecoderBuffer; } -namespace webkit { -namespace gpu { -class ContextProviderWebContext; -} -} - namespace content { class PepperVideoDecoderHost; @@ -92,7 +90,7 @@ PepperVideoDecoderHost* host_; scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; - scoped_refptr<webkit::gpu::ContextProviderWebContext> context_provider_; + scoped_refptr<cc_blink::ContextProviderWebContext> context_provider_; // The current decoded frame size. gfx::Size texture_size_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 876e8ae..b9c3fc7 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -157,7 +157,7 @@ #include "content/renderer/media/android/stream_texture_factory_impl.h" #include "content/renderer/media/android/webmediaplayer_android.h" #else -#include "webkit/common/gpu/context_provider_web_context.h" +#include "cc/blink/context_provider_web_context.h" #endif #if defined(ENABLE_PEPPER_CDMS) @@ -2041,13 +2041,13 @@ DCHECK(!frame_ || frame_ == frame); // At this point we should have non-null data source. DCHECK(frame->dataSource()); - if (!ChildThread::current()) + if (!ChildThreadImpl::current()) return NULL; // May be null in some tests. ServiceWorkerNetworkProvider* provider = ServiceWorkerNetworkProvider::FromDocumentState( DocumentState::FromDataSource(frame->dataSource())); return new WebServiceWorkerProviderImpl( - ChildThread::current()->thread_safe_sender(), + ChildThreadImpl::current()->thread_safe_sender(), provider ? provider->context() : NULL); } @@ -2587,7 +2587,7 @@ // new navigation. navigation_state->set_request_committed(true); - SendDidCommitProvisionalLoad(frame); + SendDidCommitProvisionalLoad(frame, commit_type); // Check whether we have new encoding name. UpdateEncoding(frame, frame->view()->pageEncoding().utf8()); @@ -3362,7 +3362,7 @@ callbacks.didFail(blink::WebStorageQuotaErrorAbort); return; } - ChildThread::current()->quota_dispatcher()->RequestStorageQuota( + ChildThreadImpl::current()->quota_dispatcher()->RequestStorageQuota( render_view_->GetRoutingID(), GURL(origin.toString()), static_cast<storage::StorageType>(type), @@ -3661,7 +3661,9 @@ } // Tell the embedding application that the URL of the active page has changed. -void RenderFrameImpl::SendDidCommitProvisionalLoad(blink::WebFrame* frame) { +void RenderFrameImpl::SendDidCommitProvisionalLoad( + blink::WebFrame* frame, + blink::WebHistoryCommitType commit_type) { DCHECK(!frame_ || frame_ == frame); WebDataSource* ds = frame->dataSource(); DCHECK(ds); @@ -3724,7 +3726,7 @@ render_view_->navigation_gesture_ = NavigationGestureUnknown; // Make navigation state a part of the DidCommitProvisionalLoad message so - // that commited entry has it at all times. + // that committed entry has it at all times. HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry(); if (entry) params.page_state = HistoryEntryToPageState(entry); @@ -3829,13 +3831,12 @@ // Subframe navigation: the type depends on whether this navigation // generated a new session history entry. When they do generate a session // history entry, it means the user initiated the navigation and we should - // mark it as such. This test checks if this is the first time - // SendDidCommitProvisionalLoad has been called since WillNavigateToURL was - // called to initiate the load. - if (render_view_->page_id_ > render_view_->last_page_id_sent_to_browser_) - params.transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME; - else + // mark it as such. + bool is_history_navigation = commit_type == blink::WebBackForwardCommit; + if (is_history_navigation || ds->replacesCurrentHistoryItem()) params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME; + else + params.transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME; DCHECK(!navigation_state->history_list_was_cleared()); params.history_list_was_cleared = false; @@ -3846,10 +3847,6 @@ Send(new FrameHostMsg_DidCommitProvisionalLoad(routing_id_, params)); } - render_view_->last_page_id_sent_to_browser_ = - std::max(render_view_->last_page_id_sent_to_browser_, - render_view_->page_id_); - // If we end up reusing this WebRequest (for example, due to a #ref click), // we don't want the transition type to persist. Just clear it. navigation_state->set_transition_type(ui::PAGE_TRANSITION_LINK); @@ -4442,7 +4439,7 @@ SynchronousCompositorFactory::GetInstance()) { stream_texture_factory = factory->CreateStreamTextureFactory(routing_id_); } else { - scoped_refptr<webkit::gpu::ContextProviderWebContext> context_provider = + scoped_refptr<cc_blink::ContextProviderWebContext> context_provider = RenderThreadImpl::current()->SharedMainThreadContextProvider(); if (!context_provider.get()) {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index f387e4f..f6784e7 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -571,7 +571,8 @@ void RemoveObserver(RenderFrameObserver* observer); // Builds and sends DidCommitProvisionalLoad to the host. - void SendDidCommitProvisionalLoad(blink::WebFrame* frame); + void SendDidCommitProvisionalLoad(blink::WebFrame* frame, + blink::WebHistoryCommitType commit_type); // IPC message handlers ------------------------------------------------------ //
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 2914c9c..2044f81 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -282,8 +282,8 @@ scoped_ptr<cc::SharedBitmap> AllocateSharedBitmapFunction( const gfx::Size& size) { - return ChildThread::current()->shared_bitmap_manager()->AllocateSharedBitmap( - size); + return ChildThreadImpl::current()->shared_bitmap_manager()-> + AllocateSharedBitmap(size); } void EnableBlinkPlatformLogChannels(const std::string& channels) { @@ -423,18 +423,18 @@ // When we run plugins in process, we actually run them on the render thread, // which means that we need to make the render thread pump UI events. RenderThreadImpl::RenderThreadImpl() - : ChildThread(Options(ShouldUseMojoChannel())) { + : ChildThreadImpl(Options(ShouldUseMojoChannel())) { Init(); } RenderThreadImpl::RenderThreadImpl(const std::string& channel_name) - : ChildThread(Options(channel_name, ShouldUseMojoChannel())) { + : ChildThreadImpl(Options(channel_name, ShouldUseMojoChannel())) { Init(); } RenderThreadImpl::RenderThreadImpl( scoped_ptr<base::MessageLoop> main_message_loop) - : ChildThread(Options(ShouldUseMojoChannel())), + : ChildThreadImpl(Options(ShouldUseMojoChannel())), main_message_loop_(main_message_loop.Pass()) { Init(); } @@ -593,6 +593,8 @@ } else { gpu_rasterization_msaa_sample_count_ = 0; } + is_threaded_gpu_rasterization_enabled_ = + command_line.HasSwitch(switches::kEnableThreadedGpuRasterization); if (command_line.HasSwitch(switches::kDisableDistanceFieldText)) { is_distance_field_text_enabled_ = false; @@ -655,7 +657,7 @@ } base::DiscardableMemoryShmemAllocator::SetInstance( - ChildThread::discardable_shared_memory_manager()); + ChildThreadImpl::discardable_shared_memory_manager()); service_registry()->AddService<RenderFrameSetup>( base::Bind(CreateRenderFrameSetup)); @@ -670,7 +672,7 @@ FOR_EACH_OBSERVER( RenderProcessObserver, observers_, OnRenderProcessShutdown()); - ChildThread::Shutdown(); + ChildThreadImpl::Shutdown(); if (memory_observer_) { message_loop()->RemoveTaskObserver(memory_observer_.get()); @@ -811,7 +813,7 @@ #endif } - bool rv = ChildThread::Send(msg); + bool rv = ChildThreadImpl::Send(msg); if (pumping_events) { #if defined(ENABLE_PLUGINS) @@ -860,7 +862,7 @@ } void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) { - ChildThread::GetRouter()->AddRoute(routing_id, listener); + ChildThreadImpl::GetRouter()->AddRoute(routing_id, listener); PendingRenderFrameConnectMap::iterator it = pending_render_frame_connects_.find(routing_id); if (it == pending_render_frame_connects_.end()) @@ -881,7 +883,7 @@ } void RenderThreadImpl::RemoveRoute(int32 routing_id) { - ChildThread::GetRouter()->RemoveRoute(routing_id); + ChildThreadImpl::GetRouter()->RemoveRoute(routing_id); } void RenderThreadImpl::AddEmbeddedWorkerRoute(int32 routing_id, @@ -1112,7 +1114,7 @@ scoped_ptr<base::SharedMemory> RenderThreadImpl::HostAllocateSharedMemoryBuffer(size_t size) { - return ChildThread::AllocateSharedMemory(size, thread_safe_sender()); + return ChildThreadImpl::AllocateSharedMemory(size, thread_safe_sender()); } cc::SharedBitmapManager* RenderThreadImpl::GetSharedBitmapManager() { @@ -1268,7 +1270,7 @@ NULL)); } -scoped_refptr<webkit::gpu::ContextProviderWebContext> +scoped_refptr<cc_blink::ContextProviderWebContext> RenderThreadImpl::SharedMainThreadContextProvider() { DCHECK(IsMainThread()); if (!shared_main_thread_contexts_.get() || @@ -1326,14 +1328,6 @@ Send(new ViewHostMsg_PreCacheFontCharacters(log_font, str)); } -void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) { - Send(new ChildProcessHostMsg_PreCacheFont(log_font)); -} - -void RenderThreadImpl::ReleaseCachedFonts() { - Send(new ChildProcessHostMsg_ReleaseCachedFonts()); -} - #endif // OS_WIN ServiceRegistry* RenderThreadImpl::GetServiceRegistry() { @@ -1352,6 +1346,10 @@ return is_gpu_rasterization_enabled_; } +bool RenderThreadImpl::IsThreadedGpuRasterizationEnabled() { + return is_threaded_gpu_rasterization_enabled_; +} + int RenderThreadImpl::GetGpuRasterizationMSAASampleCount() { return gpu_rasterization_msaa_sample_count_; } @@ -1384,6 +1382,7 @@ uint32 RenderThreadImpl::GetImageTextureTarget() { return use_image_texture_target_; } + scoped_refptr<base::SingleThreadTaskRunner> RenderThreadImpl::GetCompositorMainThreadTaskRunner() { return main_thread_compositor_task_runner_;
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index e204c63d..288f4ffd 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -18,7 +18,7 @@ #include "base/threading/thread_checker.h" #include "base/timer/timer.h" #include "build/build_config.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/content_export.h" #include "content/common/frame_replication_state.h" #include "content/common/gpu/client/gpu_channel_host.h" @@ -56,6 +56,10 @@ class ContextProvider; } +namespace cc_blink { +class ContextProviderWebContext; +} + namespace IPC { class MessageFilter; } @@ -69,13 +73,6 @@ class Extension; } -namespace webkit { -namespace gpu { -class ContextProviderWebContext; -class GrContextForWebGraphicsContext3D; -} -} - namespace content { class AppCacheDispatcher; @@ -110,6 +107,12 @@ class WebGraphicsContext3DCommandBufferImpl; class WebRTCIdentityService; +#if defined(COMPILER_MSVC) +// See explanation for other RenderViewHostImpl which is the same issue. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + // The RenderThreadImpl class represents a background thread where RenderView // instances live. The RenderThread supports an API that is used by its // consumer to talk indirectly to the RenderViews and supporting objects. @@ -121,7 +124,7 @@ // The routing IDs correspond to RenderView instances. class CONTENT_EXPORT RenderThreadImpl : public RenderThread, - public ChildThread, + public ChildThreadImpl, public GpuChannelHostFactory, NON_EXPORTED_BASE(public CompositorDependencies) { public: @@ -175,16 +178,13 @@ int PostTaskToAllWebWorkers(const base::Closure& closure) override; bool ResolveProxy(const GURL& url, std::string* proxy_list) override; base::WaitableEvent* GetShutdownEvent() override; -#if defined(OS_WIN) - virtual void PreCacheFont(const LOGFONT& log_font) override; - virtual void ReleaseCachedFonts() override; -#endif ServiceRegistry* GetServiceRegistry() override; // CompositorDependencies implementation. bool IsImplSidePaintingEnabled() override; bool IsGpuRasterizationForced() override; bool IsGpuRasterizationEnabled() override; + bool IsThreadedGpuRasterizationEnabled() override; int GetGpuRasterizationMSAASampleCount() override; bool IsLcdTextEnabled() override; bool IsDistanceFieldTextEnabled() override; @@ -324,8 +324,8 @@ scoped_refptr<media::GpuVideoAcceleratorFactories> GetGpuFactories(); - scoped_refptr<webkit::gpu::ContextProviderWebContext> - SharedMainThreadContextProvider(); + scoped_refptr<cc_blink::ContextProviderWebContext> + SharedMainThreadContextProvider(); // AudioRendererMixerManager instance which manages renderer side mixer // instances shared based on configured audio parameters. Lazily created on @@ -566,7 +566,7 @@ scoped_ptr<InputHandlerManager> input_handler_manager_; scoped_refptr<CompositorForwardingMessageFilter> compositor_message_filter_; - scoped_refptr<webkit::gpu::ContextProviderWebContext> + scoped_refptr<cc_blink::ContextProviderWebContext> shared_main_thread_contexts_; ObserverList<RenderProcessObserver> observers_; @@ -595,6 +595,7 @@ bool is_gpu_rasterization_enabled_; bool is_gpu_rasterization_forced_; int gpu_rasterization_msaa_sample_count_; + bool is_threaded_gpu_rasterization_enabled_; bool is_impl_side_painting_enabled_; bool is_lcd_text_enabled_; bool is_distance_field_text_enabled_; @@ -625,6 +626,10 @@ DISALLOW_COPY_AND_ASSIGN(RenderThreadImpl); }; +#if defined(COMPILER_MSVC) +#pragma warning(pop) +#endif + } // namespace content #endif // CONTENT_RENDERER_RENDER_THREAD_IMPL_H_
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index 3e4a795..39bf764 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -77,6 +77,12 @@ int count_; }; +#if defined(COMPILER_MSVC) +// See explanation for other RenderViewHostImpl which is the same issue. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + class RenderThreadImplForTest : public RenderThreadImpl { public: RenderThreadImplForTest(const std::string& channel_id, @@ -91,12 +97,16 @@ RenderThreadImpl::SetResourceDispatchTaskQueue(test_task_counter_); } - using ChildThread::OnMessageReceived; + using ChildThreadImpl::OnMessageReceived; private: scoped_refptr<TestTaskCounter> test_task_counter_; }; +#if defined(COMPILER_MSVC) +#pragma warning(pop) +#endif + void QuitTask(base::MessageLoop* message_loop) { message_loop->QuitWhenIdle(); }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 3be3eb3d..4bd9146e 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -35,7 +35,6 @@ #include "content/child/appcache/appcache_dispatcher.h" #include "content/child/appcache/web_application_cache_host_impl.h" #include "content/child/child_shared_bitmap_manager.h" -#include "content/child/child_thread.h" #include "content/child/npapi/webplugin_delegate_impl.h" #include "content/child/request_extra_data.h" #include "content/child/webmessageportchannel_impl.h" @@ -642,7 +641,6 @@ opener_suppressed_(false), suppress_dialogs_until_swap_out_(false), page_id_(-1), - last_page_id_sent_to_browser_(-1), next_page_id_(params.next_page_id), history_list_offset_(-1), history_list_length_(0), @@ -3671,39 +3669,6 @@ return true; } -void RenderViewImpl::InstrumentWillBeginFrame(int frame_id) { - if (!webview()) - return; - if (!webview()->devToolsAgent()) - return; - webview()->devToolsAgent()->didBeginFrame(frame_id); -} - -void RenderViewImpl::InstrumentDidBeginFrame() { - if (!webview()) - return; - if (!webview()->devToolsAgent()) - return; - // TODO(jamesr/caseq): Decide if this needs to be renamed. - webview()->devToolsAgent()->didComposite(); -} - -void RenderViewImpl::InstrumentDidCancelFrame() { - if (!webview()) - return; - if (!webview()->devToolsAgent()) - return; - webview()->devToolsAgent()->didCancelFrame(); -} - -void RenderViewImpl::InstrumentWillComposite() { - if (!webview()) - return; - if (!webview()->devToolsAgent()) - return; - webview()->devToolsAgent()->willComposite(); -} - void RenderViewImpl::DidCompletePageScaleAnimation() { FocusChangeComplete(); }
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index db5540b..e6f99ae 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -501,10 +501,6 @@ void GetCompositionRange(gfx::Range* range) override; bool CanComposeInline() override; void DidCommitCompositorFrame() override; - void InstrumentWillBeginFrame(int frame_id) override; - void InstrumentDidBeginFrame() override; - void InstrumentDidCancelFrame() override; - void InstrumentWillComposite() override; void DidCompletePageScaleAnimation() override; protected: @@ -856,13 +852,6 @@ // See documentation in RenderView. int32 page_id_; - // Indicates the ID of the last page that we sent a FrameNavigate to the - // browser for. This is used to determine if the most recent transition - // generated a history entry (less than page_id_), or not (equal to or - // greater than). Note that this will be greater than page_id_ if the user - // goes back. - int32 last_page_id_sent_to_browser_; - // The next available page ID to use for this RenderView. These IDs are // specific to a given RenderView and the frames within it. int32 next_page_id_;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 0712b77..a149616 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -255,11 +255,6 @@ // Returns whether we currently should handle an IME event. bool ShouldHandleImeEvent(); - virtual void InstrumentWillBeginFrame(int frame_id) {} - virtual void InstrumentDidBeginFrame() {} - virtual void InstrumentDidCancelFrame() {} - virtual void InstrumentWillComposite() {} - // Called by the compositor when page scale animation completed. virtual void DidCompletePageScaleAnimation() {}
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 2894dc6..d0c1d88 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -14,6 +14,7 @@ #include "base/numerics/safe_conversions.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "cc/blink/context_provider_web_context.h" #include "content/child/database_util.h" #include "content/child/file_info_util.h" #include "content/child/fileapi/webfilesystem_impl.h" @@ -79,7 +80,6 @@ #include "third_party/WebKit/public/platform/WebVector.h" #include "ui/gfx/color_profile.h" #include "url/gurl.h" -#include "webkit/common/gpu/context_provider_web_context.h" #if defined(OS_ANDROID) #include "content/renderer/android/synchronous_compositor_factory.h" @@ -245,10 +245,10 @@ } // ChildThread may not exist in some tests. - if (ChildThread::current()) { - sync_message_filter_ = ChildThread::current()->sync_message_filter(); - thread_safe_sender_ = ChildThread::current()->thread_safe_sender(); - quota_message_filter_ = ChildThread::current()->quota_message_filter(); + if (ChildThreadImpl::current()) { + sync_message_filter_ = ChildThreadImpl::current()->sync_message_filter(); + thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender(); + quota_message_filter_ = ChildThreadImpl::current()->quota_message_filter(); blob_registry_.reset(new WebBlobRegistryImpl(thread_safe_sender_.get())); web_idb_factory_.reset(new WebIDBFactoryImpl(thread_safe_sender_.get())); web_database_observer_impl_.reset( @@ -1009,7 +1009,7 @@ blink::WebGraphicsContext3DProvider* RendererBlinkPlatformImpl::createSharedOffscreenGraphicsContext3DProvider() { - scoped_refptr<webkit::gpu::ContextProviderWebContext> provider = + scoped_refptr<cc_blink::ContextProviderWebContext> provider = RenderThreadImpl::current()->SharedMainThreadContextProvider(); if (!provider.get()) return NULL;
diff --git a/content/renderer/renderer_clipboard_delegate.cc b/content/renderer/renderer_clipboard_delegate.cc index b8d0b0c..0ed03f6 100644 --- a/content/renderer/renderer_clipboard_delegate.cc +++ b/content/renderer/renderer_clipboard_delegate.cc
@@ -143,7 +143,7 @@ // Allocate a shared memory buffer to hold the bitmap bits. uint32 buf_size = checked_buf_size.ValueOrDie(); - shared_buf = ChildThread::current()->AllocateSharedMemory(buf_size); + shared_buf = ChildThreadImpl::current()->AllocateSharedMemory(buf_size); if (!shared_buf) return false; if (!shared_buf->Map(buf_size))
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.cc b/content/renderer/scheduler/renderer_scheduler_impl.cc index 7f006144..fbd8cbe6 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl.cc +++ b/content/renderer/scheduler/renderer_scheduler_impl.cc
@@ -45,6 +45,8 @@ CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false); + // TODO(skyostil): Increase this to 4 (crbug.com/444764). + task_queue_manager_->SetWorkBatchSize(1); for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) { task_queue_manager_->SetQueueName( @@ -255,8 +257,15 @@ renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); } +void RendererSchedulerImpl::SetTimeSourceForTesting( + scoped_refptr<cc::TestNowSource> time_source) { + main_thread_checker_.CalledOnValidThread(); + time_source_ = time_source; + task_queue_manager_->SetTimeSourceForTesting(time_source); +} + base::TimeTicks RendererSchedulerImpl::Now() const { - return gfx::FrameTime::Now(); + return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now(); } RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
diff --git a/content/renderer/scheduler/renderer_scheduler_impl.h b/content/renderer/scheduler/renderer_scheduler_impl.h index ccf5881c..9b4fdcf 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl.h +++ b/content/renderer/scheduler/renderer_scheduler_impl.h
@@ -8,6 +8,7 @@ #include "base/atomicops.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" +#include "cc/test/test_now_source.h" #include "content/renderer/scheduler/cancelable_closure_holder.h" #include "content/renderer/scheduler/renderer_scheduler.h" #include "content/renderer/scheduler/single_thread_idle_task_runner.h" @@ -42,9 +43,7 @@ bool ShouldYieldForHighPriorityWork() override; void Shutdown() override; - protected: - // Virtual for testing. - virtual base::TimeTicks Now() const; + void SetTimeSourceForTesting(scoped_refptr<cc::TestNowSource> time_source); private: friend class RendererSchedulerImplTest; @@ -116,6 +115,8 @@ void StartIdlePeriod(); void EndIdlePeriod(); + base::TimeTicks Now() const; + base::ThreadChecker main_thread_checker_; scoped_ptr<RendererTaskQueueSelector> renderer_task_queue_selector_; scoped_ptr<TaskQueueManager> task_queue_manager_; @@ -139,6 +140,8 @@ base::TimeTicks last_input_time_; PollableNeedsUpdateFlag policy_may_need_update_; + scoped_refptr<cc::TestNowSource> time_source_; + base::WeakPtr<RendererSchedulerImpl> weak_renderer_scheduler_ptr_; base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_;
diff --git a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc index 36c85d3..ee16d04 100644 --- a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc +++ b/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
@@ -12,31 +12,18 @@ namespace content { -class RendererSchedulerImplForTest : public RendererSchedulerImpl { - public: - RendererSchedulerImplForTest( - scoped_refptr<cc::OrderedSimpleTaskRunner> task_runner, - scoped_refptr<cc::TestNowSource> clock) - : RendererSchedulerImpl(task_runner), clock_(clock) {} - ~RendererSchedulerImplForTest() override {} - - protected: - base::TimeTicks Now() const override { return clock_->Now(); } - - private: - scoped_refptr<cc::TestNowSource> clock_; -}; - class RendererSchedulerImplTest : public testing::Test { public: RendererSchedulerImplTest() : clock_(cc::TestNowSource::Create(5000)), mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), - scheduler_(new RendererSchedulerImplForTest(mock_task_runner_, clock_)), + scheduler_(new RendererSchedulerImpl(mock_task_runner_)), default_task_runner_(scheduler_->DefaultTaskRunner()), compositor_task_runner_(scheduler_->CompositorTaskRunner()), loading_task_runner_(scheduler_->LoadingTaskRunner()), - idle_task_runner_(scheduler_->IdleTaskRunner()) {} + idle_task_runner_(scheduler_->IdleTaskRunner()) { + scheduler_->SetTimeSourceForTesting(clock_); + } ~RendererSchedulerImplTest() override {} void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); }
diff --git a/content/renderer/scheduler/task_queue_manager.cc b/content/renderer/scheduler/task_queue_manager.cc index 07d5e66..083c773 100644 --- a/content/renderer/scheduler/task_queue_manager.cc +++ b/content/renderer/scheduler/task_queue_manager.cc
@@ -4,13 +4,18 @@ #include "content/renderer/scheduler/task_queue_manager.h" +#include <queue> + #include "base/bind.h" -#include "base/debug/trace_event.h" -#include "base/debug/trace_event_argument.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" +#include "cc/test/test_now_source.h" #include "content/renderer/scheduler/task_queue_selector.h" +namespace { +const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max(); +} + namespace content { namespace internal { @@ -42,7 +47,7 @@ void SetAutoPump(bool auto_pump); void PumpQueue(); - bool UpdateWorkQueue(); + bool UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task); base::PendingTask TakeTaskFromWorkQueue(); void WillDeleteTaskQueueManager(); @@ -76,6 +81,9 @@ base::TaskQueue incoming_queue_; bool auto_pump_; const char* name_; + std::priority_queue<base::TimeTicks, + std::vector<base::TimeTicks>, + std::greater<base::TimeTicks>> delayed_task_run_times_; base::TaskQueue work_queue_; @@ -115,6 +123,8 @@ task_queue_manager_->DidQueueTask(&pending_task); if (delay > base::TimeDelta()) { + pending_task.delayed_run_time = task_queue_manager_->Now() + delay; + delayed_task_run_times_.push(pending_task.delayed_run_time); return task_queue_manager_->PostDelayedTask( from_here, Bind(&TaskQueue::EnqueueTask, this, pending_task), delay); } @@ -132,12 +142,16 @@ } } -bool TaskQueue::UpdateWorkQueue() { +bool TaskQueue::UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task) { if (!work_queue_.empty()) return true; { base::AutoLock lock(lock_); + if (!delayed_task_run_times_.empty()) { + *next_pending_delayed_task = + std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); + } if (!auto_pump_ || incoming_queue_.empty()) return false; work_queue_.Swap(&incoming_queue_); @@ -172,6 +186,17 @@ if (auto_pump_ && incoming_queue_.empty()) task_queue_manager_->MaybePostDoWorkOnMainRunner(); incoming_queue_.push(pending_task); + + if (!pending_task.delayed_run_time.is_null()) { + // Update the time of the next pending delayed task. + while (!delayed_task_run_times_.empty() && + delayed_task_run_times_.top() <= pending_task.delayed_run_time) { + delayed_task_run_times_.pop(); + } + // Clear the delayed run time because we've already applied the delay + // before getting here. + incoming_queue_.back().delayed_run_time = base::TimeTicks(); + } } void TaskQueue::SetAutoPump(bool auto_pump) { @@ -247,6 +272,8 @@ : main_task_runner_(main_task_runner), selector_(selector), pending_dowork_count_(0), + work_batch_size_(1), + time_source_(nullptr), weak_factory_(this) { DCHECK(main_task_runner->RunsTasksOnCurrentThread()); TRACE_EVENT_OBJECT_CREATED_WITH_ID( @@ -301,14 +328,21 @@ queue->PumpQueue(); } -bool TaskQueueManager::UpdateWorkQueues() { +bool TaskQueueManager::UpdateWorkQueues( + base::TimeTicks* next_pending_delayed_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. main_thread_checker_.CalledOnValidThread(); bool has_work = false; - for (auto& queue : queues_) - has_work |= queue->UpdateWorkQueue(); + for (auto& queue : queues_) { + has_work |= queue->UpdateWorkQueue(next_pending_delayed_task); + if (!queue->work_queue().empty()) { + // Currently we should not be getting tasks with delayed run times in any + // of the work queues. + DCHECK(queue->work_queue().front().delayed_run_time.is_null()); + } + } return has_work; } @@ -334,14 +368,26 @@ DCHECK_GE(pending_dowork_count_, 0); } main_thread_checker_.CalledOnValidThread(); - if (!UpdateWorkQueues()) - return; - size_t queue_index; - if (!SelectWorkQueueToService(&queue_index)) - return; - MaybePostDoWorkOnMainRunner(); - ProcessTaskFromWorkQueue(queue_index); + base::TimeTicks next_pending_delayed_task( + base::TimeTicks::FromInternalValue(kMaxTimeTicks)); + for (int i = 0; i < work_batch_size_; i++) { + if (!UpdateWorkQueues(&next_pending_delayed_task)) + return; + + // Interrupt the work batch if we should run the next delayed task. + if (i > 0 && next_pending_delayed_task.ToInternalValue() != kMaxTimeTicks && + Now() >= next_pending_delayed_task) + return; + + size_t queue_index; + if (!SelectWorkQueueToService(&queue_index)) + return; + // Note that this function won't post another call to DoWork if one is + // already pending, so it is safe to call it in a loop. + MaybePostDoWorkOnMainRunner(); + ProcessTaskFromWorkQueue(queue_index); + } } bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { @@ -390,6 +436,22 @@ queue->set_name(name); } +void TaskQueueManager::SetWorkBatchSize(int work_batch_size) { + main_thread_checker_.CalledOnValidThread(); + DCHECK_GE(work_batch_size, 1); + work_batch_size_ = work_batch_size; +} + +void TaskQueueManager::SetTimeSourceForTesting( + scoped_refptr<cc::TestNowSource> time_source) { + main_thread_checker_.CalledOnValidThread(); + time_source_ = time_source; +} + +base::TimeTicks TaskQueueManager::Now() const { + return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now(); +} + scoped_refptr<base::debug::ConvertableToTraceFormat> TaskQueueManager::AsValueWithSelectorResult(bool should_run, size_t selected_queue) const {
diff --git a/content/renderer/scheduler/task_queue_manager.h b/content/renderer/scheduler/task_queue_manager.h index 100c6d570..a0a1a44 100644 --- a/content/renderer/scheduler/task_queue_manager.h +++ b/content/renderer/scheduler/task_queue_manager.h
@@ -22,6 +22,10 @@ } } +namespace cc { +class TestNowSource; +} + namespace content { namespace internal { class TaskQueue; @@ -80,6 +84,14 @@ // to a static string. void SetQueueName(size_t queue_index, const char* name); + // Set the number of tasks executed in a single invocation of the task queue + // manager. Increasing the batch size can reduce the overhead of yielding + // back to the main message loop -- at the cost of potentially delaying other + // tasks posted to the main loop. The batch size is 1 by default. + void SetWorkBatchSize(int work_batch_size); + + void SetTimeSourceForTesting(scoped_refptr<cc::TestNowSource> time_source); + private: friend class internal::TaskQueue; @@ -97,7 +109,9 @@ // Reloads any empty work queues which have automatic pumping enabled. // Returns true if any work queue has tasks after doing this. - bool UpdateWorkQueues(); + // |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); // 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 @@ -118,6 +132,8 @@ base::TimeDelta delay); internal::TaskQueue* Queue(size_t queue_index) const; + base::TimeTicks Now() const; + scoped_refptr<base::debug::ConvertableToTraceFormat> AsValueWithSelectorResult(bool should_run, size_t selected_queue) const; @@ -135,6 +151,10 @@ // where re-entrant problems happen. int pending_dowork_count_; + int work_batch_size_; + + scoped_refptr<cc::TestNowSource> time_source_; + base::WeakPtrFactory<TaskQueueManager> weak_factory_; DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
diff --git a/content/renderer/scheduler/task_queue_manager_unittest.cc b/content/renderer/scheduler/task_queue_manager_unittest.cc index a6c1347..6d4d26b 100644 --- a/content/renderer/scheduler/task_queue_manager_unittest.cc +++ b/content/renderer/scheduler/task_queue_manager_unittest.cc
@@ -6,6 +6,7 @@ #include "base/test/test_simple_task_runner.h" #include "base/threading/thread.h" +#include "cc/test/test_now_source.h" #include "content/renderer/scheduler/task_queue_selector.h" #include "testing/gmock/include/gmock/gmock.h" @@ -256,6 +257,31 @@ EXPECT_THAT(run_order, ElementsAre(1)); } +TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotStayDelayed) { + Initialize(1u); + + std::vector<int> run_order; + scoped_refptr<base::SingleThreadTaskRunner> runner = + manager_->TaskRunnerForQueue(0); + + selector_->AppendQueueToService(0); + + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); + runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), + delay); + test_task_runner_->RunPendingTasks(); + + // Reload the work queue so we see the next pending task. It should no longer + // be marked as delayed. + manager_->PumpQueue(0); + EXPECT_TRUE(selector_->work_queues()[0]->front().delayed_run_time.is_null()); + + // Let the task run normally. + selector_->AppendQueueToService(0); + test_task_runner_->RunUntilIdle(); + EXPECT_THAT(run_order, ElementsAre(1)); +} + TEST_F(TaskQueueManagerTest, ManualPumping) { Initialize(1u); manager_->SetAutoPump(0, false); @@ -480,5 +506,81 @@ EXPECT_THAT(run_order, ElementsAre(0, 2, 1)); } +TEST_F(TaskQueueManagerTest, WorkBatching) { + Initialize(1u); + + manager_->SetWorkBatchSize(2); + + std::vector<int> run_order; + scoped_refptr<base::SingleThreadTaskRunner> runner = + manager_->TaskRunnerForQueue(0); + + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + + runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); + + // Running one task in the host message loop should cause two posted tasks to + // get executed. + EXPECT_EQ(test_task_runner_->GetPendingTasks().size(), 1u); + test_task_runner_->RunPendingTasks(); + EXPECT_THAT(run_order, ElementsAre(1, 2)); + + // The second task runs the remaining two posted tasks. + EXPECT_EQ(test_task_runner_->GetPendingTasks().size(), 1u); + test_task_runner_->RunPendingTasks(); + EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); +} + +void AdvanceNowTestTask(int value, + std::vector<int>* out_result, + scoped_refptr<cc::TestNowSource> time_source, + base::TimeDelta delta) { + TestTask(value, out_result); + time_source->AdvanceNow(delta); +} + +TEST_F(TaskQueueManagerTest, InterruptWorkBatchForDelayedTask) { + scoped_refptr<cc::TestNowSource> clock(cc::TestNowSource::Create()); + Initialize(1u); + + manager_->SetWorkBatchSize(2); + manager_->SetTimeSourceForTesting(clock); + + std::vector<int> run_order; + scoped_refptr<base::SingleThreadTaskRunner> runner = + manager_->TaskRunnerForQueue(0); + + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + selector_->AppendQueueToService(0); + + base::TimeDelta delta(base::TimeDelta::FromMilliseconds(10)); + runner->PostTask( + FROM_HERE, base::Bind(&AdvanceNowTestTask, 2, &run_order, clock, delta)); + runner->PostTask( + FROM_HERE, base::Bind(&AdvanceNowTestTask, 3, &run_order, clock, delta)); + + base::TimeDelta delay(base::TimeDelta::FromMilliseconds(5)); + runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), + delay); + + // At this point we have two posted tasks: one for DoWork and one of the + // delayed task. Only the first non-delayed task should get executed because + // the work batch is interrupted by the pending delayed task. + EXPECT_EQ(test_task_runner_->GetPendingTasks().size(), 2u); + test_task_runner_->RunPendingTasks(); + EXPECT_THAT(run_order, ElementsAre(2)); + + // Running all remaining tasks should execute both pending tasks. + test_task_runner_->RunUntilIdle(); + EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); +} + } // namespace } // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_context_client.cc b/content/renderer/service_worker/embedded_worker_context_client.cc index d04fc06a..958e8f1 100644 --- a/content/renderer/service_worker/embedded_worker_context_client.cc +++ b/content/renderer/service_worker/embedded_worker_context_client.cc
@@ -103,7 +103,7 @@ service_worker_scope_(service_worker_scope), script_url_(script_url), worker_devtools_agent_route_id_(worker_devtools_agent_route_id), - sender_(ChildThread::current()->thread_safe_sender()), + sender_(ChildThreadImpl::current()->thread_safe_sender()), main_thread_proxy_(base::MessageLoopProxy::current()), weak_factory_(this) { TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker", @@ -392,6 +392,12 @@ script_context_->SkipWaiting(callbacks); } +void EmbeddedWorkerContextClient::claim( + blink::WebServiceWorkerClientsClaimCallbacks* callbacks) { + DCHECK(script_context_); + script_context_->ClaimClients(callbacks); +} + void EmbeddedWorkerContextClient::OnMessageToWorker( int thread_id, int embedded_worker_id,
diff --git a/content/renderer/service_worker/embedded_worker_context_client.h b/content/renderer/service_worker/embedded_worker_context_client.h index 9bdbeca..9cf8595 100644 --- a/content/renderer/service_worker/embedded_worker_context_client.h +++ b/content/renderer/service_worker/embedded_worker_context_client.h
@@ -10,11 +10,6 @@ #include "base/strings/string16.h" #include "content/common/service_worker/service_worker_types.h" #include "ipc/ipc_listener.h" -#include "third_party/WebKit/public/platform/WebServiceWorkerClientFocusCallback.h" -#include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h" -#include "third_party/WebKit/public/platform/WebServiceWorkerEventResult.h" -#include "third_party/WebKit/public/platform/WebServiceWorkerSkipWaitingCallbacks.h" -#include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/web/WebServiceWorkerContextClient.h" #include "url/gurl.h" @@ -117,6 +112,7 @@ blink::WebServiceWorkerClientFocusCallback*); virtual void skipWaiting( blink::WebServiceWorkerSkipWaitingCallbacks* callbacks); + virtual void claim(blink::WebServiceWorkerClientsClaimCallbacks* callbacks); // TODO: Implement DevTools related method overrides.
diff --git a/content/renderer/service_worker/embedded_worker_context_message_filter.cc b/content/renderer/service_worker/embedded_worker_context_message_filter.cc index cbc141df..4ecaa17 100644 --- a/content/renderer/service_worker/embedded_worker_context_message_filter.cc +++ b/content/renderer/service_worker/embedded_worker_context_message_filter.cc
@@ -4,45 +4,38 @@ #include "content/renderer/service_worker/embedded_worker_context_message_filter.h" -#include "base/message_loop/message_loop_proxy.h" -#include "content/child/child_thread.h" -#include "content/child/thread_safe_sender.h" -#include "content/child/worker_thread_task_runner.h" +#include "content/child/child_thread_impl.h" #include "content/renderer/service_worker/embedded_worker_context_client.h" #include "ipc/ipc_message_macros.h" namespace content { EmbeddedWorkerContextMessageFilter::EmbeddedWorkerContextMessageFilter() - : main_thread_loop_proxy_(base::MessageLoopProxy::current()), - thread_safe_sender_(ChildThread::current()->thread_safe_sender()) {} + : WorkerThreadMessageFilter( + ChildThreadImpl::current()->thread_safe_sender()) { +} EmbeddedWorkerContextMessageFilter::~EmbeddedWorkerContextMessageFilter() {} -base::TaskRunner* -EmbeddedWorkerContextMessageFilter::OverrideTaskRunnerForMessage( - const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != EmbeddedWorkerContextMsgStart) - return NULL; - int ipc_thread_id = 0; - const bool success = PickleIterator(msg).ReadInt(&ipc_thread_id); - DCHECK(success); - if (!ipc_thread_id) - return main_thread_loop_proxy_.get(); - return new WorkerThreadTaskRunner(ipc_thread_id); +bool EmbeddedWorkerContextMessageFilter::ShouldHandleMessage( + const IPC::Message& msg) const { + return IPC_MESSAGE_CLASS(msg) == EmbeddedWorkerContextMsgStart; } -bool EmbeddedWorkerContextMessageFilter::OnMessageReceived( +void EmbeddedWorkerContextMessageFilter::OnFilteredMessageReceived( const IPC::Message& msg) { - if (IPC_MESSAGE_CLASS(msg) != EmbeddedWorkerContextMsgStart) - return false; EmbeddedWorkerContextClient* client = EmbeddedWorkerContextClient::ThreadSpecificInstance(); - if (!client) { + if (!client) LOG(ERROR) << "Stray message is sent to nonexistent worker"; - return true; - } - return client->OnMessageReceived(msg); + else + client->OnMessageReceived(msg); +} + +bool EmbeddedWorkerContextMessageFilter::GetWorkerThreadIdForMessage( + const IPC::Message& msg, + int* ipc_thread_id) { + return PickleIterator(msg).ReadInt(ipc_thread_id); } } // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_context_message_filter.h b/content/renderer/service_worker/embedded_worker_context_message_filter.h index 366c39f..cefdc58 100644 --- a/content/renderer/service_worker/embedded_worker_context_message_filter.h +++ b/content/renderer/service_worker/embedded_worker_context_message_filter.h
@@ -5,30 +5,24 @@ #ifndef CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_CONTEXT_MESSAGE_FILTER_H_ #define CONTENT_RENDERER_SERVICE_WORKER_EMBEDDED_WORKER_CONTEXT_MESSAGE_FILTER_H_ -#include "content/child/child_message_filter.h" - -namespace base { -class MessageLoopProxy; -} +#include "content/child/worker_thread_message_filter.h" namespace content { -class EmbeddedWorkerContextMessageFilter : public ChildMessageFilter { +class EmbeddedWorkerContextMessageFilter : public WorkerThreadMessageFilter { public: EmbeddedWorkerContextMessageFilter(); protected: ~EmbeddedWorkerContextMessageFilter() override; - // ChildMessageFilter implementation: - base::TaskRunner* OverrideTaskRunnerForMessage( - const IPC::Message& msg) override; - bool OnMessageReceived(const IPC::Message& msg) override; + // WorkerThreadMessageFilter: + bool ShouldHandleMessage(const IPC::Message& msg) const override; + void OnFilteredMessageReceived(const IPC::Message& msg) override; + bool GetWorkerThreadIdForMessage(const IPC::Message& msg, + int* ipc_thread_id) override; private: - scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; - scoped_refptr<ThreadSafeSender> thread_safe_sender_; - DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerContextMessageFilter); };
diff --git a/content/renderer/service_worker/embedded_worker_devtools_agent.cc b/content/renderer/service_worker/embedded_worker_devtools_agent.cc index 791a2ca..e1c640a 100644 --- a/content/renderer/service_worker/embedded_worker_devtools_agent.cc +++ b/content/renderer/service_worker/embedded_worker_devtools_agent.cc
@@ -4,7 +4,6 @@ #include "content/renderer/service_worker/embedded_worker_devtools_agent.h" -#include "content/child/child_thread.h" #include "content/common/devtools_messages.h" #include "content/renderer/render_thread_impl.h" #include "third_party/WebKit/public/platform/WebCString.h"
diff --git a/content/renderer/service_worker/service_worker_script_context.cc b/content/renderer/service_worker/service_worker_script_context.cc index 9d8acc4..f68a0053 100644 --- a/content/renderer/service_worker/service_worker_script_context.cc +++ b/content/renderer/service_worker/service_worker_script_context.cc
@@ -106,6 +106,8 @@ IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FocusClientResponse, OnFocusClientResponse) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidSkipWaiting, OnDidSkipWaiting) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidClaimClients, OnDidClaimClients) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ClaimClientsError, OnClaimClientsError) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -243,6 +245,13 @@ GetRoutingID(), request_id, client_id)); } +void ServiceWorkerScriptContext::ClaimClients( + blink::WebServiceWorkerClientsClaimCallbacks* callbacks) { + DCHECK(callbacks); + int request_id = pending_claim_clients_callbacks_.Add(callbacks); + Send(new ServiceWorkerHostMsg_ClaimClients(GetRoutingID(), request_id)); +} + void ServiceWorkerScriptContext::SkipWaiting( blink::WebServiceWorkerSkipWaitingCallbacks* callbacks) { DCHECK(callbacks); @@ -460,4 +469,35 @@ pending_skip_waiting_callbacks_.Remove(request_id); } +void ServiceWorkerScriptContext::OnDidClaimClients(int request_id) { + TRACE_EVENT0("ServiceWorker", + "ServiceWorkerScriptContext::OnDidClaimClients"); + blink::WebServiceWorkerClientsClaimCallbacks* callbacks = + pending_claim_clients_callbacks_.Lookup(request_id); + if (!callbacks) { + NOTREACHED() << "Got stray response: " << request_id; + return; + } + callbacks->onSuccess(); + pending_claim_clients_callbacks_.Remove(request_id); +} + +void ServiceWorkerScriptContext::OnClaimClientsError( + int request_id, + blink::WebServiceWorkerError::ErrorType error_type, + const base::string16& message) { + TRACE_EVENT0("ServiceWorker", + "ServiceWorkerScriptContext::OnClaimClientsError"); + blink::WebServiceWorkerClientsClaimCallbacks* callbacks = + pending_claim_clients_callbacks_.Lookup(request_id); + if (!callbacks) { + NOTREACHED() << "Got stray response: " << request_id; + return; + } + scoped_ptr<blink::WebServiceWorkerError> error( + new blink::WebServiceWorkerError(error_type, message)); + callbacks->onError(error.release()); + pending_claim_clients_callbacks_.Remove(request_id); +} + } // namespace content
diff --git a/content/renderer/service_worker/service_worker_script_context.h b/content/renderer/service_worker/service_worker_script_context.h index 5c8ff2c..3259a4f2 100644 --- a/content/renderer/service_worker/service_worker_script_context.h +++ b/content/renderer/service_worker/service_worker_script_context.h
@@ -20,7 +20,9 @@ #include "third_party/WebKit/public/platform/WebGeofencingEventType.h" #include "third_party/WebKit/public/platform/WebMessagePortChannel.h" #include "third_party/WebKit/public/platform/WebServiceWorkerClientFocusCallback.h" +#include "third_party/WebKit/public/platform/WebServiceWorkerClientsClaimCallbacks.h" #include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h" +#include "third_party/WebKit/public/platform/WebServiceWorkerError.h" #include "third_party/WebKit/public/platform/WebServiceWorkerEventResult.h" #include "third_party/WebKit/public/platform/WebServiceWorkerSkipWaitingCallbacks.h" @@ -83,6 +85,7 @@ void FocusClient(int client_id, blink::WebServiceWorkerClientFocusCallback* callback); void SkipWaiting(blink::WebServiceWorkerSkipWaitingCallbacks* callbacks); + void ClaimClients(blink::WebServiceWorkerClientsClaimCallbacks* callbacks); // Send a message to the browser. Takes ownership of |message|. void Send(IPC::Message* message); @@ -98,6 +101,8 @@ private: typedef IDMap<blink::WebServiceWorkerClientsCallbacks, IDMapOwnPointer> ClientsCallbacksMap; + typedef IDMap<blink::WebServiceWorkerClientsClaimCallbacks, IDMapOwnPointer> + ClaimClientsCallbacksMap; typedef IDMap<blink::WebServiceWorkerClientFocusCallback, IDMapOwnPointer> FocusClientCallbacksMap; typedef IDMap<blink::WebServiceWorkerSkipWaitingCallbacks, IDMapOwnPointer> @@ -130,6 +135,10 @@ int request_id, const std::vector<ServiceWorkerClientInfo>& clients); void OnFocusClientResponse(int request_id, bool result); void OnDidSkipWaiting(int request_id); + void OnDidClaimClients(int request_id); + void OnClaimClientsError(int request_id, + blink::WebServiceWorkerError::ErrorType error_type, + const base::string16& message); scoped_ptr<ServiceWorkerCacheStorageDispatcher> cache_storage_dispatcher_; @@ -153,6 +162,9 @@ // Pending callbacks for SkipWaiting(). SkipWaitingCallbacksMap pending_skip_waiting_callbacks_; + // Pending callbacks for ClaimClients(). + ClaimClientsCallbacksMap pending_claim_clients_callbacks_; + // Capture timestamps for UMA std::map<int, base::TimeTicks> activate_start_timings_; std::map<int, base::TimeTicks> fetch_start_timings_;
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc index d026cec..121831f 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -168,7 +168,7 @@ GURL(origin.toString()), origin.isUnique(), route_id_, - ChildThread::current()->thread_safe_sender()); + ChildThreadImpl::current()->thread_safe_sender()); } void EmbeddedSharedWorkerStub::sendDevToolsMessage(
diff --git a/content/renderer/shared_worker_repository.cc b/content/renderer/shared_worker_repository.cc index a883464f..46dcb915 100644 --- a/content/renderer/shared_worker_repository.cc +++ b/content/renderer/shared_worker_repository.cc
@@ -4,7 +4,7 @@ #include "content/renderer/shared_worker_repository.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/view_messages.h" #include "content/renderer/render_frame_impl.h" #include "content/renderer/websharedworker_proxy.h" @@ -39,7 +39,7 @@ if (route_id == MSG_ROUTING_NONE) return NULL; documents_with_workers_.insert(document_id); - return new WebSharedWorkerProxy(ChildThread::current()->GetRouter(), + return new WebSharedWorkerProxy(ChildThreadImpl::current()->GetRouter(), document_id, route_id, params.render_frame_route_id);
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.cc b/content/renderer/webgraphicscontext3d_provider_impl.cc index 7a31a05..855bd3d 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.cc +++ b/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -4,13 +4,14 @@ #include "content/renderer/webgraphicscontext3d_provider_impl.h" -#include "webkit/common/gpu/context_provider_web_context.h" +#include "cc/blink/context_provider_web_context.h" namespace content { WebGraphicsContext3DProviderImpl::WebGraphicsContext3DProviderImpl( - scoped_refptr<webkit::gpu::ContextProviderWebContext> provider) - : provider_(provider) {} + scoped_refptr<cc_blink::ContextProviderWebContext> provider) + : provider_(provider) { +} WebGraphicsContext3DProviderImpl::~WebGraphicsContext3DProviderImpl() {}
diff --git a/content/renderer/webgraphicscontext3d_provider_impl.h b/content/renderer/webgraphicscontext3d_provider_impl.h index 69c2e984..8225ded 100644 --- a/content/renderer/webgraphicscontext3d_provider_impl.h +++ b/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -10,11 +10,9 @@ #include "content/common/content_export.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3DProvider.h" -namespace webkit { -namespace gpu { +namespace cc_blink { class ContextProviderWebContext; -} // namespace webkit -} // namespace gpu +} namespace content { @@ -22,7 +20,7 @@ : public NON_EXPORTED_BASE(blink::WebGraphicsContext3DProvider) { public: explicit WebGraphicsContext3DProviderImpl( - scoped_refptr<webkit::gpu::ContextProviderWebContext> provider); + scoped_refptr<cc_blink::ContextProviderWebContext> provider); virtual ~WebGraphicsContext3DProviderImpl(); // WebGraphicsContext3DProvider implementation. @@ -30,7 +28,7 @@ virtual GrContext* grContext() override; private: - scoped_refptr<webkit::gpu::ContextProviderWebContext> provider_; + scoped_refptr<cc_blink::ContextProviderWebContext> provider_; }; } // namespace content
diff --git a/content/shell/browser/layout_test/layout_test_devtools_frontend.cc b/content/shell/browser/layout_test/layout_test_devtools_frontend.cc index c8941c6..a9c1af33 100644 --- a/content/shell/browser/layout_test/layout_test_devtools_frontend.cc +++ b/content/shell/browser/layout_test/layout_test_devtools_frontend.cc
@@ -33,15 +33,6 @@ return devtools_frontend; } -LayoutTestDevToolsFrontend::LayoutTestDevToolsFrontend( - Shell* frontend_shell, - DevToolsAgentHost* agent_host) - : ShellDevToolsFrontend(frontend_shell, agent_host) { -} - -LayoutTestDevToolsFrontend::~LayoutTestDevToolsFrontend() { -} - // static. GURL LayoutTestDevToolsFrontend::GetDevToolsPathAsURL( const std::string& settings, @@ -70,6 +61,27 @@ return result; } +void LayoutTestDevToolsFrontend::ReuseFrontend(WebContents* inspected_contents, + const std::string& settings, + const std::string frontend_url) { + AttachTo(inspected_contents); + frontend_shell()->LoadURL(GetDevToolsPathAsURL(settings, frontend_url)); +} + +LayoutTestDevToolsFrontend::LayoutTestDevToolsFrontend( + Shell* frontend_shell, + DevToolsAgentHost* agent_host) + : ShellDevToolsFrontend(frontend_shell, agent_host) { +} + +LayoutTestDevToolsFrontend::~LayoutTestDevToolsFrontend() { +} + +void LayoutTestDevToolsFrontend::AgentHostClosed( + DevToolsAgentHost* agent_host, bool replaced) { + // Do not close the front-end shell. +} + void LayoutTestDevToolsFrontend::RenderProcessGone( base::TerminationStatus status) { WebKitTestController::Get()->DevToolsProcessCrashed();
diff --git a/content/shell/browser/layout_test/layout_test_devtools_frontend.h b/content/shell/browser/layout_test/layout_test_devtools_frontend.h index 5106a9b..20db644 100644 --- a/content/shell/browser/layout_test/layout_test_devtools_frontend.h +++ b/content/shell/browser/layout_test/layout_test_devtools_frontend.h
@@ -24,11 +24,18 @@ static GURL GetDevToolsPathAsURL(const std::string& settings, const std::string& frontend_url); + void ReuseFrontend(WebContents* inspected_contents, + const std::string& settings, + const std::string frontend_url); + private: LayoutTestDevToolsFrontend(Shell* frontend_shell, DevToolsAgentHost* agent_host); ~LayoutTestDevToolsFrontend() override; + // content::DevToolsAgentHostClient implementation. + void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override; + // WebContentsObserver implementation. void RenderProcessGone(base::TerminationStatus status) override;
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index 5357b1f..546e5e3 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -213,10 +213,10 @@ void Shell::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { - CreateShell(new_contents, AdjustWindowSize(initial_pos.size())); + CreateShell(new_contents, AdjustWindowSize(initial_rect.size())); if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDumpRenderTree)) NotifyDoneForwarder::CreateForWebContents(new_contents); @@ -248,19 +248,14 @@ } void Shell::ShowDevTools() { - InnerShowDevTools("", ""); + InnerShowDevTools(); } void Shell::ShowDevToolsForElementAt(int x, int y) { - InnerShowDevTools("", ""); + InnerShowDevTools(); devtools_frontend_->InspectElementAt(x, y); } -void Shell::ShowDevToolsForTest(const std::string& settings, - const std::string& frontend_url) { - InnerShowDevTools(settings, frontend_url); -} - void Shell::CloseDevTools() { if (!devtools_frontend_) return; @@ -418,16 +413,9 @@ PlatformSetTitle(entry->GetTitle()); } -void Shell::InnerShowDevTools(const std::string& settings, - const std::string& frontend_url) { +void Shell::InnerShowDevTools() { if (!devtools_frontend_) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDumpRenderTree)) { - devtools_frontend_ = LayoutTestDevToolsFrontend::Show( - web_contents(), settings, frontend_url); - } else { - devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents()); - } + devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents()); devtools_observer_.reset(new DevToolsWebContentsObserver( this, devtools_frontend_->frontend_shell()->web_contents())); }
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index c9f9c9f..1245315 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -70,8 +70,6 @@ void Close(); void ShowDevTools(); void ShowDevToolsForElementAt(int x, int y); - void ShowDevToolsForTest(const std::string& settings, - const std::string& frontend_url); void CloseDevTools(); #if defined(OS_MACOSX) // Resizes the web content view to the given dimensions. @@ -117,7 +115,7 @@ void AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void LoadingStateChanged(WebContents* source, @@ -216,8 +214,7 @@ // WebContentsObserver void TitleWasSet(NavigationEntry* entry, bool explicit_set) override; - void InnerShowDevTools(const std::string& settings, - const std::string& frontend_url); + void InnerShowDevTools(); void OnDevToolsWebContentsDestroyed(); scoped_ptr<ShellJavaScriptDialogManager> dialog_manager_;
diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc index 42ffa70..a6bead6 100644 --- a/content/shell/browser/shell_devtools_frontend.cc +++ b/content/shell/browser/shell_devtools_frontend.cc
@@ -60,13 +60,21 @@ } void ShellDevToolsFrontend::InspectElementAt(int x, int y) { - agent_host_->InspectElement(x, y); + if (agent_host_) + agent_host_->InspectElement(x, y); } void ShellDevToolsFrontend::Close() { frontend_shell_->Close(); } +void ShellDevToolsFrontend::DisconnectFromTarget() { + if (!agent_host_) + return; + agent_host_->DetachClient(); + agent_host_ = NULL; +} + ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell, DevToolsAgentHost* agent_host) : WebContentsObserver(frontend_shell->web_contents()), @@ -82,17 +90,26 @@ if (!frontend_host_) { frontend_host_.reset( DevToolsFrontendHost::Create(web_contents()->GetMainFrame(), this)); - agent_host_->AttachClient(this); } } +void ShellDevToolsFrontend::DidNavigateMainFrame( + const LoadCommittedDetails& details, + const FrameNavigateParams& params) { + if (agent_host_) + agent_host_->AttachClient(this); +} + void ShellDevToolsFrontend::WebContentsDestroyed() { - agent_host_->DetachClient(); + if (agent_host_) + agent_host_->DetachClient(); delete this; } void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontend( const std::string& message) { + if (!agent_host_) + return; std::string method; int id = 0; base::ListValue* params = NULL; @@ -127,7 +144,8 @@ void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend( const std::string& message) { - agent_host_->DispatchProtocolMessage(message); + if (agent_host_) + agent_host_->DispatchProtocolMessage(message); } void ShellDevToolsFrontend::DispatchProtocolMessage( @@ -151,6 +169,11 @@ } } +void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) { + DisconnectFromTarget(); + agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents); +} + void ShellDevToolsFrontend::AgentHostClosed( DevToolsAgentHost* agent_host, bool replaced) { frontend_shell_->Close();
diff --git a/content/shell/browser/shell_devtools_frontend.h b/content/shell/browser/shell_devtools_frontend.h index 038b88b..adfe90e7 100644 --- a/content/shell/browser/shell_devtools_frontend.h +++ b/content/shell/browser/shell_devtools_frontend.h
@@ -30,15 +30,26 @@ void InspectElementAt(int x, int y); void Close(); + void DisconnectFromTarget(); + Shell* frontend_shell() const { return frontend_shell_; } protected: ShellDevToolsFrontend(Shell* frontend_shell, DevToolsAgentHost* agent_host); ~ShellDevToolsFrontend() override; + // content::DevToolsAgentHostClient implementation. + void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override; + void DispatchProtocolMessage(DevToolsAgentHost* agent_host, + const std::string& message) override; + void AttachTo(WebContents* inspected_contents); + private: // WebContentsObserver overrides void RenderViewCreated(RenderViewHost* render_view_host) override; + void DidNavigateMainFrame( + const LoadCommittedDetails& details, + const FrameNavigateParams& params) override; void WebContentsDestroyed() override; // content::DevToolsFrontendHost::Delegate implementation. @@ -46,11 +57,6 @@ void HandleMessageFromDevToolsFrontendToBackend( const std::string& message) override; - // content::DevToolsAgentHostClient implementation. - void DispatchProtocolMessage(DevToolsAgentHost* agent_host, - const std::string& message) override; - void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override; - Shell* frontend_shell_; scoped_refptr<DevToolsAgentHost> agent_host_; scoped_ptr<DevToolsFrontendHost> frontend_host_;
diff --git a/content/shell/browser/webkit_test_controller.cc b/content/shell/browser/webkit_test_controller.cc index 3712d32..a4dc574 100644 --- a/content/shell/browser/webkit_test_controller.cc +++ b/content/shell/browser/webkit_test_controller.cc
@@ -205,7 +205,8 @@ is_leak_detection_enabled_( base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableLeakDetection)), - crash_when_leak_found_(false) { + crash_when_leak_found_(false), + devtools_frontend_(NULL) { CHECK(!instance_); instance_ = this; @@ -433,7 +434,9 @@ void WebKitTestController::DevToolsProcessCrashed() { DCHECK(CalledOnValidThread()); printer_->AddErrorMessage("#CRASHED - devtools"); - DiscardMainWindow(); + if (devtools_frontend_) + devtools_frontend_->Close(); + devtools_frontend_ = NULL; } void WebKitTestController::WebContentsDestroyed() { @@ -586,11 +589,20 @@ void WebKitTestController::OnShowDevTools(const std::string& settings, const std::string& frontend_url) { - main_window_->ShowDevToolsForTest(settings, frontend_url); + if (!devtools_frontend_) { + devtools_frontend_ = LayoutTestDevToolsFrontend::Show( + main_window_->web_contents(), settings, frontend_url); + } else { + devtools_frontend_->ReuseFrontend( + main_window_->web_contents(), settings, frontend_url); + } + devtools_frontend_->Activate(); + devtools_frontend_->Focus(); } void WebKitTestController::OnCloseDevTools() { - main_window_->CloseDevTools(); + if (devtools_frontend_) + devtools_frontend_->DisconnectFromTarget(); } void WebKitTestController::OnGoToOffset(int offset) { @@ -653,8 +665,10 @@ void WebKitTestController::OnCloseRemainingWindows() { DevToolsAgentHost::DetachAllClients(); std::vector<Shell*> open_windows(Shell::windows()); + Shell* devtools_shell = devtools_frontend_ ? + devtools_frontend_->frontend_shell() : NULL; for (size_t i = 0; i < open_windows.size(); ++i) { - if (open_windows[i] != main_window_) + if (open_windows[i] != main_window_ && open_windows[i] != devtools_shell) open_windows[i]->Close(); } base::MessageLoop::current()->RunUntilIdle();
diff --git a/content/shell/browser/webkit_test_controller.h b/content/shell/browser/webkit_test_controller.h index 0bbe9957..1680c67 100644 --- a/content/shell/browser/webkit_test_controller.h +++ b/content/shell/browser/webkit_test_controller.h
@@ -28,6 +28,7 @@ namespace content { +class LayoutTestDevToolsFrontend; class Shell; #if defined(OS_ANDROID) @@ -214,6 +215,8 @@ const bool is_leak_detection_enabled_; bool crash_when_leak_found_; + LayoutTestDevToolsFrontend* devtools_frontend_; + #if defined(OS_ANDROID) // Because of the nested message pump implementation, Android needs to allow // waiting on the UI thread while layout tests are being ran.
diff --git a/content/test/data/accessibility/aria/aria-document-expected-android.txt b/content/test/data/accessibility/aria/aria-document-expected-android.txt index 4783e71..cb393f69 100644 --- a/content/test/data/accessibility/aria/aria-document-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-document-expected-android.txt
@@ -1,2 +1,2 @@ android.webkit.WebView focusable focused scrollable - android.view.View clickable scrollable name='aria role document' + android.view.View clickable name='aria role document'
diff --git a/content/test/data/accessibility/aria/aria-grid-expected-android.txt b/content/test/data/accessibility/aria/aria-grid-expected-android.txt new file mode 100644 index 0000000..52b4bb3 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-grid-expected-android.txt
@@ -0,0 +1,11 @@ +android.webkit.WebView focusable focused scrollable + android.widget.GridView collection row_count=2 column_count=2 + android.view.View + android.view.View clickable collection_item heading name='Browser' row_span=1 column_span=1 + android.view.View clickable collection_item heading name='Rendering Engine' row_span=1 column_index=1 column_span=1 + android.view.View + android.view.View clickable collection_item name='Chrome' row_index=1 row_span=1 column_span=1 + android.view.View clickable collection_item name='Blink' row_index=1 row_span=1 column_index=1 column_span=1 + android.view.View + android.view.View + android.view.View
diff --git a/content/test/data/accessibility/aria/aria-grid-expected-mac.txt b/content/test/data/accessibility/aria/aria-grid-expected-mac.txt new file mode 100644 index 0000000..60efdf7 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-grid-expected-mac.txt
@@ -0,0 +1,15 @@ +AXWebArea AXRoleDescription='HTML content' + AXTable AXRoleDescription='table' + AXRow AXRoleDescription='row' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Browser' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Rendering Engine' + AXRow AXRoleDescription='row' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Chrome' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Blink' + AXColumn AXRoleDescription='column' + AXColumn AXRoleDescription='column' + AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/aria/aria-grid-expected-win.txt b/content/test/data/accessibility/aria/aria-grid-expected-win.txt new file mode 100644 index 0000000..c6e0ec4 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-grid-expected-win.txt
@@ -0,0 +1,15 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE + ROLE_SYSTEM_TABLE MULTISELECTABLE EXTSELECTABLE xml-roles:grid + ROLE_SYSTEM_ROW xml-roles:row + ROLE_SYSTEM_COLUMNHEADER xml-roles:columnheader + ROLE_SYSTEM_STATICTEXT name='Browser' + ROLE_SYSTEM_COLUMNHEADER xml-roles:columnheader + ROLE_SYSTEM_STATICTEXT name='Rendering Engine' + ROLE_SYSTEM_ROW xml-roles:row + ROLE_SYSTEM_CELL xml-roles:gridcell + ROLE_SYSTEM_STATICTEXT name='Chrome' + ROLE_SYSTEM_CELL xml-roles:gridcell + ROLE_SYSTEM_STATICTEXT name='Blink' + ROLE_SYSTEM_COLUMN + ROLE_SYSTEM_COLUMN + IA2_ROLE_SECTION
diff --git a/content/test/data/accessibility/aria/aria-grid.html b/content/test/data/accessibility/aria/aria-grid.html new file mode 100644 index 0000000..519ee29 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-grid.html
@@ -0,0 +1,20 @@ +<!-- +@MAC-ALLOW:AXRole* +@WIN-ALLOW:*SELECTABLE +@WIN-ALLOW:xml-roles* +--> +<!DOCTYPE html> +<html> +<body> +<div role="grid"> + <div role="row"> + <span role="columnheader">Browser</span> + <span role="columnheader">Rendering Engine</span> + </div> + <div role="row"> + <span role="gridcell">Chrome</span> + <span role="gridcell">Blink</span> + </div> +</div> +</body> +</html>
diff --git a/content/test/data/accessibility/aria/aria-gridcell-expected-android.txt b/content/test/data/accessibility/aria/aria-gridcell-expected-android.txt new file mode 100644 index 0000000..52b4bb3 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-gridcell-expected-android.txt
@@ -0,0 +1,11 @@ +android.webkit.WebView focusable focused scrollable + android.widget.GridView collection row_count=2 column_count=2 + android.view.View + android.view.View clickable collection_item heading name='Browser' row_span=1 column_span=1 + android.view.View clickable collection_item heading name='Rendering Engine' row_span=1 column_index=1 column_span=1 + android.view.View + android.view.View clickable collection_item name='Chrome' row_index=1 row_span=1 column_span=1 + android.view.View clickable collection_item name='Blink' row_index=1 row_span=1 column_index=1 column_span=1 + android.view.View + android.view.View + android.view.View
diff --git a/content/test/data/accessibility/aria/aria-gridcell-expected-mac.txt b/content/test/data/accessibility/aria/aria-gridcell-expected-mac.txt new file mode 100644 index 0000000..60efdf7 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-gridcell-expected-mac.txt
@@ -0,0 +1,15 @@ +AXWebArea AXRoleDescription='HTML content' + AXTable AXRoleDescription='table' + AXRow AXRoleDescription='row' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Browser' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Rendering Engine' + AXRow AXRoleDescription='row' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Chrome' + AXCell AXRoleDescription='cell' + AXStaticText AXRoleDescription='text' AXValue='Blink' + AXColumn AXRoleDescription='column' + AXColumn AXRoleDescription='column' + AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/aria/aria-gridcell-expected-win.txt b/content/test/data/accessibility/aria/aria-gridcell-expected-win.txt new file mode 100644 index 0000000..c6e0ec4 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-gridcell-expected-win.txt
@@ -0,0 +1,15 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE + ROLE_SYSTEM_TABLE MULTISELECTABLE EXTSELECTABLE xml-roles:grid + ROLE_SYSTEM_ROW xml-roles:row + ROLE_SYSTEM_COLUMNHEADER xml-roles:columnheader + ROLE_SYSTEM_STATICTEXT name='Browser' + ROLE_SYSTEM_COLUMNHEADER xml-roles:columnheader + ROLE_SYSTEM_STATICTEXT name='Rendering Engine' + ROLE_SYSTEM_ROW xml-roles:row + ROLE_SYSTEM_CELL xml-roles:gridcell + ROLE_SYSTEM_STATICTEXT name='Chrome' + ROLE_SYSTEM_CELL xml-roles:gridcell + ROLE_SYSTEM_STATICTEXT name='Blink' + ROLE_SYSTEM_COLUMN + ROLE_SYSTEM_COLUMN + IA2_ROLE_SECTION
diff --git a/content/test/data/accessibility/aria/aria-gridcell.html b/content/test/data/accessibility/aria/aria-gridcell.html new file mode 100644 index 0000000..519ee29 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-gridcell.html
@@ -0,0 +1,20 @@ +<!-- +@MAC-ALLOW:AXRole* +@WIN-ALLOW:*SELECTABLE +@WIN-ALLOW:xml-roles* +--> +<!DOCTYPE html> +<html> +<body> +<div role="grid"> + <div role="row"> + <span role="columnheader">Browser</span> + <span role="columnheader">Rendering Engine</span> + </div> + <div role="row"> + <span role="gridcell">Chrome</span> + <span role="gridcell">Blink</span> + </div> +</div> +</body> +</html>
diff --git a/content/test/data/accessibility/aria/aria-group-expected-android.txt b/content/test/data/accessibility/aria/aria-group-expected-android.txt new file mode 100644 index 0000000..fe79120 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-group-expected-android.txt
@@ -0,0 +1,4 @@ +android.webkit.WebView focusable focused scrollable + android.view.View + android.view.View clickable link name='Group Link1' + android.view.View clickable link name='Group Link2'
diff --git a/content/test/data/accessibility/aria/aria-group-expected-mac.txt b/content/test/data/accessibility/aria/aria-group-expected-mac.txt new file mode 100644 index 0000000..8004720 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-group-expected-mac.txt
@@ -0,0 +1,6 @@ +AXWebArea AXRoleDescription='HTML content' + AXGroup AXRoleDescription='group' + AXLink AXRoleDescription='link' AXTitle='Group Link1' + AXStaticText AXRoleDescription='text' AXValue='Group Link1' + AXLink AXRoleDescription='link' AXTitle='Group Link2' + AXStaticText AXRoleDescription='text' AXValue='Group Link2'
diff --git a/content/test/data/accessibility/aria/aria-group-expected-win.txt b/content/test/data/accessibility/aria/aria-group-expected-win.txt new file mode 100644 index 0000000..89c9c48 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-group-expected-win.txt
@@ -0,0 +1,6 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE + ROLE_SYSTEM_GROUPING xml-roles:group + ROLE_SYSTEM_LINK name='Group Link1' xml-roles:link + ROLE_SYSTEM_STATICTEXT name='Group Link1' + ROLE_SYSTEM_LINK name='Group Link2' xml-roles:link + ROLE_SYSTEM_STATICTEXT name='Group Link2'
diff --git a/content/test/data/accessibility/aria/aria-group.html b/content/test/data/accessibility/aria/aria-group.html new file mode 100644 index 0000000..f70f4a5 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-group.html
@@ -0,0 +1,13 @@ +<!-- +@MAC-ALLOW:AXRole* +@WIN-ALLOW:xml-roles* +--> +<!DOCTYPE html> +<html> +<body> + <div role="group"> + <div role="link">Group Link1</div> + <div role="link">Group Link2</div> + </div> +</body> +</html>
diff --git a/content/test/data/accessibility/aria/aria-selected-expected-android.txt b/content/test/data/accessibility/aria/aria-selected-expected-android.txt index 9ee8f685..2b31af84 100644 --- a/content/test/data/accessibility/aria/aria-selected-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-selected-expected-android.txt
@@ -1,4 +1,4 @@ android.webkit.WebView focusable focused scrollable android.widget.ListView collection item_count=2 row_count=2 - android.view.View clickable collection_item focusable selected name='4' - android.view.View clickable collection_item focusable selected name='5' item_index=1 row_index=1 + android.view.View clickable collection_item focusable selected name='1' + android.view.View clickable collection_item focusable name='2' item_index=1 row_index=1
diff --git a/content/test/data/accessibility/aria/aria-selected-expected-mac.txt b/content/test/data/accessibility/aria/aria-selected-expected-mac.txt index 5f50267e..3ffd2f2 100644 --- a/content/test/data/accessibility/aria/aria-selected-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-selected-expected-mac.txt
@@ -1,4 +1,5 @@ +#<skip -- Expose AXSelected on selected child> AXWebArea - AXList AXSelectedChildren=["AXStaticText 4","AXStaticText 5"] - AXStaticText AXTitle='Item 4' - AXStaticText AXTitle='Item 5' + AXList AXSelectedChildren=["AXStaticText 1"] + AXStaticText AXTitle='Item 1' + AXStaticText AXTitle='Item 2'
diff --git a/content/test/data/accessibility/aria/aria-selected-expected-win.txt b/content/test/data/accessibility/aria/aria-selected-expected-win.txt index 1dee781..af8726e5 100644 --- a/content/test/data/accessibility/aria/aria-selected-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-selected-expected-win.txt
@@ -1,4 +1,4 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ROLE_SYSTEM_LIST - ROLE_SYSTEM_LISTITEM name='4' SELECTED FOCUSABLE - ROLE_SYSTEM_LISTITEM name='5' SELECTED FOCUSABLE + ROLE_SYSTEM_LISTITEM name='1' SELECTED FOCUSABLE + ROLE_SYSTEM_LISTITEM name='2' FOCUSABLE
diff --git a/content/test/data/accessibility/aria/aria-selected.html b/content/test/data/accessibility/aria/aria-selected.html index 7934adb..521998d 100644 --- a/content/test/data/accessibility/aria/aria-selected.html +++ b/content/test/data/accessibility/aria/aria-selected.html
@@ -6,8 +6,8 @@ <html> <body> <div role="listbox"> - <div tabIndex="-1" aria-selected="true" aria-label="4" role="option">Item 4</div> - <div tabIndex="-1" aria-selected="true" aria-label="5" role="option">Item 5</div> + <div tabIndex="-1" aria-selected="true" aria-label="1" role="option">Item 1</div> + <div tabIndex="-1" aria-selected="false" aria-label="2" role="option">Item 2</div> </div> </body> </html>
diff --git a/content/test/data/accessibility/aria/aria-tabpanel-expected-android.txt b/content/test/data/accessibility/aria/aria-tabpanel-expected-android.txt new file mode 100644 index 0000000..299eb2ab --- /dev/null +++ b/content/test/data/accessibility/aria/aria-tabpanel-expected-android.txt
@@ -0,0 +1,4 @@ +android.webkit.WebView focusable focused scrollable + android.view.View + android.view.View clickable name='Item' + android.view.View clickable name='Prices'
diff --git a/content/test/data/accessibility/aria/aria-tabpanel-expected-mac.txt b/content/test/data/accessibility/aria/aria-tabpanel-expected-mac.txt new file mode 100644 index 0000000..d32959c --- /dev/null +++ b/content/test/data/accessibility/aria/aria-tabpanel-expected-mac.txt
@@ -0,0 +1,4 @@ +AXWebArea AXRoleDescription='HTML content' + AXGroup AXSubrole=AXTabPanel AXRoleDescription='tabpanel' + AXRadioButton AXRoleDescription='tab' AXTitle='Item' AXValue='0' + AXRadioButton AXRoleDescription='tab' AXTitle='Prices' AXValue='0'
diff --git a/content/test/data/accessibility/aria/aria-tabpanel-expected-win.txt b/content/test/data/accessibility/aria/aria-tabpanel-expected-win.txt new file mode 100644 index 0000000..567c1908 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-tabpanel-expected-win.txt
@@ -0,0 +1,4 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE + ROLE_SYSTEM_PROPERTYPAGE xml-roles:tabpanel + ROLE_SYSTEM_PAGETAB name='Item' xml-roles:tab + ROLE_SYSTEM_PAGETAB name='Prices' xml-roles:tab
diff --git a/content/test/data/accessibility/aria/aria-tabpanel.html b/content/test/data/accessibility/aria/aria-tabpanel.html new file mode 100644 index 0000000..e1dfa941 --- /dev/null +++ b/content/test/data/accessibility/aria/aria-tabpanel.html
@@ -0,0 +1,18 @@ +<!-- +@MAC-ALLOW:AXRole* +@MAC-ALLOW:AXSubrole* +@WIN-ALLOW:xml-roles* +--> +<!DOCTYPE html> +<html> +<body> +<div role="tabpanel"> + <div role="tab"> + <h3>Item</h3> + </div> + <div role="tab"> + <h3>Prices</h3> + </div> +</div> +</body> +</html>
diff --git a/content/test/data/accessibility/html/b-expected-android.txt b/content/test/data/accessibility/html/b-expected-android.txt new file mode 100644 index 0000000..9f21fc6 --- /dev/null +++ b/content/test/data/accessibility/html/b-expected-android.txt
@@ -0,0 +1 @@ +#<skip -- Doesn't have an accessible>
diff --git a/content/test/data/accessibility/html/b-expected-mac.txt b/content/test/data/accessibility/html/b-expected-mac.txt new file mode 100644 index 0000000..9f21fc6 --- /dev/null +++ b/content/test/data/accessibility/html/b-expected-mac.txt
@@ -0,0 +1 @@ +#<skip -- Doesn't have an accessible>
diff --git a/content/test/data/accessibility/html/b-expected-win.txt b/content/test/data/accessibility/html/b-expected-win.txt new file mode 100644 index 0000000..9f21fc6 --- /dev/null +++ b/content/test/data/accessibility/html/b-expected-win.txt
@@ -0,0 +1 @@ +#<skip -- Doesn't have an accessible>
diff --git a/content/test/data/accessibility/html/b.html b/content/test/data/accessibility/html/b.html new file mode 100644 index 0000000..76b9c8b --- /dev/null +++ b/content/test/data/accessibility/html/b.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<body> + + <b>This is bold text</b> + +</body> +</html>
diff --git a/content/test/data/accessibility/html/base-expected-android.txt b/content/test/data/accessibility/html/base-expected-android.txt new file mode 100644 index 0000000..4ce8140 --- /dev/null +++ b/content/test/data/accessibility/html/base-expected-android.txt
@@ -0,0 +1 @@ +#<skip - Not Mapped>
diff --git a/content/test/data/accessibility/html/base-expected-mac.txt b/content/test/data/accessibility/html/base-expected-mac.txt new file mode 100644 index 0000000..4ce8140 --- /dev/null +++ b/content/test/data/accessibility/html/base-expected-mac.txt
@@ -0,0 +1 @@ +#<skip - Not Mapped>
diff --git a/content/test/data/accessibility/html/base-expected-win.txt b/content/test/data/accessibility/html/base-expected-win.txt new file mode 100644 index 0000000..4ce8140 --- /dev/null +++ b/content/test/data/accessibility/html/base-expected-win.txt
@@ -0,0 +1 @@ +#<skip - Not Mapped>
diff --git a/content/test/data/accessibility/html/base.html b/content/test/data/accessibility/html/base.html new file mode 100644 index 0000000..d53d9cb --- /dev/null +++ b/content/test/data/accessibility/html/base.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<head> +<base href="http://www.chromium.org/" target="_blank"> +</head> +<body> +</body> +</html>
diff --git a/content/test/data/accessibility/html/input-hidden-expected-android.txt b/content/test/data/accessibility/html/input-hidden-expected-android.txt new file mode 100644 index 0000000..d7df040 --- /dev/null +++ b/content/test/data/accessibility/html/input-hidden-expected-android.txt
@@ -0,0 +1 @@ +#<skip - Do not expose this object>
diff --git a/content/test/data/accessibility/html/input-hidden-expected-mac.txt b/content/test/data/accessibility/html/input-hidden-expected-mac.txt new file mode 100644 index 0000000..d7df040 --- /dev/null +++ b/content/test/data/accessibility/html/input-hidden-expected-mac.txt
@@ -0,0 +1 @@ +#<skip - Do not expose this object>
diff --git a/content/test/data/accessibility/html/input-hidden-expected-win.txt b/content/test/data/accessibility/html/input-hidden-expected-win.txt new file mode 100644 index 0000000..d7df040 --- /dev/null +++ b/content/test/data/accessibility/html/input-hidden-expected-win.txt
@@ -0,0 +1 @@ +#<skip - Do not expose this object>
diff --git a/content/test/data/accessibility/html/input-hidden.html b/content/test/data/accessibility/html/input-hidden.html new file mode 100644 index 0000000..eec394ce --- /dev/null +++ b/content/test/data/accessibility/html/input-hidden.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> + <body> + <input type="hidden"> + </body> +</html>
diff --git a/content/test/data/accessibility/html/input-password-expected-android.txt b/content/test/data/accessibility/html/input-password-expected-android.txt new file mode 100644 index 0000000..1825c38 --- /dev/null +++ b/content/test/data/accessibility/html/input-password-expected-android.txt
@@ -0,0 +1,3 @@ +android.webkit.WebView focusable focused scrollable + android.view.View + android.widget.EditText clickable editable_text focusable password input_type=225
diff --git a/content/test/data/accessibility/html/input-password-expected-mac.txt b/content/test/data/accessibility/html/input-password-expected-mac.txt new file mode 100644 index 0000000..4a6d2d4 --- /dev/null +++ b/content/test/data/accessibility/html/input-password-expected-mac.txt
@@ -0,0 +1,3 @@ +AXWebArea AXRoleDescription='HTML content' + AXGroup AXRoleDescription='group' + AXTextField AXSubrole=AXSecureTextField AXRoleDescription='text field'
diff --git a/content/test/data/accessibility/html/input-password-expected-win.txt b/content/test/data/accessibility/html/input-password-expected-win.txt new file mode 100644 index 0000000..f98f047 --- /dev/null +++ b/content/test/data/accessibility/html/input-password-expected-win.txt
@@ -0,0 +1,3 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE + IA2_ROLE_SECTION + ROLE_SYSTEM_TEXT FOCUSABLE PROTECTED IA2_STATE_EDITABLE IA2_STATE_SELECTABLE_TEXT IA2_STATE_SINGLE_LINE text-input-type:password
diff --git a/content/test/data/accessibility/html/input-password.html b/content/test/data/accessibility/html/input-password.html new file mode 100644 index 0000000..e6d23eb --- /dev/null +++ b/content/test/data/accessibility/html/input-password.html
@@ -0,0 +1,13 @@ +<!-- +@MAC-ALLOW:AXRole* +@MAC-ALLOW:AXSubrole* +@WIN-ALLOW:PROTECTED +@WIN-ALLOW:IA2_STATE* +@WIN-ALLOW:text-input-type* +--> +<!DOCTYPE html> +<html> +<body> + <input type="password"> +</body> +</html>
diff --git a/content/test/data/accessibility/html/small-expected-android.txt b/content/test/data/accessibility/html/small-expected-android.txt new file mode 100644 index 0000000..5d7ed88 --- /dev/null +++ b/content/test/data/accessibility/html/small-expected-android.txt
@@ -0,0 +1 @@ +#<skip - Doesn't have an accessible>
diff --git a/content/test/data/accessibility/html/small-expected-mac.txt b/content/test/data/accessibility/html/small-expected-mac.txt new file mode 100644 index 0000000..312c6da --- /dev/null +++ b/content/test/data/accessibility/html/small-expected-mac.txt
@@ -0,0 +1,4 @@ +AXWebArea + AXGroup + AXStaticText AXValue='Chromium' + AXStaticText AXValue='open source project'
diff --git a/content/test/data/accessibility/html/small-expected-win.txt b/content/test/data/accessibility/html/small-expected-win.txt new file mode 100644 index 0000000..5d7ed88 --- /dev/null +++ b/content/test/data/accessibility/html/small-expected-win.txt
@@ -0,0 +1 @@ +#<skip - Doesn't have an accessible>
diff --git a/content/test/data/accessibility/html/small.html b/content/test/data/accessibility/html/small.html new file mode 100644 index 0000000..acdcb89 --- /dev/null +++ b/content/test/data/accessibility/html/small.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<body> + + <p>Chromium<small>open source project</small></p> + +</body> +</html>
diff --git a/content/test/data/frame_tree/page_with_one_frame.html b/content/test/data/frame_tree/page_with_one_frame.html index ecf5140..0f121d9 100644 --- a/content/test/data/frame_tree/page_with_one_frame.html +++ b/content/test/data/frame_tree/page_with_one_frame.html
@@ -2,7 +2,7 @@ <html> <head></head> <body> - This page has one iframe without src. - <iframe></iframe> + This page has one cross-site iframe. + <iframe src="/cross-site/baz.com/title1.html"></iframe> </body> </html>
diff --git a/content/test/data/frame_tree/page_with_two_frames.html b/content/test/data/frame_tree/page_with_two_frames.html index a4bd921..3313ce4 100644 --- a/content/test/data/frame_tree/page_with_two_frames.html +++ b/content/test/data/frame_tree/page_with_two_frames.html
@@ -2,9 +2,9 @@ <head> </head> <body> - This page has two iframes without src. - <iframe></iframe> - <iframe></iframe> + This page has two iframes: one is cross-site, the other is same-site. + <iframe src="/cross-site/bar.com/title1.html"></iframe> + <iframe src="../title1.html"></iframe> </body> </html>
diff --git a/content/test/data/frame_tree/page_with_two_frames_nested.html b/content/test/data/frame_tree/page_with_two_frames_nested.html new file mode 100644 index 0000000..5b556c5 --- /dev/null +++ b/content/test/data/frame_tree/page_with_two_frames_nested.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<head> +</head> +<body> + This page has two iframes: one is cross-site, the other is same-site. + The cross-site frame also loads a cross-site page in it. + <iframe src="/cross-site/bar.com/frame_tree/page_with_one_frame.html"></iframe> + <iframe src="../title1.html"></iframe> +</body> +</html> +
diff --git a/content/test/data/media/OWNERS b/content/test/data/media/OWNERS index fe807ce8..61ca624 100644 --- a/content/test/data/media/OWNERS +++ b/content/test/data/media/OWNERS
@@ -5,5 +5,4 @@ sandersd@chromium.org scherkus@chromium.org tommi@chromium.org -vrk@chromium.org xhwang@chromium.org
diff --git a/content/test/data/service_worker/fetch_event_blob.js b/content/test/data/service_worker/fetch_event_blob.js new file mode 100644 index 0000000..8f15e1f --- /dev/null +++ b/content/test/data/service_worker/fetch_event_blob.js
@@ -0,0 +1,9 @@ +// 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.onfetch = function(event) { + var blob = new Blob(['<title>Title</title>']); + var response = new Response(blob); + event.respondWith(response); +};
diff --git a/content/test/data/service_worker/fetch_event_blob.js.mock-http-headers b/content/test/data/service_worker/fetch_event_blob.js.mock-http-headers new file mode 100644 index 0000000..c9a3625 --- /dev/null +++ b/content/test/data/service_worker/fetch_event_blob.js.mock-http-headers
@@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +Content-Type: text/javascript
diff --git a/content/test/fake_compositor_dependencies.cc b/content/test/fake_compositor_dependencies.cc index 1f090a0..e33b7ef1 100644 --- a/content/test/fake_compositor_dependencies.cc +++ b/content/test/fake_compositor_dependencies.cc
@@ -26,6 +26,10 @@ return false; } +bool FakeCompositorDependencies::IsThreadedGpuRasterizationEnabled() { + return false; +} + int FakeCompositorDependencies::GetGpuRasterizationMSAASampleCount() { return 0; }
diff --git a/content/test/fake_compositor_dependencies.h b/content/test/fake_compositor_dependencies.h index d31c307..8e23ba4 100644 --- a/content/test/fake_compositor_dependencies.h +++ b/content/test/fake_compositor_dependencies.h
@@ -20,6 +20,7 @@ bool IsImplSidePaintingEnabled() override; bool IsGpuRasterizationForced() override; bool IsGpuRasterizationEnabled() override; + bool IsThreadedGpuRasterizationEnabled() override; int GetGpuRasterizationMSAASampleCount() override; bool IsLcdTextEnabled() override; bool IsDistanceFieldTextEnabled() override;
diff --git a/content/test/gpu/gpu_tests/trace_test.py b/content/test/gpu/gpu_tests/trace_test.py index fb4de0f..df9e5b7 100644 --- a/content/test/gpu/gpu_tests/trace_test.py +++ b/content/test/gpu/gpu_tests/trace_test.py
@@ -8,11 +8,12 @@ from telemetry.page import page_test from telemetry.core.platform import tracing_category_filter from telemetry.core.platform import tracing_options -from telemetry.timeline import model +from telemetry.timeline import model as model_module TOPLEVEL_GL_CATEGORY = 'gpu_toplevel' -TOPLEVEL_CATEGORIES = ['disabled-by-default-gpu.device', - 'disabled-by-default-gpu.service'] +TOPLEVEL_SERVICE_CATEGORY = 'disabled-by-default-gpu.service' +TOPLEVEL_DEVICE_CATEGORY = 'disabled-by-default-gpu.device' +TOPLEVEL_CATEGORIES = [TOPLEVEL_SERVICE_CATEGORY, TOPLEVEL_DEVICE_CATEGORY] test_harness_script = r""" var domAutomationController = {}; @@ -28,19 +29,24 @@ window.domAutomationController = domAutomationController; """ -class _TraceValidator(page_test.PageTest): + +class _TraceValidatorBase(page_test.PageTest): + def GetCategoryName(self): + raise NotImplementedError("GetCategoryName() Not implemented!") + def ValidateAndMeasurePage(self, page, tab, results): timeline_data = tab.browser.platform.tracing_controller.Stop() - timeline_model = model.TimelineModel(timeline_data) + timeline_model = model_module.TimelineModel(timeline_data) - categories_set = set(TOPLEVEL_CATEGORIES) - for event in timeline_model.IterAllEvents(): - if event.args.get('gl_category', None) == TOPLEVEL_GL_CATEGORY: - categories_set.discard(event.category) - if not categories_set: + category_name = self.GetCategoryName() + event_iter = timeline_model.IterAllEvents( + event_type_predicate=model_module.IsSliceOrAsyncSlice) + for event in event_iter: + if (event.args.get('gl_category', None) == TOPLEVEL_GL_CATEGORY and + event.category == category_name): break else: - raise page_test.Failure(self._FormatException(sorted(categories_set))) + raise page_test.Failure(self._FormatException(category_name)) def CustomizeBrowserOptions(self, options): options.AppendExtraBrowserArgs('--enable-logging') @@ -52,11 +58,32 @@ options.enable_chrome_trace = True tab.browser.platform.tracing_controller.Start(options, cat_filter, 60) - def _FormatException(self, categories): - return 'Trace markers for GPU categories were not found: %s' % categories + def _FormatException(self, category): + return 'Trace markers for GPU category was not found: %s' % category -class TraceTest(benchmark.Benchmark): - """Tests GPU traces""" + +class _TraceValidator(_TraceValidatorBase): + def GetCategoryName(self): + return TOPLEVEL_SERVICE_CATEGORY + + +class _DeviceTraceValidator(_TraceValidatorBase): + def GetCategoryName(self): + return TOPLEVEL_DEVICE_CATEGORY + + +class _TraceTestBase(benchmark.Benchmark): + """Base class for the trace tests.""" + def CreatePageSet(self, options): + # Utilize pixel tests page set as a set of simple pages to load. + page_set = page_sets.PixelTestsPageSet() + for page in page_set.pages: + page.script_to_evaluate_on_commit = test_harness_script + return page_set + + +class TraceTest(_TraceTestBase): + """Tests GPU traces are plumbed through properly.""" test = _TraceValidator @classmethod @@ -66,9 +93,14 @@ def CreateExpectations(self): return trace_test_expectations.TraceTestExpectations() - def CreatePageSet(self, options): - # Utilize pixel tests page set as a set of simple pages to load. - page_set = page_sets.PixelTestsPageSet() - for page in page_set.pages: - page.script_to_evaluate_on_commit = test_harness_script - return page_set + +class DeviceTraceTest(_TraceTestBase): + """Tests GPU Device traces show up on devices that support it.""" + test = _DeviceTraceValidator + + @classmethod + def Name(cls): + return 'device_trace_test' + + def CreateExpectations(self): + return trace_test_expectations.DeviceTraceTestExpectations()
diff --git a/content/test/gpu/gpu_tests/trace_test_expectations.py b/content/test/gpu/gpu_tests/trace_test_expectations.py index 24f0cc75..f6c35b65 100644 --- a/content/test/gpu/gpu_tests/trace_test_expectations.py +++ b/content/test/gpu/gpu_tests/trace_test_expectations.py
@@ -12,6 +12,9 @@ # self.Fail('Pixel.Canvas2DRedBox', # ['mac', 'amd', ('nvidia', 0x1234)], bug=123) - # Temporarily skip everything while bot recipes are being put in place. - self.Skip('*') pass + +class DeviceTraceTestExpectations(GpuTestExpectations): + def SetExpectations(self): + # Device traces are not supported on all machines. + self.Skip('*')
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index 67693578..f71fc76 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -87,7 +87,7 @@ // RenderWidgetHostViewBase implementation. void InitAsPopup(RenderWidgetHostView* parent_host_view, - const gfx::Rect& pos) override {} + const gfx::Rect& bounds) override {} void InitAsFullscreen(RenderWidgetHostView* reference_host_view) override {} void MovePluginWindows(const std::vector<WebPluginGeometry>& moves) override { }
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index 3009f5d..be20dcc 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -256,12 +256,12 @@ void TestWebContents::ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { } void TestWebContents::ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) { + const gfx::Rect& initial_rect) { } void TestWebContents::ShowCreatedFullscreenWidget(int route_id) {
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index 8e3c2b5..92f8db3 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h
@@ -112,9 +112,9 @@ void CreateNewFullscreenWidget(int render_process_id, int route_id) override; void ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; - void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos) override; + void ShowCreatedWidget(int route_id, const gfx::Rect& initial_rect) override; void ShowCreatedFullscreenWidget(int route_id) override; RenderViewHostDelegateView* delegate_view_override_;
diff --git a/content/test/web_layer_tree_view_impl_for_testing.h b/content/test/web_layer_tree_view_impl_for_testing.h index 9dabf4c3..904c985 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.h +++ b/content/test/web_layer_tree_view_impl_for_testing.h
@@ -65,7 +65,7 @@ virtual void clearSelection() override; // cc::LayerTreeHostClient implementation. - void WillBeginMainFrame(int frame_id) override {} + void WillBeginMainFrame() override {} void DidBeginMainFrame() override {} void BeginMainFrame(const cc::BeginFrameArgs& args) override {} void Layout() override;
diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc index 32f9814..26af2b1 100644 --- a/content/utility/utility_thread_impl.cc +++ b/content/utility/utility_thread_impl.cc
@@ -40,7 +40,7 @@ } UtilityThreadImpl::UtilityThreadImpl(const std::string& channel_name) - : ChildThread(Options(channel_name, false)), + : ChildThreadImpl(Options(channel_name, false)), single_process_(true) { Init(); } @@ -49,16 +49,12 @@ } void UtilityThreadImpl::Shutdown() { - ChildThread::Shutdown(); + ChildThreadImpl::Shutdown(); if (!single_process_) blink::shutdown(); } -bool UtilityThreadImpl::Send(IPC::Message* msg) { - return ChildThread::Send(msg); -} - void UtilityThreadImpl::ReleaseProcessIfNeeded() { if (batch_mode_) return; @@ -74,18 +70,6 @@ } } -#if defined(OS_WIN) - -void UtilityThreadImpl::PreCacheFont(const LOGFONT& log_font) { - Send(new ChildProcessHostMsg_PreCacheFont(log_font)); -} - -void UtilityThreadImpl::ReleaseCachedFonts() { - Send(new ChildProcessHostMsg_ReleaseCachedFonts()); -} - -#endif // OS_WIN - void UtilityThreadImpl::Init() { batch_mode_ = false; ChildProcess::current()->AddRefProcess();
diff --git a/content/utility/utility_thread_impl.h b/content/utility/utility_thread_impl.h index 5b186fc..043aea9 100644 --- a/content/utility/utility_thread_impl.h +++ b/content/utility/utility_thread_impl.h
@@ -10,7 +10,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "content/child/child_thread.h" +#include "content/child/child_thread_impl.h" #include "content/common/content_export.h" #include "content/public/utility/utility_thread.h" @@ -21,9 +21,15 @@ namespace content { class BlinkPlatformImpl; +#if defined(COMPILER_MSVC) +// See explanation for other RenderViewHostImpl which is the same issue. +#pragma warning(push) +#pragma warning(disable: 4250) +#endif + // This class represents the background thread where the utility task runs. class UtilityThreadImpl : public UtilityThread, - public ChildThread { + public ChildThreadImpl { public: UtilityThreadImpl(); // Constructor that's used when running in single process mode. @@ -31,12 +37,7 @@ ~UtilityThreadImpl() override; void Shutdown() override; - bool Send(IPC::Message* msg) override; void ReleaseProcessIfNeeded() override; -#if defined(OS_WIN) - virtual void PreCacheFont(const LOGFONT& log_font) override; - virtual void ReleaseCachedFonts() override; -#endif private: void Init(); @@ -63,6 +64,10 @@ DISALLOW_COPY_AND_ASSIGN(UtilityThreadImpl); }; +#if defined(COMPILER_MSVC) +#pragma warning(pop) +#endif + } // namespace content #endif // CONTENT_UTILITY_UTILITY_THREAD_IMPL_H_
diff --git a/crypto/openssl_util.cc b/crypto/openssl_util.cc index f41b55a..8ea12323 100644 --- a/crypto/openssl_util.cc +++ b/crypto/openssl_util.cc
@@ -48,6 +48,18 @@ private: friend struct DefaultSingletonTraits<OpenSSLInitSingleton>; OpenSSLInitSingleton() { +#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL) + const bool has_neon = + (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; + // CRYPTO_set_NEON_capable is called before |SSL_library_init| because this + // stops BoringSSL from probing for NEON support via SIGILL in the case + // that getauxval isn't present. + CRYPTO_set_NEON_capable(has_neon); + // See https://code.google.com/p/chromium/issues/detail?id=341598 + base::CPU cpu; + CRYPTO_set_NEON_functional(!cpu.has_broken_neon()); +#endif + SSL_load_error_strings(); SSL_library_init(); int num_locks = CRYPTO_num_locks(); @@ -56,16 +68,6 @@ locks_.push_back(new base::Lock()); CRYPTO_set_locking_callback(LockingCallback); CRYPTO_THREADID_set_callback(CurrentThreadId); - -#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL) - const bool has_neon = - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; - if (has_neon) - CRYPTO_set_NEON_capable(1); - // See https://code.google.com/p/chromium/issues/detail?id=341598 - base::CPU cpu; - CRYPTO_set_NEON_functional(!cpu.has_broken_neon()); -#endif } ~OpenSSLInitSingleton() {
diff --git a/device/serial/data_receiver.cc b/device/serial/data_receiver.cc index 2f238e3..fdc23caa 100644 --- a/device/serial/data_receiver.cc +++ b/device/serial/data_receiver.cc
@@ -107,19 +107,16 @@ bool dispatched; }; -DataReceiver::DataReceiver( - mojo::InterfacePtr<serial::DataSource> source, - mojo::InterfaceRequest<serial::DataSourceClient> client, - uint32_t buffer_size, - int32_t fatal_error_value) +DataReceiver::DataReceiver(mojo::InterfacePtr<serial::DataSource> source, + uint32_t buffer_size, + int32_t fatal_error_value) : source_(source.Pass()), - client_(this, client.Pass()), fatal_error_value_(fatal_error_value), shut_down_(false), weak_factory_(this) { + source_.set_client(this); source_.set_error_handler(this); source_->Init(buffer_size); - client_.set_error_handler(this); } bool DataReceiver::Receive(const ReceiveDataCallback& callback,
diff --git a/device/serial/data_receiver.h b/device/serial/data_receiver.h index 95be6402..942bb5c 100644 --- a/device/serial/data_receiver.h +++ b/device/serial/data_receiver.h
@@ -29,7 +29,6 @@ // size of |buffer_size|, with connection errors reported as // |fatal_error_value|. DataReceiver(mojo::InterfacePtr<serial::DataSource> source, - mojo::InterfaceRequest<serial::DataSourceClient> client, uint32_t buffer_size, int32_t fatal_error_value); @@ -73,7 +72,6 @@ // The control connection to the data source. mojo::InterfacePtr<serial::DataSource> source_; - mojo::Binding<serial::DataSourceClient> client_; // The error value to report in the event of a fatal error. const int32_t fatal_error_value_;
diff --git a/device/serial/data_sender.cc b/device/serial/data_sender.cc index bea8eb8..18b1a43e 100644 --- a/device/serial/data_sender.cc +++ b/device/serial/data_sender.cc
@@ -62,17 +62,15 @@ }; DataSender::DataSender(mojo::InterfacePtr<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSinkClient> client, uint32_t buffer_size, int32_t fatal_error_value) : sink_(sink.Pass()), - client_(this, client.Pass()), fatal_error_value_(fatal_error_value), available_buffer_capacity_(buffer_size), shut_down_(false) { sink_.set_error_handler(this); + sink_.set_client(this); sink_->Init(buffer_size); - client_.set_error_handler(this); } DataSender::~DataSender() {
diff --git a/device/serial/data_sender.h b/device/serial/data_sender.h index 0b5ea09a..f4db8bc 100644 --- a/device/serial/data_sender.h +++ b/device/serial/data_sender.h
@@ -27,7 +27,6 @@ // Constructs a DataSender to send data to |sink|, using a buffer size of // |buffer_size|, with connection errors reported as |fatal_error_value|. DataSender(mojo::InterfacePtr<serial::DataSink> sink, - mojo::InterfaceRequest<serial::DataSinkClient> client, uint32_t buffer_size, int32_t fatal_error_value); @@ -74,7 +73,6 @@ // The control connection to the data sink. mojo::InterfacePtr<serial::DataSink> sink_; - mojo::Binding<serial::DataSinkClient> client_; // The error value to report in the event of a fatal error. const int32_t fatal_error_value_;
diff --git a/device/serial/data_sink_receiver.cc b/device/serial/data_sink_receiver.cc index 18dd5690..170f8b2c 100644 --- a/device/serial/data_sink_receiver.cc +++ b/device/serial/data_sink_receiver.cc
@@ -61,15 +61,10 @@ uint32_t offset_; }; -DataSinkReceiver::DataSinkReceiver( - mojo::InterfaceRequest<serial::DataSink> request, - mojo::InterfacePtr<serial::DataSinkClient> client, - const ReadyCallback& ready_callback, - const CancelCallback& cancel_callback, - const ErrorCallback& error_callback) - : binding_(this, request.Pass()), - client_(client.Pass()), - ready_callback_(ready_callback), +DataSinkReceiver::DataSinkReceiver(const ReadyCallback& ready_callback, + const CancelCallback& cancel_callback, + const ErrorCallback& error_callback) + : ready_callback_(ready_callback), cancel_callback_(cancel_callback), error_callback_(error_callback), flush_pending_(false), @@ -78,8 +73,6 @@ available_buffer_capacity_(0), shut_down_(false), weak_factory_(this) { - binding_.set_error_handler(this); - client_.set_error_handler(this); } void DataSinkReceiver::ShutDown() { @@ -158,7 +151,7 @@ void DataSinkReceiver::Done(uint32_t bytes_read) { if (!DoneInternal(bytes_read)) return; - client_->ReportBytesSent(bytes_read); + client()->ReportBytesSent(bytes_read); if (!pending_data_buffers_.empty()) { base::MessageLoop::current()->PostTask( FROM_HERE, @@ -191,8 +184,9 @@ // When we encounter an error, we must discard the data from any send buffers // transmitted by the DataSinkClient before it receives this error. flush_pending_ = true; - client_->ReportBytesSentAndError( - bytes_read, error, + client()->ReportBytesSentAndError( + bytes_read, + error, base::Bind(&DataSinkReceiver::DoFlush, weak_factory_.GetWeakPtr())); }
diff --git a/device/serial/data_sink_receiver.h b/device/serial/data_sink_receiver.h index 0709f90..2126cdd9 100644 --- a/device/serial/data_sink_receiver.h +++ b/device/serial/data_sink_receiver.h
@@ -18,8 +18,7 @@ namespace device { class DataSinkReceiver : public base::RefCounted<DataSinkReceiver>, - public serial::DataSink, - public mojo::ErrorHandler { + public mojo::InterfaceImpl<serial::DataSink> { public: typedef base::Callback<void(scoped_ptr<ReadOnlyBuffer>)> ReadyCallback; typedef base::Callback<void(int32_t error)> CancelCallback; @@ -32,9 +31,7 @@ // and the DataSinkReceiver will act as if ShutDown() had been called. If // |cancel_callback| is valid, it will be called when the DataSinkClient // requests cancellation of the in-progress read. - DataSinkReceiver(mojo::InterfaceRequest<serial::DataSink> request, - mojo::InterfacePtr<serial::DataSinkClient> client, - const ReadyCallback& ready_callback, + DataSinkReceiver(const ReadyCallback& ready_callback, const CancelCallback& cancel_callback, const ErrorCallback& error_callback); @@ -78,9 +75,6 @@ // Reports a fatal error to the client and shuts down. void DispatchFatalError(); - mojo::Binding<serial::DataSink> binding_; - mojo::InterfacePtr<serial::DataSinkClient> client_; - // The callback to call when there is data ready to read. const ReadyCallback ready_callback_;
diff --git a/device/serial/data_sink_unittest.cc b/device/serial/data_sink_unittest.cc index 4108692b..24843623 100644 --- a/device/serial/data_sink_unittest.cc +++ b/device/serial/data_sink_unittest.cc
@@ -38,16 +38,13 @@ void SetUp() override { message_loop_.reset(new base::MessageLoop); mojo::InterfacePtr<serial::DataSink> sink_handle; - mojo::InterfacePtr<serial::DataSinkClient> sink_client_handle; - mojo::InterfaceRequest<serial::DataSinkClient> sink_client_request = - mojo::GetProxy(&sink_client_handle); - sink_receiver_ = new DataSinkReceiver( - mojo::GetProxy(&sink_handle), sink_client_handle.Pass(), - base::Bind(&DataSinkTest::OnDataToRead, base::Unretained(this)), - base::Bind(&DataSinkTest::OnCancel, base::Unretained(this)), - base::Bind(&DataSinkTest::OnError, base::Unretained(this))); - sender_.reset(new DataSender(sink_handle.Pass(), sink_client_request.Pass(), - kBufferSize, kFatalError)); + sink_receiver_ = mojo::WeakBindToProxy( + new DataSinkReceiver( + base::Bind(&DataSinkTest::OnDataToRead, base::Unretained(this)), + base::Bind(&DataSinkTest::OnCancel, base::Unretained(this)), + base::Bind(&DataSinkTest::OnError, base::Unretained(this))), + &sink_handle); + sender_.reset(new DataSender(sink_handle.Pass(), kBufferSize, kFatalError)); } void TearDown() override {
diff --git a/device/serial/data_source_sender.cc b/device/serial/data_source_sender.cc index 97029dda..f9cc4f1 100644 --- a/device/serial/data_source_sender.cc +++ b/device/serial/data_source_sender.cc
@@ -71,22 +71,15 @@ uint32_t buffer_size_; }; -DataSourceSender::DataSourceSender( - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> client, - const ReadyCallback& ready_callback, - const ErrorCallback& error_callback) - : binding_(this, source.Pass()), - client_(client.Pass()), - ready_callback_(ready_callback), +DataSourceSender::DataSourceSender(const ReadyCallback& ready_callback, + const ErrorCallback& error_callback) + : ready_callback_(ready_callback), error_callback_(error_callback), available_buffer_capacity_(0), paused_(false), shut_down_(false), weak_factory_(this) { DCHECK(!ready_callback.is_null() && !error_callback.is_null()); - binding_.set_error_handler(this); - client_.set_error_handler(this); } void DataSourceSender::ShutDown() { @@ -145,7 +138,7 @@ int32_t error) { DoneInternal(data); if (!shut_down_) - client_->OnError(error); + client()->OnError(error); paused_ = true; // We don't call GetMoreData here so we don't send any additional data until // Resume() is called. @@ -160,7 +153,7 @@ if (!data.empty()) { mojo::Array<uint8_t> data_to_send(data.size()); std::copy(data.begin(), data.end(), &data_to_send[0]); - client_->OnData(data_to_send.Pass()); + client()->OnData(data_to_send.Pass()); } pending_send_.reset(); }
diff --git a/device/serial/data_source_sender.h b/device/serial/data_source_sender.h index a8c2c63..3a90240f 100644 --- a/device/serial/data_source_sender.h +++ b/device/serial/data_source_sender.h
@@ -19,8 +19,7 @@ // A DataSourceSender is an interface between a source of data and a // DataSourceClient. class DataSourceSender : public base::RefCounted<DataSourceSender>, - public serial::DataSource, - public mojo::ErrorHandler { + public mojo::InterfaceImpl<serial::DataSource> { public: typedef base::Callback<void(scoped_ptr<WritableBuffer>)> ReadyCallback; typedef base::Callback<void()> ErrorCallback; @@ -30,9 +29,7 @@ // |ready_callback| will not be called again until the previous WritableBuffer // is destroyed. If a connection error occurs, |error_callback| will be // called and the DataSourceSender will act as if ShutDown() had been called. - DataSourceSender(mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> client, - const ReadyCallback& ready_callback, + DataSourceSender(const ReadyCallback& ready_callback, const ErrorCallback& error_callback); // Shuts down this DataSourceSender. After shut down, |ready_callback| and @@ -68,9 +65,6 @@ // Reports a fatal error to the client and shuts down. void DispatchFatalError(); - mojo::Binding<serial::DataSource> binding_; - mojo::InterfacePtr<serial::DataSourceClient> client_; - // The callback to call when the client is ready for more data. ReadyCallback ready_callback_;
diff --git a/device/serial/data_source_unittest.cc b/device/serial/data_source_unittest.cc index b725f35..71dfa81 100644 --- a/device/serial/data_source_unittest.cc +++ b/device/serial/data_source_unittest.cc
@@ -31,18 +31,12 @@ void SetUp() override { message_loop_.reset(new base::MessageLoop); mojo::InterfacePtr<serial::DataSource> source_sender_handle; - mojo::InterfacePtr<serial::DataSourceClient> source_sender_client_handle; - mojo::InterfaceRequest<serial::DataSourceClient> - source_sender_client_request = - mojo::GetProxy(&source_sender_client_handle); - source_sender_ = new DataSourceSender( - mojo::GetProxy(&source_sender_handle), - source_sender_client_handle.Pass(), - base::Bind(&DataSourceTest::CanWriteData, base::Unretained(this)), - base::Bind(&DataSourceTest::OnError, base::Unretained(this))); - receiver_ = - new DataReceiver(source_sender_handle.Pass(), - source_sender_client_request.Pass(), 100, kFatalError); + source_sender_ = mojo::WeakBindToProxy( + new DataSourceSender( + base::Bind(&DataSourceTest::CanWriteData, base::Unretained(this)), + base::Bind(&DataSourceTest::OnError, base::Unretained(this))), + &source_sender_handle); + receiver_ = new DataReceiver(source_sender_handle.Pass(), 100, kFatalError); } void TearDown() override {
diff --git a/device/serial/data_stream.mojom b/device/serial/data_stream.mojom index e5478067..a288eb2 100644 --- a/device/serial/data_stream.mojom +++ b/device/serial/data_stream.mojom
@@ -4,6 +4,7 @@ module device.serial; +[Client=DataSourceClient] interface DataSource { // Initializes this DataSource with the amount of data its client will // buffer. @@ -26,6 +27,7 @@ OnData(array<uint8> data); }; +[Client=DataSinkClient] interface DataSink { // Initializes this DataSink with the amount of data it is expected to // buffer.
diff --git a/device/serial/data_stream_serialization.mojom b/device/serial/data_stream_serialization.mojom index de580d3..259be28 100644 --- a/device/serial/data_stream_serialization.mojom +++ b/device/serial/data_stream_serialization.mojom
@@ -10,8 +10,6 @@ struct SerializedDataSender { // The control channel to the DataSink to which this DataSender sends data. DataSink sink; - // DataSinkClient& - handle<message_pipe> sink_client; // The error to report for sends in progress when a fatal error occurs. int32 fatal_error_value; @@ -34,8 +32,6 @@ // The control channel to the DataSource from which this DataReceiver receives // data. DataSource source; - // DataSourceClient& - handle<message_pipe> source_client; // The error to report for a receive in progress when a fatal error occurs. int32 fatal_error_value;
diff --git a/device/serial/serial.mojom b/device/serial/serial.mojom index 877d1e2..6714a946 100644 --- a/device/serial/serial.mojom +++ b/device/serial/serial.mojom
@@ -94,9 +94,7 @@ ConnectionOptions? options, Connection& connection, DataSink& sink, - DataSinkClient sink_client, - DataSource& source, - DataSourceClient source_client); + DataSource& source); }; interface Connection {
diff --git a/device/serial/serial_connection.cc b/device/serial/serial_connection.cc index 04cccbe5..0d3e4171 100644 --- a/device/serial/serial_connection.cc +++ b/device/serial/serial_connection.cc
@@ -15,19 +15,20 @@ SerialConnection::SerialConnection( scoped_refptr<SerialIoHandler> io_handler, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client) + mojo::InterfaceRequest<serial::DataSource> source) : io_handler_(io_handler) { - receiver_ = new DataSinkReceiver( - sink.Pass(), sink_client.Pass(), - base::Bind(&SerialConnection::OnSendPipeReady, base::Unretained(this)), - base::Bind(&SerialConnection::OnSendCancelled, base::Unretained(this)), - base::Bind(base::DoNothing)); - sender_ = new DataSourceSender( - source.Pass(), source_client.Pass(), - base::Bind(&SerialConnection::OnReceivePipeReady, base::Unretained(this)), - base::Bind(base::DoNothing)); + receiver_ = mojo::WeakBindToRequest( + new DataSinkReceiver(base::Bind(&SerialConnection::OnSendPipeReady, + base::Unretained(this)), + base::Bind(&SerialConnection::OnSendCancelled, + base::Unretained(this)), + base::Bind(base::DoNothing)), + &sink); + sender_ = mojo::WeakBindToRequest( + new DataSourceSender(base::Bind(&SerialConnection::OnReceivePipeReady, + base::Unretained(this)), + base::Bind(base::DoNothing)), + &source); } SerialConnection::~SerialConnection() {
diff --git a/device/serial/serial_connection.h b/device/serial/serial_connection.h index 6143c8b1..d0b940f 100644 --- a/device/serial/serial_connection.h +++ b/device/serial/serial_connection.h
@@ -22,9 +22,7 @@ public: SerialConnection(scoped_refptr<SerialIoHandler> io_handler, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client); + mojo::InterfaceRequest<serial::DataSource> source); ~SerialConnection() override; // mojo::InterfaceImpl<serial::Connection> overrides.
diff --git a/device/serial/serial_connection_factory.cc b/device/serial/serial_connection_factory.cc index 9beb33ae..6b01490 100644 --- a/device/serial/serial_connection_factory.cc +++ b/device/serial/serial_connection_factory.cc
@@ -37,9 +37,7 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client); + mojo::InterfaceRequest<serial::DataSource> source); void Run(); private: @@ -53,9 +51,7 @@ serial::ConnectionOptionsPtr options_; mojo::InterfaceRequest<serial::Connection> connection_request_; mojo::InterfaceRequest<serial::DataSink> sink_; - mojo::InterfacePtr<serial::DataSinkClient> sink_client_; mojo::InterfaceRequest<serial::DataSource> source_; - mojo::InterfacePtr<serial::DataSourceClient> source_client_; scoped_refptr<SerialIoHandler> io_handler_; DISALLOW_COPY_AND_ASSIGN(ConnectTask); @@ -73,12 +69,13 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client) { - scoped_refptr<ConnectTask> task(new ConnectTask( - this, path, options.Pass(), connection_request.Pass(), sink.Pass(), - sink_client.Pass(), source.Pass(), source_client.Pass())); + mojo::InterfaceRequest<serial::DataSource> source) { + scoped_refptr<ConnectTask> task(new ConnectTask(this, + path, + options.Pass(), + connection_request.Pass(), + sink.Pass(), + source.Pass())); task->Run(); } @@ -91,17 +88,13 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client) + mojo::InterfaceRequest<serial::DataSource> source) : factory_(factory), path_(path), options_(options.Pass()), connection_request_(connection_request.Pass()), sink_(sink.Pass()), - sink_client_(sink_client.Pass()), - source_(source.Pass()), - source_client_(source_client.Pass()) { + source_(source.Pass()) { if (!options_) { options_ = serial::ConnectionOptions::New(); } @@ -131,8 +124,7 @@ } mojo::BindToRequest( - new SerialConnection(io_handler_, sink_.Pass(), sink_client_.Pass(), - source_.Pass(), source_client_.Pass()), + new SerialConnection(io_handler_, sink_.Pass(), source_.Pass()), &connection_request_); }
diff --git a/device/serial/serial_connection_factory.h b/device/serial/serial_connection_factory.h index 2e1dcca..4200dca 100644 --- a/device/serial/serial_connection_factory.h +++ b/device/serial/serial_connection_factory.h
@@ -32,9 +32,7 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client); + mojo::InterfaceRequest<serial::DataSource> source); private: friend class base::RefCountedThreadSafe<SerialConnectionFactory>;
diff --git a/device/serial/serial_connection_unittest.cc b/device/serial/serial_connection_unittest.cc index 53d530329..151ed77 100644 --- a/device/serial/serial_connection_unittest.cc +++ b/device/serial/serial_connection_unittest.cc
@@ -74,23 +74,17 @@ scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)), &service); service.set_error_handler(this); - mojo::InterfacePtr<serial::DataSink> sink; - mojo::InterfacePtr<serial::DataSinkClient> sink_client; - mojo::InterfaceRequest<serial::DataSinkClient> sink_client_request = - mojo::GetProxy(&sink_client); - mojo::InterfacePtr<serial::DataSource> source; - mojo::InterfacePtr<serial::DataSourceClient> source_client; - mojo::InterfaceRequest<serial::DataSourceClient> source_client_request = - mojo::GetProxy(&source_client); - service->Connect("device", serial::ConnectionOptions::New(), - mojo::GetProxy(&connection_), mojo::GetProxy(&sink), - sink_client.Pass(), mojo::GetProxy(&source), - source_client.Pass()); - sender_.reset(new DataSender(sink.Pass(), sink_client_request.Pass(), - kBufferSize, serial::SEND_ERROR_DISCONNECTED)); - receiver_ = - new DataReceiver(source.Pass(), source_client_request.Pass(), - kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED); + mojo::InterfacePtr<serial::DataSink> consumer; + mojo::InterfacePtr<serial::DataSource> producer; + service->Connect("device", + serial::ConnectionOptions::New(), + mojo::GetProxy(&connection_), + mojo::GetProxy(&consumer), + mojo::GetProxy(&producer)); + sender_.reset(new DataSender( + consumer.Pass(), kBufferSize, serial::SEND_ERROR_DISCONNECTED)); + receiver_ = new DataReceiver( + producer.Pass(), kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED); connection_.set_error_handler(this); connection_->GetInfo( base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this)));
diff --git a/device/serial/serial_service_impl.cc b/device/serial/serial_service_impl.cc index 6fd6ce0..fceb448 100644 --- a/device/serial/serial_service_impl.cc +++ b/device/serial/serial_service_impl.cc
@@ -61,14 +61,14 @@ serial::ConnectionOptionsPtr options, mojo::InterfaceRequest<serial::Connection> connection_request, mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client) { + mojo::InterfaceRequest<serial::DataSource> source) { if (!IsValidPath(path)) return; - connection_factory_->CreateConnection( - path, options.Pass(), connection_request.Pass(), sink.Pass(), - sink_client.Pass(), source.Pass(), source_client.Pass()); + connection_factory_->CreateConnection(path, + options.Pass(), + connection_request.Pass(), + sink.Pass(), + source.Pass()); } SerialDeviceEnumerator* SerialServiceImpl::GetDeviceEnumerator() {
diff --git a/device/serial/serial_service_impl.h b/device/serial/serial_service_impl.h index 8e6ce3bf..0caf00e 100644 --- a/device/serial/serial_service_impl.h +++ b/device/serial/serial_service_impl.h
@@ -36,14 +36,11 @@ void GetDevices( const mojo::Callback<void(mojo::Array<serial::DeviceInfoPtr>)>& callback) override; - void Connect( - const mojo::String& path, - serial::ConnectionOptionsPtr options, - mojo::InterfaceRequest<serial::Connection> connection_request, - mojo::InterfaceRequest<serial::DataSink> sink, - mojo::InterfacePtr<serial::DataSinkClient> sink_client, - mojo::InterfaceRequest<serial::DataSource> source, - mojo::InterfacePtr<serial::DataSourceClient> source_client) override; + void Connect(const mojo::String& path, + serial::ConnectionOptionsPtr options, + mojo::InterfaceRequest<serial::Connection> connection_request, + mojo::InterfaceRequest<serial::DataSink> sink, + mojo::InterfaceRequest<serial::DataSource> source) override; private: SerialDeviceEnumerator* GetDeviceEnumerator();
diff --git a/device/serial/serial_service_unittest.cc b/device/serial/serial_service_unittest.cc index 103fb20..7f8beb23 100644 --- a/device/serial/serial_service_unittest.cc +++ b/device/serial/serial_service_unittest.cc
@@ -84,15 +84,12 @@ &service); mojo::InterfacePtr<serial::Connection> connection; mojo::InterfacePtr<serial::DataSink> sink; - mojo::InterfacePtr<serial::DataSinkClient> sink_client; - mojo::GetProxy(&sink_client); mojo::InterfacePtr<serial::DataSource> source; - mojo::InterfacePtr<serial::DataSourceClient> source_client; - mojo::GetProxy(&source_client); - service->Connect(path, serial::ConnectionOptions::New(), - mojo::GetProxy(&connection), mojo::GetProxy(&sink), - sink_client.Pass(), mojo::GetProxy(&source), - source_client.Pass()); + service->Connect(path, + serial::ConnectionOptions::New(), + mojo::GetProxy(&connection), + mojo::GetProxy(&sink), + mojo::GetProxy(&source)); connection.set_error_handler(this); expecting_error_ = !expecting_success; connection->GetInfo(
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index b11f1d2..17d6563b 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -10,7 +10,6 @@ sources = [] deps = [ - "//components/copresence_endpoints", "//components/keyed_service/content", "//components/keyed_service/core", "//components/pref_registry", @@ -109,10 +108,6 @@ "api/cast_channel/logger.h", "api/cast_channel/logger_util.cc", "api/cast_channel/logger_util.h", - "api/copresence_endpoints/copresence_endpoints_api.cc", - "api/copresence_endpoints/copresence_endpoints_api.h", - "api/copresence_endpoints/copresence_endpoint_resource.cc", - "api/copresence_endpoints/copresence_endpoint_resource.h", "api/declarative/declarative_api.cc", "api/declarative/declarative_api.h", "api/declarative/declarative_rule.h", @@ -344,6 +339,8 @@ "content_verifier_io_data.h", "content_verify_job.cc", "content_verify_job.h", + "crx_file_info.cc", + "crx_file_info.h", "error_map.cc", "error_map.h", "event_listener_map.cc", @@ -580,6 +577,9 @@ if (is_chromeos) { sources += [ + "api/diagnostics/diagnostics_api.cc", + "api/diagnostics/diagnostics_api.h", + "api/diagnostics/diagnostics_api_chromeos.cc", "api/networking_config/networking_config_api.cc", "api/networking_config/networking_config_api.h", "api/networking_config/networking_config_service.cc",
diff --git a/extensions/browser/api/copresence_endpoints/DEPS b/extensions/browser/api/copresence_endpoints/DEPS deleted file mode 100644 index e2c798c7..0000000 --- a/extensions/browser/api/copresence_endpoints/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+components/copresence_endpoints", -]
diff --git a/extensions/browser/api/copresence_endpoints/OWNERS b/extensions/browser/api/copresence_endpoints/OWNERS deleted file mode 100644 index 6a2cb03..0000000 --- a/extensions/browser/api/copresence_endpoints/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -rkc@chromium.org
diff --git a/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.cc b/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.cc deleted file mode 100644 index 45d4542e..0000000 --- a/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.cc +++ /dev/null
@@ -1,43 +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/copresence_endpoints/copresence_endpoint_resource.h" - -#include "base/lazy_instance.h" -#include "components/copresence_endpoints/public/copresence_endpoint.h" -#include "content/public/browser/browser_context.h" - -using copresence_endpoints::CopresenceEndpoint; - -namespace extensions { - -// CopresenceEndpointResource. - -// static -static base::LazyInstance<BrowserContextKeyedAPIFactory< - ApiResourceManager<CopresenceEndpointResource>>> g_endpoint_factory = - LAZY_INSTANCE_INITIALIZER; - -// static -template <> -BrowserContextKeyedAPIFactory<ApiResourceManager<CopresenceEndpointResource>>* -ApiResourceManager<CopresenceEndpointResource>::GetFactoryInstance() { - return g_endpoint_factory.Pointer(); -} - -CopresenceEndpointResource::CopresenceEndpointResource( - const std::string& owner_extension_id, - scoped_ptr<copresence_endpoints::CopresenceEndpoint> endpoint) - : ApiResource(owner_extension_id), endpoint_(endpoint.Pass()) { -} - -CopresenceEndpointResource::~CopresenceEndpointResource() { -} - -copresence_endpoints::CopresenceEndpoint* -CopresenceEndpointResource::endpoint() { - return endpoint_.get(); -} - -} // namespace extensions
diff --git a/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.h b/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.h deleted file mode 100644 index bfadb3b..0000000 --- a/extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_BROWSER_API_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_RESOURCES_H_ -#define EXTENSIONS_BROWSER_API_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_RESOURCES_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "extensions/browser/api/api_resource.h" -#include "extensions/browser/api/api_resource_manager.h" - -namespace copresence_endpoints { -class CopresenceEndpoint; -} - -namespace extensions { - -class CopresenceEndpointResource : public ApiResource { - public: - CopresenceEndpointResource( - const std::string& owner_extension_id, - scoped_ptr<copresence_endpoints::CopresenceEndpoint> endpoint); - ~CopresenceEndpointResource() override; - - copresence_endpoints::CopresenceEndpoint* endpoint(); - - std::string& packet() { return packet_; } - - static const content::BrowserThread::ID kThreadId = - content::BrowserThread::UI; - - private: - friend class ApiResourceManager<CopresenceEndpointResource>; - static const char* service_name() { - return "CopresenceEndpointResourceManager"; - } - - scoped_ptr<copresence_endpoints::CopresenceEndpoint> endpoint_; - std::string packet_; - - DISALLOW_COPY_AND_ASSIGN(CopresenceEndpointResource); -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_RESOURCES_H_
diff --git a/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.cc b/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.cc deleted file mode 100644 index 6ecb7728..0000000 --- a/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.cc +++ /dev/null
@@ -1,336 +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/copresence_endpoints/copresence_endpoints_api.h" - -#include "base/base64.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/lazy_instance.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "components/copresence_endpoints/public/copresence_endpoint.h" -#include "content/public/browser/browser_context.h" -#include "extensions/browser/api/copresence_endpoints/copresence_endpoint_resource.h" -#include "extensions/browser/event_router.h" -#include "extensions/common/api/copresence_endpoints.h" -#include "net/base/io_buffer.h" - -using copresence_endpoints::CopresenceEndpoint; - -namespace extensions { - -namespace { - -const size_t kSizeBytes = 2; -const char kToField[] = "to"; -const char kDataField[] = "data"; -const char kReplyToField[] = "replyTo"; - -bool Base64DecodeWithoutPadding(const std::string& data, std::string* out) { - std::string ret = data; - while (ret.size() % 4) - ret.push_back('='); - - if (!base::Base64Decode(ret, &ret)) - return false; - - out->swap(ret); - return true; -} - -std::string Base64EncodeWithoutPadding(const std::string& data) { - std::string ret = data; - base::Base64Encode(ret, &ret); - while (*(ret.end() - 1) == '=') - ret.erase(ret.end() - 1); - return ret; -} - -// Create a message to send to another endpoint. -std::string CreateMessage(const std::vector<char>& data, - const std::string& local_endpoint_locator, - int remote_endpoint_id) { - base::DictionaryValue dict; - dict.SetString(kToField, base::IntToString(remote_endpoint_id)); - dict.SetString(kDataField, Base64EncodeWithoutPadding( - std::string(data.begin(), data.end()))); - dict.SetString(kReplyToField, - Base64EncodeWithoutPadding(local_endpoint_locator)); - - std::string json; - base::JSONWriter::Write(&dict, &json); - - std::string message; - message.push_back(static_cast<unsigned char>(json.size() & 0xff)); - message.push_back(static_cast<unsigned char>(json.size() >> 8)); - - message.append(json); - return message; -} - -bool IsMessageComplete(const std::string& message, size_t* length) { - if (message.size() < kSizeBytes) - return false; - - // message[1] = upper order 8 bits. - // message[0] = lower order 8 bits. - size_t message_length = (static_cast<size_t>(message[1]) << 8) | - (static_cast<size_t>(message[0]) & 0xff); - - if (message.size() >= kSizeBytes + message_length) { - *length = message_length; - return true; - } - - return false; -} - -bool ExtractEndpointId(const std::string& endpoint_locator, int* id) { - std::vector<std::string> tokens; - if (Tokenize(endpoint_locator, ".", &tokens) <= 1) - return false; - - if (!base::StringToInt(tokens[0], id)) - return false; - - return true; -} - -// Parse a message received from another endpoint. -bool ParseReceivedMessage(const std::string& message, - std::string* data, - int* remote_endpoint_id) { - scoped_ptr<base::Value> value(base::JSONReader::Read(message)); - - // Check to see that we have a valid dictionary. - base::DictionaryValue* dict = nullptr; - if (!value || !value->GetAsDictionary(&dict) || !dict->HasKey(kDataField)) { - LOG(WARNING) << "Invalid message: " << message; - return false; - } - - // The fields in the json string are, - // to: Endpoint Id this message is meant for (unused atm, we only support one - // local endpoint). TODO(rkc): Fix this to support multiple endpoints. - // data: Data content of the message. - // replyTo: Sender of this message (in the locator data format). We only need - // the endpoint id that we have to reply to, but currently we get - // the full locator. TODO(rkc): Fix this once other platforms change - // over to only sending us the ID. - if (!dict->GetStringASCII(kDataField, data)) - return false; - if (!Base64DecodeWithoutPadding(*data, data)) - return false; - - std::string endpoint_locator; - if (!dict->GetStringASCII(kReplyToField, &endpoint_locator)) - return false; - if (!Base64DecodeWithoutPadding(endpoint_locator, &endpoint_locator)) - return false; - - if (!ExtractEndpointId(endpoint_locator, remote_endpoint_id)) - return false; - - VLOG(3) << "Valid message parsed."; - return true; -} - -} // namespace - -// CopresenceEndpointFunction public methods: - -CopresenceEndpointFunction::CopresenceEndpointFunction() - : endpoints_manager_(nullptr) { -} - -void CopresenceEndpointFunction::DispatchOnConnectedEvent(int endpoint_id) { - // Send the messages to the client app. - scoped_ptr<Event> event(new Event( - core_api::copresence_endpoints::OnConnected::kEventName, - core_api::copresence_endpoints::OnConnected::Create(endpoint_id), - browser_context())); - EventRouter::Get(browser_context()) - ->DispatchEventToExtension(extension_id(), event.Pass()); - VLOG(2) << "Dispatched OnConnected event: endpointId = " << endpoint_id; -} - -// CopresenceEndpointFunction protected methods: - -int CopresenceEndpointFunction::AddEndpoint( - CopresenceEndpointResource* endpoint) { - return endpoints_manager_->Add(endpoint); -} - -void CopresenceEndpointFunction::ReplaceEndpoint( - const std::string& extension_id, - int endpoint_id, - CopresenceEndpointResource* endpoint) { - endpoints_manager_->Replace(extension_id, endpoint_id, endpoint); -} - -CopresenceEndpointResource* CopresenceEndpointFunction::GetEndpoint( - int endpoint_id) { - return endpoints_manager_->Get(extension_id(), endpoint_id); -} - -void CopresenceEndpointFunction::RemoveEndpoint(int endpoint_id) { - endpoints_manager_->Remove(extension_id(), endpoint_id); -} - -ExtensionFunction::ResponseAction CopresenceEndpointFunction::Run() { - Initialize(); - return Execute(); -} - -// CopresenceEndpointFunction private methods: - -CopresenceEndpointFunction::~CopresenceEndpointFunction() { -} - -void CopresenceEndpointFunction::Initialize() { - endpoints_manager_ = - ApiResourceManager<CopresenceEndpointResource>::Get(browser_context()); -} - -void CopresenceEndpointFunction::OnDataReceived( - int local_endpoint_id, - const scoped_refptr<net::IOBuffer>& buffer, - int size) { - CopresenceEndpointResource* local_endpoint = GetEndpoint(local_endpoint_id); - if (!local_endpoint) { - VLOG(2) << "Receiving endpoint not found. ID = " << local_endpoint_id; - return; - } - - std::string& packet = local_endpoint->packet(); - packet.append(std::string(buffer->data(), size)); - size_t message_length; - if (IsMessageComplete(packet, &message_length)) { - std::string message_data; - int remote_endpoint_id; - if (ParseReceivedMessage(packet.substr(kSizeBytes, message_length), - &message_data, &remote_endpoint_id)) { - DispatchOnReceiveEvent(local_endpoint_id, remote_endpoint_id, - message_data); - } else { - LOG(WARNING) << "Invalid message received: " - << packet.substr(kSizeBytes, message_length) - << " of length: " << message_length; - } - - if (packet.size() > message_length + kSizeBytes) { - packet = packet.substr(message_length + kSizeBytes); - } else { - packet.clear(); - } - } -} - -void CopresenceEndpointFunction::DispatchOnReceiveEvent( - int local_endpoint_id, - int remote_endpoint_id, - const std::string& data) { - core_api::copresence_endpoints::ReceiveInfo info; - info.local_endpoint_id = local_endpoint_id; - info.remote_endpoint_id = remote_endpoint_id; - info.data.assign(data.begin(), data.end()); - // Send the data to the client app. - scoped_ptr<Event> event( - new Event(core_api::copresence_endpoints::OnReceive::kEventName, - core_api::copresence_endpoints::OnReceive::Create(info), - browser_context())); - EventRouter::Get(browser_context()) - ->DispatchEventToExtension(extension_id(), event.Pass()); - VLOG(2) << "Dispatched OnReceive event: localEndpointId = " - << local_endpoint_id << ", remoteEndpointId = " << remote_endpoint_id - << " and data = " << data; -} - -// CopresenceEndpointsCreateLocalEndpointFunction implementation: -ExtensionFunction::ResponseAction -CopresenceEndpointsCreateLocalEndpointFunction::Execute() { - // Add an empty endpoint to create a placeholder endpoint_id. We will need to - // bind - // this id to the OnConnected event dispatcher, so we need it before we - // create the actual endpoint. Once we have the endpoint created, we'll - // replace the - // placeholder with the actual endpoint object. - int endpoint_id = - AddEndpoint(new CopresenceEndpointResource(extension_id(), nullptr)); - - scoped_ptr<CopresenceEndpoint> endpoint = - make_scoped_ptr(new CopresenceEndpoint( - endpoint_id, - base::Bind(&CopresenceEndpointsCreateLocalEndpointFunction::OnCreated, - this, endpoint_id), - base::Bind(&CopresenceEndpointFunction::DispatchOnConnectedEvent, - this, endpoint_id), - base::Bind(&CopresenceEndpointFunction::OnDataReceived, this, - endpoint_id))); - - ReplaceEndpoint( - extension_id(), endpoint_id, - new CopresenceEndpointResource(extension_id(), endpoint.Pass())); - - return RespondLater(); -} - -void CopresenceEndpointsCreateLocalEndpointFunction::OnCreated( - int endpoint_id, - const std::string& locator) { - core_api::copresence_endpoints::EndpointInfo endpoint_info; - endpoint_info.endpoint_id = endpoint_id; - endpoint_info.locator = locator; - Respond(ArgumentList( - core_api::copresence_endpoints::CreateLocalEndpoint::Results::Create( - endpoint_info))); -} - -// CopresenceEndpointsDestroyEndpointFunction implementation: -ExtensionFunction::ResponseAction -CopresenceEndpointsDestroyEndpointFunction::Execute() { - scoped_ptr<core_api::copresence_endpoints::DestroyEndpoint::Params> params( - core_api::copresence_endpoints::DestroyEndpoint::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - - RemoveEndpoint(params->endpoint_id); - return RespondNow(NoArguments()); -} - -// CopresenceEndpointsSendFunction implementation: -ExtensionFunction::ResponseAction CopresenceEndpointsSendFunction::Execute() { - scoped_ptr<core_api::copresence_endpoints::Send::Params> params( - core_api::copresence_endpoints::Send::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - - CopresenceEndpointResource* endpoint = GetEndpoint(params->local_endpoint_id); - if (!endpoint) { - VLOG(1) << "Endpoint not found. ID = " << params->local_endpoint_id; - return RespondNow( - ArgumentList(core_api::copresence_endpoints::Send::Results::Create( - core_api::copresence_endpoints:: - ENDPOINT_STATUS_INVALID_LOCAL_ENDPOINT))); - } - DCHECK(endpoint->endpoint()); - - const std::string& message = - CreateMessage(params->data, endpoint->endpoint()->GetLocator(), - params->remote_endpoint_id); - VLOG(3) << "Sending message to remote_endpoint_id = " - << params->remote_endpoint_id - << " from local_endpoint_id = " << params->local_endpoint_id - << " with data[0] = " << static_cast<int>(message[0]) - << ", data[1] = " << static_cast<int>(message[1]) << ", data[2:] = " - << std::string((message.c_str() + 2), message.size() - 2); - - endpoint->endpoint()->Send(new net::StringIOBuffer(message), message.size()); - - return RespondNow( - ArgumentList(core_api::copresence_endpoints::Send::Results::Create( - core_api::copresence_endpoints::ENDPOINT_STATUS_NO_ERROR))); -} - -} // namespace extensions
diff --git a/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.h b/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.h deleted file mode 100644 index e02ce4c..0000000 --- a/extensions/browser/api/copresence_endpoints/copresence_endpoints_api.h +++ /dev/null
@@ -1,111 +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_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_API_H_ -#define EXTENSIONS_BROWSER_API_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_API_H_ - -#include <map> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "extensions/browser/api/api_resource_manager.h" -#include "extensions/browser/browser_context_keyed_api_factory.h" -#include "extensions/browser/extension_function.h" -#include "extensions/browser/extension_function_histogram_value.h" - -namespace copresence_endpoints { -class CopresenceEndpoint; -} - -namespace net { -class IOBuffer; -} - -namespace extensions { - -class CopresenceEndpointResource; - -class CopresenceEndpointFunction : public UIThreadExtensionFunction { - public: - CopresenceEndpointFunction(); - - void DispatchOnConnectedEvent(int endpoint_id); - - // Needs to be used from CreateLocalEndpoint. - void OnDataReceived(int endpoint_id, - const scoped_refptr<net::IOBuffer>& buffer, - int size); - - protected: - ~CopresenceEndpointFunction() override; - - // Override this and do actual work here. - virtual ExtensionFunction::ResponseAction Execute() = 0; - - // Takes ownership of endpoint. - int AddEndpoint(CopresenceEndpointResource* endpoint); - - // Takes ownership of endpoint. - void ReplaceEndpoint(const std::string& extension_id, - int endpoint_id, - CopresenceEndpointResource* endpoint); - - CopresenceEndpointResource* GetEndpoint(int endpoint_id); - - void RemoveEndpoint(int endpoint_id); - - // ExtensionFunction overrides: - ExtensionFunction::ResponseAction Run() override; - - private: - void Initialize(); - - void DispatchOnReceiveEvent(int local_endpoint_id, - int remote_endpoint_id, - const std::string& data); - - ApiResourceManager<CopresenceEndpointResource>* endpoints_manager_; -}; - -class CopresenceEndpointsCreateLocalEndpointFunction - : public CopresenceEndpointFunction { - public: - DECLARE_EXTENSION_FUNCTION("copresenceEndpoints.createLocalEndpoint", - COPRESENCEENDPOINTS_CREATELOCALENDPOINT); - - protected: - ~CopresenceEndpointsCreateLocalEndpointFunction() override {} - ExtensionFunction::ResponseAction Execute() override; - - private: - void OnCreated(int endpoint_id, const std::string& locator); -}; - -class CopresenceEndpointsDestroyEndpointFunction - : public CopresenceEndpointFunction { - public: - DECLARE_EXTENSION_FUNCTION("copresenceEndpoints.destroyLocalEndpoint", - COPRESENCEENDPOINTS_DESTROYLOCALENDPOINT); - - protected: - ~CopresenceEndpointsDestroyEndpointFunction() override {} - ExtensionFunction::ResponseAction Execute() override; -}; - -class CopresenceEndpointsSendFunction : public CopresenceEndpointFunction { - public: - DECLARE_EXTENSION_FUNCTION("copresenceEndpoints.send", - COPRESENCEENDPOINTS_SEND); - - protected: - ~CopresenceEndpointsSendFunction() override {} - ExtensionFunction::ResponseAction Execute() override; -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_COPRESENCE_ENDPOINTS_COPRESENCE_ENDPOINTS_API_H_
diff --git a/chrome/browser/extensions/api/diagnostics/diagnostics_api.cc b/extensions/browser/api/diagnostics/diagnostics_api.cc similarity index 85% rename from chrome/browser/extensions/api/diagnostics/diagnostics_api.cc rename to extensions/browser/api/diagnostics/diagnostics_api.cc index 0f6e8d2..684577c 100644 --- a/chrome/browser/extensions/api/diagnostics/diagnostics_api.cc +++ b/extensions/browser/api/diagnostics/diagnostics_api.cc
@@ -2,22 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/extensions/api/diagnostics/diagnostics_api.h" - -namespace SendPacket = extensions::api::diagnostics::SendPacket; +#include "extensions/browser/api/diagnostics/diagnostics_api.h" namespace { const char kErrorPingNotImplemented[] = "Not implemented"; const char kErrorPingFailed[] = "Failed to send ping packet"; - } namespace extensions { -DiagnosticsSendPacketFunction::DiagnosticsSendPacketFunction() {} +namespace SendPacket = core_api::diagnostics::SendPacket; -DiagnosticsSendPacketFunction::~DiagnosticsSendPacketFunction() {} +DiagnosticsSendPacketFunction::DiagnosticsSendPacketFunction() { +} + +DiagnosticsSendPacketFunction::~DiagnosticsSendPacketFunction() { +} bool DiagnosticsSendPacketFunction::Prepare() { parameters_ = SendPacket::Params::Create(*args_); @@ -35,7 +36,7 @@ double latency) { switch (result_code) { case SEND_PACKET_OK: { - extensions::api::diagnostics::SendPacketResult result; + core_api::diagnostics::SendPacketResult result; result.ip = ip; result.latency = latency; results_ = SendPacket::Results::Create(result);
diff --git a/chrome/browser/extensions/api/diagnostics/diagnostics_api.h b/extensions/browser/api/diagnostics/diagnostics_api.h similarity index 73% rename from chrome/browser/extensions/api/diagnostics/diagnostics_api.h rename to extensions/browser/api/diagnostics/diagnostics_api.h index ac0da63..451bd79 100644 --- a/chrome/browser/extensions/api/diagnostics/diagnostics_api.h +++ b/extensions/browser/api/diagnostics/diagnostics_api.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_EXTENSIONS_API_DIAGNOSTICS_DIAGNOSTICS_API_H_ -#define CHROME_BROWSER_EXTENSIONS_API_DIAGNOSTICS_DIAGNOSTICS_API_H_ +#ifndef EXTENSIONS_BROWSER_API_DIAGNOSTICS_DIAGNOSTICS_API_H_ +#define EXTENSIONS_BROWSER_API_DIAGNOSTICS_DIAGNOSTICS_API_H_ #include <string> #include "base/memory/scoped_ptr.h" -#include "chrome/common/extensions/api/diagnostics.h" #include "extensions/browser/api/async_api_function.h" +#include "extensions/common/api/diagnostics.h" namespace extensions { @@ -28,8 +28,7 @@ SEND_PACKET_FAILED, }; - DECLARE_EXTENSION_FUNCTION("diagnostics.sendPacket", - DIAGNOSTICS_SENDPACKET); + DECLARE_EXTENSION_FUNCTION("diagnostics.sendPacket", DIAGNOSTICS_SENDPACKET); DiagnosticsSendPacketFunction(); @@ -48,10 +47,9 @@ const std::string& ip, double latency); - scoped_ptr<extensions::api::diagnostics::SendPacket::Params> - parameters_; + scoped_ptr<core_api::diagnostics::SendPacket::Params> parameters_; }; } // namespace extensions -#endif // CHROME_BROWSER_EXTENSIONS_API_DIAGNOSTICS_DIAGNOSTICS_API_H_ +#endif // EXTENSIONS_BROWSER_API_DIAGNOSTICS_DIAGNOSTICS_API_H_
diff --git a/chrome/browser/extensions/api/diagnostics/diagnostics_api_chromeos.cc b/extensions/browser/api/diagnostics/diagnostics_api_chromeos.cc similarity index 79% rename from chrome/browser/extensions/api/diagnostics/diagnostics_api_chromeos.cc rename to extensions/browser/api/diagnostics/diagnostics_api_chromeos.cc index 9ae0f18..f14b8fb 100644 --- a/chrome/browser/extensions/api/diagnostics/diagnostics_api_chromeos.cc +++ b/extensions/browser/api/diagnostics/diagnostics_api_chromeos.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/extensions/api/diagnostics/diagnostics_api.h" +#include "extensions/browser/api/diagnostics/diagnostics_api.h" #include "base/bind.h" #include "base/callback.h" @@ -25,12 +25,9 @@ typedef base::Callback<void( DiagnosticsSendPacketFunction::SendPacketResultCode result_code, const std::string& ip, - double latency)> - SendPacketCallback; + double latency)> SendPacketCallback; -bool ParseResult(const std::string& status, - std::string* ip, - double* latency) { +bool ParseResult(const std::string& status, std::string* ip, double* latency) { // Parses the result and returns IP and latency. scoped_ptr<base::Value> parsed_value(base::JSONReader::Read(status)); if (!parsed_value) @@ -54,18 +51,15 @@ return true; } -void OnTestICMPCompleted( - const SendPacketCallback& callback, - bool succeeded, - const std::string& status) { +void OnTestICMPCompleted(const SendPacketCallback& callback, + bool succeeded, + const std::string& status) { std::string ip; double latency; if (!succeeded || !ParseResult(status, &ip, &latency)) { callback.Run(DiagnosticsSendPacketFunction::SEND_PACKET_FAILED, "", 0.0); } else { - callback.Run(DiagnosticsSendPacketFunction::SEND_PACKET_OK, - ip, - latency); + callback.Run(DiagnosticsSendPacketFunction::SEND_PACKET_OK, ip, latency); } } @@ -81,8 +75,9 @@ if (parameters_->options.size) config[kSize] = base::IntToString(*parameters_->options.size); - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> - TestICMPWithOptions( + chromeos::DBusThreadManager::Get() + ->GetDebugDaemonClient() + ->TestICMPWithOptions( parameters_->options.ip, config, base::Bind( OnTestICMPCompleted,
diff --git a/extensions/browser/api/printer_provider/printer_provider_api.cc b/extensions/browser/api/printer_provider/printer_provider_api.cc index 04f663b..d0244e4 100644 --- a/extensions/browser/api/printer_provider/printer_provider_api.cc +++ b/extensions/browser/api/printer_provider/printer_provider_api.cc
@@ -24,6 +24,35 @@ static base::LazyInstance<BrowserContextKeyedAPIFactory<PrinterProviderAPI>> g_api_factory = LAZY_INSTANCE_INITIALIZER; +// The separator between extension id and the extension's internal printer id +// used when generating a printer id unique across extensions. +const char kPrinterIdSeparator = ':'; + +// Given an extension ID and an ID of a printer reported by the extension, it +// generates a ID for the printer unique across extensions (assuming that the +// printer id is unique in the extension's space). +std::string GeneratePrinterId(const std::string& extension_id, + const std::string& internal_printer_id) { + std::string result = extension_id; + result.append(1, kPrinterIdSeparator); + result.append(internal_printer_id); + return result; +} + +// Parses an ID created using |GeneratePrinterId| to it's components: +// the extension ID and the printer ID internal to the extension. +// Returns whenter the ID was succesfully parsed. +bool ParsePrinterId(const std::string& printer_id, + std::string* extension_id, + std::string* internal_printer_id) { + size_t separator = printer_id.find_first_of(kPrinterIdSeparator); + if (separator == std::string::npos) + return false; + *extension_id = printer_id.substr(0, separator); + *internal_printer_id = printer_id.substr(separator + 1); + return true; +} + PrinterProviderAPI::PrintError APIPrintErrorToInternalType( core_api::printer_provider_internal::PrintError error) { switch (error) { @@ -100,9 +129,15 @@ } void PrinterProviderAPI::DispatchGetCapabilityRequested( - const std::string& extension_id, const std::string& printer_id, const PrinterProviderAPI::GetCapabilityCallback& callback) { + std::string extension_id; + std::string internal_printer_id; + if (!ParsePrinterId(printer_id, &extension_id, &internal_printer_id)) { + callback.Run(base::DictionaryValue()); + return; + } + EventRouter* event_router = EventRouter::Get(browser_context_); if (!event_router->ExtensionHasEventListener( extension_id, @@ -117,7 +152,7 @@ // Request id is not part of the public API, but it will be massaged out in // custom bindings. internal_args->AppendInteger(request_id); - internal_args->AppendString(printer_id); + internal_args->AppendString(internal_printer_id); scoped_ptr<Event> event(new Event( core_api::printer_provider::OnGetCapabilityRequested::kEventName, @@ -127,9 +162,15 @@ } void PrinterProviderAPI::DispatchPrintRequested( - const std::string& extension_id, const PrinterProviderAPI::PrintJob& job, const PrinterProviderAPI::PrintCallback& callback) { + std::string extension_id; + std::string internal_printer_id; + if (!ParsePrinterId(job.printer_id, &extension_id, &internal_printer_id)) { + callback.Run(PRINT_ERROR_FAILED); + return; + } + EventRouter* event_router = EventRouter::Get(browser_context_); if (!event_router->ExtensionHasEventListener( extension_id, @@ -139,7 +180,7 @@ } core_api::printer_provider::PrintJob print_job; - print_job.printer_id = job.printer_id; + print_job.printer_id = internal_printer_id; print_job.content_type = job.content_type; print_job.document = std::vector<char>(job.document_bytes.begin(), job.document_bytes.end()); @@ -268,11 +309,26 @@ return true; } -void PrinterProviderAPI::OnGetPrintersResult(const Extension* extension, - int request_id, - const base::ListValue& result) { +void PrinterProviderAPI::OnGetPrintersResult( + const Extension* extension, + int request_id, + const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) { + base::ListValue printer_list; + + // Update some printer description properties to better identify the extension + // managing the printer. + for (size_t i = 0; i < result.size(); ++i) { + scoped_ptr<base::DictionaryValue> printer(result[i]->ToValue()); + std::string internal_printer_id; + CHECK(printer->GetString("id", &internal_printer_id)); + printer->SetString("id", + GeneratePrinterId(extension->id(), internal_printer_id)); + printer->SetString("extensionId", extension->id()); + printer_list.Append(printer.release()); + } + pending_get_printers_requests_.CompleteForExtension(extension->id(), - request_id, result); + request_id, printer_list); } void PrinterProviderAPI::OnGetCapabilityResult(
diff --git a/extensions/browser/api/printer_provider/printer_provider_api.h b/extensions/browser/api/printer_provider/printer_provider_api.h index fbec8b3a9..04fde74b 100644 --- a/extensions/browser/api/printer_provider/printer_provider_api.h +++ b/extensions/browser/api/printer_provider/printer_provider_api.h
@@ -49,9 +49,11 @@ PrintJob(); ~PrintJob(); - // The id of the printer that should handle the print job. This identifies - // a printer within an extension and is provided by the extension via - // chrome.printerProvider.onGetPrintersRequested event callback. + // The id of the printer that should handle the print job. The id is + // formatted as <extension_id>:<printer_id>, where <extension_id> is the + // id of the extension that manages the printer, and <printer_id> is + // the the printer's id within the extension (as reported via + // chrome.printerProvider.onGetPrintersRequested event callback). std::string printer_id; // The print job ticket. @@ -83,25 +85,28 @@ // supported printers. The printer values reported by an extension are // added "extensionId" property that is set to the ID of the extension // returning the list. + // Note that the "id" property of printer values reported by an extension are + // rewriten as "<extension_id>:<id>" to ensure they are unique across + // different extensions. void DispatchGetPrintersRequested(const GetPrintersCallback& callback); - // Requests printer capability from the extension with id |extension_id| for - // the printer with id |printer_id|. |printer_id| should be one of the printer - // ids reported by |GetPrinters| callback. + // Requests printer capability for a printer with id |printer_id|. + // |printer_id| should be one of the printer ids reported by |GetPrinters| + // callback. // It dispatches chrome.printerProvider.onGetCapabilityRequested event - // to the extension. + // to the extension that manages the printer (which can be determined from + // |printer_id| value). // |callback| is passed a dictionary value containing printer capabilities as // reported by the extension. - void DispatchGetCapabilityRequested(const std::string& extension_id, - const std::string& printer_id, + void DispatchGetCapabilityRequested(const std::string& printer_id, const GetCapabilityCallback& callback); - // It dispatches chrome.printerProvider.onPrintRequested event to the - // extension with id |extension_id| with the provided print job. + // It dispatches chrome.printerProvider.onPrintRequested event with the + // provided print job. The event is dispatched only to the extension that + // manages printer with id |job.printer_id|. // |callback| is passed the print status returned by the extension, and it // must not be null. - void DispatchPrintRequested(const std::string& extension_id, - const PrintJob& job, + void DispatchPrintRequested(const PrintJob& job, const PrintCallback& callback); private: @@ -207,9 +212,11 @@ static const char* service_name() { return "PrinterProvider"; } // PrinterProviderInternalAPIObserver implementation: - void OnGetPrintersResult(const Extension* extension, - int request_id, - const base::ListValue& result) override; + void OnGetPrintersResult( + const Extension* extension, + int request_id, + const PrinterProviderInternalAPIObserver::PrinterInfoVector& result) + override; void OnGetCapabilityResult(const Extension* extension, int request_id, const base::DictionaryValue& result) override;
diff --git a/extensions/browser/api/printer_provider/printer_provider_apitest.cc b/extensions/browser/api/printer_provider/printer_provider_apitest.cc index 3be5c56..0dd8df0 100644 --- a/extensions/browser/api/printer_provider/printer_provider_apitest.cc +++ b/extensions/browser/api/printer_provider/printer_provider_apitest.cc
@@ -72,14 +72,14 @@ void StartPrintRequest(const std::string& extension_id, const PrinterProviderAPI::PrintCallback& callback) { PrinterProviderAPI::PrintJob job; - job.printer_id = "printer_id"; + job.printer_id = extension_id + ":printer_id"; job.ticket_json = "{}"; job.content_type = "content_type"; job.document_bytes = "bytes"; PrinterProviderAPI::GetFactoryInstance() ->Get(browser_context()) - ->DispatchPrintRequested(extension_id, job, callback); + ->DispatchPrintRequested(job, callback); } void StartCapabilityRequest( @@ -87,7 +87,8 @@ const PrinterProviderAPI::GetCapabilityCallback& callback) { PrinterProviderAPI::GetFactoryInstance() ->Get(browser_context()) - ->DispatchGetCapabilityRequested(extension_id, "printer_id", callback); + ->DispatchGetCapabilityRequested(extension_id + ":printer_id", + callback); } // Loads chrome.printerProvider test app and initializes is for test @@ -266,15 +267,15 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%s\"," - "\"id\":\"printerNoDesc\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", extension_id.c_str())); @@ -304,8 +305,8 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id.c_str())); @@ -342,30 +343,30 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id_1.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%s\"," - "\"id\":\"printerNoDesc\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", extension_id_1.c_str())); expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%s\"," - "\"id\":\"printerNoDesc\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", extension_id_2.c_str())); @@ -403,15 +404,15 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%s\"," - "\"id\":\"printerNoDesc\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", extension_id_2.c_str())); @@ -449,15 +450,15 @@ expected_printers.push_back(base::StringPrintf( "{" "\"description\":\"Test printer\"," - "\"extensionId\":\"%s\"," - "\"id\":\"printer1\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printer1\"," "\"name\":\"Printer 1\"" "}", extension_id_2.c_str())); expected_printers.push_back(base::StringPrintf( "{" - "\"extensionId\":\"%s\"," - "\"id\":\"printerNoDesc\"," + "\"extensionId\":\"%1$s\"," + "\"id\":\"%1$s:printerNoDesc\"," "\"name\":\"Printer 2\"" "}", extension_id_2.c_str()));
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc index a5bd9eb..e887965 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc +++ b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.cc
@@ -47,7 +47,7 @@ void PrinterProviderInternalAPI::NotifyGetPrintersResult( const Extension* extension, int request_id, - const base::ListValue& printers) { + const PrinterProviderInternalAPIObserver::PrinterInfoVector& printers) { FOR_EACH_OBSERVER(PrinterProviderInternalAPIObserver, observers_, OnGetPrintersResult(extension, request_id, printers)); } @@ -132,17 +132,17 @@ base::ListValue printers; if (params->printers) { - for (size_t i = 0; i < params->printers->size(); ++i) { - scoped_ptr<base::DictionaryValue> printer( - params->printers->at(i)->ToValue()); - printer->SetString("extensionId", extension()->id()); - printers.Append(printer.release()); - } + PrinterProviderInternalAPI::GetFactoryInstance() + ->Get(browser_context()) + ->NotifyGetPrintersResult(extension(), params->request_id, + *params->printers); + } else { + PrinterProviderInternalAPI::GetFactoryInstance() + ->Get(browser_context()) + ->NotifyGetPrintersResult( + extension(), params->request_id, + PrinterProviderInternalAPIObserver::PrinterInfoVector()); } - - PrinterProviderInternalAPI::GetFactoryInstance() - ->Get(browser_context()) - ->NotifyGetPrintersResult(extension(), params->request_id, printers); return RespondNow(NoArguments()); }
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h index f2493027..ac34c50 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h +++ b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api.h
@@ -49,9 +49,10 @@ // Notifies observers that a printerProvider.onGetPrintersRequested callback // has been called. Called from // |PrinterProviderInternalReportPrintersFunction|. - void NotifyGetPrintersResult(const Extension* extension, - int request_id, - const base::ListValue& printers); + void NotifyGetPrintersResult( + const Extension* extension, + int request_id, + const PrinterProviderInternalAPIObserver::PrinterInfoVector& printers); // Notifies observers that a printerProvider.onGetCapabilityRequested callback // has been called. Called from
diff --git a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h index 86337aa5..02cbacd8a6 100644 --- a/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h +++ b/extensions/browser/api/printer_provider_internal/printer_provider_internal_api_observer.h
@@ -5,6 +5,9 @@ #ifndef EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ #define EXTENSIONS_BROWSER_API_PRINTER_PROVIDER_INTERNAL_PRINTER_PROVIDER_INTERNAL_API_OBSERVER_H_ +#include <vector> + +#include "extensions/common/api/printer_provider.h" #include "extensions/common/api/printer_provider_internal.h" namespace base { @@ -19,6 +22,9 @@ // Interface for observing chrome.printerProviderInternal API function calls. class PrinterProviderInternalAPIObserver { public: + using PrinterInfoVector = + std::vector<linked_ptr<core_api::printer_provider::PrinterInfo>>; + // Used by chrome.printerProviderInternal API to report // chrome.printerProvider.onGetPrintersRequested result returned by the // extension |extension|. @@ -26,7 +32,7 @@ // chrome.printerProvider.onGetPrintersRequested event. virtual void OnGetPrintersResult(const Extension* extension, int request_id, - const base::ListValue& result) = 0; + const PrinterInfoVector& result) = 0; // Used by chrome.printerProviderInternal API to report // chrome.printerProvider.onGetCapabilityRequested result returned by the
diff --git a/extensions/browser/api_unittest.cc b/extensions/browser/api_unittest.cc index c7023a1d..ab8fc276 100644 --- a/extensions/browser/api_unittest.cc +++ b/extensions/browser/api_unittest.cc
@@ -32,8 +32,6 @@ ApiUnitTest::ApiUnitTest() : notification_service_(content::NotificationService::Create()) { - extensions_browser_client()->set_extension_system_factory( - &extension_system_factory_); } ApiUnitTest::~ApiUnitTest() {
diff --git a/extensions/browser/api_unittest.h b/extensions/browser/api_unittest.h index f26629d..dcb09fa 100644 --- a/extensions/browser/api_unittest.h +++ b/extensions/browser/api_unittest.h
@@ -11,7 +11,6 @@ #include "base/memory/scoped_ptr.h" #include "base/prefs/testing_pref_service.h" #include "extensions/browser/extensions_test.h" -#include "extensions/browser/mock_extension_system.h" namespace base { class Value; @@ -92,8 +91,6 @@ scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; TestingPrefServiceSimple testing_pref_service_; - MockExtensionSystemFactory<MockExtensionSystem> extension_system_factory_; - // The WebContents used to associate a RenderViewHost with API function calls, // or null. scoped_ptr<content::WebContents> contents_;
diff --git a/extensions/browser/app_window/app_delegate.h b/extensions/browser/app_window/app_delegate.h index 70f9f12..36bcc92 100644 --- a/extensions/browser/app_window/app_delegate.h +++ b/extensions/browser/app_window/app_delegate.h
@@ -50,7 +50,7 @@ virtual void AddNewContents(content::BrowserContext* context, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) = 0;
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index fe9b758..9256228d 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc
@@ -373,14 +373,14 @@ void AppWindow::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { DCHECK(new_contents->GetBrowserContext() == browser_context_); app_delegate_->AddNewContents(browser_context_, new_contents, disposition, - initial_pos, + initial_rect, user_gesture, was_blocked); }
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index 3eef866..8d6ffea1 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h
@@ -394,7 +394,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; bool PreHandleKeyboardEvent(content::WebContents* source,
diff --git a/extensions/browser/crx_file_info.cc b/extensions/browser/crx_file_info.cc new file mode 100644 index 0000000..34c48820 --- /dev/null +++ b/extensions/browser/crx_file_info.cc
@@ -0,0 +1,36 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/crx_file_info.h" + +#include "base/logging.h" + +namespace extensions { + +CRXFileInfo::CRXFileInfo() : path() { +} + +CRXFileInfo::CRXFileInfo(const std::string& i, + const base::FilePath& p, + const std::string& h) + : extension_id(i), path(p), expected_hash(h) { + DCHECK(!path.empty()); +} + +CRXFileInfo::CRXFileInfo(const std::string& i, const base::FilePath& p) + : extension_id(i), path(p), expected_hash() { + DCHECK(!path.empty()); +} + +CRXFileInfo::CRXFileInfo(const base::FilePath& p) + : extension_id(), path(p), expected_hash() { + DCHECK(!path.empty()); +} + +bool CRXFileInfo::operator==(const CRXFileInfo& that) const { + return extension_id == that.extension_id && path == that.path && + expected_hash == that.expected_hash; +} + +} // namespace extensions
diff --git a/extensions/browser/crx_file_info.h b/extensions/browser/crx_file_info.h new file mode 100644 index 0000000..49a5341 --- /dev/null +++ b/extensions/browser/crx_file_info.h
@@ -0,0 +1,34 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_CRX_FILE_INFO_H_ +#define EXTENSIONS_BROWSER_CRX_FILE_INFO_H_ + +#include <string> + +#include "base/files/file_path.h" + +namespace extensions { + +// CRXFileInfo holds general information about a cached CRX file +struct CRXFileInfo { + CRXFileInfo(); + CRXFileInfo(const std::string& extension_id, + const base::FilePath& path, + const std::string& hash); + CRXFileInfo(const std::string& extension_id, const base::FilePath& path); + explicit CRXFileInfo(const base::FilePath& path); + + bool operator==(const CRXFileInfo& that) const; + + // The only mandatory field is the file path, whereas extension_id and hash + // are only being checked if those are non-empty. + std::string extension_id; + base::FilePath path; + std::string expected_hash; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_CRX_FILE_H_
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index ae8e2cd3..ab2f8af 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -995,9 +995,9 @@ AUTOTESTPRIVATE_SETNATURALSCROLL, AUTOTESTPRIVATE_SETMOUSESENSITIVITY, AUTOTESTPRIVATE_SETPRIMARYBUTTONRIGHT, - COPRESENCEENDPOINTS_CREATELOCALENDPOINT, - COPRESENCEENDPOINTS_DESTROYLOCALENDPOINT, - COPRESENCEENDPOINTS_SEND, + DELETED_COPRESENCEENDPOINTS_CREATELOCALENDPOINT, + DELETED_COPRESENCEENDPOINTS_DESTROYLOCALENDPOINT, + DELETED_COPRESENCEENDPOINTS_SEND, INLINE_INSTALL_PRIVATE_INSTALL, LAUNCHERPAGE_SETENABLED, CRYPTOTOKENPRIVATE_REQUESTPERMISSION,
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc index 3125701..7874528 100644 --- a/extensions/browser/extension_host.cc +++ b/extensions/browser/extension_host.cc
@@ -434,7 +434,7 @@ void ExtensionHost::AddNewContents(WebContents* source, WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { // First, if the creating extension view was associated with a tab contents, @@ -453,7 +453,7 @@ WebContentsDelegate* delegate = associated_contents->GetDelegate(); if (delegate) { delegate->AddNewContents( - associated_contents, new_contents, disposition, initial_pos, + associated_contents, new_contents, disposition, initial_rect, user_gesture, was_blocked); return; } @@ -461,7 +461,7 @@ } delegate_->CreateTab( - new_contents, extension_id_, disposition, initial_pos, user_gesture); + new_contents, extension_id_, disposition, initial_rect, user_gesture); } void ExtensionHost::RenderViewReady() {
diff --git a/extensions/browser/extension_host.h b/extensions/browser/extension_host.h index 62925fc3..567499b 100644 --- a/extensions/browser/extension_host.h +++ b/extensions/browser/extension_host.h
@@ -109,7 +109,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void CloseContents(content::WebContents* contents) override;
diff --git a/extensions/browser/extension_host_delegate.h b/extensions/browser/extension_host_delegate.h index b14580d5..71c0990 100644 --- a/extensions/browser/extension_host_delegate.h +++ b/extensions/browser/extension_host_delegate.h
@@ -46,7 +46,7 @@ virtual void CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) = 0; // Requests access to an audio or video media stream. Invokes |callback|
diff --git a/extensions/browser/extensions_test.cc b/extensions/browser/extensions_test.cc index 103ade09..c6962ed05 100644 --- a/extensions/browser/extensions_test.cc +++ b/extensions/browser/extensions_test.cc
@@ -32,6 +32,8 @@ content::SetUtilityClientForTesting(content_utility_client_.get()); content::SetBrowserClientForTesting(content_browser_client_.get()); ExtensionsBrowserClient::Set(extensions_browser_client_.get()); + extensions_browser_client_->set_extension_system_factory( + &extension_system_factory_); } ExtensionsTest::~ExtensionsTest() {
diff --git a/extensions/browser/extensions_test.h b/extensions/browser/extensions_test.h index 3189e27e..e930421 100644 --- a/extensions/browser/extensions_test.h +++ b/extensions/browser/extensions_test.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "content/public/test/test_renderer_host.h" +#include "extensions/browser/mock_extension_system.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -61,6 +62,8 @@ // RenderViewHostTester. content::RenderViewHostTestEnabler rvh_test_enabler_; + MockExtensionSystemFactory<MockExtensionSystem> extension_system_factory_; + DISALLOW_COPY_AND_ASSIGN(ExtensionsTest); };
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index e9c25ba2..3641898 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -48,6 +48,7 @@ #include "net/base/escape.h" #include "net/base/net_errors.h" #include "ui/base/models/simple_menu_model.h" +#include "url/url_constants.h" using base::UserMetricsAction; using content::RenderFrameHost; @@ -879,6 +880,7 @@ if (scheme_is_blocked || !url.is_valid()) { LoadAbort(true /* is_top_level */, url, net::ErrorToShortString(net::ERR_ABORTED)); + NavigateGuest(url::kAboutBlankURL, true /* force_navigation */); return; } if (!force_navigation && (src_ == url)) @@ -1084,13 +1086,13 @@ void WebViewGuest::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { if (was_blocked) *was_blocked = false; RequestNewWindowPermission(disposition, - initial_pos, + initial_rect, user_gesture, new_contents); }
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 35daea01..a7ccfff 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -148,7 +148,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; content::WebContents* OpenURLFromTab(
diff --git a/extensions/browser/mojo/keep_alive_impl_unittest.cc b/extensions/browser/mojo/keep_alive_impl_unittest.cc index b9ca700..4bdb588b 100644 --- a/extensions/browser/mojo/keep_alive_impl_unittest.cc +++ b/extensions/browser/mojo/keep_alive_impl_unittest.cc
@@ -7,12 +7,8 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "content/public/browser/notification_service.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/browser/extension_system.h" #include "extensions/browser/extensions_test.h" -#include "extensions/browser/mock_extension_system.h" #include "extensions/browser/process_manager.h" -#include "extensions/browser/test_extensions_browser_client.h" #include "extensions/common/extension_builder.h" namespace extensions { @@ -26,9 +22,6 @@ void SetUp() override { ExtensionsTest::SetUp(); message_loop_.reset(new base::MessageLoop); - browser_client_.reset(new TestExtensionsBrowserClient(browser_context())); - browser_client_->set_extension_system_factory(&extension_system_factory_); - ExtensionsBrowserClient::Set(browser_client_.get()); extension_ = ExtensionBuilder() .SetManifest( @@ -71,10 +64,8 @@ private: scoped_ptr<base::MessageLoop> message_loop_; - MockExtensionSystemFactory<MockExtensionSystem> extension_system_factory_; scoped_ptr<content::NotificationService> notification_service_; scoped_refptr<const Extension> extension_; - scoped_ptr<TestExtensionsBrowserClient> browser_client_; DISALLOW_COPY_AND_ASSIGN(KeepAliveTest); };
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index cd535a83..76d44e9 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -18,6 +18,7 @@ #include "base/numerics/safe_conversions.h" #include "base/path_service.h" #include "base/sequenced_task_runner.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_worker_pool.h" #include "components/crx_file/constants.h" @@ -26,6 +27,8 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/utility_process_host.h" #include "content/public/common/common_param_traits.h" +#include "crypto/secure_hash.h" +#include "crypto/sha2.h" #include "crypto/signature_verifier.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -35,6 +38,7 @@ #include "extensions/common/file_util.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/icons_handler.h" +#include "extensions/common/switches.h" #include "grit/extensions_strings.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" @@ -209,19 +213,25 @@ } // namespace SandboxedUnpacker::SandboxedUnpacker( - const base::FilePath& crx_path, + const CRXFileInfo& file, Manifest::Location location, int creation_flags, const base::FilePath& extensions_dir, const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner, SandboxedUnpackerClient* client) - : crx_path_(crx_path), + : crx_path_(file.path), + package_hash_(file.expected_hash), + check_crx_hash_(false), client_(client), extensions_dir_(extensions_dir), got_response_(false), location_(location), creation_flags_(creation_flags), unpacker_io_task_runner_(unpacker_io_task_runner) { + if (!package_hash_.empty()) { + check_crx_hash_ = base::CommandLine::ForCurrentProcess()->HasSwitch( + extensions::switches::kEnableCrxHashCheck); + } } bool SandboxedUnpacker::CreateTempDirectory() { @@ -402,9 +412,49 @@ l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_ERROR_MESSAGE, error)); } +static size_t ReadAndHash(void* ptr, + size_t size, + size_t nmemb, + FILE* stream, + scoped_ptr<crypto::SecureHash>& hash) { + size_t len = fread(ptr, size, nmemb, stream); + if (len > 0 && hash) { + hash->Update(ptr, len * size); + } + return len; +} + +bool SandboxedUnpacker::FinalizeHash(scoped_ptr<crypto::SecureHash>& hash) { + if (hash) { + uint8 output[crypto::kSHA256Length]; + hash->Finish(output, sizeof(output)); + bool result = (base::StringToLowerASCII(base::HexEncode( + output, sizeof(output))) == package_hash_); + UMA_HISTOGRAM_BOOLEAN("Extensions.SandboxUnpackHashCheck", result); + if (!result && check_crx_hash_) { + // Package hash verification failed + std::string name = crx_path_.BaseName().AsUTF8Unsafe(); + LOG(ERROR) << "Hash check failed for extension: " << name; + ReportFailure(CRX_HASH_VERIFICATION_FAILED, + l10n_util::GetStringFUTF16( + IDS_EXTENSION_PACKAGE_ERROR_CODE, + ASCIIToUTF16("CRX_HASH_VERIFICATION_FAILED"))); + return false; + } + } + + return true; +} + bool SandboxedUnpacker::ValidateSignature() { base::ScopedFILE file(base::OpenFile(crx_path_, "rb")); + scoped_ptr<crypto::SecureHash> hash; + + if (!package_hash_.empty()) { + hash.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); + } + if (!file.get()) { // Could not open crx file for reading. #if defined(OS_WIN) @@ -437,7 +487,7 @@ // code in the code base. So for now, this assumes that we're running // on a little endian machine with 4 byte alignment. CrxFile::Header header; - size_t len = fread(&header, 1, sizeof(header), file.get()); + size_t len = ReadAndHash(&header, 1, sizeof(header), file.get(), hash); if (len < sizeof(header)) { // Invalid crx header ReportFailure(CRX_HEADER_INVALID, l10n_util::GetStringFUTF16( @@ -492,7 +542,8 @@ std::vector<uint8> key; key.resize(header.key_size); - len = fread(&key.front(), sizeof(uint8), header.key_size, file.get()); + len = ReadAndHash(&key.front(), sizeof(uint8), header.key_size, file.get(), + hash); if (len < header.key_size) { // Invalid public key ReportFailure( @@ -504,8 +555,8 @@ std::vector<uint8> signature; signature.resize(header.signature_size); - len = fread(&signature.front(), sizeof(uint8), header.signature_size, - file.get()); + len = ReadAndHash(&signature.front(), sizeof(uint8), header.signature_size, + file.get(), hash); if (len < header.signature_size) { // Invalid signature ReportFailure( @@ -530,7 +581,7 @@ } unsigned char buf[1 << 12]; - while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0) + while ((len = ReadAndHash(buf, 1, sizeof(buf), file.get(), hash)) > 0) verifier.VerifyUpdate(buf, len); if (!verifier.VerifyFinal()) { @@ -542,6 +593,10 @@ return false; } + if (!FinalizeHash(hash)) { + return false; + } + std::string public_key = std::string(reinterpret_cast<char*>(&key.front()), key.size()); base::Base64Encode(public_key, &public_key_);
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index 60a5bbd..398600bf 100644 --- a/extensions/browser/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h
@@ -12,6 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "content/public/browser/utility_process_host_client.h" +#include "extensions/browser/crx_file_info.h" #include "extensions/common/manifest.h" class SkBitmap; @@ -21,6 +22,10 @@ class SequencedTaskRunner; } +namespace crypto { +class SecureHash; +} + namespace extensions { class Extension; @@ -79,7 +84,7 @@ // |client| with the result. If |run_out_of_process| is provided, unpacking // is done in a sandboxed subprocess. Otherwise, it is done in-process. SandboxedUnpacker( - const base::FilePath& crx_path, + const CRXFileInfo& file, Manifest::Location location, int creation_flags, const base::FilePath& extensions_dir, @@ -148,6 +153,9 @@ ERROR_SERIALIZING_CATALOG, ERROR_SAVING_CATALOG, + // SandboxedUnpacker::ValidateSignature() + CRX_HASH_VERIFICATION_FAILED, + NUM_FAILURE_REASONS }; @@ -160,6 +168,11 @@ // Return true on success. virtual bool CreateTempDirectory(); + // Finalizes hash calculation and checks the result against the expected + // package hash. In case of mismatch, depending on the command-line option, + // we will either fail installation, or just update histograms. + bool FinalizeHash(scoped_ptr<crypto::SecureHash>& hash); + // Validates the signature of the extension and extract the key to // |public_key_|. Returns true if the signature validates, false otherwise. // @@ -202,6 +215,12 @@ // The path to the CRX to unpack. base::FilePath crx_path_; + // The package hash that was reported from the Web Store. + std::string package_hash_; + + // Whether we need to check the .crx hash sum. + bool check_crx_hash_; + // Our client. scoped_refptr<SandboxedUnpackerClient> client_;
diff --git a/extensions/browser/sandboxed_unpacker_unittest.cc b/extensions/browser/sandboxed_unpacker_unittest.cc index 7451b28..5d4281b 100644 --- a/extensions/browser/sandboxed_unpacker_unittest.cc +++ b/extensions/browser/sandboxed_unpacker_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/bind.h" +#include "base/command_line.h" #include "base/files/file_util.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" @@ -17,6 +18,7 @@ #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/extension_paths.h" +#include "extensions/common/switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -32,6 +34,7 @@ } base::FilePath temp_dir() const { return temp_dir_; } + base::string16 unpack_err() const { return error_; } private: ~MockSandboxedUnpackerClient() override {} @@ -46,9 +49,11 @@ } void OnUnpackFailure(const base::string16& error) override { - ASSERT_TRUE(false); + error_ = error; + quit_closure_.Run(); } + base::string16 error_; base::Closure quit_closure_; base::FilePath temp_dir_; }; @@ -74,15 +79,17 @@ ExtensionsTest::TearDown(); } - void SetupUnpacker(const std::string& crx_name) { + void SetupUnpacker(const std::string& crx_name, + const std::string& package_hash) { base::FilePath original_path; ASSERT_TRUE(PathService::Get(extensions::DIR_TEST_DATA, &original_path)); original_path = original_path.AppendASCII("unpacker").AppendASCII(crx_name); ASSERT_TRUE(base::PathExists(original_path)) << original_path.value(); sandboxed_unpacker_ = new SandboxedUnpacker( - original_path, Manifest::INTERNAL, Extension::NO_FLAGS, - extensions_dir_.path(), base::MessageLoopProxy::current(), client_); + extensions::CRXFileInfo(std::string(), original_path, package_hash), + Manifest::INTERNAL, Extension::NO_FLAGS, extensions_dir_.path(), + base::MessageLoopProxy::current(), client_); base::MessageLoopProxy::current()->PostTask( FROM_HERE, @@ -94,6 +101,8 @@ return client_->temp_dir().AppendASCII(kTempExtensionName); } + base::string16 GetInstallError() { return client_->unpack_err(); } + protected: base::ScopedTempDir extensions_dir_; MockSandboxedUnpackerClient* client_; @@ -104,17 +113,41 @@ }; TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) { - SetupUnpacker("no_l10n.crx"); + SetupUnpacker("no_l10n.crx", ""); // Check that there is no _locales folder. base::FilePath install_path = GetInstallPath().Append(kLocaleFolder); EXPECT_FALSE(base::PathExists(install_path)); } TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) { - SetupUnpacker("good_l10n.crx"); + SetupUnpacker("good_l10n.crx", ""); // Check that there is _locales folder. base::FilePath install_path = GetInstallPath().Append(kLocaleFolder); EXPECT_TRUE(base::PathExists(install_path)); } +TEST_F(SandboxedUnpackerTest, FailHashCheck) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + extensions::switches::kEnableCrxHashCheck); + SetupUnpacker("good_l10n.crx", "badhash"); + // Check that there is an error message. + EXPECT_NE(base::string16(), GetInstallError()); +} + +TEST_F(SandboxedUnpackerTest, PassHashCheck) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + extensions::switches::kEnableCrxHashCheck); + SetupUnpacker( + "good_l10n.crx", + "6fa171c726373785aa4fcd2df448c3db0420a95d5044fbee831f089b979c4068"); + // Check that there is no error message. + EXPECT_EQ(base::string16(), GetInstallError()); +} + +TEST_F(SandboxedUnpackerTest, SkipHashCheck) { + SetupUnpacker("good_l10n.crx", "badhash"); + // Check that there is no error message. + EXPECT_EQ(base::string16(), GetInstallError()); +} + } // namespace extensions
diff --git a/extensions/browser/updater/extension_downloader.cc b/extensions/browser/updater/extension_downloader.cc index da4ff410..3e06083 100644 --- a/extensions/browser/updater/extension_downloader.cc +++ b/extensions/browser/updater/extension_downloader.cc
@@ -731,13 +731,10 @@ scoped_ptr<ExtensionFetch> fetch_data, const base::FilePath& crx_path, bool file_ownership_passed) { - delegate_->OnExtensionDownloadFinished(fetch_data->id, - crx_path, - file_ownership_passed, - fetch_data->url, - fetch_data->version, - ping_results_[fetch_data->id], - fetch_data->request_ids); + delegate_->OnExtensionDownloadFinished( + CRXFileInfo(fetch_data->id, crx_path, fetch_data->package_hash), + file_ownership_passed, fetch_data->url, fetch_data->version, + ping_results_[fetch_data->id], fetch_data->request_ids); ping_results_.erase(fetch_data->id); }
diff --git a/extensions/browser/updater/extension_downloader_delegate.h b/extensions/browser/updater/extension_downloader_delegate.h index aed6885..2e5eaa5 100644 --- a/extensions/browser/updater/extension_downloader_delegate.h +++ b/extensions/browser/updater/extension_downloader_delegate.h
@@ -9,6 +9,7 @@ #include <string> #include "base/time/time.h" +#include "extensions/browser/crx_file_info.h" #include "extensions/browser/updater/manifest_fetch_data.h" class GURL; @@ -82,8 +83,7 @@ // successfully downloaded to |path|. |ownership_passed| is true if delegate // should get ownership of the file. virtual void OnExtensionDownloadFinished( - const std::string& id, - const base::FilePath& path, + const CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version,
diff --git a/extensions/browser/updater/update_service.cc b/extensions/browser/updater/update_service.cc index ece627a..10a86c3 100644 --- a/extensions/browser/updater/update_service.cc +++ b/extensions/browser/updater/update_service.cc
@@ -53,8 +53,7 @@ } void UpdateService::OnExtensionDownloadFinished( - const std::string& id, - const base::FilePath& path, + const CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version,
diff --git a/extensions/browser/updater/update_service.h b/extensions/browser/updater/update_service.h index 008917d..2f4cd80 100644 --- a/extensions/browser/updater/update_service.h +++ b/extensions/browser/updater/update_service.h
@@ -48,8 +48,7 @@ Error error, const PingResult& ping, const std::set<int>& request_ids) override; - void OnExtensionDownloadFinished(const std::string& id, - const base::FilePath& path, + void OnExtensionDownloadFinished(const CRXFileInfo& file, bool file_ownership_passed, const GURL& download_url, const std::string& version,
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 68e3fa3..c42f525 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -106,9 +106,9 @@ "dependencies": ["permission:declarativeWebRequest"], "contexts": ["blessed_extension"] }, - "copresenceEndpoints": { - "channel" : "canary", - "dependencies": ["permission:copresence"], + "diagnostics": { + "dependencies": ["permission:diagnostics"], + "extension_types": ["platform_app"], "contexts": ["blessed_extension"] }, "dns": {
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index 9f24ab9..d2f39ff 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json
@@ -151,6 +151,21 @@ "channel": "beta", "extension_types": ["extension", "legacy_packaged_app"] }, + "diagnostics": [ + { + "channel": "dev", + "extension_types": ["platform_app"] + }, + { + "channel": "stable", + "extension_types": ["platform_app"], + "whitelist": [ + "7AE714FFD394E073F0294CFA134C9F91DB5FBAA4", // CCD Development + "C7DA3A55C2355F994D3FDDAD120B426A0DF63843", // CCD Testing + "75E3CFFFC530582C583E4690EF97C70B9C8423B7" // CCD Release + ] + } + ], "dns": [ { "channel": "dev",
diff --git a/extensions/common/api/copresence_endpoints.idl b/extensions/common/api/copresence_endpoints.idl deleted file mode 100644 index b77bde4b..0000000 --- a/extensions/common/api/copresence_endpoints.idl +++ /dev/null
@@ -1,99 +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. - -// Use the <code>chrome.copresenceEndpoints</code> API to create persistent -// sockets to send data to and receive from data nearby devices. -namespace copresenceEndpoints { - // Result of the <code>createEndpoint</code> call. - [noinline_doc] dictionary EndpointInfo { - // The ID of the newly created endpoint. - long endpointId; - - // An opaque string containing the locator data for this endpoint. This - // locator is needed to connect to this endpoint. - DOMString locator; - }; - - // Data from an <code>onReceive</code> event. - [noinline_doc] dictionary ReceiveInfo { - // The local endpoint this data is for. - long localEndpointId; - - // The remote endpoint this data came from. - long remoteEndpointId; - - // The data received. - ArrayBuffer data; - }; - - // Status of a socket operation. - enum EndpointStatus { - // There was no error in the previous operation. - no_error, - - // The socket was disconnected. - disconnected, - - // The local endpoint id provided is invalid. - invalid_local_endpoint, - - // The remote endpoint id provided is invalid. - invalid_remote_endpoint, - - // There was a failure during connection. - connect_failure, - - // There was an error while trying to send data. - send_failure, - - // There was an error while trying to receive data. - receive_failure - }; - - // Callback from the <code>createEndpoint</code> method. - // |endpointInfo| : The result of the endpoint creation. - callback CreateCallback = void (EndpointInfo endpointInfo); - - // Callback from the <code>send</code> method. - // |status| : Status of the send operation. - callback SendCallback = void (EndpointStatus status); - - // These functions all report failures via chrome.runtime.lastError. - interface Functions { - // Endpoint functions. - - // Creates a endpoint that can be connected to by a nearby devices. - // |callback| : Called when the endpoint has been created. - static void createLocalEndpoint(CreateCallback callback); - - // Destroys the endpoint. This will close any connections to this endpoint - // from remote hosts and will prevent any further connections to it. - // |endpointId|: Endpoint ID returned by <code>createEndpoint</code>. - static void destroyEndpoint(long endpointId); - - // Sends data from a local Copresence endpoint to a remote endpoint. - // |localEndpointId| : The local endpoint identifier. - // |remoteEndpointId| : The remote endpoint identifier. - // |data| : The data to send. - // |callback| : Called when the <code>send</code> operation completes. - static void send(long localEndpointId, long remoteEndpointId, - ArrayBuffer data, optional SendCallback callback); - }; - - interface Events { - // Event raised when data has been received for a given socket. - // |info| : The event data. - static void onReceive(ReceiveInfo info); - - // Event raised when a endpoint receives a new connection. A new socket is - // created and the id is passed to this event via socketId. - // |localEndpointId| : ID of the local endpoint that received this - // connection. - // TODO(rkc): This API needs to be modified to give a valid remote endpoint - // id also. This currently doesn't happen because of the lack of a - // handshake on a sockets connection. Once we have a handshake, modify this - // API to also return a remote endpoint id. - static void onConnected(long localEndpointId); - }; -};
diff --git a/chrome/common/extensions/api/diagnostics.idl b/extensions/common/api/diagnostics.idl similarity index 100% rename from chrome/common/extensions/api/diagnostics.idl rename to extensions/common/api/diagnostics.idl
diff --git a/extensions/common/api/schemas.gypi b/extensions/common/api/schemas.gypi index ab8f880..0d170f9 100644 --- a/extensions/common/api/schemas.gypi +++ b/extensions/common/api/schemas.gypi
@@ -20,7 +20,6 @@ 'bluetooth_private.json', 'bluetooth_socket.idl', 'cast_channel.idl', - 'copresence_endpoints.idl', 'dns.idl', 'events.json', 'extensions_manifest_types.json', @@ -59,6 +58,7 @@ ], # ChromeOS-specific schemas. 'chromeos_schema_files': [ + 'diagnostics.idl', 'networking_config.idl', 'vpn_provider.idl', 'webcam_private.idl',
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index 825ccf2..d9a811e 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -61,6 +61,9 @@ APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_DECLARATIVE_WEB_REQUEST, PermissionMessage::kDeclarativeWebRequest}, + {APIPermission::kDiagnostics, + "diagnostics", + APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kDns, "dns"}, {APIPermission::kExtensionView, "extensionview",
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc index fcc6f499..f3ea11a 100644 --- a/extensions/common/switches.cc +++ b/extensions/common/switches.cc
@@ -101,6 +101,10 @@ // Pass launch source to platform apps. const char kTraceAppSource[] = "enable-trace-app-source"; +// Enable package hash check: the .crx file sha256 hash sum should be equal to +// the one received from update manifest. +const char kEnableCrxHashCheck[] = "enable-crx-hash-check"; + } // namespace switches } // namespace extensions
diff --git a/extensions/common/switches.h b/extensions/common/switches.h index dcad5c1..a55028b 100644 --- a/extensions/common/switches.h +++ b/extensions/common/switches.h
@@ -35,6 +35,7 @@ extern const char kShowComponentExtensionOptions[]; extern const char kTraceAppSource[]; extern const char kWhitelistedExtensionID[]; +extern const char kEnableCrxHashCheck[]; } // namespace switches
diff --git a/extensions/common/update_manifest.cc b/extensions/common/update_manifest.cc index 26d794f..57162da 100644 --- a/extensions/common/update_manifest.cc +++ b/extensions/common/update_manifest.cc
@@ -187,9 +187,9 @@ } } - // package_hash is optional. It is only required for blacklist. It is a - // sha256 hash of the package in hex format. - result->package_hash = GetAttribute(updatecheck, "hash"); + // package_hash is optional. It is a sha256 hash of the package in hex + // format. + result->package_hash = GetAttribute(updatecheck, "hash_sha256"); int size = 0; if (base::StringToInt(GetAttribute(updatecheck, "size"), &size)) {
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp index a0e4370..ac43483 100644 --- a/extensions/extensions.gyp +++ b/extensions/extensions.gyp
@@ -321,7 +321,6 @@ 'dependencies': [ '../base/base.gyp:base', '../base/base.gyp:base_prefs', - '../components/components.gyp:copresence_endpoints', '../components/components.gyp:keyed_service_content', '../components/components.gyp:keyed_service_core', '../components/components.gyp:onc_component', @@ -431,10 +430,6 @@ 'browser/api/cast_channel/logger.h', 'browser/api/cast_channel/logger_util.cc', 'browser/api/cast_channel/logger_util.h', - 'browser/api/copresence_endpoints/copresence_endpoints_api.cc', - 'browser/api/copresence_endpoints/copresence_endpoints_api.h', - 'browser/api/copresence_endpoints/copresence_endpoint_resource.cc', - 'browser/api/copresence_endpoints/copresence_endpoint_resource.h', 'browser/api/declarative/deduping_factory.h', 'browser/api/declarative/declarative_api.cc', 'browser/api/declarative/declarative_api.h', @@ -666,6 +661,8 @@ 'browser/content_verifier_io_data.h', 'browser/content_verify_job.cc', 'browser/content_verify_job.h', + 'browser/crx_file_info.cc', + 'browser/crx_file_info.h', 'browser/error_map.cc', 'browser/error_map.h', 'browser/event_listener_map.cc', @@ -890,6 +887,9 @@ '../chromeos/chromeos.gyp:chromeos', ], 'sources': [ + 'browser/api/diagnostics/diagnostics_api.cc', + 'browser/api/diagnostics/diagnostics_api.h', + 'browser/api/diagnostics/diagnostics_api_chromeos.cc', 'browser/api/networking_config/networking_config_api.cc', 'browser/api/networking_config/networking_config_api.h', 'browser/api/networking_config/networking_config_service.cc',
diff --git a/extensions/extensions_browsertests.isolate b/extensions/extensions_browsertests.isolate index f0381c0..6cae91bf 100644 --- a/extensions/extensions_browsertests.isolate +++ b/extensions/extensions_browsertests.isolate
@@ -28,6 +28,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -51,6 +53,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/extensions/renderer/api/serial/data_receiver_unittest.cc b/extensions/renderer/api/serial/data_receiver_unittest.cc index 1be15969..f699d02 100644 --- a/extensions/renderer/api/serial/data_receiver_unittest.cc +++ b/extensions/renderer/api/serial/data_receiver_unittest.cc
@@ -7,56 +7,10 @@ #include "device/serial/data_source_sender.h" #include "device/serial/data_stream.mojom.h" #include "extensions/renderer/api_test_base.h" -#include "gin/dictionary.h" -#include "gin/wrappable.h" #include "grit/extensions_renderer_resources.h" namespace extensions { -class DataReceiverFactory : public gin::Wrappable<DataReceiverFactory> { - public: - using Callback = base::Callback<void( - mojo::InterfaceRequest<device::serial::DataSource>, - mojo::InterfacePtr<device::serial::DataSourceClient>)>; - static gin::Handle<DataReceiverFactory> Create(v8::Isolate* isolate, - const Callback& callback) { - return gin::CreateHandle(isolate, - new DataReceiverFactory(callback, isolate)); - } - - gin::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override { - return Wrappable<DataReceiverFactory>::GetObjectTemplateBuilder(isolate) - .SetMethod("create", &DataReceiverFactory::CreateReceiver); - } - - gin::Dictionary CreateReceiver() { - mojo::InterfacePtr<device::serial::DataSource> sink; - mojo::InterfacePtr<device::serial::DataSourceClient> client; - mojo::InterfaceRequest<device::serial::DataSourceClient> client_request = - mojo::GetProxy(&client); - callback_.Run(mojo::GetProxy(&sink), client.Pass()); - - gin::Dictionary result = gin::Dictionary::CreateEmpty(isolate_); - result.Set("source", sink.PassMessagePipe().release()); - result.Set("client", client_request.PassMessagePipe().release()); - return result; - } - - static gin::WrapperInfo kWrapperInfo; - - private: - DataReceiverFactory(const Callback& callback, v8::Isolate* isolate) - : callback_(callback), isolate_(isolate) {} - - base::Callback<void(mojo::InterfaceRequest<device::serial::DataSource>, - mojo::InterfacePtr<device::serial::DataSourceClient>)> - callback_; - v8::Isolate* isolate_; -}; - -gin::WrapperInfo DataReceiverFactory::kWrapperInfo = {gin::kEmbedderNativeGin}; - // Runs tests defined in extensions/test/data/data_receiver_unittest.js class DataReceiverTest : public ApiTestBase { public: @@ -64,13 +18,8 @@ void SetUp() override { ApiTestBase::SetUp(); - gin::ModuleRegistry::From(env()->context()->v8_context()) - ->AddBuiltinModule(env()->isolate(), - "device/serial/data_receiver_test_factory", - DataReceiverFactory::Create( - env()->isolate(), - base::Bind(&DataReceiverTest::CreateDataSource, - base::Unretained(this))).ToV8()); + service_provider()->AddService(base::Bind( + &DataReceiverTest::CreateDataSource, base::Unretained(this))); } void TearDown() override { @@ -86,12 +35,12 @@ private: void CreateDataSource( - mojo::InterfaceRequest<device::serial::DataSource> request, - mojo::InterfacePtr<device::serial::DataSourceClient> client) { - sender_ = new device::DataSourceSender( - request.Pass(), client.Pass(), - base::Bind(&DataReceiverTest::ReadyToSend, base::Unretained(this)), - base::Bind(base::DoNothing)); + mojo::InterfaceRequest<device::serial::DataSource> request) { + sender_ = mojo::WeakBindToRequest( + new device::DataSourceSender( + base::Bind(&DataReceiverTest::ReadyToSend, base::Unretained(this)), + base::Bind(base::DoNothing)), + &request); } void ReadyToSend(scoped_ptr<device::WritableBuffer> buffer) {
diff --git a/extensions/renderer/api/serial/data_sender_unittest.cc b/extensions/renderer/api/serial/data_sender_unittest.cc index f137007..e6a13af 100644 --- a/extensions/renderer/api/serial/data_sender_unittest.cc +++ b/extensions/renderer/api/serial/data_sender_unittest.cc
@@ -7,55 +7,10 @@ #include "device/serial/data_sink_receiver.h" #include "device/serial/data_stream.mojom.h" #include "extensions/renderer/api_test_base.h" -#include "gin/dictionary.h" -#include "gin/wrappable.h" #include "grit/extensions_renderer_resources.h" namespace extensions { -class DataSenderFactory : public gin::Wrappable<DataSenderFactory> { - public: - using Callback = - base::Callback<void(mojo::InterfaceRequest<device::serial::DataSink>, - mojo::InterfacePtr<device::serial::DataSinkClient>)>; - static gin::Handle<DataSenderFactory> Create(v8::Isolate* isolate, - const Callback& callback) { - return gin::CreateHandle(isolate, new DataSenderFactory(callback, isolate)); - } - - gin::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override { - return Wrappable<DataSenderFactory>::GetObjectTemplateBuilder(isolate) - .SetMethod("create", &DataSenderFactory::CreateReceiver); - } - - gin::Dictionary CreateReceiver() { - mojo::InterfacePtr<device::serial::DataSink> sink; - mojo::InterfacePtr<device::serial::DataSinkClient> client; - mojo::InterfaceRequest<device::serial::DataSinkClient> client_request = - mojo::GetProxy(&client); - callback_.Run(mojo::GetProxy(&sink), client.Pass()); - - gin::Dictionary result = gin::Dictionary::CreateEmpty(isolate_); - result.Set("sink", sink.PassMessagePipe().release()); - result.Set("client", client_request.PassMessagePipe().release()); - return result; - } - - static gin::WrapperInfo kWrapperInfo; - - private: - DataSenderFactory(const Callback& callback, v8::Isolate* isolate) - : callback_(callback), isolate_(isolate) {} - - base::Callback<void(mojo::InterfaceRequest<device::serial::DataSink>, - mojo::InterfacePtr<device::serial::DataSinkClient>)> - callback_; - v8::Isolate* isolate_; -}; - -gin::WrapperInfo DataSenderFactory::kWrapperInfo = {gin::kEmbedderNativeGin}; - // Runs tests defined in extensions/test/data/data_sender_unittest.js class DataSenderTest : public ApiTestBase { public: @@ -63,12 +18,8 @@ void SetUp() override { ApiTestBase::SetUp(); - gin::ModuleRegistry::From(env()->context()->v8_context()) - ->AddBuiltinModule( - env()->isolate(), "device/serial/data_sender_test_factory", - DataSenderFactory::Create( - env()->isolate(), base::Bind(&DataSenderTest::CreateDataSink, - base::Unretained(this))).ToV8()); + service_provider()->AddService( + base::Bind(&DataSenderTest::CreateDataSink, base::Unretained(this))); } void TearDown() override { @@ -86,13 +37,13 @@ private: void CreateDataSink( - mojo::InterfaceRequest<device::serial::DataSink> request, - mojo::InterfacePtr<device::serial::DataSinkClient> client) { - receiver_ = new device::DataSinkReceiver( - request.Pass(), client.Pass(), - base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)), - base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)), - base::Bind(base::DoNothing)); + mojo::InterfaceRequest<device::serial::DataSink> request) { + receiver_ = mojo::WeakBindToRequest( + new device::DataSinkReceiver( + base::Bind(&DataSenderTest::ReadyToReceive, base::Unretained(this)), + base::Bind(&DataSenderTest::OnCancel, base::Unretained(this)), + base::Bind(base::DoNothing)), + &request); } void ReadyToReceive(scoped_ptr<device::ReadOnlyBuffer> buffer) {
diff --git a/extensions/renderer/resources/data_receiver.js b/extensions/renderer/resources/data_receiver.js index 8df9d25..0f286be 100644 --- a/extensions/renderer/resources/data_receiver.js +++ b/extensions/renderer/resources/data_receiver.js
@@ -86,16 +86,15 @@ /** * A DataReceiver that receives data from a DataSource. - * @param {!MojoHandle} source The handle to the DataSource. - * @param {!MojoHandle} client The handle to the DataSourceClient. + * @param {!MojoHandle} handle The handle to the DataSource. * @param {number} bufferSize How large a buffer to use. * @param {number} fatalErrorValue The receive error value to report in the * event of a fatal error. * @constructor * @alias module:data_receiver.DataReceiver */ - function DataReceiver(source, client, bufferSize, fatalErrorValue) { - this.init_(source, client, fatalErrorValue, 0, null, [], false); + function DataReceiver(handle, bufferSize, fatalErrorValue) { + this.init_(handle, fatalErrorValue, 0, null, [], false); this.source_.init(bufferSize); } @@ -110,7 +109,6 @@ return; this.shutDown_ = true; this.router_.close(); - this.clientRouter_.close(); if (this.receive_) { this.receive_.dispatchFatalError(this.fatalErrorValue_); this.receive_ = null; @@ -119,8 +117,7 @@ /** * Initialize this DataReceiver. - * @param {!MojoHandle} source A handle to the DataSource. - * @param {!MojoHandle} client A handle to the DataSourceClient. + * @param {!MojoHandle} source A handle to the DataSource * @param {number} fatalErrorValue The error to dispatch in the event of a * fatal error. * @param {number} bytesReceived The number of bytes already received. @@ -131,9 +128,12 @@ * @param {boolean} paused Whether the DataSource is paused. * @private */ - DataReceiver.prototype.init_ = function(source, client, fatalErrorValue, - bytesReceived, pendingError, - pendingData, paused) { + DataReceiver.prototype.init_ = function(source, + fatalErrorValue, + bytesReceived, + pendingError, + pendingData, + paused) { /** * The [Router]{@link module:mojo/public/js/router.Router} for the * connection to the DataSource. @@ -141,18 +141,11 @@ */ this.router_ = new router.Router(source); /** - * The [Router]{@link module:mojo/public/js/router.Router} for the - * connection to the DataSource. - * @private - */ - this.clientRouter_ = new router.Router(client); - /** * The connection to the DataSource. * @private */ this.source_ = new dataStream.DataSource.proxyClass(this.router_); - this.client_ = new dataStream.DataSourceClient.stubClass(this); - this.clientRouter_.setIncomingReceiver(this.client_); + this.router_.setIncomingReceiver(this); /** * The current receive operation. * @type {module:data_receiver~PendingReceive} @@ -209,7 +202,6 @@ } var serialized = new serialization.SerializedDataReceiver(); serialized.source = this.router_.connector_.handle_; - serialized.client = this.clientRouter_.connector_.handle_; serialized.fatal_error_value = this.fatalErrorValue_; serialized.paused = this.paused_; serialized.pending_error = this.pendingError_; @@ -219,8 +211,6 @@ }); this.router_.connector_.handle_ = null; this.router_.close(); - this.clientRouter_.connector_.handle_ = null; - this.clientRouter_.close(); this.shutDown_ = true; return Promise.resolve(serialized); }; @@ -252,9 +242,12 @@ buffer.set(data); pendingData.push(buffer.buffer); }); - this.init_(serialized.source, serialized.client, - serialized.fatal_error_value, serialized.bytes_received, - serialized.pending_error, pendingData, serialized.paused); + this.init_(serialized.source, + serialized.fatal_error_value, + serialized.bytes_received, + serialized.pending_error, + pendingData, + serialized.paused); }; /**
diff --git a/extensions/renderer/resources/data_sender.js b/extensions/renderer/resources/data_sender.js index 310682a..db259ec 100644 --- a/extensions/renderer/resources/data_sender.js +++ b/extensions/renderer/resources/data_sender.js
@@ -165,16 +165,15 @@ /** * A DataSender that sends data to a DataSink. - * @param {!MojoHandle} sink The handle to the DataSink. - * @param {!MojoHandle} client The handle to the DataSinkClient. + * @param {!MojoHandle} handle The handle to the DataSink. * @param {number} bufferSize How large a buffer to use for data. * @param {number} fatalErrorValue The send error value to report in the * event of a fatal error. * @constructor * @alias module:data_sender.DataSender */ - function DataSender(sink, client, bufferSize, fatalErrorValue) { - this.init_(sink, client, fatalErrorValue, bufferSize); + function DataSender(handle, bufferSize, fatalErrorValue) { + this.init_(handle, fatalErrorValue, bufferSize); this.sink_.init(bufferSize); } @@ -189,7 +188,6 @@ return; this.shutDown_ = true; this.router_.close(); - this.clientRouter_.close(); while (this.pendingSends_.length) { this.pendingSends_.pop().reportBytesSentAndError( 0, this.fatalErrorValue_); @@ -203,15 +201,13 @@ /** * Initialize this DataSender. - * @param {!MojoHandle} sink A handle to the DataSink. - * @param {!MojoHandle} sinkClient A handle to the DataSinkClient. + * @param {!MojoHandle} sink A handle to the DataSink * @param {number} fatalErrorValue The error to dispatch in the event of a * fatal error. * @param {number} bufferSize The size of the send buffer. * @private */ - DataSender.prototype.init_ = function(sink, sinkClient, fatalErrorValue, - bufferSize) { + DataSender.prototype.init_ = function(sink, fatalErrorValue, bufferSize) { /** * The error to be dispatched in the event of a fatal error. * @const {number} @@ -231,18 +227,11 @@ */ this.router_ = new routerModule.Router(sink); /** - * The [Router]{@link module:mojo/public/js/router.Router} for the - * connection to the DataSinkClient. - * @private - */ - this.clientRouter_ = new routerModule.Router(sinkClient); - /** * The connection to the DataSink. * @private */ this.sink_ = new dataStreamMojom.DataSink.proxyClass(this.router_); - this.client_ = new dataStreamMojom.DataSinkClient.stubClass(this); - this.clientRouter_.setIncomingReceiver(this.client_); + this.router_.setIncomingReceiver(this); /** * A queue of sends that have not fully sent their data to the DataSink. * @type {!module:data_sender~PendingSend[]} @@ -301,13 +290,10 @@ return readyToSerialize.then(function() { var serialized = new serialization.SerializedDataSender(); serialized.sink = this.router_.connector_.handle_; - serialized.client = this.clientRouter_.connector_.handle_; serialized.fatal_error_value = this.fatalErrorValue_; serialized.buffer_size = this.availableBufferCapacity_; this.router_.connector_.handle_ = null; this.router_.close(); - this.clientRouter_.connector_.handle_ = null; - this.clientRouter_.close(); this.shutDown_ = true; return serialized; }.bind(this)); @@ -334,8 +320,8 @@ this.shutDown_ = true; return; } - this.init_(serialized.sink, serialized.client, serialized.fatal_error_value, - serialized.buffer_size); + this.init_( + serialized.sink, serialized.fatal_error_value, serialized.buffer_size); }; /**
diff --git a/extensions/renderer/resources/serial_service.js b/extensions/renderer/resources/serial_service.js index be232144..d0f29761 100644 --- a/extensions/renderer/resources/serial_service.js +++ b/extensions/renderer/resources/serial_service.js
@@ -134,17 +134,14 @@ clientOptions.bufferSize = options.bufferSize; }; - function Connection(connection, router, receivePipe, receiveClientPipe, - sendPipe, sendClientPipe, id, options) { + function Connection(connection, router, receivePipe, sendPipe, id, options) { var state = new serialization.ConnectionState(); state.connectionId = id; updateClientOptions(state, options); var receiver = new dataReceiver.DataReceiver( - receivePipe, receiveClientPipe, state.bufferSize, - serialMojom.ReceiveError.DISCONNECTED); - var sender = - new dataSender.DataSender(sendPipe, sendClientPipe, state.bufferSize, - serialMojom.SendError.DISCONNECTED); + receivePipe, state.bufferSize, serialMojom.ReceiveError.DISCONNECTED); + var sender = new dataSender.DataSender( + sendPipe, state.bufferSize, serialMojom.SendError.DISCONNECTED); this.init_(state, connection, router, @@ -190,16 +187,12 @@ var serviceOptions = getServiceOptions(options); var pipe = core.createMessagePipe(); var sendPipe = core.createMessagePipe(); - var sendPipeClient = core.createMessagePipe(); var receivePipe = core.createMessagePipe(); - var receivePipeClient = core.createMessagePipe(); service.connect(path, serviceOptions, pipe.handle0, sendPipe.handle0, - sendPipeClient.handle0, - receivePipe.handle0, - receivePipeClient.handle0); + receivePipe.handle0); var router = new routerModule.Router(pipe.handle1); var connection = new serialMojom.Connection.proxyClass(router); return connection.getInfo().then(convertServiceInfo).then(function(info) { @@ -207,9 +200,7 @@ }).catch(function(e) { router.close(); core.close(sendPipe.handle1); - core.close(sendPipeClient.handle1); core.close(receivePipe.handle1); - core.close(receivePipeClient.handle1); throw e; }).then(function(results) { var info = results[0]; @@ -217,9 +208,7 @@ var serialConnectionClient = new Connection(connection, router, receivePipe.handle1, - receivePipeClient.handle1, sendPipe.handle1, - sendPipeClient.handle1, id, options); var clientInfo = serialConnectionClient.getClientInfo_();
diff --git a/extensions/shell/browser/api/shell_gcd/shell_gcd_api.cc b/extensions/shell/browser/api/shell_gcd/shell_gcd_api.cc index 637e8ce..ea3d35c 100644 --- a/extensions/shell/browser/api/shell_gcd/shell_gcd_api.cc +++ b/extensions/shell/browser/api/shell_gcd/shell_gcd_api.cc
@@ -4,6 +4,8 @@ #include "extensions/shell/browser/api/shell_gcd/shell_gcd_api.h" +#include <string> + #include "base/values.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/privet_daemon_client.h" @@ -30,4 +32,20 @@ Respond(OneArgument(new base::FundamentalValue(success))); } +/////////////////////////////////////////////////////////////////////////////// + +ShellGcdGetWiFiBootstrapStateFunction::ShellGcdGetWiFiBootstrapStateFunction() { +} + +ShellGcdGetWiFiBootstrapStateFunction:: + ~ShellGcdGetWiFiBootstrapStateFunction() { +} + +ExtensionFunction::ResponseAction ShellGcdGetWiFiBootstrapStateFunction::Run() { + std::string state = chromeos::DBusThreadManager::Get() + ->GetPrivetDaemonClient() + ->GetWifiBootstrapState(); + return RespondNow(OneArgument(new base::StringValue(state))); +} + } // namespace extensions
diff --git a/extensions/shell/browser/api/shell_gcd/shell_gcd_api.h b/extensions/shell/browser/api/shell_gcd/shell_gcd_api.h index 986f32fc..327f3aad 100644 --- a/extensions/shell/browser/api/shell_gcd/shell_gcd_api.h +++ b/extensions/shell/browser/api/shell_gcd/shell_gcd_api.h
@@ -10,7 +10,7 @@ namespace extensions { -// See shell_gcd.idl for documentation. +// Used for manual testing in app_shell. See shell_gcd.idl for documentation. class ShellGcdPingFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("shell.gcd.ping", UNKNOWN); @@ -30,6 +30,24 @@ DISALLOW_COPY_AND_ASSIGN(ShellGcdPingFunction); }; +/////////////////////////////////////////////////////////////////////////////// + +// Used for manual testing in app_shell. See shell_gcd.idl for documentation. +class ShellGcdGetWiFiBootstrapStateFunction : public UIThreadExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("shell.gcd.getWiFiBootstrapState", UNKNOWN); + + ShellGcdGetWiFiBootstrapStateFunction(); + + // ExtensionFunction: + ResponseAction Run() override; + + private: + ~ShellGcdGetWiFiBootstrapStateFunction() override; + + DISALLOW_COPY_AND_ASSIGN(ShellGcdGetWiFiBootstrapStateFunction); +}; + } // namespace extensions #endif // EXTENSIONS_SHELL_BROWSER_API_SHELL_GCD_SHELL_GCD_API_H_
diff --git a/extensions/shell/browser/api/shell_gcd/shell_gcd_api_unittest.cc b/extensions/shell/browser/api/shell_gcd/shell_gcd_api_unittest.cc index 046fc7a..66e4401b 100644 --- a/extensions/shell/browser/api/shell_gcd/shell_gcd_api_unittest.cc +++ b/extensions/shell/browser/api/shell_gcd/shell_gcd_api_unittest.cc
@@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/values.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/privet_daemon_client.h" #include "extensions/browser/api_unittest.h" namespace extensions { @@ -33,7 +34,7 @@ DISALLOW_COPY_AND_ASSIGN(ShellGcdApiTest); }; -TEST_F(ShellGcdApiTest, GetBootstrapStatus) { +TEST_F(ShellGcdApiTest, Ping) { // Function succeeds and returns a result (for its callback). scoped_ptr<base::Value> result = RunFunctionAndReturnValue(new ShellGcdPingFunction, "[{}]"); @@ -43,4 +44,14 @@ EXPECT_TRUE(success); } +TEST_F(ShellGcdApiTest, GetWiFiBootstrapState) { + // Function succeeds and returns a result (for its callback). + scoped_ptr<base::Value> result = RunFunctionAndReturnValue( + new ShellGcdGetWiFiBootstrapStateFunction, "[{}]"); + ASSERT_TRUE(result.get()); + std::string state; + result->GetAsString(&state); + EXPECT_EQ(privetd::kWiFiBootstrapStateMonitoring, state); +} + } // namespace extensions
diff --git a/extensions/shell/browser/shell_app_delegate.cc b/extensions/shell/browser/shell_app_delegate.cc index fcb46a6..3871027 100644 --- a/extensions/shell/browser/shell_app_delegate.cc +++ b/extensions/shell/browser/shell_app_delegate.cc
@@ -42,7 +42,7 @@ void ShellAppDelegate::AddNewContents(content::BrowserContext* context, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { NOTIMPLEMENTED();
diff --git a/extensions/shell/browser/shell_app_delegate.h b/extensions/shell/browser/shell_app_delegate.h index a5fff4aa..6690d7a0 100644 --- a/extensions/shell/browser/shell_app_delegate.h +++ b/extensions/shell/browser/shell_app_delegate.h
@@ -29,7 +29,7 @@ void AddNewContents(content::BrowserContext* context, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
diff --git a/extensions/shell/browser/shell_extension_host_delegate.cc b/extensions/shell/browser/shell_extension_host_delegate.cc index a02d604..d06363e 100644 --- a/extensions/shell/browser/shell_extension_host_delegate.cc +++ b/extensions/shell/browser/shell_extension_host_delegate.cc
@@ -36,7 +36,7 @@ void ShellExtensionHostDelegate::CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { // TODO(jamescook): Should app_shell support opening popup windows? NOTREACHED();
diff --git a/extensions/shell/browser/shell_extension_host_delegate.h b/extensions/shell/browser/shell_extension_host_delegate.h index 4f796016..ba2a364 100644 --- a/extensions/shell/browser/shell_extension_host_delegate.h +++ b/extensions/shell/browser/shell_extension_host_delegate.h
@@ -23,7 +23,7 @@ void CreateTab(content::WebContents* web_contents, const std::string& extension_id, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; void ProcessMediaAccessRequest(content::WebContents* web_contents, const content::MediaStreamRequest& request,
diff --git a/extensions/shell/common/api/shell_gcd.idl b/extensions/shell/common/api/shell_gcd.idl index 7f2175a..65c80300 100644 --- a/extensions/shell/common/api/shell_gcd.idl +++ b/extensions/shell/common/api/shell_gcd.idl
@@ -5,12 +5,20 @@ // Setup related functions for a Google Cloud Devices (GCD) target device // running on Chrome OS Core. The actual bootstrapping and GCD registration is // handled by the privetd and buffet system daemons. +// +// TODO(jamescook): This API exists only for manual testing of GCD in app_shell. +// Delete it when GCD setup is integrated into OOBE. namespace shell.gcd { callback PingCallback = void(boolean success); + callback StateCallback = void(DOMString state); interface Functions { // Attempts to ping the daemon via D-Bus. static void ping(PingCallback callback); + + // Returns the Wi-Fi bootstrap state. Return values are found in + // platform2/privetd/dbus_bindings/org.chromium.privetd.Manager.xml. + static void getWiFiBootstrapState(StateCallback callback); }; };
diff --git a/extensions/test/data/data_receiver_unittest.js b/extensions/test/data/data_receiver_unittest.js index b46189a4..75d3ca76f 100644 --- a/extensions/test/data/data_receiver_unittest.js +++ b/extensions/test/data/data_receiver_unittest.js
@@ -13,14 +13,17 @@ // Returns a promise to a newly created DataReceiver. function createReceiver() { return Promise.all([ + requireAsync('content/public/renderer/service_provider'), requireAsync('data_receiver'), - requireAsync('device/serial/data_receiver_test_factory'), + requireAsync('device/serial/data_stream.mojom'), ]).then(function(modules) { - var dataReceiver = modules[0]; - var factory = modules[1]; - var receiver = factory.create(); - return new dataReceiver.DataReceiver(receiver.source, receiver.client, - BUFFER_SIZE, FATAL_ERROR); + var serviceProvider = modules[0]; + var dataReceiver = modules[1]; + var dataStream = modules[2]; + return new dataReceiver.DataReceiver( + serviceProvider.connectToService(dataStream.DataSource.name), + BUFFER_SIZE, + FATAL_ERROR); }); }
diff --git a/extensions/test/data/data_sender_unittest.js b/extensions/test/data/data_sender_unittest.js index 9cd1771..0b6a5cfe 100644 --- a/extensions/test/data/data_sender_unittest.js +++ b/extensions/test/data/data_sender_unittest.js
@@ -24,14 +24,17 @@ // Returns a promise to a newly created DataSender. function createSender() { return Promise.all([ + requireAsync('content/public/renderer/service_provider'), requireAsync('data_sender'), - requireAsync('device/serial/data_sender_test_factory'), + requireAsync('device/serial/data_stream.mojom'), ]).then(function(modules) { - var dataSender = modules[0]; - var factory = modules[1]; - var sender = factory.create(); - return new dataSender.DataSender(sender.sink, sender.client, BUFFER_SIZE, - FATAL_ERROR); + var serviceProvider = modules[0]; + var dataSender = modules[1]; + var dataStream = modules[2]; + return new dataSender.DataSender( + serviceProvider.connectToService(dataStream.DataSink.name), + BUFFER_SIZE, + FATAL_ERROR); }); }
diff --git a/extensions/test/data/web_view/apitest/main.js b/extensions/test/data/web_view/apitest/main.js index 4495ed4..95fee6e 100644 --- a/extensions/test/data/web_view/apitest/main.js +++ b/extensions/test/data/web_view/apitest/main.js
@@ -964,16 +964,14 @@ // chrome URL is provided. function testLoadAbortIllegalChromeURL() { var webview = document.createElement('webview'); - var onFirstLoadStop = function(e) { - webview.removeEventListener('loadstop', onFirstLoadStop); - webview.setAttribute('src', 'chrome://newtab'); - }; - webview.addEventListener('loadstop', onFirstLoadStop); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); - webview.setAttribute('src', 'about:blank'); + webview.src = 'chrome://newtab'; document.body.appendChild(webview); } @@ -981,9 +979,12 @@ var webview = document.createElement('webview'); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); - webview.setAttribute('src', 'file://foo'); + webview.src = 'file://foo'; document.body.appendChild(webview); } @@ -991,6 +992,9 @@ var webview = document.createElement('webview'); webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.setAttribute('src', 'javascript:void(document.bgColor="#0000FF")'); @@ -1000,17 +1004,19 @@ // Verifies that navigating to invalid URL (e.g. 'http:') doesn't cause a crash. function testLoadAbortInvalidNavigation() { var webview = document.createElement('webview'); - var validSchemeWithEmptyURL = 'http:'; webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); embedder.test.assertEq('', e.url); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.addEventListener('exit', function(e) { // We should not crash. embedder.test.fail(); }); - webview.setAttribute('src', validSchemeWithEmptyURL); + webview.src = 'http:'; document.body.appendChild(webview); } @@ -1018,17 +1024,20 @@ // pseudo-scheme fires loadabort and doesn't cause a crash. function testLoadAbortNonWebSafeScheme() { var webview = document.createElement('webview'); - var chromeGuestURL = 'chrome-guest://abc123'; + var chromeGuestURL = 'chrome-guest://abc123/'; webview.addEventListener('loadabort', function(e) { embedder.test.assertEq('ERR_ABORTED', e.reason); - embedder.test.assertEq('chrome-guest://abc123/', e.url); + embedder.test.assertEq(chromeGuestURL, e.url); + }); + webview.addEventListener('loadstop', function(e) { + embedder.test.assertEq('about:blank', webview.src); embedder.test.succeed(); }); webview.addEventListener('exit', function(e) { // We should not crash. embedder.test.fail(); }); - webview.setAttribute('src', chromeGuestURL); + webview.src = chromeGuestURL; document.body.appendChild(webview); };
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index affe4d8..82a3f58 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -142,6 +142,7 @@ "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",
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc index 7196372..205d1b9 100644 --- a/gpu/command_buffer/client/program_info_manager.cc +++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -4,6 +4,8 @@ #include "gpu/command_buffer/client/program_info_manager.h" +#include "base/numerics/safe_math.h" + namespace { template<typename T> static T LocalGetAs( @@ -44,11 +46,23 @@ ProgramInfoManager::Program::UniformInfo::~UniformInfo() { } +ProgramInfoManager::Program::UniformBlock::UniformBlock() + : binding(0), + data_size(0), + referenced_by_vertex_shader(false), + referenced_by_fragment_shader(false) { +} + +ProgramInfoManager::Program::UniformBlock::~UniformBlock() { +} + ProgramInfoManager::Program::Program() - : cached_(false), + : cached_es2_(false), max_attrib_name_length_(0), max_uniform_name_length_(0), - link_status_(false) { + link_status_(false), + cached_es3_uniform_blocks_(false), + active_uniform_block_max_name_length_(0) { } ProgramInfoManager::Program::~Program() { @@ -78,6 +92,11 @@ &uniform_infos_[index] : NULL; } +const ProgramInfoManager::Program::UniformBlock* +ProgramInfoManager::Program::GetUniformBlock(GLuint index) const { + return (index < uniform_blocks_.size()) ? &uniform_blocks_[index] : NULL; +} + GLint ProgramInfoManager::Program::GetUniformLocation( const std::string& name) const { bool getting_array_location = false; @@ -125,31 +144,45 @@ GLenum pname, GLint* params) { switch (pname) { case GL_LINK_STATUS: - *params = link_status_; + *params = static_cast<GLint>(link_status_); return true; case GL_ACTIVE_ATTRIBUTES: - *params = attrib_infos_.size(); + *params = static_cast<GLint>(attrib_infos_.size()); return true; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = max_attrib_name_length_; + *params = static_cast<GLint>(max_attrib_name_length_); return true; case GL_ACTIVE_UNIFORMS: - *params = uniform_infos_.size(); + *params = static_cast<GLint>(uniform_infos_.size()); return true; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = max_uniform_name_length_; + *params = static_cast<GLint>(max_uniform_name_length_); + return true; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = static_cast<GLint>(uniform_blocks_.size()); + return true; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = static_cast<GLint>(active_uniform_block_max_name_length_); return true; default: + NOTREACHED(); break; } return false; } -void ProgramInfoManager::Program::Update( - GLES2Implementation* gl, - GLuint program, - const std::vector<int8>& result) { - if (cached_) { +GLuint ProgramInfoManager::Program::GetUniformBlockIndex( + const std::string& name) const { + for (size_t ii = 0; ii < uniform_blocks_.size(); ++ii) { + if (uniform_blocks_[ii].name == name) { + return static_cast<GLuint>(ii); + } + } + return GL_INVALID_INDEX; +} + +void ProgramInfoManager::Program::UpdateES2(const std::vector<int8>& result) { + if (cached_es2_) { return; } if (result.empty()) { @@ -200,12 +233,91 @@ ++input; } DCHECK_EQ(header->num_attribs + header->num_uniforms, - static_cast<uint32>(input - inputs)); - cached_ = true; + static_cast<uint32>(input - inputs)); + cached_es2_ = true; } -bool ProgramInfoManager::Program::cached() const { - return cached_; +void ProgramInfoManager::Program::UpdateES3UniformBlocks( + const std::vector<int8>& result) { + if (cached_es3_uniform_blocks_) { + return; + } + if (result.empty()) { + // This should only happen on a lost context. + return; + } + uniform_blocks_.clear(); + active_uniform_block_max_name_length_ = 0; + + uint32_t header_size = sizeof(UniformBlocksHeader); + DCHECK_GE(result.size(), header_size); + const UniformBlocksHeader* header = LocalGetAs<const UniformBlocksHeader*>( + result, 0, header_size); + DCHECK(header); + if (header->num_uniform_blocks == 0) { + DCHECK_EQ(result.size(), header_size); + // TODO(zmo): Here we can't tell if no uniform blocks are defined, or + // the previous link failed. + return; + } + uniform_blocks_.resize(header->num_uniform_blocks); + + uint32_t entry_size = sizeof(UniformBlockInfo) * header->num_uniform_blocks; + DCHECK_GE(result.size(), header_size + entry_size); + uint32_t data_size = result.size() - header_size - entry_size; + DCHECK_LT(0u, data_size); + const UniformBlockInfo* entries = LocalGetAs<const UniformBlockInfo*>( + result, header_size, entry_size); + DCHECK(entries); + const char* data = LocalGetAs<const char*>( + result, header_size + entry_size, data_size); + DCHECK(data); + + uint32_t size = 0; + for (uint32_t ii = 0; ii < header->num_uniform_blocks; ++ii) { + uniform_blocks_[ii].binding = static_cast<GLuint>(entries[ii].binding); + uniform_blocks_[ii].data_size = static_cast<GLuint>(entries[ii].data_size); + uniform_blocks_[ii].active_uniform_indices.resize( + entries[ii].active_uniforms); + uniform_blocks_[ii].referenced_by_vertex_shader = static_cast<GLboolean>( + entries[ii].referenced_by_vertex_shader); + uniform_blocks_[ii].referenced_by_fragment_shader = static_cast<GLboolean>( + entries[ii].referenced_by_fragment_shader); + // Uniform block names can't be empty strings. + DCHECK_LT(1u, entries[ii].name_length); + if (entries[ii].name_length > active_uniform_block_max_name_length_) { + active_uniform_block_max_name_length_ = entries[ii].name_length; + } + size += entries[ii].name_length; + DCHECK_GE(data_size, size); + uniform_blocks_[ii].name = std::string(data, entries[ii].name_length - 1); + data += entries[ii].name_length; + size += entries[ii].active_uniforms * sizeof(uint32_t); + DCHECK_GE(data_size, size); + const uint32_t* indices = reinterpret_cast<const uint32_t*>(data); + for (uint32_t uu = 0; uu < entries[ii].active_uniforms; ++uu) { + uniform_blocks_[ii].active_uniform_indices[uu] = + static_cast<GLuint>(indices[uu]); + } + indices += entries[ii].active_uniforms; + data = reinterpret_cast<const char*>(indices); + } + DCHECK_EQ(data_size, size); + cached_es3_uniform_blocks_ = true; +} + +bool ProgramInfoManager::Program::IsCached(ProgramInfoType type) const { + switch (type) { + case kES2: + return cached_es2_; + case kES3UniformBlocks: + return cached_es3_uniform_blocks_; + case kNone: + return true; + default: + NOTREACHED(); + return true; + } } @@ -216,29 +328,42 @@ } ProgramInfoManager::Program* ProgramInfoManager::GetProgramInfo( - GLES2Implementation* gl, GLuint program) { + GLES2Implementation* gl, GLuint program, ProgramInfoType type) { lock_.AssertAcquired(); ProgramInfoMap::iterator it = program_infos_.find(program); if (it == program_infos_.end()) { return NULL; } Program* info = &it->second; - if (info->cached()) + if (info->IsCached(type)) return info; - std::vector<int8> result; - { - base::AutoUnlock unlock(lock_); - // lock_ can't be held across IPC call or else it may deadlock in pepper. - // http://crbug.com/418651 - gl->GetProgramInfoCHROMIUMHelper(program, &result); - } - it = program_infos_.find(program); - if (it == program_infos_.end()) { - return NULL; + std::vector<int8> result; + switch (type) { + case kES2: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + gl->GetProgramInfoCHROMIUMHelper(program, &result); + } + info->UpdateES2(result); + break; + case kES3UniformBlocks: + { + base::AutoUnlock unlock(lock_); + // lock_ can't be held across IPC call or else it may deadlock in + // pepper. http://crbug.com/418651 + + // TODO(zmo): Uncomment the below line once GetUniformBlocksCHROMIUM + // command is implemented. + // gl->GetUniformBlocksCHROMIUMHeler(program, &result); + } + info->UpdateES3UniformBlocks(result); + default: + NOTREACHED(); + return NULL; } - info = &it->second; - info->Update(gl, program, result); return info; } @@ -259,7 +384,23 @@ bool ProgramInfoManager::GetProgramiv( GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + ProgramInfoType type = kNone; + switch (pname) { + case GL_ACTIVE_ATTRIBUTES: + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + case GL_ACTIVE_UNIFORMS: + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + case GL_LINK_STATUS: + type = kES2; + break; + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + type = kES3UniformBlocks; + break; + default: + return false; + } + Program* info = GetProgramInfo(gl, program, type); if (!info) { return false; } @@ -270,7 +411,7 @@ GLES2Implementation* gl, GLuint program, const char* name) { { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kES2); if (info) { return info->GetAttribLocation(name); } @@ -282,7 +423,7 @@ GLES2Implementation* gl, GLuint program, const char* name) { { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kES2); if (info) { return info->GetUniformLocation(name); } @@ -296,7 +437,7 @@ // fetched altogether from the service side. See crbug.com/452104. { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kNone); if (info) { GLint possible_loc = info->GetFragDataLocation(name); if (possible_loc != -1) @@ -306,7 +447,7 @@ GLint loc = gl->GetFragDataLocationHelper(program, name); if (loc != -1) { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kNone); if (info) { info->CacheFragDataLocation(name, loc); } @@ -320,7 +461,7 @@ GLint* size, GLenum* type, char* name) { { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kES2); if (info) { const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); if (attrib_info) { @@ -356,7 +497,7 @@ GLint* size, GLenum* type, char* name) { { base::AutoLock auto_lock(lock_); - Program* info = GetProgramInfo(gl, program); + Program* info = GetProgramInfo(gl, program, kES2); if (info) { const Program::UniformInfo* uniform_info = info->GetUniformInfo(index); if (uniform_info) { @@ -386,6 +527,108 @@ program, index, bufsize, length, size, type, name); } +GLuint ProgramInfoManager::GetUniformBlockIndex( + GLES2Implementation* gl, GLuint program, const char* name) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + return info->GetUniformBlockIndex(name); + } + } + return false; + // TODO(zmo): return gl->GetUniformBlockIndexHelper(program, name); +} + +bool ProgramInfoManager::GetActiveUniformBlockName( + GLES2Implementation* gl, GLuint program, GLuint index, + GLsizei buf_size, GLsizei* length, char* name) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); + if (uniform_block && buf_size >= 1) { + GLsizei written_size = std::min( + buf_size, static_cast<GLsizei>(uniform_block->name.size()) + 1); + if (length) { + *length = written_size - 1; + } + memcpy(name, uniform_block->name.c_str(), written_size); + return true; + } + } + } + return false; + // TODO(zmo): return gl->GetActiveUniformBlockNameHelper( + // program, index, buf_size, length, name); +} + +bool ProgramInfoManager::GetActiveUniformBlockiv( + GLES2Implementation* gl, GLuint program, GLuint index, + GLenum pname, GLint* params) { + { + base::AutoLock auto_lock(lock_); + Program* info = GetProgramInfo(gl, program, kES3UniformBlocks); + if (info) { + const Program::UniformBlock* uniform_block = info->GetUniformBlock(index); + bool valid_pname; + switch (pname) { + case GL_UNIFORM_BLOCK_BINDING: + case GL_UNIFORM_BLOCK_DATA_SIZE: + case GL_UNIFORM_BLOCK_NAME_LENGTH: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + valid_pname = true; + break; + default: + valid_pname = false; + break; + } + if (uniform_block && valid_pname && params) { + switch (pname) { + case GL_UNIFORM_BLOCK_BINDING: + *params = static_cast<GLint>(uniform_block->binding); + break; + case GL_UNIFORM_BLOCK_DATA_SIZE: + *params = static_cast<GLint>(uniform_block->data_size); + break; + case GL_UNIFORM_BLOCK_NAME_LENGTH: + *params = static_cast<GLint>(uniform_block->name.size()) + 1; + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + *params = static_cast<GLint>( + uniform_block->active_uniform_indices.size()); + break; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + for (size_t ii = 0; + ii < uniform_block->active_uniform_indices.size(); ++ii) { + params[ii] = static_cast<GLint>( + uniform_block->active_uniform_indices[ii]); + } + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + *params = static_cast<GLint>( + uniform_block->referenced_by_vertex_shader); + break; + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + *params = static_cast<GLint>( + uniform_block->referenced_by_fragment_shader); + break; + default: + NOTREACHED(); + } + return true; + } + } + } + return false; + // TODO(zmo): return gl->GetActiveUniformBlockivHelper( + // program, index, pname, params); +} + } // namespace gles2 } // namespace gpu
diff --git a/gpu/command_buffer/client/program_info_manager.h b/gpu/command_buffer/client/program_info_manager.h index 712b8ed..efbff73f 100644 --- a/gpu/command_buffer/client/program_info_manager.h +++ b/gpu/command_buffer/client/program_info_manager.h
@@ -5,12 +5,13 @@ #ifndef GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_ #define GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_ -#include <GLES2/gl2.h> +#include <GLES3/gl3.h> #include <string> #include <vector> #include "base/containers/hash_tables.h" +#include "base/gtest_prod_util.h" #include "base/synchronization/lock.h" #include "gles2_impl_export.h" #include "gpu/command_buffer/client/gles2_implementation.h" @@ -48,8 +49,30 @@ GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); + GLuint GetUniformBlockIndex( + GLES2Implementation* gl, GLuint program, const char* name); + + bool GetActiveUniformBlockName( + GLES2Implementation* gl, GLuint program, GLuint index, + GLsizei buf_size, GLsizei* length, char* name); + + bool GetActiveUniformBlockiv( + GLES2Implementation* gl, GLuint program, GLuint index, + GLenum pname, GLint* params); + private: - class Program { + friend class ProgramInfoManagerTest; + + FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES3UniformBlocks); + + enum ProgramInfoType { + kES2, + kES3UniformBlocks, + kNone, + }; + + // Need GLES2_IMPL_EXPORT for tests. + class GLES2_IMPL_EXPORT Program { public: struct UniformInfo { UniformInfo(GLsizei _size, GLenum _type, const std::string& _name); @@ -71,6 +94,17 @@ GLint location; std::string name; }; + struct UniformBlock { + UniformBlock(); + ~UniformBlock(); + + GLuint binding; + GLuint data_size; + std::vector<GLuint> active_uniform_indices; + GLboolean referenced_by_vertex_shader; + GLboolean referenced_by_fragment_shader; + std::string name; + }; Program(); ~Program(); @@ -89,15 +123,20 @@ bool GetProgramiv(GLenum pname, GLint* params); - // Updates the program info after a successful link. - void Update(GLES2Implementation* gl, - GLuint program, - const std::vector<int8>& result); + // Gets the index of a uniform block by name. + GLuint GetUniformBlockIndex(const std::string& name) const; + const UniformBlock* GetUniformBlock(GLuint index) const; - bool cached() const; + // Updates the ES2 only program info after a successful link. + void UpdateES2(const std::vector<int8>& result); + + // Updates the ES3 UniformBlock info after a successful link. + void UpdateES3UniformBlocks(const std::vector<int8>& result); + + bool IsCached(ProgramInfoType type) const; private: - bool cached_; + bool cached_es2_; GLsizei max_attrib_name_length_; @@ -109,13 +148,23 @@ // Uniform info by index. std::vector<UniformInfo> uniform_infos_; - base::hash_map<std::string, GLint> frag_data_locations_; - // This is true if glLinkProgram was successful last time it was called. bool link_status_; + + // BELOW ARE ES3 ONLY INFORMATION. + + bool cached_es3_uniform_blocks_; + + uint32_t active_uniform_block_max_name_length_; + + // Uniform blocks by index. + std::vector<UniformBlock> uniform_blocks_; + + base::hash_map<std::string, GLint> frag_data_locations_; }; - Program* GetProgramInfo(GLES2Implementation* gl, GLuint program); + Program* GetProgramInfo( + GLES2Implementation* gl, GLuint program, ProgramInfoType type); typedef base::hash_map<GLuint, Program> ProgramInfoMap;
diff --git a/gpu/command_buffer/client/program_info_manager_unittest.cc b/gpu/command_buffer/client/program_info_manager_unittest.cc new file mode 100644 index 0000000..a2fc722 --- /dev/null +++ b/gpu/command_buffer/client/program_info_manager_unittest.cc
@@ -0,0 +1,111 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/client/program_info_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +uint32 ComputeOffset(const void* start, const void* position) { + return static_cast<const uint8*>(position) - + static_cast<const uint8*>(start); +} + +} // namespace anonymous + +namespace gpu { +namespace gles2 { + +class ProgramInfoManagerTest : public testing::Test { + public: + ProgramInfoManagerTest() {} + ~ProgramInfoManagerTest() override {} + + protected: + void SetUp() override {} + + void TearDown() override {} +}; + +TEST_F(ProgramInfoManagerTest, UpdateES3UniformBlocks) { + struct Data { + UniformBlocksHeader header; + UniformBlockInfo entry[2]; + char name0[4]; + uint32_t indices0[2]; + char name1[8]; + uint32_t indices1[1]; + }; + Data data; + // The names needs to be of size 4*k-1 to avoid padding in the struct Data. + // This is a testing only problem. + const char* kName[] = { "cow", "chicken" }; + const uint32_t kIndices0[] = { 1, 2 }; + const uint32_t kIndices1[] = { 3 }; + const uint32_t* kIndices[] = { kIndices0, kIndices1 }; + data.header.num_uniform_blocks = 2; + data.entry[0].binding = 0; + data.entry[0].data_size = 8; + data.entry[0].name_offset = ComputeOffset(&data, data.name0); + data.entry[0].name_length = arraysize(data.name0); + data.entry[0].active_uniforms = arraysize(data.indices0); + data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0); + data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true); + data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false); + data.entry[1].binding = 1; + data.entry[1].data_size = 4; + data.entry[1].name_offset = ComputeOffset(&data, data.name1); + data.entry[1].name_length = arraysize(data.name1); + data.entry[1].active_uniforms = arraysize(data.indices1); + data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1); + data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false); + data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true); + memcpy(data.name0, kName[0], arraysize(data.name0)); + data.indices0[0] = kIndices[0][0]; + data.indices0[1] = kIndices[0][1]; + memcpy(data.name1, kName[1], arraysize(data.name1)); + data.indices1[0] = kIndices[1][0]; + + std::vector<int8> result(sizeof(data)); + memcpy(&result[0], &data, sizeof(data)); + + ProgramInfoManager::Program program; + EXPECT_FALSE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); + program.UpdateES3UniformBlocks(result); + EXPECT_TRUE(program.IsCached(ProgramInfoManager::kES3UniformBlocks)); + GLint uniform_block_count = 0; + EXPECT_TRUE(program.GetProgramiv( + GL_ACTIVE_UNIFORM_BLOCKS, &uniform_block_count)); + EXPECT_EQ(data.header.num_uniform_blocks, + static_cast<uint32_t>(uniform_block_count)); + GLint max_name_length = 0; + EXPECT_TRUE(program.GetProgramiv( + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length)); + for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) { + EXPECT_EQ(ii, program.GetUniformBlockIndex(kName[ii])); + const ProgramInfoManager::Program::UniformBlock* info = + program.GetUniformBlock(ii); + EXPECT_TRUE(info != NULL); + EXPECT_EQ(data.entry[ii].binding, info->binding); + EXPECT_EQ(data.entry[ii].data_size, info->data_size); + EXPECT_EQ(data.entry[ii].active_uniforms, + info->active_uniform_indices.size()); + for (uint32_t uu = 0; uu < data.entry[ii].active_uniforms; ++uu) { + EXPECT_EQ(kIndices[ii][uu], info->active_uniform_indices[uu]); + } + EXPECT_EQ(data.entry[ii].referenced_by_vertex_shader, + static_cast<GLboolean>(info->referenced_by_vertex_shader)); + EXPECT_EQ(data.entry[ii].referenced_by_fragment_shader, + static_cast<GLboolean>(info->referenced_by_fragment_shader)); + EXPECT_EQ(kName[ii], info->name); + EXPECT_GE(max_name_length, static_cast<GLint>(info->name.size()) + 1); + } + + EXPECT_EQ(GL_INVALID_INDEX, program.GetUniformBlockIndex("BadName")); + EXPECT_EQ(NULL, program.GetUniformBlock(data.header.num_uniform_blocks)); +} + +} // namespace gles2 +} // namespace gpu +
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 138d858..73a1059 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp
@@ -178,6 +178,7 @@ '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',
diff --git a/gpu/gpu_unittests.isolate b/gpu/gpu_unittests.isolate index 3380606..48fb1c5 100644 --- a/gpu/gpu_unittests.isolate +++ b/gpu/gpu_unittests.isolate
@@ -21,6 +21,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -37,6 +39,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }], @@ -49,6 +53,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ios/chrome/browser/arch_util.cc b/ios/chrome/browser/arch_util.cc new file mode 100644 index 0000000..eb0111b --- /dev/null +++ b/ios/chrome/browser/arch_util.cc
@@ -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. + +#include "ios/chrome/browser/arch_util.h" + +namespace arch_util { + +// const char[] can be initialized only with literal. +#define _ARM_ARCH "arm" +#define _ARM_64_ARCH "arm64" + +const char kARMArch[] = _ARM_ARCH; + +const char kARM64Arch[] = _ARM_64_ARCH; + +#if defined(__LP64__) +const char kCurrentArch[] = _ARM_64_ARCH; +#else +const char kCurrentArch[] = _ARM_ARCH; +#endif + +} // namespace arch_util
diff --git a/ios/chrome/browser/arch_util.h b/ios/chrome/browser/arch_util.h new file mode 100644 index 0000000..74ab9f2 --- /dev/null +++ b/ios/chrome/browser/arch_util.h
@@ -0,0 +1,24 @@ +// 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 IOS_CHROME_BROWSER_ARCH_UTIL_H_ +#define IOS_CHROME_BROWSER_ARCH_UTIL_H_ + +namespace arch_util { + +// Architecture of the currently running binary. Depends on the combination of +// app binary archs and device's arch. e.g. for arm7/arm64 fat binary running +// on 64-bit processor the value will be "arm64", but for the same fat binary +// running on 32-bit processor the value will be "arm". +extern const char kCurrentArch[]; + +// Constant for 32-bit ARM architecture. +extern const char kARMArch[]; + +// Constant for 64-bit ARM architecture. +extern const char kARM64Arch[]; + +} // namespace arch_util + +#endif // IOS_CHROME_BROWSER_ARCH_UTIL_H_
diff --git a/ios/chrome/browser/chrome_url_constants.cc b/ios/chrome/browser/chrome_url_constants.cc new file mode 100644 index 0000000..f8b2c91 --- /dev/null +++ b/ios/chrome/browser/chrome_url_constants.cc
@@ -0,0 +1,9 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/chrome_url_constants.h" + +const char kChromeUIExternalFileHost[] = "external-file"; +const char kChromeUIOmahaHost[] = "omaha"; +const char kChromeUISetUpForTestingHost[] = "setupfortesting";
diff --git a/ios/chrome/browser/chrome_url_constants.h b/ios/chrome/browser/chrome_url_constants.h new file mode 100644 index 0000000..df061b46 --- /dev/null +++ b/ios/chrome/browser/chrome_url_constants.h
@@ -0,0 +1,15 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Contains constants for known URLs and portions thereof. + +#ifndef IOS_CHROME_BROWSER_CHROME_URL_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_CHROME_URL_CONSTANTS_H_ + +// URL components for Chrome on iOS. +extern const char kChromeUIExternalFileHost[]; +extern const char kChromeUIOmahaHost[]; +extern const char kChromeUISetUpForTestingHost[]; + +#endif // IOS_CHROME_BROWSER_CHROME_URL_CONSTANTS_H_
diff --git a/ios/chrome/browser/translate/translate_service_ios_unittest.cc b/ios/chrome/browser/translate/translate_service_ios_unittest.cc index 0cbd6b00..f9ea614b 100644 --- a/ios/chrome/browser/translate/translate_service_ios_unittest.cc +++ b/ios/chrome/browser/translate/translate_service_ios_unittest.cc
@@ -10,9 +10,6 @@ #include "url/gurl.h" TEST(TranslateServiceIOSTest, CheckTranslatableURL) { - // TODO(droger): Remove this once http://crbug.com/437332 is fixed. - ios::TestChromeProviderInitializer test_chrome_provider_initializer; - GURL empty_url = GURL(std::string()); EXPECT_FALSE(TranslateServiceIOS::IsTranslatableURL(empty_url));
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 76cb0c8d..89f7abe 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -48,8 +48,12 @@ 'browser/application_context.h', 'browser/application_context_impl.cc', 'browser/application_context_impl.h', + 'browser/arch_util.cc', + 'browser/arch_util.h', 'browser/browser_state/browser_state_otr_helper.cc', 'browser/browser_state/browser_state_otr_helper.h', + 'browser/chrome_url_constants.cc', + 'browser/chrome_url_constants.h', 'browser/infobars/confirm_infobar_controller.h', 'browser/infobars/confirm_infobar_controller.mm', 'browser/infobars/infobar.h',
diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp index 17370a9..ce9adfa 100644 --- a/ios/chrome/ios_chrome_tests.gyp +++ b/ios/chrome/ios_chrome_tests.gyp
@@ -11,7 +11,6 @@ 'type': '<(gtest_target_type)', 'dependencies': [ '../../base/base.gyp:base', - '../../base/base.gyp:run_all_unittests', '../../base/base.gyp:test_support_base', '../../net/net.gyp:net_test_support', '../../testing/gmock.gyp:gmock', @@ -21,6 +20,7 @@ '../web/ios_web.gyp:ios_web', '../web/ios_web.gyp:test_support_ios_web', 'ios_chrome.gyp:ios_chrome_browser', + 'ios_chrome_test_support', ], 'sources': [ 'browser/net/image_fetcher_unittest.mm', @@ -35,10 +35,14 @@ 'type': 'static_library', 'dependencies': [ '../../base/base.gyp:base', + '../../testing/gtest.gyp:gtest', '../provider/ios_provider_chrome.gyp:ios_provider_chrome_browser', 'ios_chrome.gyp:ios_chrome_browser', ], 'sources': [ + 'test/ios_chrome_unit_test_suite.cc', + 'test/ios_chrome_unit_test_suite.h', + 'test/run_all_unittests.cc', 'test/testing_application_context.cc', 'test/testing_application_context.h', ],
diff --git a/ios/chrome/test/ios_chrome_unit_test_suite.cc b/ios/chrome/test/ios_chrome_unit_test_suite.cc new file mode 100644 index 0000000..1043e59e --- /dev/null +++ b/ios/chrome/test/ios_chrome_unit_test_suite.cc
@@ -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. + +#include "ios/chrome/test/ios_chrome_unit_test_suite.h" + +#include "ios/public/test/test_chrome_browser_provider.h" +#include "ios/public/test/test_chrome_provider_initializer.h" +#include "ios/web/public/web_client.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ui_base_paths.h" +#include "url/url_util.h" + +namespace { + +class IOSChromeUnitTestSuiteInitializer + : public testing::EmptyTestEventListener { + public: + IOSChromeUnitTestSuiteInitializer() {} + ~IOSChromeUnitTestSuiteInitializer() override {} + + void OnTestStart(const testing::TestInfo& test_info) override { + web_client_.reset(new web::WebClient()); + web::SetWebClient(web_client_.get()); + test_ios_chrome_provider_initializer_.reset( + new ios::TestChromeProviderInitializer()); + } + + void OnTestEnd(const testing::TestInfo& test_info) override { + web_client_.reset(); + web::SetWebClient(NULL); + test_ios_chrome_provider_initializer_.reset(); + } + + private: + scoped_ptr<web::WebClient> web_client_; + scoped_ptr<ios::TestChromeProviderInitializer> + test_ios_chrome_provider_initializer_; + DISALLOW_COPY_AND_ASSIGN(IOSChromeUnitTestSuiteInitializer); +}; + +} // namespace + +IOSChromeUnitTestSuite::IOSChromeUnitTestSuite(int argc, char** argv) + : base::TestSuite(argc, argv) { +} + +IOSChromeUnitTestSuite::~IOSChromeUnitTestSuite() { +} + +void IOSChromeUnitTestSuite::Initialize() { + // Add an additional listener to do the extra initialization for unit tests. + // It will be started before the base class listeners and ended after the + // base class listeners. + testing::TestEventListeners& listeners = + testing::UnitTest::GetInstance()->listeners(); + listeners.Append(new IOSChromeUnitTestSuiteInitializer); + + ui::RegisterPathProvider(); + + { + ios::TestChromeBrowserProvider provider; + url::AddStandardScheme(provider.GetChromeUIScheme()); + } + + base::TestSuite::Initialize(); +}
diff --git a/ios/chrome/test/ios_chrome_unit_test_suite.h b/ios/chrome/test/ios_chrome_unit_test_suite.h new file mode 100644 index 0000000..5185ab56 --- /dev/null +++ b/ios/chrome/test/ios_chrome_unit_test_suite.h
@@ -0,0 +1,25 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_TEST_IOS_CHROME_UNIT_TEST_SUITE_H_ +#define IOS_CHROME_TEST_IOS_CHROME_UNIT_TEST_SUITE_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/test/test_suite.h" + +// Test suite for unit tests. +class IOSChromeUnitTestSuite : public base::TestSuite { + public: + IOSChromeUnitTestSuite(int argc, char** argv); + ~IOSChromeUnitTestSuite() override; + + // base::TestSuite overrides: + void Initialize() override; + + private: + DISALLOW_COPY_AND_ASSIGN(IOSChromeUnitTestSuite); +}; + +#endif // IOS_CHROME_TEST_IOS_CHROME_UNIT_TEST_SUITE_H_
diff --git a/ios/chrome/test/run_all_unittests.cc b/ios/chrome/test/run_all_unittests.cc new file mode 100644 index 0000000..f7c0f95 --- /dev/null +++ b/ios/chrome/test/run_all_unittests.cc
@@ -0,0 +1,14 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/test/launcher/unit_test_launcher.h" +#include "ios/chrome/test/ios_chrome_unit_test_suite.h" + +int main(int argc, char** argv) { + IOSChromeUnitTestSuite test_suite(argc, argv); + return base::LaunchUnitTests( + argc, argv, + base::Bind(&IOSChromeUnitTestSuite::Run, base::Unretained(&test_suite))); +}
diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h index 2d677aa..e57008b 100644 --- a/ipc/ipc_message.h +++ b/ipc/ipc_message.h
@@ -8,7 +8,6 @@ #include <string> #include "base/basictypes.h" -#include "base/debug/trace_event.h" #include "base/memory/ref_counted.h" #include "base/pickle.h" #include "base/trace_event/trace_event.h"
diff --git a/media/BUILD.gn b/media/BUILD.gn index c4d3ea3..f71d6f8 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -347,7 +347,7 @@ } } - if (cpu_arch != "arm" && is_chromeos && use_x11) { + if (cpu_arch != "arm" && is_chromeos) { sources += [ "filters/h264_bitstream_buffer.cc", "filters/h264_bitstream_buffer.h",
diff --git a/media/OWNERS b/media/OWNERS index b7a0a75..fdb8c86 100644 --- a/media/OWNERS +++ b/media/OWNERS
@@ -3,7 +3,6 @@ jrummell@chromium.org sandersd@chromium.org scherkus@chromium.org -vrk@chromium.org wolenetz@chromium.org xhwang@chromium.org
diff --git a/media/blink/BUILD.gn b/media/blink/BUILD.gn index 9db1cb9..48dd8dcc 100644 --- a/media/blink/BUILD.gn +++ b/media/blink/BUILD.gn
@@ -15,6 +15,7 @@ "//media", "//media:shared_memory_support", "//net", + "//skia", "//third_party/WebKit/public:blink", "//ui/gfx", "//ui/gfx/geometry",
diff --git a/media/blink/media_blink.gyp b/media/blink/media_blink.gyp index 71751fe..6c6ccc7 100644 --- a/media/blink/media_blink.gyp +++ b/media/blink/media_blink.gyp
@@ -15,6 +15,7 @@ '../../gpu/blink/gpu_blink.gyp:gpu_blink', '../../ui/gfx/gfx.gyp:gfx_geometry', '../../net/net.gyp:net', + '../../skia/skia.gyp:skia', '../../third_party/WebKit/public/blink.gyp:blink', '../media.gyp:media', '../media.gyp:shared_memory_support',
diff --git a/media/blink/webcontentdecryptionmoduleaccess_impl.cc b/media/blink/webcontentdecryptionmoduleaccess_impl.cc index ec4e9194..ab98b43 100644 --- a/media/blink/webcontentdecryptionmoduleaccess_impl.cc +++ b/media/blink/webcontentdecryptionmoduleaccess_impl.cc
@@ -2,24 +2,31 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "webcontentdecryptionmoduleaccess_impl.h" +#include "media/blink/webcontentdecryptionmoduleaccess_impl.h" #include "base/basictypes.h" #include "base/bind.h" #include "base/location.h" #include "base/message_loop/message_loop_proxy.h" -#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h" -#include "webcontentdecryptionmodule_impl.h" +#include "media/blink/webencryptedmediaclient_impl.h" namespace media { // The caller owns the created cdm (passed back using |result|). -static void CreateCdm(CdmFactory* cdm_factory, - blink::WebSecurityOrigin security_origin, - blink::WebString key_system, +static void CreateCdm(const base::WeakPtr<WebEncryptedMediaClientImpl>& client, + const blink::WebString& key_system, + const blink::WebSecurityOrigin& security_origin, blink::WebContentDecryptionModuleResult result) { - WebContentDecryptionModuleImpl::Create(cdm_factory, security_origin, - key_system, result); + // If |client| is gone (due to the frame getting destroyed), it is + // impossible to create the CDM, so fail. + if (!client) { + result.completeWithError( + blink::WebContentDecryptionModuleExceptionInvalidStateError, 0, + "Failed to create CDM."); + return; + } + + client->CreateCdm(key_system, security_origin, result); } WebContentDecryptionModuleAccessImpl* @@ -27,20 +34,20 @@ const blink::WebString& key_system, const blink::WebMediaKeySystemConfiguration& configuration, const blink::WebSecurityOrigin& security_origin, - CdmFactory* cdm_factory) { + const base::WeakPtr<WebEncryptedMediaClientImpl>& client) { return new WebContentDecryptionModuleAccessImpl(key_system, configuration, - security_origin, cdm_factory); + security_origin, client); } WebContentDecryptionModuleAccessImpl::WebContentDecryptionModuleAccessImpl( const blink::WebString& key_system, const blink::WebMediaKeySystemConfiguration& configuration, const blink::WebSecurityOrigin& security_origin, - CdmFactory* cdm_factory) + const base::WeakPtr<WebEncryptedMediaClientImpl>& client) : key_system_(key_system), configuration_(configuration), security_origin_(security_origin), - cdm_factory_(cdm_factory) { + client_(client) { } WebContentDecryptionModuleAccessImpl::~WebContentDecryptionModuleAccessImpl() { @@ -58,8 +65,8 @@ // blink side, copy all values needed by CreateCdm() in case the blink object // gets garbage-collected. base::MessageLoopProxy::current()->PostTask( - FROM_HERE, base::Bind(&CreateCdm, cdm_factory_, security_origin_, - key_system_, result)); + FROM_HERE, + base::Bind(&CreateCdm, client_, key_system_, security_origin_, result)); } } // namespace media
diff --git a/media/blink/webcontentdecryptionmoduleaccess_impl.h b/media/blink/webcontentdecryptionmoduleaccess_impl.h index 9d54823..131bb21 100644 --- a/media/blink/webcontentdecryptionmoduleaccess_impl.h +++ b/media/blink/webcontentdecryptionmoduleaccess_impl.h
@@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "media/base/cdm_factory.h" #include "third_party/WebKit/public/platform/WebContentDecryptionModuleAccess.h" #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" @@ -19,6 +20,8 @@ namespace media { +class WebEncryptedMediaClientImpl; + class WebContentDecryptionModuleAccessImpl : public blink::WebContentDecryptionModuleAccess { public: @@ -26,7 +29,7 @@ const blink::WebString& key_system, const blink::WebMediaKeySystemConfiguration& configuration, const blink::WebSecurityOrigin& security_origin, - CdmFactory* cdm_factory); + const base::WeakPtr<WebEncryptedMediaClientImpl>& client); virtual ~WebContentDecryptionModuleAccessImpl(); // blink::WebContentDecryptionModuleAccess interface. @@ -39,14 +42,16 @@ const blink::WebString& key_system, const blink::WebMediaKeySystemConfiguration& configuration, const blink::WebSecurityOrigin& security_origin, - CdmFactory* cdm_factory); + const base::WeakPtr<WebEncryptedMediaClientImpl>& client); DISALLOW_COPY_AND_ASSIGN(WebContentDecryptionModuleAccessImpl); blink::WebString key_system_; blink::WebMediaKeySystemConfiguration configuration_; blink::WebSecurityOrigin security_origin_; - CdmFactory* cdm_factory_; + + // Keep a WeakPtr as client is owned by render_frame_impl. + base::WeakPtr<WebEncryptedMediaClientImpl> client_; }; } // namespace media
diff --git a/media/blink/webencryptedmediaclient_impl.cc b/media/blink/webencryptedmediaclient_impl.cc index 5cd9611..264d5c6d 100644 --- a/media/blink/webencryptedmediaclient_impl.cc +++ b/media/blink/webencryptedmediaclient_impl.cc
@@ -15,6 +15,7 @@ #include "third_party/WebKit/public/platform/WebMediaKeySystemConfiguration.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebVector.h" +#include "webcontentdecryptionmodule_impl.h" #include "webcontentdecryptionmoduleaccess_impl.h" namespace media { @@ -189,7 +190,7 @@ WebEncryptedMediaClientImpl::WebEncryptedMediaClientImpl( scoped_ptr<CdmFactory> cdm_factory, MediaPermission* media_permission) - : cdm_factory_(cdm_factory.Pass()) { + : cdm_factory_(cdm_factory.Pass()), weak_factory_(this) { // TODO(sandersd): Use |media_permission| to check for media permissions in // this class. DCHECK(media_permission); @@ -237,7 +238,7 @@ reporter->ReportSupported(); request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create( request.keySystem(), blink::WebMediaKeySystemConfiguration(), - request.securityOrigin(), cdm_factory_.get())); + request.securityOrigin(), weak_factory_.GetWeakPtr())); return; } @@ -250,7 +251,7 @@ reporter->ReportSupported(); request.requestSucceeded(WebContentDecryptionModuleAccessImpl::Create( request.keySystem(), accumulated_configuration, - request.securityOrigin(), cdm_factory_.get())); + request.securityOrigin(), weak_factory_.GetWeakPtr())); return; } } @@ -260,6 +261,14 @@ "None of the requested configurations were supported."); } +void WebEncryptedMediaClientImpl::CreateCdm( + const blink::WebString& key_system, + const blink::WebSecurityOrigin& security_origin, + blink::WebContentDecryptionModuleResult result) { + WebContentDecryptionModuleImpl::Create(cdm_factory_.get(), security_origin, + key_system, result); +} + // Lazily create Reporters. WebEncryptedMediaClientImpl::Reporter* WebEncryptedMediaClientImpl::GetReporter( const std::string& key_system) {
diff --git a/media/blink/webencryptedmediaclient_impl.h b/media/blink/webencryptedmediaclient_impl.h index d101ecb..7b606dc4 100644 --- a/media/blink/webencryptedmediaclient_impl.h +++ b/media/blink/webencryptedmediaclient_impl.h
@@ -9,8 +9,10 @@ #include "base/containers/scoped_ptr_hash_map.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "media/base/cdm_factory.h" #include "media/base/media_export.h" +#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h" #include "third_party/WebKit/public/platform/WebEncryptedMediaClient.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h" @@ -29,6 +31,12 @@ virtual void requestMediaKeySystemAccess( blink::WebEncryptedMediaRequest request); + // Create the CDM for |key_system| and |security_origin|. The caller owns + // the created cdm (passed back using |result|). + void CreateCdm(const blink::WebString& key_system, + const blink::WebSecurityOrigin& security_origin, + blink::WebContentDecryptionModuleResult result); + private: // Report usage of key system to UMA. There are 2 different counts logged: // 1. The key system is requested. @@ -45,6 +53,8 @@ Reporters reporters_; scoped_ptr<CdmFactory> cdm_factory_; + + base::WeakPtrFactory<WebEncryptedMediaClientImpl> weak_factory_; }; } // namespace media
diff --git a/media/media_unittests.isolate b/media/media_unittests.isolate index cea8c33f..669f3fc3 100644 --- a/media/media_unittests.isolate +++ b/media/media_unittests.isolate
@@ -31,6 +31,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/xvfb.py', @@ -48,6 +50,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.so', @@ -63,6 +67,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '<(PRODUCT_DIR)/ffmpegsumo.dll',
diff --git a/media/test/data/eme_player_js/player_utils.js b/media/test/data/eme_player_js/player_utils.js index 60d4b613..23f4a29 100644 --- a/media/test/data/eme_player_js/player_utils.js +++ b/media/test/data/eme_player_js/player_utils.js
@@ -85,7 +85,8 @@ this.registerDefaultEventListeners(player); Utils.timeLog('Setting video media keys: ' + player.testConfig.keySystem); - return navigator.requestMediaKeySystemAccess(player.testConfig.keySystem) + return navigator.requestMediaKeySystemAccess( + player.testConfig.keySystem, [{}]) .then(function(access) { return access.createMediaKeys(); }) .then(function(mediaKeys) { return player.video.setMediaKeys(mediaKeys);
diff --git a/media/video/picture.cc b/media/video/picture.cc index 6b4c927..6205795 100644 --- a/media/video/picture.cc +++ b/media/video/picture.cc
@@ -7,9 +7,17 @@ namespace media { PictureBuffer::PictureBuffer(int32 id, gfx::Size size, uint32 texture_id) + : id_(id), size_(size), texture_id_(texture_id), internal_texture_id_(0) { +} + +PictureBuffer::PictureBuffer(int32 id, + gfx::Size size, + uint32 texture_id, + uint32 internal_texture_id) : id_(id), size_(size), - texture_id_(texture_id) { + texture_id_(texture_id), + internal_texture_id_(internal_texture_id) { } PictureBuffer::PictureBuffer(int32 id, @@ -19,6 +27,7 @@ : id_(id), size_(size), texture_id_(texture_id), + internal_texture_id_(0), texture_mailbox_(texture_mailbox) { }
diff --git a/media/video/picture.h b/media/video/picture.h index 2fe10bf2..1fb5096 100644 --- a/media/video/picture.h +++ b/media/video/picture.h
@@ -21,6 +21,10 @@ PictureBuffer(int32 id, gfx::Size size, uint32 texture_id, + uint32 internal_texture_id); + PictureBuffer(int32 id, + gfx::Size size, + uint32 texture_id, const gpu::Mailbox& texture_mailbox); // Returns the client-specified id of the buffer. @@ -40,6 +44,8 @@ return texture_id_; } + uint32 internal_texture_id() const { return internal_texture_id_; } + const gpu::Mailbox& texture_mailbox() const { return texture_mailbox_; } @@ -48,6 +54,7 @@ int32 id_; gfx::Size size_; uint32 texture_id_; + uint32 internal_texture_id_; gpu::Mailbox texture_mailbox_; };
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.cc b/mojo/services/html_viewer/weblayertreeview_impl.cc index 0c2811a9..a9a6945e 100644 --- a/mojo/services/html_viewer/weblayertreeview_impl.cc +++ b/mojo/services/html_viewer/weblayertreeview_impl.cc
@@ -59,7 +59,7 @@ WebLayerTreeViewImpl::~WebLayerTreeViewImpl() { } -void WebLayerTreeViewImpl::WillBeginMainFrame(int frame_id) { +void WebLayerTreeViewImpl::WillBeginMainFrame() { } void WebLayerTreeViewImpl::DidBeginMainFrame() {
diff --git a/mojo/services/html_viewer/weblayertreeview_impl.h b/mojo/services/html_viewer/weblayertreeview_impl.h index 42ae1bc..269fc9f4 100644 --- a/mojo/services/html_viewer/weblayertreeview_impl.h +++ b/mojo/services/html_viewer/weblayertreeview_impl.h
@@ -48,7 +48,7 @@ void set_view(mojo::View* view) { view_ = view; } // cc::LayerTreeHostClient implementation. - void WillBeginMainFrame(int frame_id) override; + void WillBeginMainFrame() override; void DidBeginMainFrame() override; void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override;
diff --git a/mojo/services/network/udp_socket_unittest.cc b/mojo/services/network/udp_socket_unittest.cc deleted file mode 100644 index ddb9d93d..0000000 --- a/mojo/services/network/udp_socket_unittest.cc +++ /dev/null
@@ -1,458 +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 "base/at_exit.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "mojo/services/network/public/cpp/udp_socket_wrapper.h" -#include "mojo/services/network/public/interfaces/network_service.mojom.h" -#include "mojo/services/network/public/interfaces/udp_socket.mojom.h" -#include "mojo/shell/shell_test_helper.h" -#include "net/base/net_errors.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/mojo/src/mojo/public/cpp/bindings/callback.h" -#include "url/gurl.h" - -namespace mojo { -namespace service { -namespace { - -NetAddressPtr GetLocalHostWithAnyPort() { - NetAddressPtr addr(NetAddress::New()); - addr->family = NET_ADDRESS_FAMILY_IPV4; - addr->ipv4 = NetAddressIPv4::New(); - addr->ipv4->port = 0; - addr->ipv4->addr.resize(4); - addr->ipv4->addr[0] = 127; - addr->ipv4->addr[1] = 0; - addr->ipv4->addr[2] = 0; - addr->ipv4->addr[3] = 1; - - return addr.Pass(); -} - -Array<uint8_t> CreateTestMessage(uint8_t initial, size_t size) { - Array<uint8_t> array(size); - for (size_t i = 0; i < size; ++i) - array[i] = static_cast<uint8_t>((i + initial) % 256); - return array.Pass(); -} - -template <typename CallbackType> -class TestCallbackBase { - public: - TestCallbackBase() : state_(nullptr), run_loop_(nullptr), ran_(false) {} - - ~TestCallbackBase() { - state_->set_test_callback(nullptr); - } - - CallbackType callback() const { return callback_; } - - void WaitForResult() { - if (ran_) - return; - - base::RunLoop run_loop; - run_loop_ = &run_loop; - run_loop.Run(); - run_loop_ = nullptr; - } - - protected: - struct StateBase : public CallbackType::Runnable { - StateBase() : test_callback_(nullptr) {} - virtual ~StateBase() {} - - void set_test_callback(TestCallbackBase* test_callback) { - test_callback_ = test_callback; - } - - protected: - void NotifyRun() const { - if (test_callback_) { - test_callback_->ran_ = true; - if (test_callback_->run_loop_) - test_callback_->run_loop_->Quit(); - } - } - - TestCallbackBase* test_callback_; - - private: - DISALLOW_COPY_AND_ASSIGN(StateBase); - }; - - // Takes ownership of |state|, and guarantees that it lives at least as long - // as this object. - void Initialize(StateBase* state) { - state_ = state; - state_->set_test_callback(this); - callback_ = CallbackType( - static_cast<typename CallbackType::Runnable*>(state_)); - } - - private: - // The lifespan is managed by |callback_| (and its copies). - StateBase* state_; - CallbackType callback_; - base::RunLoop* run_loop_; - bool ran_; - - DISALLOW_COPY_AND_ASSIGN(TestCallbackBase); -}; - -class TestCallback : public TestCallbackBase<Callback<void(NetworkErrorPtr)>> { - public: - TestCallback() { - Initialize(new State()); - } - ~TestCallback() {} - - const NetworkErrorPtr& result() const { return result_; } - - private: - struct State: public StateBase { - ~State() override {} - - void Run(NetworkErrorPtr result) const override { - if (test_callback_) { - TestCallback* callback = static_cast<TestCallback*>(test_callback_); - callback->result_ = result.Pass(); - } - NotifyRun(); - } - }; - - NetworkErrorPtr result_; -}; - -class TestCallbackWithAddress - : public TestCallbackBase<Callback<void(NetworkErrorPtr, NetAddressPtr)>> { - public: - TestCallbackWithAddress() { - Initialize(new State()); - } - ~TestCallbackWithAddress() {} - - const NetworkErrorPtr& result() const { return result_; } - const NetAddressPtr& net_address() const { return net_address_; } - - private: - struct State : public StateBase { - ~State() override {} - - void Run(NetworkErrorPtr result, NetAddressPtr net_address) const override { - if (test_callback_) { - TestCallbackWithAddress* callback = - static_cast<TestCallbackWithAddress*>(test_callback_); - callback->result_ = result.Pass(); - callback->net_address_ = net_address.Pass(); - } - NotifyRun(); - } - }; - - NetworkErrorPtr result_; - NetAddressPtr net_address_; -}; - -class TestCallbackWithUint32 - : public TestCallbackBase<Callback<void(uint32_t)>> { - public: - TestCallbackWithUint32() : result_(0) { - Initialize(new State()); - } - ~TestCallbackWithUint32() {} - - uint32_t result() const { return result_; } - - private: - struct State : public StateBase { - ~State() override {} - - void Run(uint32_t result) const override { - if (test_callback_) { - TestCallbackWithUint32* callback = - static_cast<TestCallbackWithUint32*>(test_callback_); - callback->result_ = result; - } - NotifyRun(); - } - }; - - uint32_t result_; -}; - -class TestReceiveCallback - : public TestCallbackBase< - Callback<void(NetworkErrorPtr, NetAddressPtr, Array<uint8_t>)>> { - public: - TestReceiveCallback() { - Initialize(new State()); - } - ~TestReceiveCallback() {} - - const NetworkErrorPtr& result() const { return result_; } - const NetAddressPtr& src_addr() const { return src_addr_; } - const Array<uint8_t>& data() const { return data_; } - - private: - struct State : public StateBase { - ~State() override {} - - void Run(NetworkErrorPtr result, - NetAddressPtr src_addr, - Array<uint8_t> data) const override { - if (test_callback_) { - TestReceiveCallback* callback = - static_cast<TestReceiveCallback*>(test_callback_); - callback->result_ = result.Pass(); - callback->src_addr_ = src_addr.Pass(); - callback->data_ = data.Pass(); - } - NotifyRun(); - } - }; - - NetworkErrorPtr result_; - NetAddressPtr src_addr_; - Array<uint8_t> data_; -}; - -class UDPSocketTest : public testing::Test { - public: - UDPSocketTest() {} - virtual ~UDPSocketTest() {} - - virtual void SetUp() override { - test_helper_.Init(); - - test_helper_.application_manager()->ConnectToService( - GURL("mojo:network_service"), &network_service_); - - network_service_->CreateUDPSocket(GetProxy(&udp_socket_)); - udp_socket_.set_client(&udp_socket_client_); - } - - protected: - struct ReceiveResult { - NetworkErrorPtr result; - NetAddressPtr addr; - Array<uint8_t> data; - }; - - class UDPSocketClientImpl : public UDPSocketClient { - public: - - UDPSocketClientImpl() : run_loop_(nullptr), expected_receive_count_(0) {} - - ~UDPSocketClientImpl() override { - while (!results_.empty()) { - delete results_.front(); - results_.pop(); - } - } - - void OnReceived(NetworkErrorPtr result, - NetAddressPtr src_addr, - Array<uint8_t> data) override { - ReceiveResult* entry = new ReceiveResult(); - entry->result = result.Pass(); - entry->addr = src_addr.Pass(); - entry->data = data.Pass(); - - results_.push(entry); - - if (results_.size() == expected_receive_count_ && run_loop_) { - expected_receive_count_ = 0; - run_loop_->Quit(); - } - } - - base::RunLoop* run_loop_; - std::queue<ReceiveResult*> results_; - size_t expected_receive_count_; - - DISALLOW_COPY_AND_ASSIGN(UDPSocketClientImpl); - }; - - std::queue<ReceiveResult*>* GetReceiveResults() { - return &udp_socket_client_.results_; - } - - void WaitForReceiveResults(size_t count) { - if (GetReceiveResults()->size() == count) - return; - - udp_socket_client_.expected_receive_count_ = count; - base::RunLoop run_loop; - udp_socket_client_.run_loop_ = &run_loop; - run_loop.Run(); - udp_socket_client_.run_loop_ = nullptr; - } - - base::ShadowingAtExitManager at_exit_; - shell::ShellTestHelper test_helper_; - - NetworkServicePtr network_service_; - UDPSocketPtr udp_socket_; - UDPSocketClientImpl udp_socket_client_; - - DISALLOW_COPY_AND_ASSIGN(UDPSocketTest); -}; - -} // namespace - -TEST_F(UDPSocketTest, Settings) { - TestCallback callback1; - udp_socket_->AllowAddressReuse(callback1.callback()); - callback1.WaitForResult(); - EXPECT_EQ(net::OK, callback1.result()->code); - - // Should fail because the socket hasn't been bound. - TestCallback callback2; - udp_socket_->SetSendBufferSize(1024, callback2.callback()); - callback2.WaitForResult(); - EXPECT_NE(net::OK, callback2.result()->code); - - // Should fail because the socket hasn't been bound. - TestCallback callback3; - udp_socket_->SetReceiveBufferSize(2048, callback3.callback()); - callback3.WaitForResult(); - EXPECT_NE(net::OK, callback3.result()->code); - - TestCallbackWithAddress callback4; - udp_socket_->Bind(GetLocalHostWithAnyPort(), callback4.callback()); - callback4.WaitForResult(); - EXPECT_EQ(net::OK, callback4.result()->code); - EXPECT_NE(0u, callback4.net_address()->ipv4->port); - - // Should fail because the socket has been bound. - TestCallback callback5; - udp_socket_->AllowAddressReuse(callback5.callback()); - callback5.WaitForResult(); - EXPECT_NE(net::OK, callback5.result()->code); - - TestCallback callback6; - udp_socket_->SetSendBufferSize(1024, callback6.callback()); - callback6.WaitForResult(); - EXPECT_EQ(net::OK, callback6.result()->code); - - TestCallback callback7; - udp_socket_->SetReceiveBufferSize(2048, callback7.callback()); - callback7.WaitForResult(); - EXPECT_EQ(net::OK, callback7.result()->code); - - TestCallbackWithUint32 callback8; - udp_socket_->NegotiateMaxPendingSendRequests(0, callback8.callback()); - callback8.WaitForResult(); - EXPECT_GT(callback8.result(), 0u); - - TestCallbackWithUint32 callback9; - udp_socket_->NegotiateMaxPendingSendRequests(16, callback9.callback()); - callback9.WaitForResult(); - EXPECT_GT(callback9.result(), 0u); -} - -TEST_F(UDPSocketTest, TestReadWrite) { - TestCallbackWithAddress callback1; - udp_socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback()); - callback1.WaitForResult(); - ASSERT_EQ(net::OK, callback1.result()->code); - ASSERT_NE(0u, callback1.net_address()->ipv4->port); - - NetAddressPtr server_addr = callback1.net_address().Clone(); - - UDPSocketPtr client_socket; - network_service_->CreateUDPSocket(GetProxy(&client_socket)); - - TestCallbackWithAddress callback2; - client_socket->Bind(GetLocalHostWithAnyPort(), callback2.callback()); - callback2.WaitForResult(); - ASSERT_EQ(net::OK, callback2.result()->code); - ASSERT_NE(0u, callback2.net_address()->ipv4->port); - - NetAddressPtr client_addr = callback2.net_address().Clone(); - - const size_t kDatagramCount = 6; - const size_t kDatagramSize = 255; - udp_socket_->ReceiveMore(kDatagramCount); - - for (size_t i = 0; i < kDatagramCount; ++i) { - TestCallback callback; - client_socket->SendTo( - server_addr.Clone(), - CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize), - callback.callback()); - callback.WaitForResult(); - EXPECT_EQ(255, callback.result()->code); - } - - WaitForReceiveResults(kDatagramCount); - for (size_t i = 0; i < kDatagramCount; ++i) { - scoped_ptr<ReceiveResult> result(GetReceiveResults()->front()); - GetReceiveResults()->pop(); - - EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code); - EXPECT_TRUE(result->addr.Equals(client_addr)); - EXPECT_TRUE(result->data.Equals( - CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize))); - } -} - -TEST_F(UDPSocketTest, TestUDPSocketWrapper) { - UDPSocketWrapper udp_socket(udp_socket_.Pass(), 4, 4); - - TestCallbackWithAddress callback1; - udp_socket.Bind(GetLocalHostWithAnyPort(), callback1.callback()); - callback1.WaitForResult(); - ASSERT_EQ(net::OK, callback1.result()->code); - ASSERT_NE(0u, callback1.net_address()->ipv4->port); - - NetAddressPtr server_addr = callback1.net_address().Clone(); - - UDPSocketPtr raw_client_socket; - network_service_->CreateUDPSocket(GetProxy(&raw_client_socket)); - UDPSocketWrapper client_socket(raw_client_socket.Pass(), 4, 4); - - TestCallbackWithAddress callback2; - client_socket.Bind(GetLocalHostWithAnyPort(), callback2.callback()); - callback2.WaitForResult(); - ASSERT_EQ(net::OK, callback2.result()->code); - ASSERT_NE(0u, callback2.net_address()->ipv4->port); - - NetAddressPtr client_addr = callback2.net_address().Clone(); - - const size_t kDatagramCount = 16; - const size_t kDatagramSize = 255; - - for (size_t i = 1; i < kDatagramCount; ++i) { - scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]); - scoped_ptr<TestReceiveCallback[]> receive_callbacks( - new TestReceiveCallback[i]); - - for (size_t j = 0; j < i; ++j) { - client_socket.SendTo( - server_addr.Clone(), - CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize), - send_callbacks[j].callback()); - - udp_socket.ReceiveFrom(receive_callbacks[j].callback()); - } - - receive_callbacks[i - 1].WaitForResult(); - - for (size_t j = 0; j < i; ++j) { - EXPECT_EQ(static_cast<int>(kDatagramSize), - receive_callbacks[j].result()->code); - EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr)); - EXPECT_TRUE(receive_callbacks[j].data().Equals( - CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize))); - } - } -} - -} // namespace service -} // namespace mojo
diff --git a/mojo/services/network/upload_network_service.py b/mojo/services/network/upload_network_service.py deleted file mode 100755 index ac7b619a..0000000 --- a/mojo/services/network/upload_network_service.py +++ /dev/null
@@ -1,101 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import argparse -import imp -import os -import subprocess -import sys -import tempfile -import time -import zipfile - -if not sys.platform.startswith("linux"): - print "Only support linux for now" - sys.exit(1) - -root_path = os.path.realpath( - os.path.join( - os.path.dirname( - os.path.realpath(__file__)), - os.pardir, - os.pardir, - os.pardir)) -version = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=root_path) -version = version.strip() - -find_depot_tools_path = os.path.join(root_path, "tools", "find_depot_tools.py") -find_depot_tools = imp.load_source("find_depot_tools", find_depot_tools_path) - -depot_tools_path = find_depot_tools.add_depot_tools_to_path() -gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") - - -def gsutil_cp(source, dest, dry_run): - if dry_run: - print "gsutil cp %s %s" % (source, dest) - else: - subprocess.check_call([gsutil_exe, "cp", source, dest]) - - -def upload_mojoms(dry_run): - absolute_mojom_directory_path = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "public", - "interfaces") - dest = "gs://mojo/network/" + version + "/" + "mojoms.zip" - with tempfile.NamedTemporaryFile() as mojom_zip_file: - with zipfile.ZipFile(mojom_zip_file, 'w') as z: - for root, _, files in os.walk(absolute_mojom_directory_path): - for filename in files: - absolute_file_path = os.path.join(root, filename) - relative_file_path = os.path.relpath(absolute_file_path, root) - z.write(absolute_file_path, relative_file_path) - gsutil_cp(mojom_zip_file.name, dest, dry_run) - - -def upload_binary(binary_path, platform, dry_run): - absolute_binary_path = os.path.join(root_path, binary_path) - binary_dest = "gs://mojo/network/" + version + "/" + platform + ".zip" - with tempfile.NamedTemporaryFile() as binary_zip_file: - with zipfile.ZipFile(binary_zip_file, 'w') as z: - with open(absolute_binary_path) as service_binary: - zipinfo = zipfile.ZipInfo("network_service.mojo") - zipinfo.external_attr = 0o777 << 16 - zipinfo.compress_type = zipfile.ZIP_DEFLATED - zipinfo.date_time = time.gmtime(os.path.getmtime(absolute_binary_path)) - z.writestr(zipinfo, service_binary.read()) - gsutil_cp(binary_zip_file.name, binary_dest, dry_run) - - -def main(): - parser = argparse.ArgumentParser( - description="Upload network service mojoms and binaries to Google " + - "storage") - parser.add_argument("-n", "--dry-run", action="store_true", help="Dry run") - parser.add_argument( - "--linux-x64-binary-path", - help="Path to the linux-x64 network service binary relative to the " + - "repo root, e.g. out/Release/network_service.mojo") - parser.add_argument( - "--android-arm-binary-path", - help="Path to the android-arm network service binary relative to the " + - "repo root, e.g. out/android_Release/network_service.mojo") - - args = parser.parse_args() - upload_mojoms(args.dry_run) - if args.linux_x64_binary_path: - upload_binary(args.linux_x64_binary_path, "linux-x64", args.dry_run) - if args.android_arm_binary_path: - upload_binary(args.android_arm_binary_path, "android-arm", args.dry_run) - - if not args.dry_run: - print "Uploaded artifacts for version %s" % (version, ) - else: - print "No artifacts uploaded (dry run)" - return 0 - -if __name__ == '__main__': - sys.exit(main())
diff --git a/mojo/services/upload_service.py b/mojo/services/upload_service.py new file mode 100755 index 0000000..5666dea --- /dev/null +++ b/mojo/services/upload_service.py
@@ -0,0 +1,140 @@ +#!/usr/bin/env python +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import imp +import os +import subprocess +import sys +import tempfile +import time +import zipfile + +# A service's name is defined as the name of its subdirectory in the directory +# containing this file. +SERVICES = [ "network", "html_viewer" ] + +SERVICE_BINARY_NAMES = { + "network" : "network_service.mojo", + "html_viewer" : "html_viewer.mojo" +} + +# The network service is downloaded out-of-band rather than dynamically by the +# shell and thus can be stored zipped in the cloud. Other services are intended +# to be downloaded dynamically by the shell, which doesn't currently understand +# zipped binaries. +SERVICES_WITH_ZIPPED_BINARIES = [ "network" ] + +if not sys.platform.startswith("linux"): + print "Only support linux for now" + sys.exit(1) + +root_path = os.path.realpath( + os.path.join( + os.path.dirname( + os.path.realpath(__file__)), + os.pardir, + os.pardir)) +version = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=root_path) +version = version.strip() + +find_depot_tools_path = os.path.join(root_path, "tools", "find_depot_tools.py") +find_depot_tools = imp.load_source("find_depot_tools", find_depot_tools_path) + +depot_tools_path = find_depot_tools.add_depot_tools_to_path() +gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") + + +def gsutil_cp(source, dest, dry_run): + if dry_run: + print "gsutil cp %s %s" % (source, dest) + else: + subprocess.check_call([gsutil_exe, "cp", source, dest]) + + +def upload_mojoms(service, dry_run): + script_dir = os.path.dirname(os.path.realpath(__file__)) + service_dir = os.path.join(script_dir, service) + absolute_mojom_directory_path = os.path.join( + service_dir, + "public", + "interfaces") + + if not os.path.exists(absolute_mojom_directory_path): + # This service has no interfaces. + return + + dest = "gs://mojo/" + service + "/" + version + "/" + "mojoms.zip" + with tempfile.NamedTemporaryFile() as mojom_zip_file: + with zipfile.ZipFile(mojom_zip_file, 'w') as z: + for root, _, files in os.walk(absolute_mojom_directory_path): + for filename in files: + absolute_file_path = os.path.join(root, filename) + relative_file_path = os.path.relpath(absolute_file_path, root) + z.write(absolute_file_path, relative_file_path) + gsutil_cp(mojom_zip_file.name, dest, dry_run) + + +def upload_binary(service, binary_dir, platform, dry_run): + binary_name = SERVICE_BINARY_NAMES[service] + absolute_binary_path = os.path.join(root_path, binary_dir, binary_name) + binary_dest_prefix = "gs://mojo/" + service + "/" + version + "/" + platform + + if service not in SERVICES_WITH_ZIPPED_BINARIES: + binary_dest = binary_dest_prefix + "/" + binary_name + gsutil_cp(absolute_binary_path, binary_dest, dry_run) + return + + # Zip the binary before uploading it to the cloud. + binary_dest = binary_dest_prefix + ".zip" + with tempfile.NamedTemporaryFile() as binary_zip_file: + with zipfile.ZipFile(binary_zip_file, 'w') as z: + with open(absolute_binary_path) as service_binary: + zipinfo = zipfile.ZipInfo(binary_name) + zipinfo.external_attr = 0o777 << 16 + zipinfo.compress_type = zipfile.ZIP_DEFLATED + zipinfo.date_time = time.gmtime(os.path.getmtime(absolute_binary_path)) + z.writestr(zipinfo, service_binary.read()) + gsutil_cp(binary_zip_file.name, binary_dest, dry_run) + + +def main(): + parser = argparse.ArgumentParser( + description="Upload service mojoms and binaries to Google storage") + parser.add_argument("-n", "--dry-run", action="store_true", help="Dry run") + parser.add_argument( + "--linux-x64-binary-dir", + help="Path to the dir containing the linux-x64 service binary relative " + "to the repo root, e.g. out/Release") + parser.add_argument( + "--android-arm-binary-dir", + help="Path to the dir containing the android-arm service binary relative " + "to the repo root, e.g. out/android_Release") + parser.add_argument("service", + help="The service to be uploaded (one of %s)" % SERVICES) + + args = parser.parse_args() + + if args.service not in SERVICES: + print args.service + " is not one of the recognized services:" + print SERVICES + return 1 + + upload_mojoms(args.service, args.dry_run) + if args.linux_x64_binary_dir: + upload_binary(args.service, args.linux_x64_binary_dir, + "linux-x64", args.dry_run) + if args.android_arm_binary_dir: + upload_binary(args.service, args.android_arm_binary_dir, + "android-arm", args.dry_run) + + if not args.dry_run: + print "Uploaded artifacts for version %s" % (version, ) + else: + print "No artifacts uploaded (dry run)" + return 0 + +if __name__ == '__main__': + sys.exit(main())
diff --git a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs.cc b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs.cc index f744750e..bb6b9cc8 100644 --- a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs.cc +++ b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs.cc
@@ -155,6 +155,9 @@ int32_t query_result = file_ref_iface_->Query( fileref_resource.pp_resource(), &file_info, PP_BlockUntilComplete()); if (query_result != PP_OK) { + if (query_result == PP_ERROR_FILENOTFOUND) { + return ENOENT; + } LOG_ERROR("Error querying file type"); return EINVAL; }
diff --git a/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc b/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc index 3cb8d164..abffa13 100644 --- a/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc +++ b/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc
@@ -198,6 +198,7 @@ ASSERT_TRUE(fs->Exists(kPath)); ASSERT_EQ(0, fs->Remove(path)); EXPECT_FALSE(fs->Exists(kPath)); + ASSERT_EQ(ENOENT, fs->Remove(path)); } TEST_F(Html5FsTest, Unlink) { @@ -213,6 +214,7 @@ ASSERT_EQ(EISDIR, fs->Unlink(Path("/dir"))); EXPECT_FALSE(fs->Exists("/file")); EXPECT_TRUE(fs->Exists("/dir")); + ASSERT_EQ(ENOENT, fs->Unlink(Path("/file"))); } TEST_F(Html5FsTest, Rmdir) { @@ -226,6 +228,7 @@ EXPECT_EQ(0, fs->Rmdir(Path("/dir"))); EXPECT_FALSE(fs->Exists("/dir")); EXPECT_TRUE(fs->Exists("/file")); + EXPECT_EQ(ENOENT, fs->Rmdir(Path("/dir"))); } TEST_F(Html5FsTest, Rename) {
diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc index 5acaab6..fc2af1b 100644 --- a/net/base/file_stream_context.cc +++ b/net/base/file_stream_context.cc
@@ -77,6 +77,12 @@ orphaned_ = true; +#if defined(OS_WIN) + // Clean up weak pointers here to ensure that they are destroyed on the + // same thread where they were created. + weak_ptr_factory_.InvalidateWeakPtrs(); +#endif + if (!async_in_progress_) { CloseAndDelete(); } else if (file_.IsValid()) {
diff --git a/net/base/file_stream_context.h b/net/base/file_stream_context.h index 82a2412..4f01d9d2 100644 --- a/net/base/file_stream_context.h +++ b/net/base/file_stream_context.h
@@ -28,6 +28,7 @@ #define NET_BASE_FILE_STREAM_CONTEXT_H_ #include "base/files/file.h" +#include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/move.h" #include "base/task_runner.h" @@ -159,6 +160,35 @@ virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) override; + + // The ReadFile call on Windows can execute synchonously at times. + // http://support.microsoft.com/kb/156932. This ends up blocking the calling + // thread which is undesirable. To avoid this we execute the ReadFile call + // on a worker thread. + // The |context| parameter is a weak pointer instance passed to the worker + // pool. + // The |file| parameter is the handle to the file being read. + // The |buf| parameter is the buffer where we want the ReadFile to read the + // data into. + // The |buf_len| parameter contains the number of bytes to be read. + // The |overlapped| parameter is a pointer to the OVERLAPPED structure being + // used. + // The |origin_thread_loop| is a MessageLoopProxy instance used to post tasks + // back to the originating thread. + static void ReadAsync( + const base::WeakPtr<FileStream::Context>& context, + HANDLE file, + scoped_refptr<net::IOBuffer> buf, + int buf_len, + OVERLAPPED* overlapped, + scoped_refptr<base::MessageLoopProxy> origin_thread_loop); + + // This callback executes on the main calling thread. It informs the caller + // about the result of the ReadFile call. + // The |os_error| parameter contains the value of the last error returned by + // the ReadFile API. + void ReadAsyncResult(DWORD os_error); + #elif defined(OS_POSIX) // ReadFileImpl() is a simple wrapper around read() that handles EINTR // signals and calls RecordAndMapError() to map errno to net error codes. @@ -179,6 +209,8 @@ base::MessageLoopForIO::IOContext io_context_; CompletionCallback callback_; scoped_refptr<IOBuffer> in_flight_buf_; + // WeakPtrFactory for posting tasks back to |this|. + base::WeakPtrFactory<Context> weak_ptr_factory_; #endif DISALLOW_COPY_AND_ASSIGN(Context);
diff --git a/net/base/file_stream_context_win.cc b/net/base/file_stream_context_win.cc index 85a5968..d225ee3 100644 --- a/net/base/file_stream_context_win.cc +++ b/net/base/file_stream_context_win.cc
@@ -8,9 +8,12 @@ #include "base/files/file_path.h" #include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_proxy.h" #include "base/metrics/histogram.h" #include "base/profiler/scoped_tracker.h" #include "base/task_runner.h" +#include "base/threading/worker_pool.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -37,7 +40,8 @@ : io_context_(), async_in_progress_(false), orphaned_(false), - task_runner_(task_runner) { + task_runner_(task_runner), + weak_ptr_factory_(this) { io_context_.handler = this; memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); } @@ -48,7 +52,8 @@ file_(file.Pass()), async_in_progress_(false), orphaned_(false), - task_runner_(task_runner) { + task_runner_(task_runner), + weak_ptr_factory_(this) { io_context_.handler = this; memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); if (file_.IsValid()) { @@ -69,20 +74,16 @@ DCHECK(!async_in_progress_); - DWORD bytes_read; - if (!ReadFile(file_.GetPlatformFile(), buf->data(), buf_len, - &bytes_read, &io_context_.overlapped)) { - IOResult error = IOResult::FromOSError(GetLastError()); - if (error.os_error == ERROR_HANDLE_EOF) - return 0; // Report EOF by returning 0 bytes read. - if (error.os_error == ERROR_IO_PENDING) - IOCompletionIsPending(callback, buf); - else - LOG(WARNING) << "ReadFile failed: " << error.os_error; - return static_cast<int>(error.result); - } - IOCompletionIsPending(callback, buf); + + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&FileStream::Context::ReadAsync, + weak_ptr_factory_.GetWeakPtr(), file_.GetPlatformFile(), + make_scoped_refptr(buf), buf_len, &io_context_.overlapped, + base::MessageLoop::current()->message_loop_proxy()), + false); + return ERR_IO_PENDING; } @@ -165,4 +166,34 @@ temp_callback.Run(result); } +// static +void FileStream::Context::ReadAsync( + const base::WeakPtr<FileStream::Context>& context, + HANDLE file, + scoped_refptr<net::IOBuffer> buf, + int buf_len, + OVERLAPPED* overlapped, + scoped_refptr<base::MessageLoopProxy> origin_thread_loop) { + DWORD bytes_read = 0; + if (!ReadFile(file, buf->data(), buf_len, &bytes_read, overlapped)) { + origin_thread_loop->PostTask( + FROM_HERE, base::Bind(&FileStream::Context::ReadAsyncResult, context, + ::GetLastError())); + } +} + +void FileStream::Context::ReadAsyncResult(DWORD os_error) { + IOResult error = IOResult::FromOSError(os_error); + if (error.os_error == ERROR_HANDLE_EOF) { + // Report EOF by returning 0 bytes read. + OnIOCompleted(&io_context_, 0, error.os_error); + } else if (error.os_error != ERROR_IO_PENDING) { + // We don't need to inform the caller about ERROR_PENDING_IO as that was + // already done when the ReadFile call was queued to the worker pool. + if (error.os_error) + LOG(WARNING) << "ReadFile failed: " << error.os_error; + OnIOCompleted(&io_context_, 0, error.os_error); + } +} + } // namespace net
diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc index fc9257e..8b47ecc 100644 --- a/net/base/file_stream_unittest.cc +++ b/net/base/file_stream_unittest.cc
@@ -546,6 +546,25 @@ const CompletionCallback& callback() const { return callback_; } + void ValidateWrittenData() { + TestCompletionCallback callback; + int rv = 0; + for (;;) { + scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4); + rv = stream_->Read(buf.get(), buf->size(), callback.callback()); + if (rv == ERR_IO_PENDING) { + base::MessageLoop::ScopedNestableTaskAllower allow( + base::MessageLoop::current()); + rv = callback.WaitForResult(); + } + EXPECT_LE(0, rv); + if (rv <= 0) + break; + *total_bytes_read_ += rv; + data_read_->append(buf->data(), rv); + } + } + private: void OnComplete(int result) { DCHECK_LT(0, result); @@ -577,22 +596,6 @@ base::MessageLoop::current()); EXPECT_LE(0, callback64.WaitForResult()); } - - TestCompletionCallback callback; - for (;;) { - scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4); - rv = stream_->Read(buf.get(), buf->size(), callback.callback()); - if (rv == ERR_IO_PENDING) { - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); - rv = callback.WaitForResult(); - } - EXPECT_LE(0, rv); - if (rv <= 0) - break; - *total_bytes_read_ += rv; - data_read_->append(buf->data(), rv); - } } result_ = *total_bytes_written_; @@ -646,6 +649,8 @@ EXPECT_LT(0, rv); EXPECT_EQ(kTestDataSize, total_bytes_written); + callback.ValidateWrittenData(); + stream.reset(); EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc index 9d91fb7f..4a8c4b5 100644 --- a/net/base/filename_util_unittest.cc +++ b/net/base/filename_util_unittest.cc
@@ -116,48 +116,56 @@ }; static const base::FilePath::CharType* kSafePortableRelativePaths[] = { - FILE_PATH_LITERAL("a/a"), + FILE_PATH_LITERAL("a/a"), #if defined(OS_WIN) - FILE_PATH_LITERAL("a\\a"), + FILE_PATH_LITERAL("a\\a"), #endif }; TEST(FilenameUtilTest, IsSafePortablePathComponent) { - for (size_t i = 0 ; i < arraysize(kSafePortableBasenames); ++i) { - EXPECT_TRUE(IsSafePortablePathComponent(base::FilePath( - kSafePortableBasenames[i]))) << kSafePortableBasenames[i]; + for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { + EXPECT_TRUE( + IsSafePortablePathComponent(base::FilePath(kSafePortableBasenames[i]))) + << kSafePortableBasenames[i]; } - for (size_t i = 0 ; i < arraysize(kUnsafePortableBasenames); ++i) { - EXPECT_FALSE(IsSafePortablePathComponent(base::FilePath( - kUnsafePortableBasenames[i]))) << kUnsafePortableBasenames[i]; + for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { + EXPECT_FALSE(IsSafePortablePathComponent( + base::FilePath(kUnsafePortableBasenames[i]))) + << kUnsafePortableBasenames[i]; } - for (size_t i = 0 ; i < arraysize(kSafePortableRelativePaths); ++i) { - EXPECT_FALSE(IsSafePortablePathComponent(base::FilePath( - kSafePortableRelativePaths[i]))) << kSafePortableRelativePaths[i]; + for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { + EXPECT_FALSE(IsSafePortablePathComponent( + base::FilePath(kSafePortableRelativePaths[i]))) + << kSafePortableRelativePaths[i]; } } TEST(FilenameUtilTest, IsSafePortableRelativePath) { base::FilePath safe_dirname(FILE_PATH_LITERAL("a")); - for (size_t i = 0 ; i < arraysize(kSafePortableBasenames); ++i) { - EXPECT_TRUE(IsSafePortableRelativePath(base::FilePath( - kSafePortableBasenames[i]))) << kSafePortableBasenames[i]; - EXPECT_TRUE(IsSafePortableRelativePath(safe_dirname.Append(base::FilePath( - kSafePortableBasenames[i])))) << kSafePortableBasenames[i]; + for (size_t i = 0; i < arraysize(kSafePortableBasenames); ++i) { + EXPECT_TRUE( + IsSafePortableRelativePath(base::FilePath(kSafePortableBasenames[i]))) + << kSafePortableBasenames[i]; + EXPECT_TRUE(IsSafePortableRelativePath( + safe_dirname.Append(base::FilePath(kSafePortableBasenames[i])))) + << kSafePortableBasenames[i]; } - for (size_t i = 0 ; i < arraysize(kSafePortableRelativePaths); ++i) { - EXPECT_TRUE(IsSafePortableRelativePath(base::FilePath( - kSafePortableRelativePaths[i]))) << kSafePortableRelativePaths[i]; - EXPECT_TRUE(IsSafePortableRelativePath(safe_dirname.Append(base::FilePath( - kSafePortableRelativePaths[i])))) << kSafePortableRelativePaths[i]; + for (size_t i = 0; i < arraysize(kSafePortableRelativePaths); ++i) { + EXPECT_TRUE(IsSafePortableRelativePath( + base::FilePath(kSafePortableRelativePaths[i]))) + << kSafePortableRelativePaths[i]; + EXPECT_TRUE(IsSafePortableRelativePath( + safe_dirname.Append(base::FilePath(kSafePortableRelativePaths[i])))) + << kSafePortableRelativePaths[i]; } - for (size_t i = 0 ; i < arraysize(kUnsafePortableBasenames); ++i) { - EXPECT_FALSE(IsSafePortableRelativePath(base::FilePath( - kUnsafePortableBasenames[i]))) << kUnsafePortableBasenames[i]; - if (!base::FilePath::StringType(kUnsafePortableBasenames[i]).empty()) { - EXPECT_FALSE(IsSafePortableRelativePath(safe_dirname.Append( - base::FilePath(kUnsafePortableBasenames[i])))) + for (size_t i = 0; i < arraysize(kUnsafePortableBasenames); ++i) { + EXPECT_FALSE( + IsSafePortableRelativePath(base::FilePath(kUnsafePortableBasenames[i]))) << kUnsafePortableBasenames[i]; + if (!base::FilePath::StringType(kUnsafePortableBasenames[i]).empty()) { + EXPECT_FALSE(IsSafePortableRelativePath( + safe_dirname.Append(base::FilePath(kUnsafePortableBasenames[i])))) + << kUnsafePortableBasenames[i]; } } } @@ -168,19 +176,18 @@ #if defined(OS_WIN) {L"C:\\foo\\bar.txt", "file:///C:/foo/bar.txt"}, {L"\\\\some computer\\foo\\bar.txt", - "file://some%20computer/foo/bar.txt"}, // UNC + "file://some%20computer/foo/bar.txt"}, // UNC {L"D:\\Name;with%some symbols*#", "file:///D:/Name%3Bwith%25some%20symbols*%23"}, // issue 14153: To be tested with the OS default codepage other than 1252. {L"D:\\latin1\\caf\x00E9\x00DD.txt", "file:///D:/latin1/caf%C3%A9%C3%9D.txt"}, - {L"D:\\otherlatin\\caf\x0119.txt", - "file:///D:/otherlatin/caf%C4%99.txt"}, + {L"D:\\otherlatin\\caf\x0119.txt", "file:///D:/otherlatin/caf%C4%99.txt"}, {L"D:\\greek\\\x03B1\x03B2\x03B3.txt", "file:///D:/greek/%CE%B1%CE%B2%CE%B3.txt"}, {L"D:\\Chinese\\\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", "file:///D:/Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD%91" - "%E9%A1%B5.doc"}, + "%E9%A1%B5.doc"}, {L"D:\\plane1\\\xD835\xDC00\xD835\xDC01.txt", // Math alphabet "AB" "file:///D:/plane1/%F0%9D%90%80%F0%9D%90%81.txt"}, #elif defined(OS_POSIX) @@ -195,7 +202,7 @@ {L"/greek/\x03B1\x03B2\x03B3.txt", "file:///greek/%CE%B1%CE%B2%CE%B3.txt"}, {L"/Chinese/\x6240\x6709\x4e2d\x6587\x7f51\x9875.doc", "file:///Chinese/%E6%89%80%E6%9C%89%E4%B8%AD%E6%96%87%E7%BD" - "%91%E9%A1%B5.doc"}, + "%91%E9%A1%B5.doc"}, {L"/plane1/\x1D400\x1D401.txt", // Math alphabet "AB" "file:///plane1/%F0%9D%90%80%F0%9D%90%81.txt"}, #endif @@ -205,8 +212,8 @@ base::FilePath output; for (size_t i = 0; i < arraysize(round_trip_cases); i++) { // convert to the file URL - GURL file_url(FilePathToFileURL( - WStringAsFilePath(round_trip_cases[i].file))); + GURL file_url( + FilePathToFileURL(WStringAsFilePath(round_trip_cases[i].file))); EXPECT_EQ(round_trip_cases[i].url, file_url.spec()); // Back to the filename. @@ -239,13 +246,13 @@ {L"/foo/bar.txt", "file:////foo////bar.txt"}, {L"/c:/foo/bar.txt", "file:\\\\\\c:/foo/bar.txt"}, {L"/c:/foo/bar.txt", "file:c:/foo/bar.txt"}, - // We get these wrong because GURL turns back slashes into forward - // slashes. - //{L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, - //{L"/c|/foo%5Cbar.txt", "file:c|/foo\\bar.txt"}, - //{L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, - //{L"/foo%5Cbar.txt", "file:////foo\\bar.txt"}, - //{L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, +// We get these wrong because GURL turns back slashes into forward +// slashes. +// {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, +// {L"/c|/foo%5Cbar.txt", "file:c|/foo\\bar.txt"}, +// {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, +// {L"/foo%5Cbar.txt", "file:////foo\\bar.txt"}, +// {L"/foo%5Cbar.txt", "file://foo\\bar.txt"}, #endif }; for (size_t i = 0; i < arraysize(url_cases); i++) { @@ -253,14 +260,13 @@ EXPECT_EQ(url_cases[i].file, FilePathAsWString(output)); } - // Unfortunately, UTF8ToWide discards invalid UTF8 input. +// Unfortunately, UTF8ToWide discards invalid UTF8 input. #ifdef BUG_878908_IS_FIXED // Test that no conversion happens if the UTF-8 input is invalid, and that // the input is preserved in UTF-8 const char invalid_utf8[] = "file:///d:/Blah/\xff.doc"; const wchar_t invalid_wide[] = L"D:\\Blah\\\xff.doc"; - EXPECT_TRUE(FileURLToFilePath( - GURL(std::string(invalid_utf8)), &output)); + EXPECT_TRUE(FileURLToFilePath(GURL(std::string(invalid_utf8)), &output)); EXPECT_EQ(std::wstring(invalid_wide), output); #endif @@ -288,144 +294,88 @@ const base::FilePath::CharType* expected_filename; } safe_tests[] = { #if defined(OS_WIN) - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\bar.htm"), - FILE_PATH_LITERAL("C:\\foo\\bar.htm") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\bar.html"), - FILE_PATH_LITERAL("C:\\foo\\bar.html") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\bar"), - FILE_PATH_LITERAL("C:\\foo\\bar.htm") - }, - { - "image/png", - FILE_PATH_LITERAL("C:\\bar.html"), - FILE_PATH_LITERAL("C:\\bar.html") - }, - { - "image/png", - FILE_PATH_LITERAL("C:\\bar"), - FILE_PATH_LITERAL("C:\\bar.png") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\bar.exe"), - FILE_PATH_LITERAL("C:\\foo\\bar.exe") - }, - { - "image/gif", - FILE_PATH_LITERAL("C:\\foo\\bar.exe"), - FILE_PATH_LITERAL("C:\\foo\\bar.exe") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\google.com"), - FILE_PATH_LITERAL("C:\\foo\\google.com") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\con.htm"), - FILE_PATH_LITERAL("C:\\foo\\_con.htm") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\con"), - FILE_PATH_LITERAL("C:\\foo\\_con.htm") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\harmless.{not-really-this-may-be-a-guid}"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\harmless.local"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\harmless.lnk"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download") - }, - { - "text/html", - FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"), - FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-") - }, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\bar.htm"), + FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\bar.html"), + FILE_PATH_LITERAL("C:\\foo\\bar.html")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\bar"), + FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, + {"image/png", + FILE_PATH_LITERAL("C:\\bar.html"), + FILE_PATH_LITERAL("C:\\bar.html")}, + {"image/png", + FILE_PATH_LITERAL("C:\\bar"), + FILE_PATH_LITERAL("C:\\bar.png")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\bar.exe"), + FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, + {"image/gif", + FILE_PATH_LITERAL("C:\\foo\\bar.exe"), + FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\google.com"), + FILE_PATH_LITERAL("C:\\foo\\google.com")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\con.htm"), + FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\con"), + FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\harmless.{not-really-this-may-be-a-guid}"), + FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\harmless.local"), + FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\harmless.lnk"), + FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, + {"text/html", + FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"), + FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-")}, // Allow extension synonyms. - { - "image/jpeg", - FILE_PATH_LITERAL("C:\\foo\\bar.jpg"), - FILE_PATH_LITERAL("C:\\foo\\bar.jpg") - }, - { - "image/jpeg", - FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"), - FILE_PATH_LITERAL("C:\\foo\\bar.jpeg") - }, -#else // !defined(OS_WIN) - { - "text/html", - FILE_PATH_LITERAL("/foo/bar.htm"), - FILE_PATH_LITERAL("/foo/bar.htm") - }, - { - "text/html", - FILE_PATH_LITERAL("/foo/bar.html"), - FILE_PATH_LITERAL("/foo/bar.html") - }, - { - "text/html", - FILE_PATH_LITERAL("/foo/bar"), - FILE_PATH_LITERAL("/foo/bar.html") - }, - { - "image/png", - FILE_PATH_LITERAL("/bar.html"), - FILE_PATH_LITERAL("/bar.html") - }, - { - "image/png", - FILE_PATH_LITERAL("/bar"), - FILE_PATH_LITERAL("/bar.png") - }, - { - "image/gif", - FILE_PATH_LITERAL("/foo/bar.exe"), - FILE_PATH_LITERAL("/foo/bar.exe") - }, - { - "text/html", - FILE_PATH_LITERAL("/foo/google.com"), - FILE_PATH_LITERAL("/foo/google.com") - }, - { - "text/html", - FILE_PATH_LITERAL("/foo/con.htm"), - FILE_PATH_LITERAL("/foo/con.htm") - }, - { - "text/html", - FILE_PATH_LITERAL("/foo/con"), - FILE_PATH_LITERAL("/foo/con.html") - }, + {"image/jpeg", + FILE_PATH_LITERAL("C:\\foo\\bar.jpg"), + FILE_PATH_LITERAL("C:\\foo\\bar.jpg")}, + {"image/jpeg", + FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"), + FILE_PATH_LITERAL("C:\\foo\\bar.jpeg")}, +#else // !defined(OS_WIN) + {"text/html", + FILE_PATH_LITERAL("/foo/bar.htm"), + FILE_PATH_LITERAL("/foo/bar.htm")}, + {"text/html", + FILE_PATH_LITERAL("/foo/bar.html"), + FILE_PATH_LITERAL("/foo/bar.html")}, + {"text/html", + FILE_PATH_LITERAL("/foo/bar"), + FILE_PATH_LITERAL("/foo/bar.html")}, + {"image/png", + FILE_PATH_LITERAL("/bar.html"), + FILE_PATH_LITERAL("/bar.html")}, + {"image/png", FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("/bar.png")}, + {"image/gif", + FILE_PATH_LITERAL("/foo/bar.exe"), + FILE_PATH_LITERAL("/foo/bar.exe")}, + {"text/html", + FILE_PATH_LITERAL("/foo/google.com"), + FILE_PATH_LITERAL("/foo/google.com")}, + {"text/html", + FILE_PATH_LITERAL("/foo/con.htm"), + FILE_PATH_LITERAL("/foo/con.htm")}, + {"text/html", + FILE_PATH_LITERAL("/foo/con"), + FILE_PATH_LITERAL("/foo/con.html")}, // Allow extension synonyms. - { - "image/jpeg", - FILE_PATH_LITERAL("/bar.jpg"), - FILE_PATH_LITERAL("/bar.jpg") - }, - { - "image/jpeg", - FILE_PATH_LITERAL("/bar.jpeg"), - FILE_PATH_LITERAL("/bar.jpeg") - }, + {"image/jpeg", + FILE_PATH_LITERAL("/bar.jpg"), + FILE_PATH_LITERAL("/bar.jpg")}, + {"image/jpeg", + FILE_PATH_LITERAL("/bar.jpeg"), + FILE_PATH_LITERAL("/bar.jpeg")}, #endif // !defined(OS_WIN) }; @@ -442,392 +392,287 @@ // parameters and that Content-Disposition headers are properly // handled including failovers when the header is malformed. const GenerateFilenameCase selection_tests[] = { - { - __LINE__, - "http://www.google.com/", - "attachment; filename=test.html", - "", - "", - "", - L"", - L"test.html" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"test.html\"", - "", - "", - "", - L"", - L"test.html" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename= \"test.html\"", - "", - "", - "", - L"", - L"test.html" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename = \"test.html\"", - "", - "", - "", - L"", - L"test.html" - }, - { // filename is whitespace. Should failover to URL host - __LINE__, - "http://www.google.com/", - "attachment; filename= ", - "", - "", - "", - L"", - L"www.google.com" - }, - { // No filename. - __LINE__, - "http://www.google.com/path/test.html", - "attachment", - "", - "", - "", - L"", - L"test.html" - }, - { // Ditto - __LINE__, - "http://www.google.com/path/test.html", - "attachment;", - "", - "", - "", - L"", - L"test.html" - }, - { // No C-D - __LINE__, - "http://www.google.com/", - "", - "", - "", - "", - L"", - L"www.google.com" - }, - { - __LINE__, - "http://www.google.com/test.html", - "", - "", - "", - "", - L"", - L"test.html" - }, - { // Now that we use src/url's ExtractFileName, this case falls back to - // the hostname. If this behavior is not desirable, we'd better change - // ExtractFileName (in url_parse.cc). - __LINE__, - "http://www.google.com/path/", - "", - "", - "", - "", - L"", - L"www.google.com" - }, - { - __LINE__, - "http://www.google.com/path", - "", - "", - "", - "", - L"", - L"path" - }, - { - __LINE__, - "file:///", - "", - "", - "", - "", - L"", - L"download" - }, - { - __LINE__, - "file:///path/testfile", - "", - "", - "", - "", - L"", - L"testfile" - }, - { - __LINE__, - "non-standard-scheme:", - "", - "", - "", - "", - L"", - L"download" - }, - { // C-D should override default - __LINE__, - "http://www.google.com/", - "attachment; filename =\"test.html\"", - "", - "", - "", - L"download", - L"test.html" - }, - { // But the URL shouldn't - __LINE__, - "http://www.google.com/", - "", - "", - "", - "", - L"download", - L"download" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"../test.html\"", - "", - "", - "", - L"", - L"-test.html" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"..\\test.html\"", - "", - "", - "", - L"", - L"test.html" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"..\\\\test.html\"", - "", - "", - "", - L"", - L"-test.html" - }, - { // Filename disappears after leading and trailing periods are removed. - __LINE__, - "http://www.google.com/", - "attachment; filename=\"..\"", - "", - "", - "", - L"default", - L"default" - }, - { // C-D specified filename disappears. Failover to final filename. - __LINE__, - "http://www.google.com/test.html", - "attachment; filename=\"..\"", - "", - "", - "", - L"default", - L"default" - }, + {__LINE__, + "http://www.google.com/", + "attachment; filename=test.html", + "", + "", + "", + L"", + L"test.html"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"test.html\"", + "", + "", + "", + L"", + L"test.html"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename= \"test.html\"", + "", + "", + "", + L"", + L"test.html"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename = \"test.html\"", + "", + "", + "", + L"", + L"test.html"}, + {// filename is whitespace. Should failover to URL host + __LINE__, + "http://www.google.com/", + "attachment; filename= ", + "", + "", + "", + L"", + L"www.google.com"}, + {// No filename. + __LINE__, + "http://www.google.com/path/test.html", + "attachment", + "", + "", + "", + L"", + L"test.html"}, + {// Ditto + __LINE__, + "http://www.google.com/path/test.html", + "attachment;", + "", + "", + "", + L"", + L"test.html"}, + {// No C-D + __LINE__, + "http://www.google.com/", + "", + "", + "", + "", + L"", + L"www.google.com"}, + {__LINE__, + "http://www.google.com/test.html", + "", + "", + "", + "", + L"", + L"test.html"}, + {// Now that we use src/url's ExtractFileName, this case falls back to + // the hostname. If this behavior is not desirable, we'd better change + // ExtractFileName (in url_parse.cc). + __LINE__, + "http://www.google.com/path/", + "", + "", + "", + "", + L"", + L"www.google.com"}, + {__LINE__, "http://www.google.com/path", "", "", "", "", L"", L"path"}, + {__LINE__, "file:///", "", "", "", "", L"", L"download"}, + {__LINE__, "file:///path/testfile", "", "", "", "", L"", L"testfile"}, + {__LINE__, "non-standard-scheme:", "", "", "", "", L"", L"download"}, + {// C-D should override default + __LINE__, + "http://www.google.com/", + "attachment; filename =\"test.html\"", + "", + "", + "", + L"download", + L"test.html"}, + {// But the URL shouldn't + __LINE__, + "http://www.google.com/", + "", + "", + "", + "", + L"download", + L"download"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"../test.html\"", + "", + "", + "", + L"", + L"-test.html"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"..\\test.html\"", + "", + "", + "", + L"", + L"test.html"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"..\\\\test.html\"", + "", + "", + "", + L"", + L"-test.html"}, + {// Filename disappears after leading and trailing periods are removed. + __LINE__, + "http://www.google.com/", + "attachment; filename=\"..\"", + "", + "", + "", + L"default", + L"default"}, + {// C-D specified filename disappears. Failover to final filename. + __LINE__, + "http://www.google.com/test.html", + "attachment; filename=\"..\"", + "", + "", + "", + L"default", + L"default"}, // Below is a small subset of cases taken from HttpContentDisposition tests. - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"%EC%98%88%EC%88%A0%20" - "%EC%98%88%EC%88%A0.jpg\"", - "", - "", - "", - L"", - L"\uc608\uc220 \uc608\uc220.jpg" - }, - { - __LINE__, - "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", - "", - "", - "", - "", - L"download", - L"\uc608\uc220 \uc608\uc220.jpg" - }, - { - __LINE__, - "http://www.google.com/", - "attachment;", - "", - "", - "", - L"\uB2E4\uC6B4\uB85C\uB4DC", - L"\uB2E4\uC6B4\uB85C\uB4DC" - }, - { - __LINE__, - "http://www.google.com/", - "attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD=" - "D13=2Epng?=\"", - "", - "", - "", - L"download", - L"\u82b8\u88533.png" - }, - { - __LINE__, - "http://www.example.com/images?id=3", - "attachment; filename=caf\xc3\xa9.png", - "iso-8859-1", - "", - "", - L"", - L"caf\u00e9.png" - }, - { - __LINE__, - "http://www.example.com/images?id=3", - "attachment; filename=caf\xe5.png", - "windows-1253", - "", - "", - L"", - L"caf\u03b5.png" - }, - { - __LINE__, - "http://www.example.com/file?id=3", - "attachment; name=\xcf\xc2\xd4\xd8.zip", - "GBK", - "", - "", - L"", - L"\u4e0b\u8f7d.zip" - }, - { // Invalid C-D header. Extracts filename from url. - __LINE__, - "http://www.google.com/test.html", - "attachment; filename==?iiso88591?Q?caf=EG?=", - "", - "", - "", - L"", - L"test.html" - }, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"%EC%98%88%EC%88%A0%20" + "%EC%98%88%EC%88%A0.jpg\"", + "", + "", + "", + L"", + L"\uc608\uc220 \uc608\uc220.jpg"}, + {__LINE__, + "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", + "", + "", + "", + "", + L"download", + L"\uc608\uc220 \uc608\uc220.jpg"}, + {__LINE__, + "http://www.google.com/", + "attachment;", + "", + "", + "", + L"\uB2E4\uC6B4\uB85C\uB4DC", + L"\uB2E4\uC6B4\uB85C\uB4DC"}, + {__LINE__, + "http://www.google.com/", + "attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD=" + "D13=2Epng?=\"", + "", + "", + "", + L"download", + L"\u82b8\u88533.png"}, + {__LINE__, + "http://www.example.com/images?id=3", + "attachment; filename=caf\xc3\xa9.png", + "iso-8859-1", + "", + "", + L"", + L"caf\u00e9.png"}, + {__LINE__, + "http://www.example.com/images?id=3", + "attachment; filename=caf\xe5.png", + "windows-1253", + "", + "", + L"", + L"caf\u03b5.png"}, + {__LINE__, + "http://www.example.com/file?id=3", + "attachment; name=\xcf\xc2\xd4\xd8.zip", + "GBK", + "", + "", + L"", + L"\u4e0b\u8f7d.zip"}, + {// Invalid C-D header. Extracts filename from url. + __LINE__, + "http://www.google.com/test.html", + "attachment; filename==?iiso88591?Q?caf=EG?=", + "", + "", + "", + L"", + L"test.html"}, // about: and data: URLs - { - __LINE__, - "about:chrome", - "", - "", - "", - "", - L"", - L"download" - }, - { - __LINE__, - "data:,looks/like/a.path", - "", - "", - "", - "", - L"", - L"download" - }, - { - __LINE__, - "data:text/plain;base64,VG8gYmUgb3Igbm90IHRvIGJlLg=", - "", - "", - "", - "", - L"", - L"download" - }, - { - __LINE__, - "data:,looks/like/a.path", - "", - "", - "", - "", - L"default_filename_is_given", - L"default_filename_is_given" - }, - { - __LINE__, - "data:,looks/like/a.path", - "", - "", - "", - "", - L"\u65e5\u672c\u8a9e", // Japanese Kanji. - L"\u65e5\u672c\u8a9e" - }, - { // The filename encoding is specified by the referrer charset. - __LINE__, - "http://example.com/V%FDvojov%E1%20psychologie.doc", - "", - "iso-8859-1", - "", - "", - L"", - L"V\u00fdvojov\u00e1 psychologie.doc" - }, - { // Suggested filename takes precedence over URL - __LINE__, - "http://www.google.com/test", - "", - "", - "suggested", - "", - L"", - L"suggested" - }, - { // The content-disposition has higher precedence over the suggested name. - __LINE__, - "http://www.google.com/test", - "attachment; filename=test.html", - "", - "suggested", - "", - L"", - L"test.html" - }, - { - __LINE__, - "http://www.google.com/test", - "attachment; filename=test", - "utf-8", - "", - "image/png", - L"", - L"test" - }, + {__LINE__, "about:chrome", "", "", "", "", L"", L"download"}, + {__LINE__, "data:,looks/like/a.path", "", "", "", "", L"", L"download"}, + {__LINE__, + "data:text/plain;base64,VG8gYmUgb3Igbm90IHRvIGJlLg=", + "", + "", + "", + "", + L"", + L"download"}, + {__LINE__, + "data:,looks/like/a.path", + "", + "", + "", + "", + L"default_filename_is_given", + L"default_filename_is_given"}, + {__LINE__, + "data:,looks/like/a.path", + "", + "", + "", + "", + L"\u65e5\u672c\u8a9e", // Japanese Kanji. + L"\u65e5\u672c\u8a9e"}, + {// The filename encoding is specified by the referrer charset. + __LINE__, + "http://example.com/V%FDvojov%E1%20psychologie.doc", + "", + "iso-8859-1", + "", + "", + L"", + L"V\u00fdvojov\u00e1 psychologie.doc"}, + {// Suggested filename takes precedence over URL + __LINE__, + "http://www.google.com/test", + "", + "", + "suggested", + "", + L"", + L"suggested"}, + {// The content-disposition has higher precedence over the suggested name. + __LINE__, + "http://www.google.com/test", + "attachment; filename=test.html", + "", + "suggested", + "", + L"", + L"test.html"}, + {__LINE__, + "http://www.google.com/test", + "attachment; filename=test", + "utf-8", + "", + "image/png", + L"", + L"test"}, #if 0 { // The filename encoding doesn't match the referrer charset, the system // charset, or UTF-8. @@ -843,108 +688,95 @@ }, #endif // Raw 8bit characters in C-D - { - __LINE__, - "http://www.example.com/images?id=3", - "attachment; filename=caf\xc3\xa9.png", - "iso-8859-1", - "", - "image/png", - L"", - L"caf\u00e9.png" - }, - { - __LINE__, - "http://www.example.com/images?id=3", - "attachment; filename=caf\xe5.png", - "windows-1253", - "", - "image/png", - L"", - L"caf\u03b5.png" - }, - { // No 'filename' keyword in the disposition, use the URL - __LINE__, - "http://www.evil.com/my_download.txt", - "a_file_name.txt", - "", - "", - "text/plain", - L"download", - L"my_download.txt" - }, - { // Spaces in the disposition file name - __LINE__, - "http://www.frontpagehacker.com/a_download.exe", - "filename=My Downloaded File.exe", - "", - "", - "application/octet-stream", - L"download", - L"My Downloaded File.exe" - }, - { // % encoded - __LINE__, - "http://www.examples.com/", - "attachment; " - "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", - "", - "", - "image/jpeg", - L"download", - L"\uc608\uc220 \uc608\uc220.jpg" - }, - { // name= parameter - __LINE__, - "http://www.examples.com/q.cgi?id=abc", - "attachment; name=abc de.pdf", - "", - "", - "application/octet-stream", - L"download", - L"abc de.pdf" - }, - { - __LINE__, - "http://www.example.com/path", - "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", - "", - "", - "image/png", - L"download", - L"\x82b8\x8853" L"3.png" - }, - { // The following two have invalid CD headers and filenames come from the - // URL. - __LINE__, - "http://www.example.com/test%20123", - "attachment; filename==?iiso88591?Q?caf=EG?=", - "", - "", - "image/jpeg", - L"download", - L"test 123" JPEG_EXT - }, - { - __LINE__, - "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", - "malformed_disposition", - "", - "", - "image/jpeg", - L"download", - L"\uc608\uc220 \uc608\uc220.jpg" - }, - { // Invalid C-D. No filename from URL. Falls back to 'download'. - __LINE__, - "http://www.google.com/path1/path2/", - "attachment; filename==?iso88591?Q?caf=E3?", - "", - "", - "image/jpeg", - L"download", - L"download" JPEG_EXT - }, + {__LINE__, + "http://www.example.com/images?id=3", + "attachment; filename=caf\xc3\xa9.png", + "iso-8859-1", + "", + "image/png", + L"", + L"caf\u00e9.png"}, + {__LINE__, + "http://www.example.com/images?id=3", + "attachment; filename=caf\xe5.png", + "windows-1253", + "", + "image/png", + L"", + L"caf\u03b5.png"}, + {// No 'filename' keyword in the disposition, use the URL + __LINE__, + "http://www.evil.com/my_download.txt", + "a_file_name.txt", + "", + "", + "text/plain", + L"download", + L"my_download.txt"}, + {// Spaces in the disposition file name + __LINE__, + "http://www.frontpagehacker.com/a_download.exe", + "filename=My Downloaded File.exe", + "", + "", + "application/octet-stream", + L"download", + L"My Downloaded File.exe"}, + {// % encoded + __LINE__, + "http://www.examples.com/", + "attachment; " + "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"", + "", + "", + "image/jpeg", + L"download", + L"\uc608\uc220 \uc608\uc220.jpg"}, + {// name= parameter + __LINE__, + "http://www.examples.com/q.cgi?id=abc", + "attachment; name=abc de.pdf", + "", + "", + "application/octet-stream", + L"download", + L"abc de.pdf"}, + {__LINE__, + "http://www.example.com/path", + "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", + "", + "", + "image/png", + L"download", + L"\x82b8\x8853" + L"3.png"}, + {// The following two have invalid CD headers and filenames come from the + // URL. + __LINE__, + "http://www.example.com/test%20123", + "attachment; filename==?iiso88591?Q?caf=EG?=", + "", + "", + "image/jpeg", + L"download", + L"test 123" JPEG_EXT}, + {__LINE__, + "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", + "malformed_disposition", + "", + "", + "image/jpeg", + L"download", + L"\uc608\uc220 \uc608\uc220.jpg"}, + {// Invalid C-D. No filename from URL. Falls back to 'download'. + __LINE__, + "http://www.google.com/path1/path2/", + "attachment; filename==?iso88591?Q?caf=E3?", + "", + "", + "image/jpeg", + L"download", + L"download" JPEG_EXT}, }; // Tests filename generation. Once the correct filename is @@ -1067,7 +899,7 @@ "text/plain", L"download", L"my-cat.jpg"}, - // Windows specific tests +// Windows specific tests #if defined(OS_WIN) {__LINE__, "http://www.goodguy.com/evil.exe",
diff --git a/net/disk_cache/blockfile/block_files.cc b/net/disk_cache/blockfile/block_files.cc index 9aa8f0f1..f46a937 100644 --- a/net/disk_cache/blockfile/block_files.cc +++ b/net/disk_cache/blockfile/block_files.cc
@@ -656,11 +656,11 @@ if (file_size < file_header.Size()) return false; // file_size > 2GB is also an error. - const int kMinBlockSize = 36; - const int kMaxBlockSize = 4096; + const int kMinHeaderBlockSize = 36; + const int kMaxHeaderBlockSize = 4096; BlockFileHeader* header = file_header.Header(); - if (header->entry_size < kMinBlockSize || - header->entry_size > kMaxBlockSize || header->num_entries < 0) + if (header->entry_size < kMinHeaderBlockSize || + header->entry_size > kMaxHeaderBlockSize || header->num_entries < 0) return false; // Make sure that we survive crashes.
diff --git a/net/dns/dns_hosts.cc b/net/dns/dns_hosts.cc index b4d213b..697ea14 100644 --- a/net/dns/dns_hosts.cc +++ b/net/dns/dns_hosts.cc
@@ -131,7 +131,6 @@ DnsHosts* dns_hosts, ParseHostsCommaMode comma_mode) { CHECK(dns_hosts); - DnsHosts& hosts = *dns_hosts; StringPiece ip_text; IPAddressNumber ip; @@ -156,9 +155,9 @@ } else { DnsHostsKey key(parser.token().as_string(), family); base::StringToLowerASCII(&key.first); - IPAddressNumber& mapped_ip = hosts[key]; - if (mapped_ip.empty()) - mapped_ip = ip; + IPAddressNumber* mapped_ip = &(*dns_hosts)[key]; + if (mapped_ip->empty()) + *mapped_ip = ip; // else ignore this entry (first hit counts) } }
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 1c70393..c3eab76 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -8508,8 +8508,9 @@ HostPortPair http_host_port_pair("www.google.com", 80); HttpServerProperties& http_server_properties = *session->http_server_properties(); - EXPECT_FALSE( - http_server_properties.HasAlternateProtocol(http_host_port_pair)); + AlternateProtocolInfo alternate = + http_server_properties.GetAlternateProtocol(http_host_port_pair); + EXPECT_EQ(alternate.protocol, UNINITIALIZED_ALTERNATE_PROTOCOL); EXPECT_EQ(OK, callback.WaitForResult()); @@ -8524,12 +8525,10 @@ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); EXPECT_EQ("hello world", response_data); - ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); - const AlternateProtocolInfo alternate = - http_server_properties.GetAlternateProtocol(http_host_port_pair); - AlternateProtocolInfo expected_alternate( - 443, AlternateProtocolFromNextProto(GetParam()), 1); - EXPECT_TRUE(expected_alternate.Equals(alternate)); + alternate = http_server_properties.GetAlternateProtocol(http_host_port_pair); + EXPECT_EQ(443, alternate.port); + EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()), alternate.protocol); + EXPECT_EQ(1.0, alternate.probability); } TEST_P(HttpNetworkTransactionTest, @@ -8583,11 +8582,10 @@ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); EXPECT_EQ("hello world", response_data); - ASSERT_TRUE(http_server_properties->HasAlternateProtocol( - HostPortPair::FromURL(request.url))); const AlternateProtocolInfo alternate = http_server_properties->GetAlternateProtocol( HostPortPair::FromURL(request.url)); + EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternate.protocol); EXPECT_TRUE(alternate.is_broken); }
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index 840a359..a73b4eb1 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h
@@ -190,11 +190,9 @@ virtual void MaybeForceHTTP11(const HostPortPair& server, SSLConfig* ssl_config) = 0; - // Returns true if |server| has an Alternate-Protocol header. - virtual bool HasAlternateProtocol(const HostPortPair& server) = 0; - - // Returns the Alternate-Protocol and port for |server|. - // HasAlternateProtocol(server) must be true. + // Returns the AlternateProtocol for |server| if it has probability equal to + // or exceeding threshold, or else the forced AlternateProtocol if there is + // one, or else one with UNINITIALIZED_ALTERNATE_PROTOCOL. virtual AlternateProtocolInfo GetAlternateProtocol( const HostPortPair& server) = 0;
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index a53e73f..0b6b9743 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc
@@ -179,10 +179,7 @@ if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second) return true; - if (!HasAlternateProtocol(host_port_pair)) - return false; - - AlternateProtocolInfo info = GetAlternateProtocol(host_port_pair); + const AlternateProtocolInfo info = GetAlternateProtocol(host_port_pair); return info.protocol == QUIC; } @@ -228,16 +225,6 @@ } } -bool HttpServerPropertiesImpl::HasAlternateProtocol( - const HostPortPair& server) { - if (g_forced_alternate_protocol) - return true; - AlternateProtocolMap::const_iterator it = - GetAlternateProtocolIterator(server); - return it != alternate_protocol_map_.end() && - it->second.probability >= alternate_protocol_probability_threshold_; -} - std::string HttpServerPropertiesImpl::GetCanonicalSuffix( const std::string& host) { // If this host ends with a canonical suffix, then return the canonical @@ -251,19 +238,19 @@ return std::string(); } -AlternateProtocolInfo -HttpServerPropertiesImpl::GetAlternateProtocol( +AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol( const HostPortPair& server) { - DCHECK(HasAlternateProtocol(server)); - AlternateProtocolMap::const_iterator it = GetAlternateProtocolIterator(server); - if (it != alternate_protocol_map_.end()) + if (it != alternate_protocol_map_.end() && + it->second.probability >= alternate_protocol_probability_threshold_) return it->second; - // We must be forcing an alternate. - DCHECK(g_forced_alternate_protocol); - return *g_forced_alternate_protocol; + if (g_forced_alternate_protocol) + return *g_forced_alternate_protocol; + + AlternateProtocolInfo uninitialized_alternate_protocol; + return uninitialized_alternate_protocol; } void HttpServerPropertiesImpl::SetAlternateProtocol( @@ -322,15 +309,16 @@ void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( const HostPortPair& server) { AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); + const AlternateProtocolInfo alternate = GetAlternateProtocol(server); if (it == alternate_protocol_map_.end()) { - if (!HasAlternateProtocol(server)) { + if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; return; } // This server's alternate protocol information is coming from a canonical // server. Add an entry in the map for this server explicitly so that // it can be marked as broken. - it = alternate_protocol_map_.Put(server, GetAlternateProtocol(server)); + it = alternate_protocol_map_.Put(server, alternate); } it->second.is_broken = true; int count = ++broken_alternate_protocol_map_[server];
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index 8d251a2..9c2a73c 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h
@@ -79,7 +79,6 @@ void SetHTTP11Required(const HostPortPair& server) override; void MaybeForceHTTP11(const HostPortPair& server, SSLConfig* ssl_config) override; - bool HasAlternateProtocol(const HostPortPair& server) override; AlternateProtocolInfo GetAlternateProtocol( const HostPortPair& server) override; void SetAlternateProtocol(const HostPortPair& server,
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index be5e6b9..e4d70470 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc
@@ -27,6 +27,11 @@ class HttpServerPropertiesImplTest : public testing::Test { protected: + bool HasAlternateProtocol(const HostPortPair& server) { + const AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(server); + return alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL; + } + HttpServerPropertiesImpl impl_; }; @@ -219,23 +224,23 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) { HostPortPair test_host_port_pair("foo", 80); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1.0); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); const AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(443, alternate.port); EXPECT_EQ(NPN_SPDY_3, alternate.protocol); impl_.Clear(); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, DefaultProbabilityExcluded) { HostPortPair test_host_port_pair("foo", 80); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, .99); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, Probability) { @@ -244,7 +249,7 @@ HostPortPair test_host_port_pair("foo", 80); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, .5); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); const AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(443, alternate.port); @@ -258,7 +263,7 @@ HostPortPair test_host_port_pair("foo", 80); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, .5); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { @@ -284,8 +289,8 @@ EXPECT_EQ(1234, it->second.port); EXPECT_EQ(NPN_SPDY_3, it->second.protocol); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1)); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair2)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair1)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair2)); alternate = impl_.GetAlternateProtocol(test_host_port_pair1); EXPECT_TRUE(alternate.is_broken); alternate = impl_.GetAlternateProtocol(test_host_port_pair2); @@ -293,26 +298,6 @@ EXPECT_EQ(NPN_SPDY_3, alternate.protocol); } -TEST_F(AlternateProtocolServerPropertiesTest, MRUOfHasAlternateProtocol) { - HostPortPair test_host_port_pair1("foo1", 80); - impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3, 1.0); - HostPortPair test_host_port_pair2("foo2", 80); - impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3, 1.0); - - const AlternateProtocolMap& map = impl_.alternate_protocol_map(); - AlternateProtocolMap::const_iterator it = map.begin(); - EXPECT_TRUE(it->first.Equals(test_host_port_pair2)); - EXPECT_EQ(1234, it->second.port); - EXPECT_EQ(NPN_SPDY_3, it->second.protocol); - - // HasAlternateProtocol should reorder the AlternateProtocol map. - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1)); - it = map.begin(); - EXPECT_TRUE(it->first.Equals(test_host_port_pair1)); - EXPECT_EQ(443, it->second.port); - EXPECT_EQ(NPN_SPDY_3, it->second.protocol); -} - TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternateProtocol) { HostPortPair test_host_port_pair1("foo1", 80); impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3, 1.0); @@ -340,7 +325,7 @@ HostPortPair test_host_port_pair("foo", 80); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1.0); impl_.SetBrokenAlternateProtocol(test_host_port_pair); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_TRUE(alternate.is_broken); @@ -354,12 +339,12 @@ HostPortPair test_host_port_pair("foo", 80); impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1.0); impl_.SetBrokenAlternateProtocol(test_host_port_pair); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_TRUE(alternate.is_broken); impl_.ClearAlternateProtocol(test_host_port_pair); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, Forced) { @@ -370,7 +355,7 @@ // Verify the forced protocol. HostPortPair test_host_port_pair("foo", 80); - EXPECT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_TRUE(HasAlternateProtocol(test_host_port_pair)); AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(default_protocol.port, alternate.port); @@ -378,7 +363,7 @@ // Verify the real protocol overrides the forced protocol. impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1.0); - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(443, alternate.port); EXPECT_EQ(NPN_SPDY_3, alternate.protocol); @@ -389,22 +374,22 @@ // Verify the forced protocol is off. HostPortPair test_host_port_pair2("bar", 80); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair2)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair2)); } TEST_F(AlternateProtocolServerPropertiesTest, Canonical) { HostPortPair test_host_port_pair("foo.c.youtube.com", 80); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); HostPortPair canonical_port_pair("bar.c.youtube.com", 80); - EXPECT_FALSE(impl_.HasAlternateProtocol(canonical_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(canonical_port_pair)); AlternateProtocolInfo canonical_protocol(1234, QUIC, 1); impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, canonical_protocol.protocol, 1.0); // Verify the forced protocol. - ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + ASSERT_TRUE(HasAlternateProtocol(test_host_port_pair)); AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(canonical_protocol.port, alternate.port); @@ -427,8 +412,8 @@ impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, canonical_protocol.protocol, canonical_protocol.probability); - EXPECT_FALSE(impl_.HasAlternateProtocol(canonical_port_pair)); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(canonical_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, CanonicalAboveThreshold) { @@ -441,8 +426,8 @@ impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, canonical_protocol.protocol, canonical_protocol.probability); - EXPECT_TRUE(impl_.HasAlternateProtocol(canonical_port_pair)); - EXPECT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_TRUE(HasAlternateProtocol(canonical_port_pair)); + EXPECT_TRUE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) { @@ -456,7 +441,7 @@ canonical_protocol.probability); impl_.ClearAlternateProtocol(canonical_port_pair); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) { @@ -470,7 +455,7 @@ canonical_protocol.probability); impl_.SetBrokenAlternateProtocol(canonical_port_pair); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken2) { @@ -500,7 +485,7 @@ canonical_protocol.probability); impl_.Clear(); - EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); + EXPECT_FALSE(HasAlternateProtocol(test_host_port_pair)); } typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest;
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc index c02518d5..c6783d3 100644 --- a/net/http/http_server_properties_manager.cc +++ b/net/http/http_server_properties_manager.cc
@@ -50,6 +50,20 @@ // Persist 200 ServerNetworkStats. const int kMaxServerNetworkStatsHostsToPersist = 200; +const char kVersionKey[] = "version"; +const char kServersKey[] = "servers"; +const char kSupportsSpdyKey[] = "supports_spdy"; +const char kSettingsKey[] = "settings"; +const char kSupportsQuicKey[] = "supports_quic"; +const char kUsedQuicKey[] = "used_quic"; +const char kAddressKey[] = "address"; +const char kAlternateProtocolKey[] = "alternate_protocol"; +const char kPortKey[] = "port"; +const char kProtocolKey[] = "protocol_str"; +const char kProbabilityKey[] = "probability"; +const char kNetworkStatsKey[] = "network_stats"; +const char kSrttKey[] = "srtt"; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -113,7 +127,7 @@ version_number = kVersionNumber; DCHECK_LE(version_number, kVersionNumber); if (version_number <= kVersionNumber) - http_server_properties_dict->SetInteger("version", version_number); + http_server_properties_dict->SetInteger(kVersionKey, version_number); } // This is required for conformance with the HttpServerProperties interface. @@ -166,12 +180,6 @@ http_server_properties_impl_->MaybeForceHTTP11(server, ssl_config); } -bool HttpServerPropertiesManager::HasAlternateProtocol( - const HostPortPair& server) { - DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); - return http_server_properties_impl_->HasAlternateProtocol(server); -} - AlternateProtocolInfo HttpServerPropertiesManager::GetAlternateProtocol( const HostPortPair& server) { DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); @@ -343,7 +351,7 @@ *pref_service_->GetDictionary(path_); int version = kMissingVersion; - if (!http_server_properties_dict.GetIntegerWithoutPathExpansion("version", + if (!http_server_properties_dict.GetIntegerWithoutPathExpansion(kVersionKey, &version)) { DVLOG(1) << "Missing version. Clearing all properties."; return; @@ -353,7 +361,7 @@ // http_server_properties_dict["servers"][server]. const base::DictionaryValue* servers_dict = NULL; if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( - "servers", &servers_dict)) { + kServersKey, &servers_dict)) { DVLOG(1) << "Malformed http_server_properties for servers."; return; } @@ -388,123 +396,19 @@ // Get if server supports Spdy. bool supports_spdy = false; - if ((server_pref_dict->GetBoolean("supports_spdy", &supports_spdy)) && + if ((server_pref_dict->GetBoolean(kSupportsSpdyKey, &supports_spdy)) && supports_spdy) { spdy_servers->push_back(server_str); } - // Get SpdySettings. - DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end()); - const base::DictionaryValue* spdy_settings_dict = NULL; - if (server_pref_dict->GetDictionaryWithoutPathExpansion( - "settings", &spdy_settings_dict)) { - SettingsMap settings_map; - for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict); - !dict_it.IsAtEnd(); - dict_it.Advance()) { - const std::string& id_str = dict_it.key(); - int id = 0; - if (!base::StringToInt(id_str, &id)) { - DVLOG(1) << "Malformed id in SpdySettings for server: " << server_str; - NOTREACHED(); - continue; - } - int value = 0; - if (!dict_it.value().GetAsInteger(&value)) { - DVLOG(1) << "Malformed value in SpdySettings for server: " - << server_str; - NOTREACHED(); - continue; - } - SettingsFlagsAndValue flags_and_value(SETTINGS_FLAG_PERSISTED, value); - settings_map[static_cast<SpdySettingsIds>(id)] = flags_and_value; - } - spdy_settings_map->Put(server, settings_map); - } - - // Get alternate_protocol server. - DCHECK(alternate_protocol_map->Peek(server) == - alternate_protocol_map->end()); - const base::DictionaryValue* port_alternate_protocol_dict = NULL; - if (server_pref_dict->GetDictionaryWithoutPathExpansion( - "alternate_protocol", &port_alternate_protocol_dict)) { - int port = 0; - if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( - "port", &port) || - !IsPortValid(port)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - std::string protocol_str; - if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion( - "protocol_str", &protocol_str)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - AlternateProtocol protocol = AlternateProtocolFromString(protocol_str); - if (!IsAlternateProtocolValid(protocol)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - - double probability = 1; - if (port_alternate_protocol_dict->HasKey("probability") && - !port_alternate_protocol_dict->GetDoubleWithoutPathExpansion( - "probability", &probability)) { - DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - - AlternateProtocolInfo port_alternate_protocol(static_cast<uint16>(port), - protocol, probability); - alternate_protocol_map->Put(server, port_alternate_protocol); - } - - // Get SupportsQuic. - DCHECK(supports_quic_map->find(server) == supports_quic_map->end()); - const base::DictionaryValue* supports_quic_dict = NULL; - if (server_pref_dict->GetDictionaryWithoutPathExpansion( - "supports_quic", &supports_quic_dict)) { - bool used_quic = 0; - if (!supports_quic_dict->GetBooleanWithoutPathExpansion( - "used_quic", &used_quic)) { - DVLOG(1) << "Malformed SupportsQuic server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - std::string address; - if (!supports_quic_dict->GetStringWithoutPathExpansion( - "address", &address)) { - DVLOG(1) << "Malformed SupportsQuic server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - SupportsQuic supports_quic(used_quic, address); - supports_quic_map->insert(std::make_pair(server, supports_quic)); - } - - // Get ServerNetworkStats. - DCHECK(server_network_stats_map->Peek(server) == - server_network_stats_map->end()); - const base::DictionaryValue* server_network_stats_dict = NULL; - if (server_pref_dict->GetDictionaryWithoutPathExpansion( - "network_stats", &server_network_stats_dict)) { - int srtt; - if (!server_network_stats_dict->GetIntegerWithoutPathExpansion("srtt", - &srtt)) { - DVLOG(1) << "Malformed ServerNetworkStats for server: " << server_str; - detected_corrupted_prefs = true; - continue; - } - ServerNetworkStats server_network_stats; - server_network_stats.srtt = base::TimeDelta::FromInternalValue(srtt); - // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist - // bandwidth_estimate. - server_network_stats_map->Put(server, server_network_stats); + AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map.get()); + if (!AddToAlternateProtocolMap(server, *server_pref_dict, + alternate_protocol_map.get()) || + !AddToSupportsQuicMap(server, *server_pref_dict, + supports_quic_map.get()) || + !AddToNetworkStatsMap(server, *server_pref_dict, + server_network_stats_map.get())) { + detected_corrupted_prefs = true; } } @@ -520,6 +424,136 @@ detected_corrupted_prefs)); } +void HttpServerPropertiesManager::AddToSpdySettingsMap( + const HostPortPair& server, + const base::DictionaryValue& server_pref_dict, + SpdySettingsMap* spdy_settings_map) { + // Get SpdySettings. + DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end()); + const base::DictionaryValue* spdy_settings_dict = NULL; + if (!server_pref_dict.GetDictionaryWithoutPathExpansion( + kSettingsKey, &spdy_settings_dict)) { + return; + } + SettingsMap settings_map; + for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict); + !dict_it.IsAtEnd(); dict_it.Advance()) { + const std::string& id_str = dict_it.key(); + int id = 0; + if (!base::StringToInt(id_str, &id)) { + DVLOG(1) << "Malformed id in SpdySettings for server: " + << server.ToString(); + NOTREACHED(); + continue; + } + int value = 0; + if (!dict_it.value().GetAsInteger(&value)) { + DVLOG(1) << "Malformed value in SpdySettings for server: " + << server.ToString(); + NOTREACHED(); + continue; + } + SettingsFlagsAndValue flags_and_value(SETTINGS_FLAG_PERSISTED, value); + settings_map[static_cast<SpdySettingsIds>(id)] = flags_and_value; + } + spdy_settings_map->Put(server, settings_map); +} + +bool HttpServerPropertiesManager::AddToAlternateProtocolMap( + const HostPortPair& server, + const base::DictionaryValue& server_pref_dict, + AlternateProtocolMap* alternate_protocol_map) { + // Get alternate_protocol server. + DCHECK(alternate_protocol_map->Peek(server) == alternate_protocol_map->end()); + const base::DictionaryValue* port_alternate_protocol_dict = NULL; + if (!server_pref_dict.GetDictionaryWithoutPathExpansion( + kAlternateProtocolKey, &port_alternate_protocol_dict)) { + return true; + } + int port = 0; + if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(kPortKey, + &port) || + !IsPortValid(port)) { + DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); + return false; + } + std::string protocol_str; + if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion( + kProtocolKey, &protocol_str)) { + DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); + return false; + } + AlternateProtocol protocol = AlternateProtocolFromString(protocol_str); + if (!IsAlternateProtocolValid(protocol)) { + DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); + return false; + } + double probability = 1; + if (port_alternate_protocol_dict->HasKey(kProbabilityKey) && + !port_alternate_protocol_dict->GetDoubleWithoutPathExpansion( + kProbabilityKey, &probability)) { + DVLOG(1) << "Malformed Alternate-Protocol server: " << server.ToString(); + return false; + } + + AlternateProtocolInfo port_alternate_protocol(static_cast<uint16>(port), + protocol, probability); + alternate_protocol_map->Put(server, port_alternate_protocol); + return true; +} + +bool HttpServerPropertiesManager::AddToSupportsQuicMap( + const HostPortPair& server, + const base::DictionaryValue& server_pref_dict, + SupportsQuicMap* supports_quic_map) { + DCHECK(supports_quic_map->find(server) == supports_quic_map->end()); + const base::DictionaryValue* supports_quic_dict = NULL; + if (!server_pref_dict.GetDictionaryWithoutPathExpansion( + kSupportsQuicKey, &supports_quic_dict)) { + return true; + } + bool used_quic = 0; + if (!supports_quic_dict->GetBooleanWithoutPathExpansion(kUsedQuicKey, + &used_quic)) { + DVLOG(1) << "Malformed SupportsQuic server: " << server.ToString(); + return false; + } + std::string address; + if (!supports_quic_dict->GetStringWithoutPathExpansion(kAddressKey, + &address)) { + DVLOG(1) << "Malformed SupportsQuic server: " << server.ToString(); + return false; + } + SupportsQuic supports_quic(used_quic, address); + supports_quic_map->insert(std::make_pair(server, supports_quic)); + return true; +} + +bool HttpServerPropertiesManager::AddToNetworkStatsMap( + const HostPortPair& server, + const base::DictionaryValue& server_pref_dict, + ServerNetworkStatsMap* network_stats_map) { + DCHECK(network_stats_map->Peek(server) == network_stats_map->end()); + const base::DictionaryValue* server_network_stats_dict = NULL; + if (!server_pref_dict.GetDictionaryWithoutPathExpansion( + kNetworkStatsKey, &server_network_stats_dict)) { + return true; + } + int srtt; + if (!server_network_stats_dict->GetIntegerWithoutPathExpansion(kSrttKey, + &srtt)) { + DVLOG(1) << "Malformed ServerNetworkStats for server: " + << server.ToString(); + return false; + } + ServerNetworkStats server_network_stats; + server_network_stats.srtt = base::TimeDelta::FromInternalValue(srtt); + // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist + // bandwidth_estimate. + network_stats_map->Put(server, server_network_stats); + return true; +} + void HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread( StringVector* spdy_servers, SpdySettingsMap* spdy_settings_map, @@ -697,14 +731,7 @@ ++list_it) { if ((*list_it)->GetAsString(&s)) { HostPortPair server = HostPortPair::FromString(s); - - ServerPrefMap::iterator it = server_pref_map.find(server); - if (it == server_pref_map.end()) { - ServerPref server_pref(true, NULL, NULL, NULL, NULL); - server_pref_map[server] = server_pref; - } else { - it->second.supports_spdy = true; - } + server_pref_map[server].supports_spdy = true; } } @@ -712,14 +739,7 @@ for (SpdySettingsMap::iterator map_it = spdy_settings_map->begin(); map_it != spdy_settings_map->end(); ++map_it) { const HostPortPair& server = map_it->first; - - ServerPrefMap::iterator it = server_pref_map.find(server); - if (it == server_pref_map.end()) { - ServerPref server_pref(false, &map_it->second, NULL, NULL, NULL); - server_pref_map[server] = server_pref; - } else { - it->second.settings_map = &map_it->second; - } + server_pref_map[server].settings_map = &map_it->second; } // Add AlternateProtocol servers to server_pref_map. @@ -731,28 +751,14 @@ if (!IsAlternateProtocolValid(port_alternate_protocol.protocol)) { continue; } - - ServerPrefMap::iterator it = server_pref_map.find(server); - if (it == server_pref_map.end()) { - ServerPref server_pref(false, NULL, &map_it->second, NULL, NULL); - server_pref_map[server] = server_pref; - } else { - it->second.alternate_protocol = &map_it->second; - } + server_pref_map[server].alternate_protocol = &map_it->second; } // Add SupportsQuic servers to server_pref_map. for (SupportsQuicMap::const_iterator map_it = supports_quic_map->begin(); map_it != supports_quic_map->end(); ++map_it) { const HostPortPair& server = map_it->first; - - ServerPrefMap::iterator it = server_pref_map.find(server); - if (it == server_pref_map.end()) { - ServerPref server_pref(false, NULL, NULL, &map_it->second, NULL); - server_pref_map[server] = server_pref; - } else { - it->second.supports_quic = &map_it->second; - } + server_pref_map[server].supports_quic = &map_it->second; } // Add ServerNetworkStats servers to server_pref_map. @@ -760,14 +766,7 @@ server_network_stats_map->begin(); map_it != server_network_stats_map->end(); ++map_it) { const HostPortPair& server = map_it->first; - - ServerPrefMap::iterator it = server_pref_map.find(server); - if (it == server_pref_map.end()) { - ServerPref server_pref(false, NULL, NULL, NULL, &map_it->second); - server_pref_map[server] = server_pref; - } else { - it->second.server_network_stats = &map_it->second; - } + server_pref_map[server].server_network_stats = &map_it->second; } // Persist properties to the |path_|. @@ -783,68 +782,19 @@ // Save supports_spdy. if (server_pref.supports_spdy) - server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy); - - // Save SPDY settings. - if (server_pref.settings_map) { - base::DictionaryValue* spdy_settings_dict = new base::DictionaryValue; - for (SettingsMap::const_iterator it = server_pref.settings_map->begin(); - it != server_pref.settings_map->end(); ++it) { - SpdySettingsIds id = it->first; - uint32 value = it->second.second; - std::string key = base::StringPrintf("%u", id); - spdy_settings_dict->SetInteger(key, value); - } - server_pref_dict->SetWithoutPathExpansion("settings", spdy_settings_dict); - } - - // Save alternate_protocol. - const AlternateProtocolInfo* port_alternate_protocol = - server_pref.alternate_protocol; - if (port_alternate_protocol && !port_alternate_protocol->is_broken) { - base::DictionaryValue* port_alternate_protocol_dict = - new base::DictionaryValue; - port_alternate_protocol_dict->SetInteger("port", - port_alternate_protocol->port); - const char* protocol_str = - AlternateProtocolToString(port_alternate_protocol->protocol); - port_alternate_protocol_dict->SetString("protocol_str", protocol_str); - port_alternate_protocol_dict->SetDouble( - "probability", port_alternate_protocol->probability); - server_pref_dict->SetWithoutPathExpansion( - "alternate_protocol", port_alternate_protocol_dict); - } - - // Save supports_quic. - if (server_pref.supports_quic) { - base::DictionaryValue* supports_quic_dict = new base::DictionaryValue; - const SupportsQuic* supports_quic = server_pref.supports_quic; - supports_quic_dict->SetBoolean("used_quic", supports_quic->used_quic); - supports_quic_dict->SetString("address", supports_quic->address); - server_pref_dict->SetWithoutPathExpansion( - "supports_quic", supports_quic_dict); - } - - // Save ServerNetworkStats. - if (server_pref.server_network_stats) { - base::DictionaryValue* server_network_stats_dict = - new base::DictionaryValue; - const ServerNetworkStats* server_network_stats = - server_pref.server_network_stats; - // Becasue JSON doesn't support int64, persist int64 as a string. - server_network_stats_dict->SetInteger( - "srtt", - static_cast<int>(server_network_stats->srtt.ToInternalValue())); - // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist - // bandwidth_estimate. - server_pref_dict->SetWithoutPathExpansion("network_stats", - server_network_stats_dict); - } + server_pref_dict->SetBoolean(kSupportsSpdyKey, server_pref.supports_spdy); + SaveSpdySettingsToServerPrefs(server_pref.settings_map, server_pref_dict); + SaveAlternateProtocolToServerPrefs(server_pref.alternate_protocol, + server_pref_dict); + SaveSupportsQuicToServerPrefs(server_pref.supports_quic, server_pref_dict); + SaveNetworkStatsToServerPrefs(server_pref.server_network_stats, + server_pref_dict); servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict); } - http_server_properties_dict.SetWithoutPathExpansion("servers", servers_dict); + http_server_properties_dict.SetWithoutPathExpansion(kServersKey, + servers_dict); SetVersion(&http_server_properties_dict, kVersionNumber); setting_prefs_ = true; pref_service_->Set(path_, http_server_properties_dict); @@ -858,6 +808,72 @@ completion.Run(); } +void HttpServerPropertiesManager::SaveSpdySettingsToServerPrefs( + const SettingsMap* settings_map, + base::DictionaryValue* server_pref_dict) { + if (!settings_map) { + return; + } + base::DictionaryValue* spdy_settings_dict = new base::DictionaryValue; + for (SettingsMap::const_iterator it = settings_map->begin(); + it != settings_map->end(); ++it) { + SpdySettingsIds id = it->first; + uint32 value = it->second.second; + std::string key = base::StringPrintf("%u", id); + spdy_settings_dict->SetInteger(key, value); + } + server_pref_dict->SetWithoutPathExpansion(kSettingsKey, spdy_settings_dict); +} + +void HttpServerPropertiesManager::SaveAlternateProtocolToServerPrefs( + const AlternateProtocolInfo* port_alternate_protocol, + base::DictionaryValue* server_pref_dict) { + if (!port_alternate_protocol || port_alternate_protocol->is_broken) + return; + + base::DictionaryValue* port_alternate_protocol_dict = + new base::DictionaryValue; + port_alternate_protocol_dict->SetInteger(kPortKey, + port_alternate_protocol->port); + const char* protocol_str = + AlternateProtocolToString(port_alternate_protocol->protocol); + port_alternate_protocol_dict->SetString(kProtocolKey, protocol_str); + port_alternate_protocol_dict->SetDouble(kProbabilityKey, + port_alternate_protocol->probability); + server_pref_dict->SetWithoutPathExpansion(kAlternateProtocolKey, + port_alternate_protocol_dict); +} + +void HttpServerPropertiesManager::SaveSupportsQuicToServerPrefs( + const SupportsQuic* supports_quic, + base::DictionaryValue* server_pref_dict) { + // Save supports_quic. + if (!supports_quic) + return; + + base::DictionaryValue* supports_quic_dict = new base::DictionaryValue; + supports_quic_dict->SetBoolean(kUsedQuicKey, supports_quic->used_quic); + supports_quic_dict->SetString(kAddressKey, supports_quic->address); + server_pref_dict->SetWithoutPathExpansion(kSupportsQuicKey, + supports_quic_dict); +} + +void HttpServerPropertiesManager::SaveNetworkStatsToServerPrefs( + const ServerNetworkStats* server_network_stats, + base::DictionaryValue* server_pref_dict) { + if (!server_network_stats) + return; + + base::DictionaryValue* server_network_stats_dict = new base::DictionaryValue; + // Becasue JSON doesn't support int64, persist int64 as a string. + server_network_stats_dict->SetInteger( + kSrttKey, static_cast<int>(server_network_stats->srtt.ToInternalValue())); + // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist + // bandwidth_estimate. + server_pref_dict->SetWithoutPathExpansion(kNetworkStatsKey, + server_network_stats_dict); +} + void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); if (!setting_prefs_)
diff --git a/net/http/http_server_properties_manager.h b/net/http/http_server_properties_manager.h index 00e5a13..21d817a0 100644 --- a/net/http/http_server_properties_manager.h +++ b/net/http/http_server_properties_manager.h
@@ -86,7 +86,6 @@ void SetHTTP11Required(const HostPortPair& server) override; void MaybeForceHTTP11(const HostPortPair& server, SSLConfig* ssl_config) override; - bool HasAlternateProtocol(const HostPortPair& server) override; AlternateProtocolInfo GetAlternateProtocol( const HostPortPair& server) override; void SetAlternateProtocol(const HostPortPair& server, @@ -181,6 +180,30 @@ private: void OnHttpServerPropertiesChanged(); + void AddToSpdySettingsMap(const HostPortPair& server, + const base::DictionaryValue& server_dict, + SpdySettingsMap* spdy_settings_map); + bool AddToAlternateProtocolMap(const HostPortPair& server, + const base::DictionaryValue& server_dict, + AlternateProtocolMap* alternate_protocol_map); + bool AddToSupportsQuicMap(const HostPortPair& server, + const base::DictionaryValue& server_dict, + SupportsQuicMap* supports_quic_map); + bool AddToNetworkStatsMap(const HostPortPair& server, + const base::DictionaryValue& server_dict, + ServerNetworkStatsMap* network_stats_map); + + void SaveSpdySettingsToServerPrefs(const SettingsMap* spdy_settings_map, + base::DictionaryValue* server_pref_dict); + void SaveAlternateProtocolToServerPrefs( + const AlternateProtocolInfo* port_alternate_protocol, + base::DictionaryValue* server_pref_dict); + void SaveSupportsQuicToServerPrefs(const SupportsQuic* supports_quic, + base::DictionaryValue* server_pref_dict); + void SaveNetworkStatsToServerPrefs( + const ServerNetworkStats* server_network_stats, + base::DictionaryValue* server_pref_dict); + // ----------- // Pref thread // -----------
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc index d021fc5..cbc2275e 100644 --- a/net/http/http_server_properties_manager_unittest.cc +++ b/net/http/http_server_properties_manager_unittest.cc
@@ -134,6 +134,12 @@ UpdatePrefsFromCacheOnNetworkThreadConcrete)); } + bool HasAlternateProtocol(const HostPortPair& server) { + const AlternateProtocolInfo alternate = + http_server_props_manager_->GetAlternateProtocol(server); + return alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL; + } + //base::RunLoop loop_; TestingPrefServiceSimple pref_service_; scoped_ptr<TestingHttpServerPropertiesManager> http_server_props_manager_; @@ -230,8 +236,6 @@ HostPortPair::FromString("foo.google.com:1337"))); // Verify AlternateProtocol. - ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(google_server)); - ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(mail_server)); AlternateProtocolInfo port_alternate_protocol = http_server_props_manager_->GetAlternateProtocol(google_server); EXPECT_EQ(443, port_alternate_protocol.port); @@ -307,8 +311,8 @@ // Verify that nothing is set. EXPECT_FALSE(http_server_props_manager_->SupportsRequestPriority( HostPortPair::FromString("www.google.com:65536"))); - EXPECT_FALSE(http_server_props_manager_->HasAlternateProtocol( - HostPortPair::FromString("www.google.com:65536"))); + EXPECT_FALSE( + HasAlternateProtocol(HostPortPair::FromString("www.google.com:65536"))); SupportsQuic supports_quic2 = http_server_props_manager_->GetSupportsQuic( HostPortPair::FromString("www.google.com:65536")); EXPECT_FALSE(supports_quic2.used_quic); @@ -352,8 +356,8 @@ Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); // Verify AlternateProtocol is not set. - EXPECT_FALSE(http_server_props_manager_->HasAlternateProtocol( - HostPortPair::FromString("www.google.com:80"))); + EXPECT_FALSE( + HasAlternateProtocol(HostPortPair::FromString("www.google.com:80"))); } TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) { @@ -477,12 +481,11 @@ Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); } -TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) { +TEST_F(HttpServerPropertiesManagerTest, GetAlternateProtocol) { ExpectPrefsUpdate(); HostPortPair spdy_server_mail("mail.google.com", 80); - EXPECT_FALSE( - http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); + EXPECT_FALSE(HasAlternateProtocol(spdy_server_mail)); http_server_props_manager_->SetAlternateProtocol(spdy_server_mail, 443, NPN_SPDY_3, 1.0); @@ -490,12 +493,11 @@ base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); - ASSERT_TRUE( - http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); - AlternateProtocolInfo port_alternate_protocol = + const AlternateProtocolInfo alternate_protocol = http_server_props_manager_->GetAlternateProtocol(spdy_server_mail); - EXPECT_EQ(443, port_alternate_protocol.port); - EXPECT_EQ(NPN_SPDY_3, port_alternate_protocol.protocol); + EXPECT_EQ(443, alternate_protocol.port); + EXPECT_EQ(NPN_SPDY_3, alternate_protocol.protocol); + EXPECT_EQ(1.0, alternate_protocol.probability); } TEST_F(HttpServerPropertiesManagerTest, SupportsQuic) { @@ -561,8 +563,7 @@ EXPECT_TRUE( http_server_props_manager_->SupportsRequestPriority(spdy_server_mail)); - EXPECT_TRUE( - http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); + EXPECT_TRUE(HasAlternateProtocol(spdy_server_mail)); SupportsQuic supports_quic = http_server_props_manager_->GetSupportsQuic(spdy_server_mail); EXPECT_TRUE(supports_quic.used_quic); @@ -591,8 +592,7 @@ EXPECT_FALSE( http_server_props_manager_->SupportsRequestPriority(spdy_server_mail)); - EXPECT_FALSE( - http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); + EXPECT_FALSE(HasAlternateProtocol(spdy_server_mail)); SupportsQuic supports_quic1 = http_server_props_manager_->GetSupportsQuic(spdy_server_mail); EXPECT_FALSE(supports_quic1.used_quic); @@ -654,8 +654,6 @@ // Verify AlternateProtocol. for (int i = 0; i < 200; ++i) { std::string server = StringPrintf("www.google.com:%d", i); - ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol( - HostPortPair::FromString(server))); AlternateProtocolInfo port_alternate_protocol = http_server_props_manager_->GetAlternateProtocol( HostPortPair::FromString(server));
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index f84b80c..754372bb 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc
@@ -86,14 +86,6 @@ if (mapping_rules) mapping_rules->RewriteHost(&host_port); - if (http_server_properties->HasAlternateProtocol(host_port)) { - const AlternateProtocolInfo existing_alternate = - http_server_properties->GetAlternateProtocol(host_port); - // If we think the alternate protocol is broken, don't change it. - if (existing_alternate.is_broken) - return; - } - http_server_properties->SetAlternateProtocol( host_port, static_cast<uint16>(port), protocol, probability); }
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 9e932ee..78238b94 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -175,8 +175,7 @@ AlternateProtocolInfo HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( const GURL& original_url, GURL* alternate_url) { - const AlternateProtocolInfo kNoAlternateProtocol = - AlternateProtocolInfo(0, UNINITIALIZED_ALTERNATE_PROTOCOL, 0); + const AlternateProtocolInfo kNoAlternateProtocol; if (!session_->params().use_alternate_protocols) return kNoAlternateProtocol; @@ -185,19 +184,17 @@ return kNoAlternateProtocol; HostPortPair origin = HostPortPair::FromURL(original_url); - HttpServerProperties& http_server_properties = *session_->http_server_properties(); - if (!http_server_properties.HasAlternateProtocol(origin)) - return kNoAlternateProtocol; - - AlternateProtocolInfo alternate = + const AlternateProtocolInfo alternate = http_server_properties.GetAlternateProtocol(origin); + + if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) + return kNoAlternateProtocol; if (alternate.is_broken) { HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); return kNoAlternateProtocol; } - if (!IsAlternateProtocolValid(alternate.protocol)) { NOTREACHED(); return kNoAlternateProtocol;
diff --git a/net/interfaces/BUILD.gn b/net/interfaces/BUILD.gn new file mode 100644 index 0000000..03a07785 --- /dev/null +++ b/net/interfaces/BUILD.gn
@@ -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. + +import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni") + +mojom("interfaces") { + sources = [ + "host_resolver_service.mojom", + "proxy_resolver_service.mojom", + ] +}
diff --git a/net/interfaces/host_resolver_service.mojom b/net/interfaces/host_resolver_service.mojom new file mode 100644 index 0000000..c8acc38 --- /dev/null +++ b/net/interfaces/host_resolver_service.mojom
@@ -0,0 +1,55 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// WARNING! Do NOT use this mojom. It is intended as a temporary interface to +// implement out-of-process proxy resolution. If you wish to use a Mojo DNS +// service, contact amistry@/sammc@ and net-dev to discuss a permanent Mojo DNS +// interface. + +// Put Mojo definitions into their own namespace to avoid collisions with C++ +// definitions. +// TODO(amistry): Resolve the conflict between these two sets of definitions. +module net.interfaces; + +// Mirror of net::AddressFamily. +enum AddressFamily { + UNSPECIFIED, + IPV4, + IPV6, +}; + +// Mirror of net::HostResolver::RequestInfo. +struct HostResolverRequestInfo { + string host; + uint16 port; + AddressFamily address_family; + bool is_my_ip_address; +}; + +// Mirror of net::IPEndPoint. +struct IPEndPoint { + // IP address as a numeric value from most to least significant byte. + // Will be of length 4 for IPv4 addresses and 16 for IPv6. + array<uint8> address; + uint16 port; +}; + +// Mirror of net::AddressList. +struct AddressList { + array<IPEndPoint> addresses; +}; + +interface HostResolverService { + // Use a HostResolverRequestClient instead of returning a result so we can + // cancel in-flight requests by destroying the client. IPC requests in Mojo + // cannot be cancelled directly. + // TODO(amistry): Add BoundNetLog. + Resolve(HostResolverRequestInfo request_info, + HostResolverRequestClient client); +}; + +interface HostResolverRequestClient { + // |error| is a value in net::Error. + ReportResult(int32 error, AddressList? result); +};
diff --git a/net/interfaces/proxy_resolver_service.mojom b/net/interfaces/proxy_resolver_service.mojom new file mode 100644 index 0000000..2cb7a0b7 --- /dev/null +++ b/net/interfaces/proxy_resolver_service.mojom
@@ -0,0 +1,48 @@ +// 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. + +// Put Mojo definitions into their own namespace to avoid collisions with C++ +// definitions. +// TODO(amistry): Resolve the conflict between these two sets of definitions. +module net.interfaces; + +import "host_resolver_service.mojom"; + +// Mirror of net::ProxyServer::Scheme. +enum ProxyScheme { + INVALID, + DIRECT, + HTTP, + SOCKS4, + SOCKS5, + HTTPS, + QUIC, +}; + +// Mirror of net::ProxyServer. +struct ProxyServer { + ProxyScheme scheme; + string host; + uint16 port; +}; + +interface ProxyResolverService { + SetPacScript(string data) => (int32 result); + + // Use a ProxyResolverRequestClient instead of returning a result so we can + // receive load state updates and cancel in-flight requests by destroying the + // client. + // TODO(amistry): Add BoundNetLog. + GetProxyForUrl(string url, ProxyResolverRequestClient client); +}; + +interface ProxyResolverRequestClient { + ReportResult(int32 error, array<ProxyServer>? proxy_servers); +}; + +interface ProxyResolverFactory { + // TODO(amistry): Add NetLog and ProxyResolverErrorObserver. + CreateResolver(ProxyResolverService& resolver, + HostResolverService host_resolver); +};
diff --git a/net/net.gyp b/net/net.gyp index 834a4c6..6dac5c8 100644 --- a/net/net.gyp +++ b/net/net.gyp
@@ -1203,6 +1203,22 @@ }, ], }], + ['use_v8_in_net == 1 and OS != "android"', { + 'targets': [ + { + # GN version: //net/interfaces + 'target_name': 'net_interfaces', + 'type': 'static_library', + 'sources': [ + 'interfaces/host_resolver_service.mojom', + 'interfaces/proxy_resolver_service.mojom', + ], + 'includes': [ + '../third_party/mojo/mojom_bindings_generator.gypi', + ], + }, + ], + }], ['OS != "ios" and OS != "android"', { 'targets': [ # iOS doesn't have the concept of simple executables, these targets
diff --git a/net/net_unittests.isolate b/net/net_unittests.isolate index e062a7d6..ec515fbe 100644 --- a/net/net_unittests.isolate +++ b/net/net_unittests.isolate
@@ -19,6 +19,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../testing/test_env.py',
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index 5219d1e..203aa3e 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -284,17 +284,14 @@ } void ExpectBrokenAlternateProtocolMapping() { - ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( - HostPortPair::FromURL(request_.url))); const AlternateProtocolInfo alternate = session_->http_server_properties()->GetAlternateProtocol( HostPortPair::FromURL(request_.url)); + EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL, alternate.protocol); EXPECT_TRUE(alternate.is_broken); } void ExpectQuicAlternateProtocolMapping() { - ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol( - HostPortPair::FromURL(request_.url))); const AlternateProtocolInfo alternate = session_->http_server_properties()->GetAlternateProtocol( HostPortPair::FromURL(request_.url));
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index f957c18..f38ae01 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -1249,7 +1249,9 @@ const HostPortPair& server = server_id.host_port_pair(); // Don't try to change the alternate-protocol state, if the // alternate-protocol state is unknown. - if (!http_server_properties_->HasAlternateProtocol(server)) + const AlternateProtocolInfo alternate = + http_server_properties_->GetAlternateProtocol(server); + if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) return; // TODO(rch): In the special case where the session has received no @@ -1258,8 +1260,6 @@ // session connected until the handshake has been confirmed. HistogramBrokenAlternateProtocolLocation( BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY); - AlternateProtocolInfo alternate = - http_server_properties_->GetAlternateProtocol(server); DCHECK_EQ(QUIC, alternate.protocol); // Since the session was active, there's no longer an
diff --git a/net/test/url_request/url_request_mock_http_job.cc b/net/test/url_request/url_request_mock_http_job.cc index 9e63c25..e0905f2 100644 --- a/net/test/url_request/url_request_mock_http_job.cc +++ b/net/test/url_request/url_request_mock_http_job.cc
@@ -122,16 +122,6 @@ } // static -void URLRequestMockHTTPJob::AddHostnameToFileHandler( - const std::string& hostname, - const base::FilePath& file, - const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { - net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); - filter->AddHostnameInterceptor( - "http", hostname, CreateInterceptorForSingleFile(file, worker_pool)); -} - -// static GURL URLRequestMockHTTPJob::GetMockUrl(const base::FilePath& path) { return GetMockUrlForScheme(path, "http"); }
diff --git a/net/test/url_request/url_request_mock_http_job.h b/net/test/url_request/url_request_mock_http_job.h index 6e454f4..61d5069 100644 --- a/net/test/url_request/url_request_mock_http_job.h +++ b/net/test/url_request/url_request_mock_http_job.h
@@ -54,13 +54,6 @@ const base::FilePath& base_path, const scoped_refptr<base::SequencedWorkerPool>& worker_pool); - // Respond to all HTTP requests of |hostname| with contents of the file - // located at |file_path|. - static void AddHostnameToFileHandler( - const std::string& hostname, - const base::FilePath& file, - const scoped_refptr<base::SequencedWorkerPool>& worker_pool); - // Given the path to a file relative to the path passed to AddUrlHandler(), // construct a mock URL. static GURL GetMockUrl(const base::FilePath& path);
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn index b028290..4ecd961f 100644 --- a/pdf/BUILD.gn +++ b/pdf/BUILD.gn
@@ -4,8 +4,7 @@ pdf_engine = 0 # 0 PDFium -# TODO(GYP) need support for loadable modules -shared_library("pdf") { +static_library("pdf") { sources = [ "button.h", "button.cc", @@ -35,7 +34,6 @@ "paint_manager.h", "pdf.cc", "pdf.h", - "pdf.rc", "progress_control.cc", "progress_control.h", "pdf_engine.h", @@ -45,8 +43,6 @@ "resource_consts.h", "thumbnail_control.cc", "thumbnail_control.h", - "../components/ui/zoom/page_zoom_constants.cc", - "../content/common/page_zoom.cc", ] if (pdf_engine == 0) { @@ -68,33 +64,15 @@ } if (is_win) { - defines = [ "COMPILE_CONTENT_STATICALLY" ] cflags = [ "/wd4267" ] # TODO(jschuh) size_t to int truncations. } - if (is_mac) { - # TODO(GYP) - #'mac_bundle': 1, - #'product_name': 'PDF', - #'product_extension': 'plugin', - ## Strip the shipping binary of symbols so "Foxit" doesn't appear in - ## the binary. Symbols are stored in a separate .dSYM. - #'variables': { - # 'mac_real_dsym': 1, - #}, - #'sources+': [ - # 'Info.plist' - #] - #'xcode_settings': { - # 'INFOPLIST_FILE': 'Info.plist', - #}, - } - deps = [ "//base", + "//components/ui/zoom:ui_zoom", + "//content/public/common", "//net", - "//ppapi:ppapi_cpp", + "//ppapi:ppapi_internal_module", "//third_party/pdfium", ] } -# TODO(GYP) pdf_linux_symbols target.
diff --git a/pdf/Info.plist b/pdf/Info.plist deleted file mode 100644 index 9f3dfdf..0000000 --- a/pdf/Info.plist +++ /dev/null
@@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>org.chromium.pdf_plugin</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>BRPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>CFPlugInDynamicRegisterFunction</key> - <string></string> - <key>CFPlugInDynamicRegistration</key> - <string>NO</string> - <key>WebPluginDescription</key> - <string>Chrome PDF Viewer</string> - <key>WebPluginMIMETypes</key> - <dict> - <key>application/pdf</key> - <dict> - <key>WebPluginExtensions</key> - <array> - <string>pdf</string> - </array> - <key>WebPluginTypeDescription</key> - <string>Acrobat Portable Document Format</string> - </dict> - </dict> - <key>WebPluginName</key> - <string>Chrome PDF Viewer</string> -</dict> -</plist>
diff --git a/pdf/pdf.cc b/pdf/pdf.cc index d6c9863..7aba412 100644 --- a/pdf/pdf.cc +++ b/pdf/pdf.cc
@@ -13,73 +13,12 @@ #include "pdf/instance.h" #include "pdf/out_of_process_instance.h" #include "ppapi/c/ppp.h" +#include "ppapi/cpp/private/internal_module.h" #include "ppapi/cpp/private/pdf.h" #include "v8/include/v8.h" bool g_sdk_initialized_via_pepper = false; -// The Mac release builds discard CreateModule and the entire PDFModule -// definition because they are not referenced here. This causes the Pepper -// exports (PPP_GetInterface etc) to not be exported. So we force the linker -// to include this code by using __attribute__((used)). -#if __GNUC__ >= 4 -#define PDF_USED __attribute__((used)) -#else -#define PDF_USED -#endif - -#if defined(OS_WIN) - -void HandleInvalidParameter(const wchar_t* expression, - const wchar_t* function, - const wchar_t* file, - unsigned int line, - uintptr_t reserved) { - // Do the same as Chrome's CHECK(false) which is undefined. - ::base::debug::BreakDebugger(); - return; -} - -void HandlePureVirtualCall() { - // Do the same as Chrome's CHECK(false) which is undefined. - ::base::debug::BreakDebugger(); - return; -} - - -BOOL APIENTRY DllMain(HMODULE module, DWORD reason_for_call, LPVOID reserved) { - if (reason_for_call == DLL_PROCESS_ATTACH) { - // On windows following handlers work only inside module. So breakpad in - // chrome.dll does not catch that. To avoid linking related code or - // duplication breakpad_win.cc::InitCrashReporter() just catch errors here - // and crash in a way interceptable by breakpad of parent module. - _set_invalid_parameter_handler(HandleInvalidParameter); - _set_purecall_handler(HandlePureVirtualCall); - -#if defined(ARCH_CPU_X86_64) && _MSC_VER <= 1800 - // VS2013's CRT only checks the existence of FMA3 instructions, not the - // enabled-ness of them at the OS level (this is fixed in VS2015). We force - // off usage of FMA3 instructions in the CRT to avoid using that path and - // hitting illegal instructions when running on CPUs that support FMA3, but - // OSs that don't. Because we use the static library CRT we have to call - // this function once in each DLL. - // See http://crbug.com/436603. - _set_FMA3_enable(0); -#endif // ARCH_CPU_X86_64 && _MSC_VER <= 1800 - } - return TRUE; -} - -#endif - -namespace pp { - -PDF_USED Module* CreateModule() { - return new chrome_pdf::PDFModule(); -} - -} // namespace pp - namespace chrome_pdf { PDFModule::PDFModule() { @@ -117,49 +56,37 @@ return new Instance(instance); } -} // namespace chrome_pdf -extern "C" { +// Implementation of Global PPP functions --------------------------------- +int32_t PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface) { + PDFModule* module = new PDFModule(); + if (!module->InternalInit(module_id, get_browser_interface)) { + delete module; + return PP_ERROR_FAILED; + } -// TODO(sanjeevr): It might make sense to provide more stateful wrappers over -// the internal PDF SDK (such as LoadDocument, LoadPage etc). Determine if we -// need to provide this. -// Wrapper exports over the PDF engine that can be used by an external module -// such as Chrome (since Chrome cannot directly pull in PDFium sources). + pp::InternalSetModuleSingleton(module); + return PP_OK; +} + +void PPP_ShutdownModule() { + delete pp::Module::Get(); + pp::InternalSetModuleSingleton(NULL); +} + +const void* PPP_GetInterface(const char* interface_name) { + if (!pp::Module::Get()) + return NULL; + return pp::Module::Get()->GetPluginInterface(interface_name); +} + #if defined(OS_WIN) -// |pdf_buffer| is the buffer that contains the entire PDF document to be -// rendered. -// |buffer_size| is the size of |pdf_buffer| in bytes. -// |page_number| is the 0-based index of the page to be rendered. -// |dc| is the device context to render into. -// |dpi_x| and |dpi_y| are the x and y resolutions respectively. If either -// value is -1, the dpi from the DC will be used. -// |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height| -// specify a bounds rectangle within the DC in which to render the PDF -// page. -// |fit_to_bounds| specifies whether the output should be shrunk to fit the -// supplied bounds if the page size is larger than the bounds in any -// dimension. If this is false, parts of the PDF page that lie outside -// the bounds will be clipped. -// |stretch_to_bounds| specifies whether the output should be stretched to fit -// the supplied bounds if the page size is smaller than the bounds in any -// dimension. -// If both |fit_to_bounds| and |stretch_to_bounds| are true, then -// |fit_to_bounds| is honored first. -// |keep_aspect_ratio| If any scaling is to be done is true, this flag -// specifies whether the original aspect ratio of the page should be -// preserved while scaling. -// |center_in_bounds| specifies whether the final image (after any scaling is -// done) should be centered within the given bounds. -// |autorotate| specifies whether the final image should be rotated to match -// the output bound. -// Returns false if the document or the page number are not valid. -PP_EXPORT bool RenderPDFPageToDC(const void* pdf_buffer, +bool RenderPDFPageToDC(const void* pdf_buffer, int buffer_size, int page_number, HDC dc, - int dpi_x, - int dpi_y, + int dpi, int bounds_origin_x, int bounds_origin_y, int bounds_width, @@ -177,8 +104,8 @@ scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports( chrome_pdf::PDFEngineExports::Create()); chrome_pdf::PDFEngineExports::RenderingSettings settings( - dpi_x, dpi_y, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, - bounds_height), + dpi, dpi, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, + bounds_height), fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds, autorotate); bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size, @@ -191,9 +118,6 @@ #endif // OS_WIN -// |page_count| and |max_page_width| are optional and can be NULL. -// Returns false if the document is not valid. -PDF_USED PP_EXPORT bool GetPDFDocInfo(const void* pdf_buffer, int buffer_size, int* page_count, double* max_page_width) { @@ -211,16 +135,6 @@ return ret; } -// Gets the dimensions of a specific page in a document. -// |pdf_buffer| is the buffer that contains the entire PDF document to be -// rendered. -// |pdf_buffer_size| is the size of |pdf_buffer| in bytes. -// |page_number| is the page number that the function will get the dimensions -// of. -// |width| is the output for the width of the page in points. -// |height| is the output for the height of the page in points. -// Returns false if the document or the page number are not valid. -PDF_USED PP_EXPORT bool GetPDFPageSizeByIndex(const void* pdf_buffer, int pdf_buffer_size, int page_number, double* width, double* height) { @@ -237,19 +151,6 @@ return ret; } -// Renders PDF page into 4-byte per pixel BGRA color bitmap. -// |pdf_buffer| is the buffer that contains the entire PDF document to be -// rendered. -// |pdf_buffer_size| is the size of |pdf_buffer| in bytes. -// |page_number| is the 0-based index of the page to be rendered. -// |bitmap_buffer| is the output buffer for bitmap. -// |bitmap_width| is the width of the output bitmap. -// |bitmap_height| is the height of the output bitmap. -// |dpi| is the resolutions. -// |autorotate| specifies whether the final image should be rotated to match -// the output bound. -// Returns false if the document or the page number are not valid. -PDF_USED PP_EXPORT bool RenderPDFPageToBitmap(const void* pdf_buffer, int pdf_buffer_size, int page_number, @@ -275,4 +176,4 @@ return ret; } -} // extern "C" +} // namespace chrome_pdf
diff --git a/pdf/pdf.def b/pdf/pdf.def deleted file mode 100644 index b36918b..0000000 --- a/pdf/pdf.def +++ /dev/null
@@ -1,7 +0,0 @@ -LIBRARY pdf - -EXPORTS - NP_GetEntryPoints @1 - NP_Initialize @2 - NP_Shutdown @3 -
diff --git a/pdf/pdf.gyp b/pdf/pdf.gyp index 02259215..d49a0f1c 100644 --- a/pdf/pdf.gyp +++ b/pdf/pdf.gyp
@@ -3,28 +3,18 @@ 'chromium_code': 1, 'pdf_engine%': 0, # 0 PDFium }, - 'target_defaults': { - 'cflags': [ - '-fPIC', - ], - }, 'targets': [ { 'target_name': 'pdf', - 'type': 'loadable_module', - 'msvs_guid': '647863C0-C7A3-469A-B1ED-AD7283C34BED', + 'type': 'static_library', 'dependencies': [ '../base/base.gyp:base', + '../components/components.gyp:ui_zoom', + '../content/content.gyp:content_common', '../net/net.gyp:net', - '../ppapi/ppapi.gyp:ppapi_cpp', + '../ppapi/ppapi.gyp:ppapi_internal_module', '../third_party/pdfium/pdfium.gyp:pdfium', ], - 'xcode_settings': { - 'INFOPLIST_FILE': 'Info.plist', - }, - 'mac_framework_dirs': [ - '$(SDKROOT)/System/Library/Frameworks/ApplicationServices.framework/Frameworks', - ], 'ldflags': [ '-L<(PRODUCT_DIR)',], 'sources': [ 'button.h', @@ -55,7 +45,6 @@ 'paint_manager.h', 'pdf.cc', 'pdf.h', - 'pdf.rc', 'progress_control.cc', 'progress_control.h', 'pdf_engine.h', @@ -65,8 +54,6 @@ 'resource_consts.h', 'thumbnail_control.cc', 'thumbnail_control.h', - '../components/ui/zoom/page_zoom_constants.cc', - '../content/common/page_zoom.cc', ], 'conditions': [ ['pdf_engine==0', { @@ -86,117 +73,11 @@ 'pdfium/pdfium_range.h', ], }], - ['OS!="win"', { - 'sources!': [ - 'pdf.rc', - ], - }], - ['OS=="mac"', { - 'mac_bundle': 1, - 'product_name': 'PDF', - 'product_extension': 'plugin', - # Strip the shipping binary of symbols so "Foxit" doesn't appear in - # the binary. Symbols are stored in a separate .dSYM. - 'variables': { - 'mac_real_dsym': 1, - }, - 'sources+': [ - 'Info.plist' - ], - }], ['OS=="win"', { - 'defines': [ - 'COMPILE_CONTENT_STATICALLY', - ], # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. 'msvs_disabled_warnings': [ 4267, ], }], - ['OS=="linux"', { - 'configurations': { - 'Release_Base': { - #'cflags': [ '-fno-weak',], # get rid of symbols that strip doesn't remove. - # Don't do this for now since official builder will take care of it. That - # way symbols can still be uploaded to the crash server. - #'ldflags': [ '-s',], # strip local symbols from binary. - }, - }, - }], ], }, ], - 'conditions': [ - # CrOS has a separate step to do this. - ['OS=="linux" and chromeos==0', - { 'targets': [ - { - 'target_name': 'pdf_linux_symbols', - 'type': 'none', - 'conditions': [ - ['linux_dump_symbols==1', { - 'actions': [ - { - 'action_name': 'dump_symbols', - 'inputs': [ - '<(DEPTH)/build/linux/dump_app_syms', - '<(PRODUCT_DIR)/dump_syms', - '<(PRODUCT_DIR)/libpdf.so', - ], - 'outputs': [ - '<(PRODUCT_DIR)/libpdf.so.breakpad.<(target_arch)', - ], - 'action': ['<(DEPTH)/build/linux/dump_app_syms', - '<(PRODUCT_DIR)/dump_syms', - '<(linux_strip_binary)', - '<(PRODUCT_DIR)/libpdf.so', - '<@(_outputs)'], - 'message': 'Dumping breakpad symbols to <(_outputs)', - 'process_outputs_as_sources': 1, - }, - ], - 'dependencies': [ - 'pdf', - '../breakpad/breakpad.gyp:dump_syms', - ], - }], - ], - }, - ], - },], # OS=="linux" and chromeos==0 - ['OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1', { - 'variables': { - 'dest_dir': '<(PRODUCT_DIR)/syzygy', - }, - 'targets': [ - { - 'target_name': 'pdf_syzyasan', - 'type': 'none', - 'sources' : [], - 'dependencies': [ - 'pdf', - ], - # Instrument PDFium with SyzyAsan. - 'actions': [ - { - 'action_name': 'Instrument PDFium with SyzyAsan', - 'inputs': [ - '<(PRODUCT_DIR)/pdf.dll', - ], - 'outputs': [ - '<(dest_dir)/pdf.dll', - '<(dest_dir)/pdf.dll.pdb', - ], - 'action': [ - 'python', - '<(DEPTH)/chrome/tools/build/win/syzygy/instrument.py', - '--mode', 'asan', - '--input_executable', '<(PRODUCT_DIR)/pdf.dll', - '--input_symbol', '<(PRODUCT_DIR)/pdf.dll.pdb', - '--destination_dir', '<(dest_dir)', - ], - }, - ], - }, - ], - }], # OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1 - ], }
diff --git a/pdf/pdf.h b/pdf/pdf.h index d797bbb..37e72e51 100644 --- a/pdf/pdf.h +++ b/pdf/pdf.h
@@ -5,6 +5,7 @@ #ifndef PDF_PDF_H_ #define PDF_PDF_H_ +#include "ppapi/c/ppb.h" #include "ppapi/cpp/module.h" namespace chrome_pdf { @@ -19,6 +20,94 @@ virtual pp::Instance* CreateInstance(PP_Instance instance); }; +int PPP_InitializeModule(PP_Module module_id, + PPB_GetInterface get_browser_interface); +void PPP_ShutdownModule(); +const void* PPP_GetInterface(const char* interface_name); + +#if defined(OS_WIN) +// |pdf_buffer| is the buffer that contains the entire PDF document to be +// rendered. +// |buffer_size| is the size of |pdf_buffer| in bytes. +// |page_number| is the 0-based index of the page to be rendered. +// |dc| is the device context to render into. +// |dpi| and |dpi_y| is the resolution. If the value is -1, the dpi from the DC +// will be used. +// |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height| +// specify a bounds rectangle within the DC in which to render the PDF +// page. +// |fit_to_bounds| specifies whether the output should be shrunk to fit the +// supplied bounds if the page size is larger than the bounds in any +// dimension. If this is false, parts of the PDF page that lie outside +// the bounds will be clipped. +// |stretch_to_bounds| specifies whether the output should be stretched to fit +// the supplied bounds if the page size is smaller than the bounds in any +// dimension. +// If both |fit_to_bounds| and |stretch_to_bounds| are true, then +// |fit_to_bounds| is honored first. +// |keep_aspect_ratio| If any scaling is to be done is true, this flag +// specifies whether the original aspect ratio of the page should be +// preserved while scaling. +// |center_in_bounds| specifies whether the final image (after any scaling is +// done) should be centered within the given bounds. +// |autorotate| specifies whether the final image should be rotated to match +// the output bound. +// Returns false if the document or the page number are not valid. +bool RenderPDFPageToDC(const void* pdf_buffer, + int buffer_size, + int page_number, + HDC dc, + int dpi, + int bounds_origin_x, + int bounds_origin_y, + int bounds_width, + int bounds_height, + bool fit_to_bounds, + bool stretch_to_bounds, + bool keep_aspect_ratio, + bool center_in_bounds, + bool autorotate); +#endif +// |page_count| and |max_page_width| are optional and can be NULL. +// Returns false if the document is not valid. +bool GetPDFDocInfo(const void* pdf_buffer, + int buffer_size, int* page_count, + double* max_page_width); + +// Gets the dimensions of a specific page in a document. +// |pdf_buffer| is the buffer that contains the entire PDF document to be +// rendered. +// |pdf_buffer_size| is the size of |pdf_buffer| in bytes. +// |page_number| is the page number that the function will get the dimensions +// of. +// |width| is the output for the width of the page in points. +// |height| is the output for the height of the page in points. +// Returns false if the document or the page number are not valid. +bool GetPDFPageSizeByIndex(const void* pdf_buffer, + int pdf_buffer_size, int page_number, + double* width, double* height); + +// Renders PDF page into 4-byte per pixel BGRA color bitmap. +// |pdf_buffer| is the buffer that contains the entire PDF document to be +// rendered. +// |pdf_buffer_size| is the size of |pdf_buffer| in bytes. +// |page_number| is the 0-based index of the page to be rendered. +// |bitmap_buffer| is the output buffer for bitmap. +// |bitmap_width| is the width of the output bitmap. +// |bitmap_height| is the height of the output bitmap. +// |dpi| is the resolutions. +// |autorotate| specifies whether the final image should be rotated to match +// the output bound. +// Returns false if the document or the page number are not valid. +bool RenderPDFPageToBitmap(const void* pdf_buffer, + int pdf_buffer_size, + int page_number, + void* bitmap_buffer, + int bitmap_width, + int bitmap_height, + int dpi, + bool autorotate); + } // namespace chrome_pdf #endif // PDF_PDF_H_
diff --git a/pdf/pdf.rc b/pdf/pdf.rc deleted file mode 100644 index 50cb295..0000000 --- a/pdf/pdf.rc +++ /dev/null
@@ -1,104 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "FileDescription", "Chrome PDF Viewer" - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "InternalName", "pdf" - VALUE "LegalCopyright", "Copyright (C) 2010" - VALUE "MIMEType", "application/pdf" - VALUE "FileExtents", "pdf" - VALUE "FileOpenName", "Acrobat Portable Document Format" - VALUE "OriginalFilename", "pdf.dll" - VALUE "ProductName", "Chrome PDF Viewer" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED -
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 81fa059..2990f40 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -9,6 +9,7 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h"
diff --git a/ppapi/examples/video_decode/OWNERS b/ppapi/examples/video_decode/OWNERS index ec1eaca9..7de84a4 100644 --- a/ppapi/examples/video_decode/OWNERS +++ b/ppapi/examples/video_decode/OWNERS
@@ -1 +1 @@ -vrk@chromium.org +bbudge@chromium.org
diff --git a/remoting/app_remoting_webapp.gyp b/remoting/app_remoting_webapp.gyp index 1ceba7b..d9d8cda85 100644 --- a/remoting/app_remoting_webapp.gyp +++ b/remoting/app_remoting_webapp.gyp
@@ -69,10 +69,12 @@ 'targets': [ { + # Sample AppRemoting app. 'target_name': 'ar_sample_app', 'app_id': 'ljacajndfccfgnfohlgkdphmbnpkjflk', 'app_name': 'App Remoting Client', 'app_description': 'App Remoting client', + 'app_capabilities': ['GOOGLE_DRIVE'], }, ], # end of targets }
diff --git a/remoting/app_remoting_webapp_build.gypi b/remoting/app_remoting_webapp_build.gypi index 1c3e68c..d5da9eb 100644 --- a/remoting/app_remoting_webapp_build.gypi +++ b/remoting/app_remoting_webapp_build.gypi
@@ -122,6 +122,8 @@ '<(remoting_app_name)', '--app_description', '<(remoting_app_description)', + '--app_capabilities', + '>@(_app_capabilities)', '--service_environment', '<@(ar_service_environment)', ],
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 1027fc9f..0f40d356 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp
@@ -59,6 +59,7 @@ 'remoting_client.gypi', 'remoting_host.gypi', 'remoting_host_srcs.gypi', + 'remoting_key_tester.gypi', 'remoting_locales.gypi', 'remoting_srcs.gypi', 'remoting_test.gypi',
diff --git a/remoting/remoting_key_tester.gypi b/remoting/remoting_key_tester.gypi new file mode 100644 index 0000000..d1aab86 --- /dev/null +++ b/remoting/remoting_key_tester.gypi
@@ -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. + +{ + 'includes': [ + '../build/common_untrusted.gypi', + ], + + 'variables': { + 'remoting_key_tester_js_files': [ + 'tools/javascript_key_tester/background.js', + 'tools/javascript_key_tester/chord_tracker.js', + 'tools/javascript_key_tester/keyboard_map.js', + 'tools/javascript_key_tester/main.js', + ], + }, + + 'conditions': [ + ['disable_nacl==0 and disable_nacl_untrusted==0', { + 'targets': [ + { + 'target_name': 'remoting_key_tester', + 'type': 'none', + 'dependencies': [ + 'remoting_key_tester_pexe', + 'remoting_key_tester_jscompile', + ], + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/remoting/key_tester', + 'files': [ + '<@(remoting_key_tester_js_files)', + 'tools/javascript_key_tester/main.css', + 'tools/javascript_key_tester/main.html', + 'tools/javascript_key_tester/manifest.json', + 'tools/javascript_key_tester/pnacl/remoting_key_tester.nmf', + '<(PRODUCT_DIR)/remoting_key_tester_newlib.pexe', + ], + } + ], + }, # end of target 'remoting_key_tester' + + { + 'target_name': 'remoting_key_tester_jscompile', + 'type': 'none', + 'conditions': [ + # TODO(lukasza): Enable when remoting_key_tester_jscompile is clean. + # ['run_jscompile != 0', { + ['0 != 0', { + 'variables': { + 'success_stamp': '<(PRODUCT_DIR)/<(_target_name).stamp', + }, + 'actions': [ + { + 'action_name': 'jscompile remoting_key_tester', + 'inputs': [ + '<@(remoting_key_tester_js_files)', + ], + 'outputs': [ + '<(success_stamp)', + ], + 'action': [ + 'python', '../third_party/closure_compiler/checker.py', + '--strict', + '--no-single-file', + '--success-stamp', '<(success_stamp)', + '<@(remoting_key_tester_js_files)', + ], + }, + ], # actions + }], + ], + }, # end of target 'remoting_key_tester_jscompile' + + { + 'target_name': 'remoting_key_tester_pexe', + 'type': 'none', + 'sources': [ + 'tools/javascript_key_tester/pnacl/remoting_key_tester.cc', + ], + 'variables': { + 'nexe_target': 'remoting_key_tester', + 'build_glibc': 0, + 'build_newlib': 0, + 'build_pnacl_newlib': 1, + 'extra_deps_pnacl_newlib': [ + '>(tc_lib_dir_pnacl_newlib)/libppapi.a', + '>(tc_lib_dir_pnacl_newlib)/libppapi_cpp.a', + ], + }, + 'link_flags': [ + '-lppapi_stub', + '-lppapi_cpp', + ], + }, # end of target 'remoting_key_tester_pexe' + ], + }] + ], +}
diff --git a/remoting/remoting_nacl.gyp b/remoting/remoting_nacl.gyp index c541296..0b66b6b 100644 --- a/remoting/remoting_nacl.gyp +++ b/remoting/remoting_nacl.gyp
@@ -4,7 +4,7 @@ { 'includes': [ - '../native_client/build/untrusted.gypi', + '../build/common_untrusted.gypi', 'remoting_srcs.gypi', ],
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi index da059785..6f1bf585 100644 --- a/remoting/remoting_webapp_files.gypi +++ b/remoting/remoting_webapp_files.gypi
@@ -57,6 +57,7 @@ ], # Remoting core JavaScript files. 'remoting_webapp_js_core_files': [ + 'webapp/base/js/app_capabilities.js', 'webapp/base/js/application.js', 'webapp/base/js/base.js', 'webapp/base/js/ipc.js', @@ -237,6 +238,7 @@ 'webapp/crd/js/background.js', 'webapp/crd/js/client_session.js', 'webapp/crd/js/error.js', + 'webapp/crd/js/hangout_consent_dialog.js', 'webapp/crd/js/host_installer.js', 'webapp/crd/js/host_session.js', 'webapp/crd/js/it2me_helpee_channel.js', @@ -246,6 +248,7 @@ 'webapp/crd/js/l10n.js', 'webapp/crd/js/oauth2.js', 'webapp/crd/js/oauth2_api.js', + 'webapp/crd/js/oauth2_api_impl.js', 'webapp/crd/js/plugin_settings.js', 'webapp/crd/js/typecheck.js', 'webapp/crd/js/xhr.js', @@ -265,6 +268,8 @@ '<@(remoting_webapp_background_js_files)', # JS files for message_window.html 'webapp/base/js/message_window.js', + # JS files for dialog_hangout_consent.html + 'webapp/crd/js/hangout_consent_dialog_main.js', # JS files for wcs_sandbox.html. # Use r_w_js_wcs_sandbox_files instead of r_w_wcs_sandbox_html_js_files # so that we don't double include error.js and plugin_settings.js. @@ -301,13 +306,15 @@ 'resources/reload.webp', 'resources/tick.webp', 'webapp/base/html/connection_stats.css', - 'webapp/base/html/message_window.html', 'webapp/base/html/main.css', + 'webapp/base/html/message_window.html', 'webapp/base/html/message_window.css', 'webapp/base/resources/open_sans.css', 'webapp/base/resources/open_sans.woff', 'webapp/base/resources/spinner.gif', 'webapp/crd/html/butter_bar.css', + 'webapp/crd/html/dialog_hangout_consent.html', + 'webapp/crd/html/dialog_hangout_consent.css', 'webapp/crd/html/toolbar.css', 'webapp/crd/html/menu_button.css', 'webapp/crd/html/window_frame.css',
diff --git a/remoting/tools/javascript_key_tester/DEPS b/remoting/tools/javascript_key_tester/DEPS new file mode 100644 index 0000000..d5f5a0bf --- /dev/null +++ b/remoting/tools/javascript_key_tester/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+ppapi" +]
diff --git a/remoting/tools/javascript_key_tester/README b/remoting/tools/javascript_key_tester/README new file mode 100644 index 0000000..0b0e492 --- /dev/null +++ b/remoting/tools/javascript_key_tester/README
@@ -0,0 +1,9 @@ +The key tester is a Chrome app that dumps: +- PNaCl KeyboardInputEvent events +- JavaScript keydown/keyup events + +To use the key tester: +1. Build: ninja -C out/Debug remoting_key_tester +2. In Chrome navigate to: chrome://extensions +3. Use "Load unpacked extension" to load the key tester +
diff --git a/remoting/tools/javascript_key_tester/chord_tracker.js b/remoting/tools/javascript_key_tester/chord_tracker.js index ee2a327..a7cded1 100644 --- a/remoting/tools/javascript_key_tester/chord_tracker.js +++ b/remoting/tools/javascript_key_tester/chord_tracker.js
@@ -14,26 +14,42 @@ }; /** - * @param {Event} event The keyup or keydown event. + * @param {number} keyCode + * @param {string} title + * @return {void} */ -ChordTracker.prototype.addKeyEvent = function(event) { - this.begin_(); - var span = document.createElement('span'); - span.title = this.makeTitle_(event); - if (event.type == 'keydown') { - span.classList.add('key-down'); - this.pressedKeys_[event.keyCode] = span; - } else { - span.classList.add('key-up'); - delete this.pressedKeys_[event.keyCode]; - } - span.innerText = this.keyName_(event.keyCode); - this.currentDiv_.appendChild(span); +ChordTracker.prototype.addKeyUpEvent = function(keyCode, title) { + var text = this.keyName_(keyCode); + var span = this.addSpanElement_('key-up', text, title); + delete this.pressedKeys_[keyCode]; if (!this.keysPressed_()) { this.end_(); } }; +/** + * @param {number} keyCode + * @param {string} title + * @return {void} + */ +ChordTracker.prototype.addKeyDownEvent = function(keyCode, title) { + var text = this.keyName_(keyCode); + var span = this.addSpanElement_('key-down', text, title); + this.pressedKeys_[keyCode] = span; +}; + +/** + * @param {string} characterText + * @param {string} title + * @return {void} + */ +ChordTracker.prototype.addCharEvent = function(characterText, title) { + this.addSpanElement_('char-event', characterText, title); +}; + +/** + * @return {void} + */ ChordTracker.prototype.releaseAllKeys = function() { this.end_(); for (var i in this.pressedKeys_) { @@ -44,6 +60,22 @@ /** * @private + * @param {string} className + * @param {string} text + * @param {string} title + */ +ChordTracker.prototype.addSpanElement_ = function(className, text, title) { + this.begin_(); + var span = document.createElement('span'); + span.classList.add(className); + span.innerText = text; + span.title = title; + this.currentDiv_.appendChild(span); + return span; +} + +/** + * @private */ ChordTracker.prototype.begin_ = function() { if (this.currentDiv_) { @@ -93,18 +125,3 @@ return result; }; -/** - * @param {Event} event The keyup or keydown event. - * @private - */ -ChordTracker.prototype.makeTitle_ = function(event) { - return 'type: ' + event.type + '\n' + - 'alt: ' + event.altKey + '\n' + - 'shift: ' + event.shiftKey + '\n' + - 'control: ' + event.controlKey + '\n' + - 'meta: ' + event.metaKey + '\n' + - 'charCode: ' + event.charCode + '\n' + - 'keyCode: ' + event.keyCode + '\n' + - 'keyIdentifier: ' + event.keyIdentifier + '\n' + - 'repeat: ' + event.repeat + '\n'; -};
diff --git a/remoting/tools/javascript_key_tester/keyboard_map.js b/remoting/tools/javascript_key_tester/keyboard_map.js index 869bf54..8fd268a 100644 --- a/remoting/tools/javascript_key_tester/keyboard_map.js +++ b/remoting/tools/javascript_key_tester/keyboard_map.js
@@ -3,6 +3,7 @@ * found in the LICENSE file. */ +/** @type {Array.<string>} */ var keyboardMap = [ '', '',
diff --git a/remoting/tools/javascript_key_tester/main.css b/remoting/tools/javascript_key_tester/main.css index 725f2ca0..8010f61 100644 --- a/remoting/tools/javascript_key_tester/main.css +++ b/remoting/tools/javascript_key_tester/main.css
@@ -12,6 +12,30 @@ height: 100%; } +#pnacl-plugin { + background-color: gray; + border: 1px solid +} + +#pnacl-plugin:focus { + background-color: yellow; +} + +.summary-log-container { + width: 50%; + height: 50vh; + overflow-y: auto; + float: left; +} + +.text-log-container { + width: 100%; + max-height: 25vh; + overflow-y: auto; + float: left; +} + +.char-event, .key-down, .key-up { border-radius: 4px; @@ -20,6 +44,14 @@ margin-right: 2px; } +.char-event { + background-color: yellow; +} + +.char-event::before { + content: "char:"; +} + .key-up { background-color: #DFD; }
diff --git a/remoting/tools/javascript_key_tester/main.html b/remoting/tools/javascript_key_tester/main.html index 141b03b..791c024 100644 --- a/remoting/tools/javascript_key_tester/main.html +++ b/remoting/tools/javascript_key_tester/main.html
@@ -15,8 +15,30 @@ </head> <body> <h2>Chrome AppsV2 Key Event Tester</h2> - <button id="clear-log">Clear log</button> - <div id="key-log"> + <div id="pnacl-listener"> + PNaCl focus box: + <embed id="pnacl-plugin" width=100 height=12 + src="remoting_key_tester.nmf" type="application/x-pnacl" /> + (click inside to get focus, yellow background means it has focus). + </div> + <button id="clear-log">Clear logs</button> + <hr/> + <div class="logs"> + <div class="summary-log-container"> + Summary of JavaScript logs: + <div id="javascript-log"> + </div> + </div> + <div class="summary-log-container"> + Summary of PNaCl logs: + <div id="pnacl-log"> + </div> + </div> + <div class="text-log-container"> + Text log of JSON-ified events: + <div id="text-log"> + </div> + </div> </div> </body> </html>
diff --git a/remoting/tools/javascript_key_tester/main.js b/remoting/tools/javascript_key_tester/main.js index e777b48..e37e426 100644 --- a/remoting/tools/javascript_key_tester/main.js +++ b/remoting/tools/javascript_key_tester/main.js
@@ -3,17 +3,142 @@ * found in the LICENSE file. */ +/** + * @param {string} eventName + * @param {number=} opt_space + * @return {string} + */ +function jsonifyJavascriptKeyEvent(event, eventName, opt_space) { + return "JavaScript '" + eventName + "' event = " + JSON.stringify( + event, + ['type', 'alt', 'shift', 'control', 'meta', 'charCode', 'keyCode', + 'keyIdentifier', 'repeat'], + opt_space); +}; + +/** + * @param {ChordTracker} jsChordTracker + * @param {Event} event + * @return {void} + */ +function handleJavascriptKeyDownEvent(jsChordTracker, event) { + appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keydown', undefined)); + jsChordTracker.addKeyDownEvent( + event.keyCode, jsonifyJavascriptKeyEvent(event, 'keydown', 2)); +} + +/** + * @param {ChordTracker} jsChordTracker + * @param {Event} event + * @return {void} + */ +function handleJavascriptKeyUpEvent(jsChordTracker, event) { + appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keyup', undefined)); + jsChordTracker.addKeyUpEvent( + event.keyCode, jsonifyJavascriptKeyEvent(event, 'keyup', 2)); +} + +/** @constructor */ +var PNaClEvent = function() { + /** @type {string} */ + this.type = ""; + /** @type {number} */ + this.modifiers = 0; + /** @type {number} */ + this.keyCode = 0; + /** @type {string|undefined} */ + this.characterText = undefined; + /** @type {string} */ + this.code = ""; +}; + +/** + * @param {PNaClEvent} event + * @param {number|undefined} space + * @return {string} + */ +function jsonifyPnaclKeyboardInputEvent(event, space) { + return "PNaCl KeyboardInputEvent = " + JSON.stringify( + event, + ['type', 'modifiers', 'keyCode', 'characterText', 'code'], + space); +}; + +/** + * @param {ChordTracker} pnaclChordTracker + * @param {Event} event + * @return {void} + */ +function handlePNaclMessage(pnaclChordTracker, event) { + var pnaclEvent = /** @type {PNaClEvent} */ (event.data); + + appendToTextLog(jsonifyPnaclKeyboardInputEvent(pnaclEvent, undefined)); + var title = jsonifyPnaclKeyboardInputEvent(pnaclEvent, 2); + if (pnaclEvent.type == "KEYDOWN") { + pnaclChordTracker.addKeyDownEvent(pnaclEvent.keyCode, title); + } + if (pnaclEvent.type == "KEYUP") { + pnaclChordTracker.addKeyUpEvent(pnaclEvent.keyCode, title); + } + if (pnaclEvent.type == "CHAR") { + pnaclChordTracker.addCharEvent(pnaclEvent.characterText, title); + } +} + +/** + * @param {string} str + * @return {void} + */ +function appendToTextLog(str) { + var textLog = document.getElementById('text-log'); + var div = document.createElement('div'); + div.innerText = str; + textLog.appendChild(div); +} + function onLoad() { - var parentDiv = document.getElementById('key-log'); - var chordTracker = new ChordTracker(parentDiv); + // Start listening to Javascript keyup/keydown events. + var jsLog = document.getElementById('javascript-log'); + var jsChordTracker = new ChordTracker(jsLog); document.body.addEventListener( - 'keydown', chordTracker.addKeyEvent.bind(chordTracker), false); + 'keydown', + function (event) { + handleJavascriptKeyDownEvent(jsChordTracker, event); + }, + false); document.body.addEventListener( - 'keyup', chordTracker.addKeyEvent.bind(chordTracker), false); + 'keyup', + function (event) { + handleJavascriptKeyUpEvent(jsChordTracker, event); + }, + false); + + // Start listening to PNaCl keyboard input events. + var pnaclLog = document.getElementById('pnacl-log'); + var pnaclChordTracker = new ChordTracker(pnaclLog); + document.getElementById('pnacl-listener').addEventListener( + 'message', + function (message) { + handlePNaclMessage(pnaclChordTracker, message); + }, + true); + + // Start listening to generic, source-agnostic events. window.addEventListener( - 'blur', chordTracker.releaseAllKeys.bind(chordTracker), false); + 'blur', + function () { + jsChordTracker.releaseAllKeys(); + pnaclChordTracker.releaseAllKeys(); + }, + false); document.getElementById('clear-log').addEventListener( - 'click', function() { parentDiv.innerText = ''; }, false); + 'click', + function() { + jsLog.innerText = ''; + pnaclLog.innerText = ''; + document.getElementById('text-log').innerText = ''; + }, + false); } window.addEventListener('load', onLoad, false);
diff --git a/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.cc b/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.cc new file mode 100644 index 0000000..408725c5 --- /dev/null +++ b/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.cc
@@ -0,0 +1,114 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <sstream> + +#include "ppapi/cpp/input_event.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/var_dictionary.h" + +namespace remoting { + +class KeyTesterInstance : public pp::Instance { + public: + explicit KeyTesterInstance(PP_Instance instance) : pp::Instance(instance) { + RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD); + } + + virtual ~KeyTesterInstance() {} + + virtual bool HandleInputEvent(const pp::InputEvent& event) { + switch (event.GetType()) { + case PP_INPUTEVENT_TYPE_KEYDOWN: + case PP_INPUTEVENT_TYPE_KEYUP: + case PP_INPUTEVENT_TYPE_CHAR: { + HandleKeyboardEvent(pp::KeyboardInputEvent(event)); + break; + } + default: + break; + } + return true; + } + + private: + void HandleKeyboardEvent(const pp::KeyboardInputEvent& event) { + pp::VarDictionary out; + out.Set("type", EventTypeToString(event.GetType())); + out.Set("modifiers", (double)event.GetModifiers()); + out.Set("keyCode", (double)event.GetKeyCode()); + out.Set("characterText", event.GetCharacterText()); + out.Set("code", event.GetCode()); + PostMessage(out); + } + + std::string EventTypeToString(PP_InputEvent_Type t) { + switch (t) { + case PP_INPUTEVENT_TYPE_UNDEFINED: + return "UNDEFINED"; + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + return "MOUSEDOWN"; + case PP_INPUTEVENT_TYPE_MOUSEUP: + return "MOUSEUP"; + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + return "MOUSEMOVE"; + case PP_INPUTEVENT_TYPE_MOUSEENTER: + return "MOUSEENTER"; + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + return "MOUSELEAVE"; + case PP_INPUTEVENT_TYPE_WHEEL: + return "WHEEL"; + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + return "RAWKEYDOWN"; + case PP_INPUTEVENT_TYPE_KEYDOWN: + return "KEYDOWN"; + case PP_INPUTEVENT_TYPE_KEYUP: + return "KEYUP"; + case PP_INPUTEVENT_TYPE_CHAR: + return "CHAR"; + case PP_INPUTEVENT_TYPE_CONTEXTMENU: + return "CONTEXTMENU"; + case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START: + return "IME_COMPOSITION_START"; + case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE: + return "IME_COMPOSITION_UPDATE"; + case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END: + return "IME_COMPOSITION_END"; + case PP_INPUTEVENT_TYPE_IME_TEXT: + return "IME_TEXT"; + case PP_INPUTEVENT_TYPE_TOUCHSTART: + return "TOUCHSTART"; + case PP_INPUTEVENT_TYPE_TOUCHMOVE: + return "TOUCHMOVE"; + case PP_INPUTEVENT_TYPE_TOUCHEND: + return "TOUCHEND"; + case PP_INPUTEVENT_TYPE_TOUCHCANCEL: + return "TOUCHCANCEL"; + default: + return "[UNRECOGNIZED]"; + } + } +}; + +class KeyTesterModule : public pp::Module { + public: + KeyTesterModule() : pp::Module() {} + virtual ~KeyTesterModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new KeyTesterInstance(instance); + } +}; + +} // namespace remoting + +namespace pp { + +Module* CreateModule() { + return new remoting::KeyTesterModule(); +} + +} // namespace pp
diff --git a/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.nmf b/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.nmf new file mode 100644 index 0000000..5f49117 --- /dev/null +++ b/remoting/tools/javascript_key_tester/pnacl/remoting_key_tester.nmf
@@ -0,0 +1,9 @@ +{ + "program": { + "portable": { + "pnacl-translate": { + "url": "remoting_key_tester_newlib.pexe" + } + } + } +}
diff --git a/remoting/webapp/app_remoting/js/app_remoting.js b/remoting/webapp/app_remoting/js/app_remoting.js index f07f847..8e8bb62 100644 --- a/remoting/webapp/app_remoting/js/app_remoting.js +++ b/remoting/webapp/app_remoting/js/app_remoting.js
@@ -214,19 +214,6 @@ }; /** - * @return {Array.<string>} A list of |ClientSession.Capability|s required - * by this application. - */ -remoting.AppRemoting.prototype.getRequiredCapabilities = function() { - return [ - remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION, - remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS, - remoting.ClientSession.Capability.VIDEO_RECORDER, - remoting.ClientSession.Capability.GOOGLE_DRIVE - ]; -}; - -/** * Called when a new session has been connected. * * @param {remoting.ClientSession} clientSession
diff --git a/remoting/webapp/app_remoting/js/ar_main.js b/remoting/webapp/app_remoting/js/ar_main.js index b15cdff..269b5ff9 100644 --- a/remoting/webapp/app_remoting/js/ar_main.js +++ b/remoting/webapp/app_remoting/js/ar_main.js
@@ -11,7 +11,7 @@ * Entry point ('load' handler) for App Remoting webapp. */ remoting.startAppRemoting = function() { - remoting.app = new remoting.Application(); + remoting.app = new remoting.Application(remoting.app_capabilities()); var app_remoting = new remoting.AppRemoting(remoting.app); remoting.app.start(); };
diff --git a/remoting/webapp/app_remoting/manifest_common.json.jinja2 b/remoting/webapp/app_remoting/manifest_common.json.jinja2 index 6001a10a..95d6908 100644 --- a/remoting/webapp/app_remoting/manifest_common.json.jinja2 +++ b/remoting/webapp/app_remoting/manifest_common.json.jinja2
@@ -49,7 +49,7 @@ "oauth2": { "client_id": "{{ REMOTING_IDENTITY_API_CLIENT_ID }}", "scopes": [ - "https://www.googleapis.com/auth/appremoting.runapplication https://www.googleapis.com/auth/googletalk https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile https://docs.google.com/feeds/ https://www.googleapis.com/auth/drive" + "https://www.googleapis.com/auth/appremoting.runapplication https://www.googleapis.com/auth/googletalk https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile {{ OAUTH_GDRIVE_SCOPE }}" ] }, "sandbox": {
diff --git a/remoting/webapp/base/js/app_capabilities.js b/remoting/webapp/base/js/app_capabilities.js new file mode 100644 index 0000000..655e913 --- /dev/null +++ b/remoting/webapp/base/js/app_capabilities.js
@@ -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. + +'use strict'; + +/** @suppress {duplicate} */ +var remoting = remoting || {}; + +/** + * Note that this needs to be a function because it gets expanded at + * compile-time into remoting.ClientSession.Capability enums and these + * are not guaranteed to be present yet when this file is loaded. + * @return {Array.<remoting.ClientSession.Capability>} + */ +remoting.app_capabilities = function() { + return ['APPLICATION_CAPABILITIES']; +}
diff --git a/remoting/webapp/base/js/application.js b/remoting/webapp/base/js/application.js index 7390d8c..d0810be7c 100644 --- a/remoting/webapp/base/js/application.js +++ b/remoting/webapp/base/js/application.js
@@ -13,9 +13,10 @@ var remoting = remoting || {}; /** + * @param {Array.<string>} app_capabilities Array of application capabilities. * @constructor */ -remoting.Application = function() { +remoting.Application = function(app_capabilities) { /** * @type {remoting.Application.Delegate} * @private @@ -23,6 +24,12 @@ this.delegate_ = null; /** + * @type {Array.<string>} + * @private + */ + this.app_capabilities_ = app_capabilities; + + /** * @type {remoting.SessionConnector} * @private */ @@ -38,6 +45,30 @@ }; /** + * @return {Array.<string>} A list of |ClientSession.Capability|s required + * by this application. + */ +remoting.Application.prototype.getRequiredCapabilities_ = function() { + var capabilities = [ + remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION, + remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS, + remoting.ClientSession.Capability.VIDEO_RECORDER + ]; + // Append the app-specific capabilities. + capabilities.push.apply(capabilities, this.app_capabilities_); + return capabilities; +}; + +/** + * @param {remoting.ClientSession.Capability} capability + * @return {boolean} + */ +remoting.Application.prototype.hasCapability = function(capability) { + var capabilities = remoting.app.getRequiredCapabilities_(); + return capabilities.indexOf(capability) != -1; +}; + +/** * Initialize the application and register all event handlers. After this * is called, the app is running and waiting for user events. * @@ -153,7 +184,7 @@ this.onError.bind(this), this.onExtensionMessage.bind(this), this.onConnectionFailed.bind(this), - this.delegate_.getRequiredCapabilities(), + this.getRequiredCapabilities_(), this.delegate_.getDefaultRemapKeys()); } return this.session_connector_; @@ -180,12 +211,6 @@ remoting.Application.Delegate.prototype.getDefaultRemapKeys = function() {}; /** - * @return {Array.<string>} A list of |ClientSession.Capability|s required - * by this application. - */ -remoting.Application.Delegate.prototype.getRequiredCapabilities = function() {}; - -/** * Called when a new session has been connected. * * @param {remoting.ClientSession} clientSession
diff --git a/remoting/webapp/base/js/base.js b/remoting/webapp/base/js/base.js index 30f13a0aa..e9454553 100644 --- a/remoting/webapp/base/js/base.js +++ b/remoting/webapp/base/js/base.js
@@ -179,6 +179,20 @@ return url + '?' + queryParameters.join('&'); }; + +/** + * @return {Object.<string, string>} The URL parameters. + */ +base.getUrlParameters = function() { + var result = {}; + var parts = window.location.search.substring(1).split('&'); + for (var i = 0; i < parts.length; i++) { + var pair = parts[i].split('='); + result[pair[0]] = decodeURIComponent(pair[1]); + } + return result; +}; + /** * Convert special characters (e.g. &, < and >) to HTML entities. * @@ -582,3 +596,16 @@ return undefined; } }; + +/** + * Size the current window to fit its content vertically. + */ +base.resizeWindowToContent = function() { + var appWindow = chrome.app.window.current(); + var outerBounds = appWindow.outerBounds; + var borderY = outerBounds.height - appWindow.innerBounds.height; + appWindow.resizeTo(outerBounds.width, document.body.clientHeight + borderY); + // Sometimes, resizing the window causes its position to be reset to (0, 0), + // so restore it explicitly. + appWindow.moveTo(outerBounds.left, outerBounds.top); +};
diff --git a/remoting/webapp/base/js/ipc.js b/remoting/webapp/base/js/ipc.js index 07d175c..122ea5f 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.
diff --git a/remoting/webapp/base/js/message_window.js b/remoting/webapp/base/js/message_window.js index d80c2053..cc7b82e7 100644 --- a/remoting/webapp/base/js/message_window.js +++ b/remoting/webapp/base/js/message_window.js
@@ -45,20 +45,6 @@ }; /** - * Size the window to its content vertically. - * @private - */ -MessageWindowImpl.prototype.updateSize_ = function() { - var outerBounds = chrome.app.window.current().outerBounds; - var innerBounds = chrome.app.window.current().innerBounds; - var borderY = outerBounds.height - innerBounds.height; - window.resizeTo(outerBounds.width, document.body.clientHeight + borderY); - // Sometimes, resizing the window causes its position to be reset to (0, 0), - // so restore it explicitly. - window.moveTo(outerBounds.left, outerBounds.top); -}; - -/** * Initializes the button with the label and the click handler. * Hides the button if the label is null or undefined. * @@ -145,7 +131,7 @@ chrome.app.window.current().onClosed.addListener( this.sendReply_.bind(this, event.source, messageId, 0)); - this.updateSize_(); + base.resizeWindowToContent(); chrome.app.window.current().show(); break; @@ -159,7 +145,7 @@ var messageDiv = document.getElementById('message'); messageDiv.innerText = message; - this.updateSize_(); + base.resizeWindowToContent(); break; default:
diff --git a/remoting/webapp/build-webapp.py b/remoting/webapp/build-webapp.py index 833e1f3ea..9868b6c 100755 --- a/remoting/webapp/build-webapp.py +++ b/remoting/webapp/build-webapp.py
@@ -75,10 +75,9 @@ rendered = template.render(context) io.open(output_file, 'w', encoding='utf-8').write(rendered) - def buildWebApp(buildtype, version, destination, zip_path, manifest_template, webapp_type, app_id, app_name, - app_description, files, locales, jinja_paths, + app_description, app_capabilities, files, locales, jinja_paths, service_environment): """Does the main work of building the webapp directory and zipfile. @@ -95,6 +94,8 @@ test API server. app_name: A string with the name of the application. app_description: A string with the description of the application. + app_capabilities: A set of strings naming the capabilities that should be + enabled for this application. files: An array of strings listing the paths for resources to include in this webapp. locales: An array of strings listing locales, which are copied, along @@ -316,6 +317,12 @@ replaceString(destination, 'API_CLIENT_ID', apiClientId) replaceString(destination, 'API_CLIENT_SECRET', apiClientSecret) + # Write the application capabilities. + appCapabilities = ','.join( + ['remoting.ClientSession.Capability.' + x for x in app_capabilities]) + findAndReplace(os.path.join(destination, 'app_capabilities.js'), + "'APPLICATION_CAPABILITIES'", appCapabilities) + # Use a consistent extension id for dev builds. # AppRemoting builds always use the dev app id - the correct app id gets # written into the manifest later. @@ -342,7 +349,11 @@ 'GOOGLE_API_HOSTS': googleApiHosts, 'APP_NAME': app_name, 'APP_DESCRIPTION': app_description, + 'OAUTH_GDRIVE_SCOPE': '', } + if 'GOOGLE_DRIVE' in app_capabilities: + context['OAUTH_GDRIVE_SCOPE'] = ('https://docs.google.com/feeds/ ' + 'https://www.googleapis.com/auth/drive') processJinjaTemplate(manifest_template, jinja_paths, os.path.join(destination, 'manifest.json'), @@ -361,6 +372,7 @@ '<webapp_type> <other files...> ' '--app_name <name> ' '--app_description <description> ' + '--app_capabilities <capabilities...> ' '[--appid <appid>] ' '[--locales <locales...>] ' '[--jinja_paths <paths...>] ' @@ -374,6 +386,7 @@ app_id = None app_name = None app_description = None + app_capabilities = set([]) service_environment = '' for arg in sys.argv[7:]: @@ -382,6 +395,7 @@ '--appid', '--app_name', '--app_description', + '--app_capabilities', '--service_environment']: arg_type = arg elif arg_type == '--locales': @@ -397,6 +411,8 @@ elif arg_type == '--app_description': app_description = arg arg_type = '' + elif arg_type == '--app_capabilities': + app_capabilities.add(arg) elif arg_type == '--service_environment': service_environment = arg arg_type = '' @@ -405,8 +421,8 @@ return buildWebApp(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], app_id, app_name, - app_description, files, locales, jinja_paths, - service_environment) + app_description, app_capabilities, files, locales, + jinja_paths, service_environment) if __name__ == '__main__':
diff --git a/remoting/webapp/crd/html/dialog_hangout_consent.css b/remoting/webapp/crd/html/dialog_hangout_consent.css new file mode 100644 index 0000000..7bd4378f --- /dev/null +++ b/remoting/webapp/crd/html/dialog_hangout_consent.css
@@ -0,0 +1,103 @@ +/* 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. + */ + +html, div, span, body, ul, li { + border: 0; + margin: 0; + padding: 0; + font-family: "Arial", "Helvetica", sans-serif; + font-weight: normal; + /* Allows the user to move the window by dragging its content. */ + -webkit-app-region: drag; +} + +.header { + height: 46px; + background: #1c91c0; + padding: 15px; +} + +.header .title { + color: white; + float: left; + font-size: 24px; + line-height: 46px; + padding-left: 15px; +} + +.header .logo { + float: left; + height: 46px; + width: 46px; + background: url('chromoting48.webp'); +} + +.content { + text-align: center; + margin: auto; + width: 70%; +} + +.content .message { + padding: 30px; + font-size: 20px; +} + +.content ul { + list-style: none; + border-width: 0px 0px 1px 0px; + border-style: solid; + border-color: #f0f0f0; +} + +.content li { + border-width: 1px 0px 0px 0px; + border-style: solid; + border-color: #f0f0f0; + padding: 15px; + text-align: left; + font-size: 14px; +} + +.button { + padding: 0px 20px; + border: 1px solid #f0f0f0; + border-radius: 5px; + font-size: 14px; + font-weight: bold; + line-height: 36px; + color: #737373; + -webkit-app-region: no-drag; +} + +.footer { + padding-top: 30px; + padding-bottom: 30px; + /* Clear the float of its children. */ + overflow: auto; + width: 100% +} + +.button.default { + background: #427fed; + color: white; +} + +.button:hover { + border-color: #cecece; +} + +.button.default:active { + background: #2c56b1; +} + +.ok-button { + float: right; + margin-left: 10px; +} + +.cancel-button { + float: right; +}
diff --git a/remoting/webapp/crd/html/dialog_hangout_consent.html b/remoting/webapp/crd/html/dialog_hangout_consent.html new file mode 100644 index 0000000..3ad7ebd --- /dev/null +++ b/remoting/webapp/crd/html/dialog_hangout_consent.html
@@ -0,0 +1,36 @@ +<!doctype html> +<!-- +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. +--> + +<html> + <head> + <meta charset="utf-8"> + <link rel="stylesheet" href="dialog_hangout_consent.css"> + <script type="text/javascript" src="base.js"></script> + <script type="text/javascript" src="hangout_consent_dialog_main.js"></script> + <script type="text/javascript" src="ipc.js"></script> + <script type="text/javascript" src="l10n.js"></script> + <script type="text/javascript" src="typecheck.js"></script> + </head> + <body> + <div class="header"> + <div class="logo"></div> + <div class="title" i18n-content="MODE_IT2ME"></div> + </div> + <div class="content"> + <div class="message" i18n-content="HANGOUTS_CONFIRM_DIALOG_MESSAGE_1"></div> + <ul> + <li i18n-content="HANGOUTS_CONFIRM_DIALOG_MESSAGE_2"></li> + <li i18n-content="HANGOUTS_CONFIRM_DIALOG_MESSAGE_3"></li> + <li i18n-content="DESCRIPTION_AUTHORIZE" class='auth-message'></li> + </ul> + <div class="footer"> + <div class="button default ok-button" i18n-content="HANGOUTS_CONFIRM_DIALOG_ACCEPT"></div> + <div class="button cancel-button" i18n-content="HANGOUTS_CONFIRM_DIALOG_DECLINE"></div> + </div> + </div> + </body> +</html>
diff --git a/remoting/webapp/crd/js/client_session.js b/remoting/webapp/crd/js/client_session.js index 73bf54e..3edecfe 100644 --- a/remoting/webapp/crd/js/client_session.js +++ b/remoting/webapp/crd/js/client_session.js
@@ -32,13 +32,6 @@ remoting.ACCESS_TOKEN_RESEND_INTERVAL_MS = 15 * 60 * 1000; /** - * True if Cast capability is supported. - * - * @type {boolean} - */ -remoting.enableCast = false; - -/** * True to enable mouse lock. * This is currently disabled because the current client plugin does not * properly handle mouse lock and delegated large cursors at the same time. @@ -1677,7 +1670,8 @@ * @private */ remoting.ClientSession.prototype.createCastExtensionHandler_ = function() { - if (remoting.enableCast && this.mode_ == remoting.ClientSession.Mode.ME2ME) { + if (remoting.app.hasCapability(remoting.ClientSession.Capability.CAST) && + this.mode_ == remoting.ClientSession.Mode.ME2ME) { this.castExtensionHandler_ = new remoting.CastExtensionHandler(this); } };
diff --git a/remoting/webapp/crd/js/crd_main.js b/remoting/webapp/crd/js/crd_main.js index f772320..1fdc7a2 100644 --- a/remoting/webapp/crd/js/crd_main.js +++ b/remoting/webapp/crd/js/crd_main.js
@@ -56,7 +56,7 @@ var onLoad = function() { // Parse URL parameters. - var urlParams = getUrlParameters_(); + var urlParams = base.getUrlParameters(); if ('mode' in urlParams) { if (urlParams['mode'] === 'me2me') { var hostId = urlParams['hostId']; @@ -188,7 +188,7 @@ * hold in some corner cases. */ remoting.startDesktopRemotingForTesting = function() { - var urlParams = getUrlParameters_(); + var urlParams = base.getUrlParameters(); if (urlParams['source'] === 'test') { document.getElementById('browser-test-continue-init').addEventListener( 'click', remoting.startDesktopRemoting, false); @@ -200,7 +200,7 @@ remoting.startDesktopRemoting = function() { - remoting.app = new remoting.Application(); + remoting.app = new remoting.Application(remoting.app_capabilities()); var desktop_remoting = new remoting.DesktopRemoting(remoting.app); remoting.app.start(); };
diff --git a/remoting/webapp/crd/js/desktop_remoting.js b/remoting/webapp/crd/js/desktop_remoting.js index 9e2e1010..5d9abb8 100644 --- a/remoting/webapp/crd/js/desktop_remoting.js +++ b/remoting/webapp/crd/js/desktop_remoting.js
@@ -156,21 +156,6 @@ }; /** - * @return {Array.<string>} A list of |ClientSession.Capability|s required - * by this application. - */ -remoting.DesktopRemoting.prototype.getRequiredCapabilities = function() { - return [ - remoting.ClientSession.Capability.SEND_INITIAL_RESOLUTION, - remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS, - remoting.ClientSession.Capability.VIDEO_RECORDER, - // TODO(aiguha): Add this capability based on a gyp/command-line flag, - // rather than by default. - remoting.ClientSession.Capability.CAST - ]; -}; - -/** * Called when a new session has been connected. * * @param {remoting.ClientSession} clientSession
diff --git a/remoting/webapp/crd/js/hangout_consent_dialog.js b/remoting/webapp/crd/js/hangout_consent_dialog.js new file mode 100644 index 0000000..87f8807 --- /dev/null +++ b/remoting/webapp/crd/js/hangout_consent_dialog.js
@@ -0,0 +1,106 @@ +// 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. + +/** @suppress {duplicate} */ +var remoting = remoting || {}; + +(function() { + +'use strict'; + +var instance_ = null; + +/** + * Shows a dialog to ask for the user's permission to accept remote assistance + * from a Hangout participant. + * + * @constructor + * @private + */ +remoting.HangoutConsentDialog = function() { + /** + * @type {base.Deferred} + * @private + */ + this.onConsentResponseDeferred_ = null; + + /** @private */ + this.requestToken_ = base.generateXsrfToken(); + + base.Ipc.getInstance().register('remoting.HangoutConsentDialog.confirm', + this.onConfirmResponse_.bind(this)); +}; + +/** + * @param {boolean} confirm Whether the user authorized the it2me connection + * @param {string} responseToken + * @private + */ +remoting.HangoutConsentDialog.prototype.onConfirmResponse_ = function( + confirm, responseToken) { + if (responseToken !== this.requestToken_) { + return; + } + + if (confirm) { + this.onConsentResponseDeferred_.resolve(); + } else { + this.onConsentResponseDeferred_.reject( + new Error(remoting.Error.CANCELLED)); + } + this.onConsentResponseDeferred_ = null; +}; + +/** + * @param {boolean} authorized If true, the consent dialog will hide the + * authorization section. + * @param {Bounds=} opt_parentBounds If present, the consent dialog will be + * centered within |opt_parentBounds|. + * @return {Promise} A Promise that will resolve when permission is granted or + * reject if the user cancels. + */ +remoting.HangoutConsentDialog.prototype.show = function(authorized, + opt_parentBounds) { + if (!this.onConsentResponseDeferred_) { + var DIALOG_WIDTH = 750; + var DIALOG_HEIGHT = 480; + + var createOptions = { + frame: 'none', + resizable: false, + outerBounds: { width: DIALOG_WIDTH, height: DIALOG_HEIGHT } + }; + + var params = { + token: this.requestToken_, + authorized: Boolean(authorized) + }; + + var url = base.urlJoin('dialog_hangout_consent.html', params); + + if (opt_parentBounds) { + // Center the dialog on the parent bounds. + var rect = opt_parentBounds; + createOptions.outerBounds.top = + Math.round(rect.top + rect.height / 2 - DIALOG_HEIGHT / 2); + createOptions.outerBounds.left = + Math.round(rect.left + rect.width / 2 - DIALOG_WIDTH / 2); + } + + this.onConsentResponseDeferred_ = new base.Deferred(); + chrome.app.window.create(url, createOptions); + } + return this.onConsentResponseDeferred_.promise(); +}; + +/** @return {remoting.HangoutConsentDialog} */ +remoting.HangoutConsentDialog.getInstance = function() { + if (!instance_) { + instance_ = new remoting.HangoutConsentDialog(); + } + return instance_; +}; + +}()); +
diff --git a/remoting/webapp/crd/js/hangout_consent_dialog_main.js b/remoting/webapp/crd/js/hangout_consent_dialog_main.js new file mode 100644 index 0000000..8ced7a86 --- /dev/null +++ b/remoting/webapp/crd/js/hangout_consent_dialog_main.js
@@ -0,0 +1,63 @@ +// 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. + +/** +* @fileoverview +* The entry point for dialog_hangout_consent.html. +*/ + + +/** @suppress {duplicate} */ +var remoting = remoting || {}; + +(function() { + +'use strict'; + +/** + * @constructor + * @param {HTMLElement} rootElement + * @param {string} requestToken + * @param {boolean} authorized Whether the user is authorized or not. + */ +var ConsentDialog = function(rootElement, requestToken, authorized) { + /** @private */ + this.okButton_ = rootElement.querySelector('.ok-button'); + /** @private */ + this.cancelButton_ = rootElement.querySelector('.cancel-button'); + /** @private */ + this.authSection_ = rootElement.querySelector('.auth-message'); + /** @private */ + this.requestToken_ = requestToken; + + if (authorized) { + this.authSection_.hidden = true; + } + + this.okButton_.addEventListener('click', this.onButton_.bind(this, true)); + this.cancelButton_.addEventListener('click',this.onButton_.bind(this, false)); + base.resizeWindowToContent(); +}; + +/** + * @param {boolean} confirm + * @private + */ +ConsentDialog.prototype.onButton_ = function(confirm) { + base.Ipc.invoke('remoting.HangoutConsentDialog.confirm', confirm, + this.requestToken_); + chrome.app.window.current().close(); +}; + +function onDomContentLoaded() { + var params = base.getUrlParameters(); + var authorized = getBooleanAttr(params, 'authorized', false); + var token = getStringAttr(params, 'token'); + l10n.localize(); + var confirmDialog = new ConsentDialog(document.body, token, authorized); +} + +window.addEventListener('load', onDomContentLoaded); + +}());
diff --git a/remoting/webapp/crd/js/it2me_helpee_channel.js b/remoting/webapp/crd/js/it2me_helpee_channel.js index af28dd49..97a14c2 100644 --- a/remoting/webapp/crd/js/it2me_helpee_channel.js +++ b/remoting/webapp/crd/js/it2me_helpee_channel.js
@@ -250,6 +250,8 @@ remoting.It2MeHelpeeChannel.prototype.handleConnect_ = function(message) { var email = getStringAttr(message, 'email'); + var bounds = + /** @type {Bounds} */ (getObjectAttr(message, 'hangoutBounds', null)); if (!email) { throw new Error('Missing required parameter: email'); @@ -259,13 +261,20 @@ throw new Error('An existing connection is in progress.'); } - this.showConfirmDialog_().then( + var that = this; + this.showConfirmDialog_(bounds).then( this.initializeHost_.bind(this) ).then( this.fetchOAuthToken_.bind(this) ).then( - /** @type {function(*):void} */(this.connectToHost_.bind(this, email)), - /** @type {function(*):void} */(this.sendErrorResponse_.bind(this, message)) + /** @type {function(*):void} */(this.connectToHost_.bind(this, email)) + ).catch( + /** @param {*} reason */ + function(reason) { + var error = /** @type {Error} */ (reason); + that.sendErrorResponse_(message, error); + that.dispose(); + } ); }; @@ -274,21 +283,22 @@ * ensures that even if Hangouts is compromised, an attacker cannot start the * host without explicit user confirmation. * - * @return {Promise} A promise that resolves to a boolean value, indicating - * whether the user accepts the remote assistance or not. + * @param {Bounds} bounds Bounds of the hangout window + * @return {Promise} A promise that will resolve if the user accepts remote + * assistance or reject otherwise. * @private */ -remoting.It2MeHelpeeChannel.prototype.showConfirmDialog_ = function() { +remoting.It2MeHelpeeChannel.prototype.showConfirmDialog_ = function(bounds) { if (base.isAppsV2()) { - return this.showConfirmDialogV2_(); + return this.showConfirmDialogV2_(bounds); } else { return this.showConfirmDialogV1_(); } }; /** - * @return {Promise} A promise that resolves to a boolean value, indicating - * whether the user accepts the remote assistance or not. + * @return {Promise} A promise that will resolve if the user accepts remote + * assistance or reject otherwise. * @private */ remoting.It2MeHelpeeChannel.prototype.showConfirmDialogV1_ = function() { @@ -310,45 +320,22 @@ }; /** - * @return {Promise} A promise that resolves to a boolean value, indicating - * whether the user accepts the remote assistance or not. + * @param {Bounds} bounds the bounds of the Hangouts Window. If set, the + * confirm dialog will be centered within |bounds|. + * @return {Promise} A promise that will resolve if the user accepts remote + * assistance or reject otherwise. * @private */ -remoting.It2MeHelpeeChannel.prototype.showConfirmDialogV2_ = function() { - var messageHeader = l10n.getTranslationOrError( - /*i18n-content*/'HANGOUTS_CONFIRM_DIALOG_MESSAGE_1'); - var message1 = l10n.getTranslationOrError( - /*i18n-content*/'HANGOUTS_CONFIRM_DIALOG_MESSAGE_2'); - var message2 = l10n.getTranslationOrError( - /*i18n-content*/'HANGOUTS_CONFIRM_DIALOG_MESSAGE_3'); - var message = '<div>' + base.escapeHTML(messageHeader) + '</div>' + - '<ul class="insetList">' + - '<li>' + base.escapeHTML(message1) + '</li>' + - '<li>' + base.escapeHTML(message2) + '</li>' + - '</ul>'; - /** - * @param {function(*=):void} resolve - * @param {function(*=):void} reject - */ - return new Promise(function(resolve, reject) { - /** @param {number} result */ - function confirmDialogCallback(result) { - if (result === 1) { - resolve(true); - } else { - reject(new Error(remoting.Error.CANCELLED)); - } - } - remoting.MessageWindow.showConfirmWindow( - '', // Empty string to use the package name as the dialog title. - message, - l10n.getTranslationOrError( - /*i18n-content*/'HANGOUTS_CONFIRM_DIALOG_ACCEPT'), - l10n.getTranslationOrError( - /*i18n-content*/'HANGOUTS_CONFIRM_DIALOG_DECLINE'), - confirmDialogCallback - ); - }); +remoting.It2MeHelpeeChannel.prototype.showConfirmDialogV2_ = function(bounds) { + var getToken = + base.Promise.as(chrome.identity.getAuthToken, [{interactive: false}]); + + return getToken.then( + /** @param {string} token */ + function(token) { + return remoting.HangoutConsentDialog.getInstance().show(Boolean(token), + bounds); + }); }; /** @@ -374,7 +361,8 @@ }; /** - * @return {Promise} Promise that resolves with the OAuth token as the value. + * @return {Promise<string>} Promise that resolves with the OAuth token as the + * value. */ remoting.It2MeHelpeeChannel.prototype.fetchOAuthToken_ = function() { if (base.isAppsV2()) { @@ -382,27 +370,25 @@ * @param {function(*=):void} resolve */ return new Promise(function(resolve){ - // TODO(jamiewalch): Make this work with {interactive: true} as well. - chrome.identity.getAuthToken({ 'interactive': false }, resolve); + chrome.identity.getAuthToken({'interactive': true}, resolve); }); } else { /** * @param {function(*=):void} resolve + * @param {function(*=):void} reject */ - return new Promise(function(resolve) { + return new Promise(function(resolve, reject) { /** @type {remoting.OAuth2} */ var oauth2 = new remoting.OAuth2(); - var onAuthenticated = function() { - oauth2.callWithToken( - resolve, - function() { throw new Error('Authentication failed.'); }); - }; /** @param {remoting.Error} error */ var onError = function(error) { - if (error != remoting.Error.NOT_AUTHENTICATED) { - throw new Error('Unexpected error fetch auth token: ' + error); + if (error === remoting.Error.NOT_AUTHENTICATED) { + oauth2.doAuthRedirect(function() { + oauth2.callWithToken(resolve, reject); + }); + return; } - oauth2.removeCachedAuthToken(); + reject(new Error(remoting.Error.NOT_AUTHENTICATED)); }; oauth2.callWithToken(resolve, onError); });
diff --git a/remoting/webapp/crd/js/remoting.js b/remoting/webapp/crd/js/remoting.js index d86e6ec3..320019c9 100644 --- a/remoting/webapp/crd/js/remoting.js +++ b/remoting/webapp/crd/js/remoting.js
@@ -144,19 +144,6 @@ } /** - * @return {Object.<string, string>} The URL parameters. - */ -function getUrlParameters_() { - var result = {}; - var parts = window.location.search.substring(1).split('&'); - for (var i = 0; i < parts.length; i++) { - var pair = parts[i].split('='); - result[pair[0]] = decodeURIComponent(pair[1]); - } - return result; -} - -/** * Return the current time as a formatted string suitable for logging. * * @return {string} The current time, formatted as [mmdd/hhmmss.xyz]
diff --git a/remoting/webapp/crd/js/typecheck.js b/remoting/webapp/crd/js/typecheck.js index fa31f55a..7365238 100644 --- a/remoting/webapp/crd/js/typecheck.js +++ b/remoting/webapp/crd/js/typecheck.js
@@ -41,7 +41,10 @@ */ function getBooleanAttr(dict, key, opt_default) { var value = /** @type {boolean} */ (dict[key]); - if (typeof value != 'boolean') { + if (value == 'true' || value == 'false') { + return (value == 'true'); + } + if (typeof value !== 'boolean') { if (opt_default === undefined) { throw 'Invalid data type for ' + key + ' (expected: boolean, actual: ' + typeof value + ')';
diff --git a/remoting/webapp/js_proto/chrome_proto.js b/remoting/webapp/js_proto/chrome_proto.js index d47ef43..99fb4598 100644 --- a/remoting/webapp/js_proto/chrome_proto.js +++ b/remoting/webapp/js_proto/chrome_proto.js
@@ -386,6 +386,17 @@ AppWindow.prototype.focus = function() {}; AppWindow.prototype.maximize = function() {}; AppWindow.prototype.minimize = function() {}; +/** + * @param {number} left + * @param {number} top + */ +AppWindow.prototype.moveTo = function(left, top) {}; +/** + * @param {number} width + * @param {number} height + */ +AppWindow.prototype.resizeTo = function(width, height) {}; + AppWindow.prototype.restore = function() {}; AppWindow.prototype.show = function() {}; /** @return {boolean} */ @@ -424,7 +435,7 @@ this.width = 0; /** @type {number} */ this.height = 0; -}; +} /** @type {Object} */ chrome.cast = {};
diff --git a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js index 4ccfb08..3a8cb962 100644 --- a/remoting/webapp/unittests/it2me_helpee_channel_unittest.js +++ b/remoting/webapp/unittests/it2me_helpee_channel_unittest.js
@@ -129,8 +129,11 @@ function() { // Stubs authentication. sinon.stub(base, 'isAppsV2').returns(true); - sinon.stub(remoting.MessageWindow, 'showConfirmWindow') - .callsArgWith(4, 1 /* 1 for OK. */); + sinon.stub(remoting.HangoutConsentDialog, 'getInstance').returns({ + show : function() { + return Promise.resolve(); + } + }); sinon.stub(chrome.identity, 'getAuthToken') .callsArgWith(1, 'token'); // Stubs Host behavior. @@ -142,7 +145,8 @@ var MessageTypes = remoting.It2MeHelpeeChannel.HangoutMessageTypes; hangoutPort.onMessage.mock$fire({ method: MessageTypes.CONNECT, - email: 'test@chromium.org' + email: 'test@chromium.org', + hangoutBounds: {widht: 10, height: 10, left:10, top: 10} }); window.requestAnimationFrame(function(){ @@ -154,7 +158,6 @@ chrome.identity.getAuthToken.restore(); base.isAppsV2.restore(); - remoting.MessageWindow.showConfirmWindow.restore(); QUnit.start(); }); });
diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc index 1209fdf29..40a2bc4 100644 --- a/sandbox/linux/services/credentials_unittest.cc +++ b/sandbox/linux/services/credentials_unittest.cc
@@ -123,11 +123,11 @@ } // Test the WorkingDirectoryIsRoot() helper. -TEST(Credentials, CanDetectRoot) { - ASSERT_EQ(0, chdir("/proc/")); - ASSERT_FALSE(WorkingDirectoryIsRoot()); - ASSERT_EQ(0, chdir("/")); - ASSERT_TRUE(WorkingDirectoryIsRoot()); +SANDBOX_TEST(Credentials, CanDetectRoot) { + PCHECK(0 == chdir("/proc/")); + CHECK(!WorkingDirectoryIsRoot()); + PCHECK(0 == chdir("/")); + CHECK(WorkingDirectoryIsRoot()); } // Disabled on ASAN because of crbug.com/451603.
diff --git a/sandbox/linux/services/namespace_sandbox_unittest.cc b/sandbox/linux/services/namespace_sandbox_unittest.cc index ace1f925..91e1db92 100644 --- a/sandbox/linux/services/namespace_sandbox_unittest.cc +++ b/sandbox/linux/services/namespace_sandbox_unittest.cc
@@ -90,7 +90,8 @@ return 0; } -TEST_F(NamespaceSandboxTest, ChrootAndDropCapabilities) { +// Temporarily disabled on ASAN due to crbug.com/451603. +TEST_F(NamespaceSandboxTest, DISABLE_ON_ASAN(ChrootAndDropCapabilities)) { TestProc("ChrootMe"); }
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc index f0b5cef..9eb538a 100644 --- a/sandbox/linux/suid/client/setuid_sandbox_client.cc +++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -18,7 +18,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" -#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/posix/eintr_wrapper.h" @@ -32,7 +31,7 @@ namespace { bool IsFileSystemAccessDenied() { - base::ScopedFD self_exe(HANDLE_EINTR(open(base::kProcSelfExe, O_RDONLY))); + base::ScopedFD self_exe(HANDLE_EINTR(open("/", O_RDONLY))); return !self_exe.is_valid(); } @@ -208,11 +207,6 @@ return true; } -bool SetuidSandboxClient::CreateInitProcessReaper( - base::Closure* post_fork_parent_callback) { - return sandbox::CreateInitProcessReaper(post_fork_parent_callback); -} - bool SetuidSandboxClient::IsSuidSandboxUpToDate() const { return GetHelperApi(env_) == kSUIDSandboxApiNumber; }
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h index e6a3e4c..b24eb4c5f 100644 --- a/sandbox/linux/suid/client/setuid_sandbox_client.h +++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -6,7 +6,8 @@ #define SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_ #include "base/basictypes.h" -#include "base/callback_forward.h" +#include "base/command_line.h" +#include "base/environment.h" #include "base/files/file_path.h" #include "base/files/scoped_file.h" #include "base/process/launch.h" @@ -52,11 +53,6 @@ // to an empty directory. // Will only work if we have been launched through the setuid helper. bool ChrootMe(); - // When a new PID namespace is created, the process with pid == 1 should - // assume the role of init. - // See sandbox/linux/services/init_process_reaper.h for more information - // on this API. - bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback); // Did we get launched through an up to date setuid binary ? bool IsSuidSandboxUpToDate() const;
diff --git a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java b/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java deleted file mode 100644 index 7660434d..0000000 --- a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java +++ /dev/null
@@ -1,438 +0,0 @@ -// Copyright 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.sync.notifier; - -import android.accounts.Account; -import android.content.ContentResolver; -import android.content.Context; -import android.content.SyncStatusObserver; -import android.os.StrictMode; - -import org.chromium.base.ObserverList; -import org.chromium.base.VisibleForTesting; -import org.chromium.sync.SyncContentResolverDelegate; -import org.chromium.sync.SystemSyncContentResolverDelegate; -import org.chromium.sync.signin.AccountManagerHelper; -import org.chromium.sync.signin.ChromeSigninController; - -import javax.annotation.concurrent.NotThreadSafe; -import javax.annotation.concurrent.ThreadSafe; - -/** - * A helper class to handle the current status of sync for Chrome in Android settings. - * - * It also provides an observer to be used whenever Android sync settings change. - * - * To retrieve an instance of this class, call SyncStatusHelper.get(someContext). - * - * All new public methods MUST call notifyObservers at the end. - */ -@ThreadSafe -public class SyncStatusHelper { - - /** - * In-memory holder of the sync configurations for a given account. On each - * access, updates the cache if the account has changed. This lazy-updating - * model is appropriate as the account changes rarely but may not be known - * when initially constructed. So long as we keep a single account, no - * expensive calls to Android are made. - */ - @NotThreadSafe - @VisibleForTesting - public static class CachedAccountSyncSettings { - private final String mContractAuthority; - private final SyncContentResolverDelegate mSyncContentResolverDelegate; - private Account mAccount; - private boolean mDidUpdate; - private boolean mSyncAutomatically; - private int mIsSyncable; - - public CachedAccountSyncSettings(String contractAuthority, - SyncContentResolverDelegate contentResolverWrapper) { - mContractAuthority = contractAuthority; - mSyncContentResolverDelegate = contentResolverWrapper; - } - - private void ensureSettingsAreForAccount(Account account) { - assert account != null; - if (account.equals(mAccount)) return; - updateSyncSettingsForAccount(account); - mDidUpdate = true; - } - - public void clearUpdateStatus() { - mDidUpdate = false; - } - - public boolean getDidUpdateStatus() { - return mDidUpdate; - } - - // Calling this method may have side-effects. - public boolean getSyncAutomatically(Account account) { - ensureSettingsAreForAccount(account); - return mSyncAutomatically; - } - - public void updateSyncSettingsForAccount(Account account) { - if (account == null) return; - updateSyncSettingsForAccountInternal(account); - } - - public void setIsSyncable(Account account) { - ensureSettingsAreForAccount(account); - if (mIsSyncable == 1) return; - setIsSyncableInternal(account); - } - - public void setSyncAutomatically(Account account, boolean value) { - ensureSettingsAreForAccount(account); - if (mSyncAutomatically == value) return; - setSyncAutomaticallyInternal(account, value); - } - - @VisibleForTesting - protected void updateSyncSettingsForAccountInternal(Account account) { - // Null check here otherwise Findbugs complains. - if (account == null) return; - - boolean oldSyncAutomatically = mSyncAutomatically; - int oldIsSyncable = mIsSyncable; - Account oldAccount = mAccount; - - mAccount = account; - - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - mSyncAutomatically = mSyncContentResolverDelegate.getSyncAutomatically( - account, mContractAuthority); - mIsSyncable = mSyncContentResolverDelegate.getIsSyncable(account, mContractAuthority); - StrictMode.setThreadPolicy(oldPolicy); - mDidUpdate = (oldIsSyncable != mIsSyncable) - || (oldSyncAutomatically != mSyncAutomatically) - || (!account.equals(oldAccount)); - } - - @VisibleForTesting - protected void setIsSyncableInternal(Account account) { - mIsSyncable = 1; - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - mSyncContentResolverDelegate.setIsSyncable(account, mContractAuthority, 1); - StrictMode.setThreadPolicy(oldPolicy); - mDidUpdate = true; - } - - @VisibleForTesting - protected void setSyncAutomaticallyInternal(Account account, boolean value) { - mSyncAutomatically = value; - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - mSyncContentResolverDelegate.setSyncAutomatically(account, mContractAuthority, value); - StrictMode.setThreadPolicy(oldPolicy); - mDidUpdate = true; - } - } - - // This should always have the same value as GaiaConstants::kChromeSyncOAuth2Scope. - public static final String CHROME_SYNC_OAUTH2_SCOPE = - "https://www.googleapis.com/auth/chromesync"; - - public static final String TAG = "SyncStatusHelper"; - - /** - * Lock for ensuring singleton instantiation across threads. - */ - private static final Object INSTANCE_LOCK = new Object(); - - private static SyncStatusHelper sSyncStatusHelper; - - private final String mContractAuthority; - - private final Context mApplicationContext; - - private final SyncContentResolverDelegate mSyncContentResolverDelegate; - - private boolean mCachedMasterSyncAutomatically; - - // Instantiation of SyncStatusHelper is guarded by a lock so volatile is unneeded. - private CachedAccountSyncSettings mCachedSettings; - - private final ObserverList<SyncSettingsChangedObserver> mObservers = - new ObserverList<SyncSettingsChangedObserver>(); - - /** - * Provides notifications when Android sync settings have changed. - */ - public interface SyncSettingsChangedObserver { - public void syncSettingsChanged(); - } - - /** - * @param context the context - * @param syncContentResolverDelegate an implementation of {@link SyncContentResolverDelegate}. - */ - private SyncStatusHelper(Context context, - SyncContentResolverDelegate syncContentResolverDelegate, - CachedAccountSyncSettings cachedAccountSettings) { - mApplicationContext = context.getApplicationContext(); - mSyncContentResolverDelegate = syncContentResolverDelegate; - mContractAuthority = getContractAuthority(); - mCachedSettings = cachedAccountSettings; - - updateMasterSyncAutomaticallySetting(); - - mSyncContentResolverDelegate.addStatusChangeListener( - ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, - new AndroidSyncSettingsChangedObserver()); - } - - private void updateMasterSyncAutomaticallySetting() { - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - synchronized (mCachedSettings) { - mCachedMasterSyncAutomatically = mSyncContentResolverDelegate - .getMasterSyncAutomatically(); - } - StrictMode.setThreadPolicy(oldPolicy); - } - - /** - * A factory method for the SyncStatusHelper. - * - * It is possible to override the {@link SyncContentResolverDelegate} to use in tests for the - * instance of the SyncStatusHelper by calling overrideSyncStatusHelperForTests(...) with - * your {@link SyncContentResolverDelegate}. - * - * @param context the ApplicationContext is retrieved from the context used as an argument. - * @return a singleton instance of the SyncStatusHelper - */ - public static SyncStatusHelper get(Context context) { - synchronized (INSTANCE_LOCK) { - if (sSyncStatusHelper == null) { - SyncContentResolverDelegate contentResolverDelegate = - new SystemSyncContentResolverDelegate(); - CachedAccountSyncSettings cache = new CachedAccountSyncSettings( - context.getPackageName(), contentResolverDelegate); - sSyncStatusHelper = new SyncStatusHelper(context, contentResolverDelegate, cache); - } - } - return sSyncStatusHelper; - } - - /** - * Tests might want to consider overriding the context and {@link SyncContentResolverDelegate} - * so they do not use the real ContentResolver in Android. - * - * @param context the context to use - * @param syncContentResolverDelegate the {@link SyncContentResolverDelegate} to use - */ - @VisibleForTesting - public static void overrideSyncStatusHelperForTests(Context context, - SyncContentResolverDelegate syncContentResolverDelegate, - CachedAccountSyncSettings cachedAccountSettings) { - synchronized (INSTANCE_LOCK) { - if (sSyncStatusHelper != null) { - throw new IllegalStateException("SyncStatusHelper already exists"); - } - sSyncStatusHelper = new SyncStatusHelper(context, syncContentResolverDelegate, - cachedAccountSettings); - } - } - - @VisibleForTesting - public static void overrideSyncStatusHelperForTests(Context context, - SyncContentResolverDelegate syncContentResolverDelegate) { - CachedAccountSyncSettings cachedAccountSettings = new CachedAccountSyncSettings( - context.getPackageName(), syncContentResolverDelegate); - overrideSyncStatusHelperForTests(context, syncContentResolverDelegate, - cachedAccountSettings); - } - - /** - * Returns the contract authority to use when requesting sync. - */ - public String getContractAuthority() { - return mApplicationContext.getPackageName(); - } - - /** - * Wrapper method for the ContentResolver.addStatusChangeListener(...) when we are only - * interested in the settings type. - */ - public void registerSyncSettingsChangedObserver(SyncSettingsChangedObserver observer) { - mObservers.addObserver(observer); - } - - /** - * Wrapper method for the ContentResolver.removeStatusChangeListener(...). - */ - public void unregisterSyncSettingsChangedObserver(SyncSettingsChangedObserver observer) { - mObservers.removeObserver(observer); - } - - /** - * Checks whether sync is currently enabled from Chrome for a given account. - * - * It checks both the master sync for the device, and Chrome sync setting for the given account. - * - * @param account the account to check if Chrome sync is enabled on. - * @return true if sync is on, false otherwise - */ - public boolean isSyncEnabled(Account account) { - if (account == null) return false; - boolean returnValue; - synchronized (mCachedSettings) { - returnValue = mCachedMasterSyncAutomatically - && mCachedSettings.getSyncAutomatically(account); - } - - notifyObserversIfAccountSettingsChanged(); - return returnValue; - } - - /** - * Checks whether sync is currently enabled from Chrome for the currently signed in account. - * - * It checks both the master sync for the device, and Chrome sync setting for the given account. - * If no user is currently signed in it returns false. - * - * @return true if sync is on, false otherwise - */ - public boolean isSyncEnabled() { - return isSyncEnabled(ChromeSigninController.get(mApplicationContext).getSignedInUser()); - } - - /** - * Checks whether sync is currently enabled from Chrome for a given account. - * - * It checks only Chrome sync setting for the given account, - * and ignores the master sync setting. - * - * @param account the account to check if Chrome sync is enabled on. - * @return true if sync is on, false otherwise - */ - public boolean isSyncEnabledForChrome(Account account) { - if (account == null) return false; - - boolean returnValue; - synchronized (mCachedSettings) { - returnValue = mCachedSettings.getSyncAutomatically(account); - } - - notifyObserversIfAccountSettingsChanged(); - return returnValue; - } - - /** - * Checks whether the master sync flag for Android is currently set. - * - * @return true if the global master sync is on, false otherwise - */ - public boolean isMasterSyncAutomaticallyEnabled() { - synchronized (mCachedSettings) { - return mCachedMasterSyncAutomatically; - } - } - - /** - * Make sure Chrome is syncable, and enable sync. - * - * @param account the account to enable sync on - */ - public void enableAndroidSync(Account account) { - makeSyncable(account); - - synchronized (mCachedSettings) { - mCachedSettings.setSyncAutomatically(account, true); - } - - notifyObserversIfAccountSettingsChanged(); - } - - /** - * Disables Android Chrome sync - * - * @param account the account to disable Chrome sync on - */ - public void disableAndroidSync(Account account) { - synchronized (mCachedSettings) { - mCachedSettings.setSyncAutomatically(account, false); - } - - notifyObserversIfAccountSettingsChanged(); - } - - /** - * Register with Android Sync Manager. This is what causes the "Chrome" option to appear in - * Settings -> Accounts / Sync . - * - * @param account the account to enable Chrome sync on - */ - private void makeSyncable(Account account) { - synchronized (mCachedSettings) { - mCachedSettings.setIsSyncable(account); - } - - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - // Disable the syncability of Chrome for all other accounts. Don't use - // our cache as we're touching many accounts that aren't signed in, so this saves - // extra calls to Android sync configuration. - Account[] googleAccounts = AccountManagerHelper.get(mApplicationContext) - .getGoogleAccounts(); - for (Account accountToSetNotSyncable : googleAccounts) { - if (!accountToSetNotSyncable.equals(account) - && mSyncContentResolverDelegate.getIsSyncable( - accountToSetNotSyncable, mContractAuthority) > 0) { - mSyncContentResolverDelegate.setIsSyncable(accountToSetNotSyncable, - mContractAuthority, 0); - } - } - StrictMode.setThreadPolicy(oldPolicy); - } - - /** - * Helper class to be used by observers whenever sync settings change. - * - * To register the observer, call SyncStatusHelper.registerObserver(...). - */ - private class AndroidSyncSettingsChangedObserver implements SyncStatusObserver { - @Override - public void onStatusChanged(int which) { - if (ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS == which) { - // Sync settings have changed; update our in-memory caches - synchronized (mCachedSettings) { - mCachedSettings.updateSyncSettingsForAccount( - ChromeSigninController.get(mApplicationContext).getSignedInUser()); - } - - boolean oldMasterSyncEnabled = isMasterSyncAutomaticallyEnabled(); - updateMasterSyncAutomaticallySetting(); - boolean didMasterSyncChanged = - oldMasterSyncEnabled != isMasterSyncAutomaticallyEnabled(); - // Notify observers if MasterSync or account level settings change. - if (didMasterSyncChanged || getAndClearDidUpdateStatus()) - notifyObservers(); - } - } - } - - private boolean getAndClearDidUpdateStatus() { - boolean didGetStatusUpdate; - synchronized (mCachedSettings) { - didGetStatusUpdate = mCachedSettings.getDidUpdateStatus(); - mCachedSettings.clearUpdateStatus(); - } - return didGetStatusUpdate; - } - - private void notifyObserversIfAccountSettingsChanged() { - if (getAndClearDidUpdateStatus()) { - notifyObservers(); - } - } - - private void notifyObservers() { - for (SyncSettingsChangedObserver observer : mObservers) { - observer.syncSettingsChanged(); - } - } -}
diff --git a/sync/internal_api/public/util/experiments.h b/sync/internal_api/public/util/experiments.h index b61742d..d2b82c62 100644 --- a/sync/internal_api/public/util/experiments.h +++ b/sync/internal_api/public/util/experiments.h
@@ -16,6 +16,7 @@ const char kGCMChannelTag[] = "gcm_channel"; const char kEnhancedBookmarksTag[] = "enhanced_bookmarks"; const char kGCMInvalidationsTag[] = "gcm_invalidations"; +const char kWalletSyncTag[] = "wallet_sync"; // A structure to hold the enable status of experimental sync features. struct Experiments { @@ -29,15 +30,16 @@ : favicon_sync_limit(200), gcm_channel_state(UNSET), enhanced_bookmarks_enabled(false), - gcm_invalidations_enabled(true) // By default GCM channel is enabled. - {} + gcm_invalidations_enabled(true), // By default GCM channel is enabled. + wallet_sync_enabled(false) {} bool Matches(const Experiments& rhs) { return (favicon_sync_limit == rhs.favicon_sync_limit && gcm_channel_state == rhs.gcm_channel_state && enhanced_bookmarks_enabled == rhs.enhanced_bookmarks_enabled && enhanced_bookmarks_ext_id == rhs.enhanced_bookmarks_ext_id && - gcm_invalidations_enabled == rhs.gcm_invalidations_enabled); + gcm_invalidations_enabled == rhs.gcm_invalidations_enabled && + wallet_sync_enabled == rhs.wallet_sync_enabled); } // The number of favicons that a client is permitted to sync. @@ -54,6 +56,9 @@ // Enhanced bookmarks extension id. std::string enhanced_bookmarks_ext_id; + + // Enable the Wallet Autofill sync datatype. + bool wallet_sync_enabled; }; } // namespace syncer
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 8ff4843..1655a24 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc
@@ -1010,6 +1010,17 @@ } } + ReadNode wallet_sync_node(&trans); + if (wallet_sync_node.InitByClientTagLookup( + syncer::EXPERIMENTS, syncer::kWalletSyncTag) == BaseNode::INIT_OK) { + const sync_pb::WalletSyncFlags& wallet_sync = + wallet_sync_node.GetExperimentsSpecifics().wallet_sync(); + if (wallet_sync.has_enabled()) { + experiments->wallet_sync_enabled = wallet_sync.enabled(); + found_experiment = true; + } + } + return found_experiment; }
diff --git a/sync/protocol/experiments_specifics.proto b/sync/protocol/experiments_specifics.proto index 723fe55..3006223 100644 --- a/sync/protocol/experiments_specifics.proto +++ b/sync/protocol/experiments_specifics.proto
@@ -55,6 +55,11 @@ optional bool enabled = 1; } +// Flags for enabling wallet data syncing. +message WalletSyncFlags { + optional bool enabled = 1; +} + // Contains one flag or set of related flags. Each node of the experiments type // will have a unique_client_tag identifying which flags it contains. By // convention, the tag name should match the sub-message name. @@ -67,4 +72,5 @@ optional GcmChannelFlags gcm_channel = 6; optional EnhancedBookmarksFlags enhanced_bookmarks = 7; optional GcmInvalidationsFlags gcm_invalidations = 8; + optional WalletSyncFlags wallet_sync = 9; }
diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc index 377a4322..d1786f8 100644 --- a/sync/protocol/proto_value_conversions.cc +++ b/sync/protocol/proto_value_conversions.cc
@@ -422,6 +422,7 @@ SET_EXPERIMENT_ENABLED_FIELD(gcm_channel); SET(enhanced_bookmarks, EnhancedBookmarksFlagsToValue); SET_EXPERIMENT_ENABLED_FIELD(gcm_invalidations); + SET_EXPERIMENT_ENABLED_FIELD(wallet_sync); return value; }
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index c9059e7..55e5481 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -101,6 +101,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -245,6 +246,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -389,6 +391,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -534,6 +537,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 452fc51c..c462aaf 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -92,6 +92,7 @@ "can_use_on_swarming_builders": true } }, + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -233,6 +234,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -382,6 +384,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -535,6 +538,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": { @@ -681,6 +685,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", + "nacl_loader_unittests", { "test": "net_unittests", "swarming": {
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json index c5e51b6a..c2d7e72 100644 --- a/testing/buildbot/chromium_trybot.json +++ b/testing/buildbot/chromium_trybot.json
@@ -174,10 +174,7 @@ "mojo_public_system_unittests", "mojo_public_utility_unittests", "mojo_system_unittests", - { - "test": "nacl_loader_unittests", - "platforms": ["linux"] - }, + "nacl_loader_unittests", { "test": "net_unittests", "swarming": {
diff --git a/testing/gtest.gyp b/testing/gtest.gyp index c4510f6..d61772e 100644 --- a/testing/gtest.gyp +++ b/testing/gtest.gyp
@@ -39,6 +39,7 @@ 'sources': [ 'gtest_mac.h', 'gtest_mac.mm', + 'platform_test_mac.mm', ], 'link_settings': { 'libraries': [ @@ -46,11 +47,6 @@ ], }, }], - ['OS == "mac"', { - 'sources': [ - 'platform_test_mac.mm', - ], - }], ['OS == "ios"', { 'dependencies' : [ '<(DEPTH)/testing/iossim/iossim.gyp:iossim#host', @@ -85,7 +81,6 @@ 'sources': [ 'coverage_util_ios.cc', 'coverage_util_ios.h', - 'platform_test_ios.mm', ], }], ['OS=="ios" and asan==1', {
diff --git a/testing/platform_test_ios.mm b/testing/platform_test_ios.mm deleted file mode 100644 index 5162c1db..0000000 --- a/testing/platform_test_ios.mm +++ /dev/null
@@ -1,18 +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 "platform_test.h" - -#import <Foundation/Foundation.h> - -#include "coverage_util_ios.h" - -PlatformTest::PlatformTest() - : pool_([[NSAutoreleasePool alloc] init]) { -} - -PlatformTest::~PlatformTest() { - [pool_ release]; - coverage_util::FlushCoverageDataIfNecessary(); -}
diff --git a/testing/test_env.py b/testing/test_env.py index 0743f34..48cbac9 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -35,7 +35,10 @@ def trim_cmd(cmd): """Removes internal flags from cmd since they're just used to communicate from the host machine to this script running on the swarm slaves.""" - internal_flags = frozenset(['--asan=0', '--asan=1', '--lsan=0', '--lsan=1']) + sanitizers = ['asan', 'lsan', 'msan', 'tsan'] + internal_flags = frozenset('--%s=%d' % (name, value) + for name in sanitizers + for value in [0, 1]) return [i for i in cmd if i not in internal_flags] @@ -49,12 +52,12 @@ return out -def get_asan_env(cmd, lsan): - """Returns the envirnoment flags needed for ASan and LSan.""" +def get_sanitizer_env(cmd, asan, lsan, msan, tsan): + """Returns the envirnoment flags needed for sanitizer tools.""" extra_env = {} - # Instruct GTK to use malloc while running ASan or LSan tests. + # Instruct GTK to use malloc while running sanitizer-instrumented tests. extra_env['G_SLICE'] = 'always-malloc' extra_env['NSS_DISABLE_ARENA_FREE_LIST'] = '1' @@ -65,25 +68,12 @@ symbolizer_path = os.path.abspath(os.path.join(ROOT_DIR, 'third_party', 'llvm-build', 'Release+Asserts', 'bin', 'llvm-symbolizer')) - asan_options = [] - if lsan: - asan_options.append('detect_leaks=1') - if sys.platform == 'linux2': - # Use the debug version of libstdc++ under LSan. If we don't, there will - # be a lot of incomplete stack traces in the reports. - extra_env['LD_LIBRARY_PATH'] = '/usr/lib/x86_64-linux-gnu/debug:' - + if lsan or tsan: # LSan is not sandbox-compatible, so we can use online symbolization. In # fact, it needs symbolization to be able to apply suppressions. symbolization_options = ['symbolize=1', 'external_symbolizer_path=%s' % symbolizer_path] - - suppressions_file = os.path.join(ROOT_DIR, 'tools', 'lsan', - 'suppressions.txt') - lsan_options = ['suppressions=%s' % suppressions_file, - 'print_suppressions=1'] - extra_env['LSAN_OPTIONS'] = ' '.join(lsan_options) - else: + elif asan or msan: # ASan uses a script for offline symbolization. # Important note: when running ASan with leak detection enabled, we must use # the LSan symbolization options above. @@ -91,16 +81,45 @@ # Set the path to llvm-symbolizer to be used by asan_symbolize.py extra_env['LLVM_SYMBOLIZER_PATH'] = symbolizer_path - asan_options.extend(symbolization_options) + if asan: + asan_options = symbolization_options[:] + if lsan: + asan_options.append('detect_leaks=1') - extra_env['ASAN_OPTIONS'] = ' '.join(asan_options) + extra_env['ASAN_OPTIONS'] = ' '.join(asan_options) - if sys.platform == 'darwin': - isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0])) - # This is needed because the test binary has @executable_path embedded in it - # it that the OS tries to resolve to the cache directory and not the mapped - # directory. - extra_env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir) + if sys.platform == 'darwin': + isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0])) + # This is needed because the test binary has @executable_path embedded in + # it that the OS tries to resolve to the cache directory and not the + # mapped directory. + extra_env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir) + + if lsan: + if asan or msan: + lsan_options = [] + else: + lsan_options = symbolization_options[:] + if sys.platform == 'linux2': + # Use the debug version of libstdc++ under LSan. If we don't, there will + # be a lot of incomplete stack traces in the reports. + extra_env['LD_LIBRARY_PATH'] = '/usr/lib/x86_64-linux-gnu/debug:' + + suppressions_file = os.path.join(ROOT_DIR, 'tools', 'lsan', + 'suppressions.txt') + lsan_options += ['suppressions=%s' % suppressions_file, + 'print_suppressions=1'] + extra_env['LSAN_OPTIONS'] = ' '.join(lsan_options) + + if msan: + msan_options = symbolization_options[:] + if lsan: + msan_options.append('detect_leaks=1') + extra_env['MSAN_OPTIONS'] = ' '.join(msan_options) + + if tsan: + tsan_options = symbolization_options[:] + extra_env['TSAN_OPTIONS'] = ' '.join(tsan_options) return extra_env @@ -159,15 +178,17 @@ # Copy logic from tools/build/scripts/slave/runtest.py. asan = '--asan=1' in cmd lsan = '--lsan=1' in cmd - use_symbolization_script = asan and not lsan + msan = '--msan=1' in cmd + tsan = '--tsan=1' in cmd + use_symbolization_script = (asan or msan) and not lsan - if asan: - extra_env.update(get_asan_env(cmd, lsan)) - # ASan is not yet sandbox-friendly on Windows (http://crbug.com/382867). - if sys.platform == 'win32': + if asan or lsan or msan or tsan: + extra_env.update(get_sanitizer_env(cmd, asan, lsan, msan, tsan)) + + if lsan or tsan or (asan and sys.platform == 'win32'): + # ASan is not yet sandbox-friendly on Windows (http://crbug.com/382867). + # LSan and TSan are not sandbox-friendly. cmd.append('--no-sandbox') - if lsan: - cmd.append('--no-sandbox') cmd = trim_cmd(cmd)
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi index 2691ef8..0750678 100644 --- a/third_party/boringssl/boringssl.gypi +++ b/third_party/boringssl/boringssl.gypi
@@ -331,6 +331,7 @@ 'linux-arm/crypto/sha/sha256-armv4.S', 'linux-arm/crypto/sha/sha512-armv4.S', 'src/crypto/chacha/chacha_vec_arm.S', + 'src/crypto/cpu-arm-asm.S', 'src/crypto/poly1305/poly1305_arm_asm.S', ], 'boringssl_linux_x86_sources': [
diff --git a/third_party/boringssl/update_gypi_and_asm.py b/third_party/boringssl/update_gypi_and_asm.py index 476e42fde..db11e647 100644 --- a/third_party/boringssl/update_gypi_and_asm.py +++ b/third_party/boringssl/update_gypi_and_asm.py
@@ -29,6 +29,7 @@ ('linux', 'arm'): [ 'src/crypto/poly1305/poly1305_arm_asm.S', 'src/crypto/chacha/chacha_vec_arm.S', + 'src/crypto/cpu-arm-asm.S', ], }
diff --git a/third_party/google_input_tools/README.chromium b/third_party/google_input_tools/README.chromium index 026f2a63f..3ae0a96b5 100644 --- a/third_party/google_input_tools/README.chromium +++ b/third_party/google_input_tools/README.chromium
@@ -2,7 +2,7 @@ Short Name: google_input_tools URL: https://github.com/googlei18n/google-input-tools.git Version: 1.0.6.0 -Revision: @9682ab568163879e00499bd94937016426afddfb +Revision: @30ffaf3940d79fe88160fa2d3eccb5134953481a License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/google_input_tools/inputview.gypi b/third_party/google_input_tools/inputview.gypi index 3c27b66..82a68ac3 100644 --- a/third_party/google_input_tools/inputview.gypi +++ b/third_party/google_input_tools/inputview.gypi
@@ -25,6 +25,7 @@ 'src/chrome/os/inputview/direction.js', 'src/chrome/os/inputview/dom.js', 'src/chrome/os/inputview/elements/content/altdataview.js', + 'src/chrome/os/inputview/elements/content/backspacekey.js', 'src/chrome/os/inputview/elements/content/candidate.js', 'src/chrome/os/inputview/elements/content/candidatebutton.js', 'src/chrome/os/inputview/elements/content/candidateview.js', @@ -50,10 +51,13 @@ 'src/chrome/os/inputview/elements/content/menuview.js', 'src/chrome/os/inputview/elements/content/modifierkey.js', 'src/chrome/os/inputview/elements/content/morekeysshiftoperation.js', + 'src/chrome/os/inputview/elements/content/selectview.js', 'src/chrome/os/inputview/elements/content/softkey.js', 'src/chrome/os/inputview/elements/content/spacekey.js', + 'src/chrome/os/inputview/elements/content/swipeview.js', 'src/chrome/os/inputview/elements/content/switcherkey.js', 'src/chrome/os/inputview/elements/content/tabbarkey.js', + 'src/chrome/os/inputview/elements/content/toolbarbutton.js', 'src/chrome/os/inputview/elements/content/voiceview.js', 'src/chrome/os/inputview/elements/element.js', 'src/chrome/os/inputview/elements/elementtype.js', @@ -66,6 +70,7 @@ 'src/chrome/os/inputview/emojitype.js', 'src/chrome/os/inputview/events.js', 'src/chrome/os/inputview/events/keycodes.js', + 'src/chrome/os/inputview/globalflags.js', 'src/chrome/os/inputview/globalsettings.js', 'src/chrome/os/inputview/handler/pointeractionbundle.js', 'src/chrome/os/inputview/handler/pointerhandler.js', @@ -92,8 +97,6 @@ 'src/chrome/os/inputview/readystate.js', 'src/chrome/os/inputview/settings.js', 'src/chrome/os/inputview/sizespec.js', - 'src/chrome/os/inputview/soundcontroller.js', - 'src/chrome/os/inputview/sounds.js', 'src/chrome/os/inputview/specnodename.js', 'src/chrome/os/inputview/statemanager.js', 'src/chrome/os/inputview/statetype.js', @@ -109,6 +112,8 @@ 'src/chrome/os/message/event.js', 'src/chrome/os/message/name.js', 'src/chrome/os/message/type.js', + 'src/chrome/os/soundcontroller.js', + 'src/chrome/os/sounds.js', 'src/chrome/os/statistics.js', 'third_party/closure_library/closure/goog/a11y/aria/announcer.js', 'third_party/closure_library/closure/goog/a11y/aria/aria.js',
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/am/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/am/messages.json index 6b7399c..8bde55a 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/am/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/am/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u12c8\u12f0 \u12e8\u130d\u120d \u1218\u12dd\u1308\u1260 \u1243\u120b\u1275 \u12a0\u12ad\u120d" + }, "advanced": { "message": "\u12e8\u120b\u1240" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u12e8\u1235\u1353\u1292\u123d\u129b \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, + "expand": { + "message": "\u12d8\u122d\u130b" + }, + "expand_candidates": { + "message": "\u12e8\u12d5\u1329 \u12dd\u122d\u12dd\u122d\u1295 \u12d8\u122d\u130b" + }, "fi_fin_settings_page": { "message": "\u12e8\u134a\u1295\u120b\u1295\u12f5\u129b \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u12e8\u1264\u120b\u1229\u1235\u129b \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, + "ignore_correction": { + "message": "\u1208\u121a\u12a8\u1270\u1208\u12cd \u12a5\u122d\u121b\u1276\u127d\u1295 \u127d\u120b \u1260\u120d" + }, "il_heb_settings_page": { "message": "\u12e8\u12a5\u1265\u122b\u12ed\u1235\u1325 \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, @@ -2847,7 +2859,7 @@ "message": "\u12e8\u122e\u121b\u1292\u12eb\u129b \u1241\u120d\u134d \u1230\u120c\u12f3" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u12e8\u122e\u121b\u1292\u12eb \u1218\u12f0\u1260\u129b \u12e8\u1241\u120d\u134d \u1230\u120c\u12f3" }, "keyboard_russian": { "message": "\u12e8\u1229\u1232\u12eb\u129b \u1241\u120d\u134d \u1230\u120c\u12f3" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u12e8\u1235\u12ca\u12f2\u1295\u129b \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, + "settings": { + "message": "\u1245\u1295\u1265\u122e\u127d" + }, "shift": { "message": "\u1218\u1240\u12e8\u122a\u12eb" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u12e8Hangul \u12a0\u1235\u1270\u12eb\u12e8\u1275 \u1325\u1246\u121b\u12ce\u127d\u1295 \u12a0\u1233\u12ed" }, + "shrink_candidates": { + "message": "\u12e8\u12d5\u1329 \u12dd\u122d\u12dd\u122d\u1295 \u12d8\u122d\u130b" + }, "si_slv_settings_page": { "message": "\u12e8\u1235\u120e\u126b\u1295\u12eb\u129b \u1241\u120d\u134d \u1230\u120c\u12f3 \u1245\u1295\u1265\u122e\u127d \u1308\u133d" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u12e8\u1270\u1218\u1228\u1321\u1275\u1295 \u12a0\u1235\u12c8\u130d\u12f5" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u12a0\u1235\u1240\u121d\u1325" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ar/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ar/messages.json index 090167f9..39b778e6 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ar/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ar/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0627\u0644\u0625\u0636\u0627\u0641\u0629 \u0625\u0644\u0649 \u0627\u0644\u0642\u0627\u0645\u0648\u0633 \u0627\u0644\u0634\u062e\u0635\u064a" + }, "advanced": { "message": "\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0645\u062a\u0642\u062f\u0645\u0629" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0625\u0633\u0628\u0627\u0646\u064a\u0629" }, + "expand": { + "message": "\u062a\u0648\u0633\u064a\u0639" + }, + "expand_candidates": { + "message": "\u062a\u0648\u0633\u064a\u0639 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0631\u0634\u062d\u064a\u0646" + }, "fi_fin_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0642\u0637\u0627\u0644\u0648\u0646\u064a\u0629" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0623\u064a\u0631\u0644\u0646\u062f\u064a\u0629" }, + "ignore_correction": { + "message": "\u062a\u062c\u0627\u0647\u0644 \u062a\u0635\u062d\u064a\u062d \u0644\u0640" + }, "il_heb_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0639\u0628\u0631\u064a\u0629" }, @@ -2847,7 +2859,7 @@ "message": "\u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0631\u0648\u0645\u0627\u0646\u064a\u0629" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0631\u0648\u0645\u0627\u0646\u064a\u0629 \u0627\u0644\u0642\u064a\u0627\u0633\u064a\u0629" }, "keyboard_russian": { "message": "\u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0631\u0648\u0633\u064a\u0629" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0633\u0648\u064a\u062f\u064a\u0629" }, + "settings": { + "message": "\u0625\u0639\u062f\u0627\u062f\u0627\u062a" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0639\u0631\u0636 \u0627\u0642\u062a\u0631\u0627\u062d\u0627\u062a \u0627\u0644\u0647\u0627\u0646\u063a\u0648\u0644" }, + "shrink_candidates": { + "message": "\u062a\u0642\u0644\u064a\u0635 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0631\u0634\u062d\u064a\u0646" + }, "si_slv_settings_page": { "message": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u0633\u0644\u0648\u0641\u0627\u0646\u064a\u0629" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0625\u0632\u0627\u0644\u0629 \u0627\u0644\u0645\u062e\u062a\u0627\u0631\u0629" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u062d\u0641\u0638" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/bg/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/bg/messages.json index 3fc8910..7c23209 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/bg/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/bg/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043a\u044a\u043c \u043b\u0438\u0447\u043d\u0438\u044f \u0440\u0435\u0447\u043d\u0438\u043a" + }, "advanced": { "message": "\u0420\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0438\u0441\u043f\u0430\u043d\u0441\u043a\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, + "expand": { + "message": "\u0420\u0430\u0437\u0433\u044a\u0432\u0430\u043d\u0435" + }, + "expand_candidates": { + "message": "\u0440\u0430\u0437\u0433\u044a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f" + }, "fi_fin_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0444\u0438\u043d\u043b\u0430\u043d\u0434\u0441\u043a\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0438\u0440\u043b\u0430\u043d\u0434\u0441\u043a\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, + "ignore_correction": { + "message": "\u041f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u0440\u0435\u043a\u0446\u0438\u044f\u0442\u0430 \u0437\u0430" + }, "il_heb_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430\u0442\u0430 \u043d\u0430 \u0438\u0432\u0440\u0438\u0442" }, @@ -2847,7 +2859,7 @@ "message": "\u0420\u0443\u043c\u044a\u043d\u0441\u043a\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0420\u0443\u043c\u044a\u043d\u0441\u043a\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, "keyboard_russian": { "message": "\u0420\u0443\u0441\u043a\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0448\u0432\u0435\u0434\u0441\u043a\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, + "settings": { + "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0445\u0430\u043d\u0433\u044a\u043b" }, + "shrink_candidates": { + "message": "\u0441\u0432\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f" + }, "si_slv_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0441\u043b\u043e\u0432\u0435\u043d\u0441\u043a\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0431\u0440\u0430\u043d\u043e\u0442\u043e" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/bn/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/bn/messages.json index 600d640..d1fbac5 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/bn/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/bn/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u09ac\u09cd\u09af\u0995\u09cd\u09a4\u09bf\u0997\u09a4 \u0985\u09ad\u09bf\u09a7\u09be\u09a8\u09c7 \u09af\u09cb\u0997 \u0995\u09b0\u09c1\u09a8" + }, "advanced": { "message": "\u0989\u09a8\u09cd\u09a8\u09a4" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u09b8\u09cd\u09aa\u09cd\u09af\u09be\u09a8\u09bf\u09b6 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, + "expand": { + "message": "\u09aa\u09cd\u09b0\u09b8\u09be\u09b0\u09bf\u09a4 \u0995\u09b0\u09c1\u09a8" + }, + "expand_candidates": { + "message": "\u09aa\u09cd\u09b0\u09be\u09b0\u09cd\u09a5\u09c0 \u09a4\u09be\u09b2\u09bf\u0995\u09be \u09aa\u09cd\u09b0\u09b8\u09be\u09b0\u09bf\u09a4 \u0995\u09b0\u09c1\u09a8" + }, "fi_fin_settings_page": { "message": "\u09ab\u09bf\u09a8\u09bf\u09b6 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0986\u0987\u09b0\u09bf\u09b6 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, + "ignore_correction": { + "message": "\u098f\u09b0 \u099c\u09a8\u09cd\u09af \u0995\u09b0\u09be \u09b8\u0982\u09b6\u09cb\u09a7\u09a8 \u0989\u09aa\u09c7\u0995\u09cd\u09b7\u09be \u0995\u09b0\u09c1\u09a8" + }, "il_heb_settings_page": { "message": "\u09b9\u09bf\u09ac\u09cd\u09b0\u09c1 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, @@ -2847,7 +2859,7 @@ "message": "\u09b0\u09cb\u09ae\u09be\u09a8\u09bf\u09df \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u09b0\u09cb\u09ae\u09be\u09a8\u09bf\u09af\u09bc\u09be\u09a8 \u0986\u09a6\u09b0\u09cd\u09b6 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1" }, "keyboard_russian": { "message": "\u09b0\u09be\u09b6\u09bf\u09df\u09be\u09a8 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u09b8\u09c1\u0987\u09a1\u09bf\u09b6 \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, + "settings": { + "message": "\u09b8\u09c7\u099f\u09bf\u0982\u09b8" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u09b9\u09be\u0999\u09cd\u0997\u09c1\u09b2 \u09aa\u09cd\u09b0\u09b8\u09cd\u09a4\u09be\u09ac\u09a8\u09be\u0997\u09c1\u09b2\u09bf \u09a6\u09c7\u0996\u09be\u09a8" }, + "shrink_candidates": { + "message": "\u09aa\u09cd\u09b0\u09be\u09b0\u09cd\u09a5\u09c0 \u09a4\u09be\u09b2\u09bf\u0995\u09be \u09b8\u0999\u09cd\u0995\u09c1\u099a\u09bf\u09a4 \u0995\u09b0\u09c1\u09a8" + }, "si_slv_settings_page": { "message": "\u09b8\u09cd\u09b2\u09cb\u09ad\u09c7\u09a8\u09bf\u09af\u09bc \u0995\u09c0\u09ac\u09cb\u09b0\u09cd\u09a1 \u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u09a8\u09bf\u09b0\u09cd\u09ac\u09be\u099a\u09bf\u09a4 \u09b8\u09b0\u09be\u09a8" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09a3 \u0995\u09b0\u09c1\u09a8" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ca/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ca/messages.json index 72ad907e..5af81f0 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ca/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ca/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Afegeix al diccionari personal" + }, "advanced": { "message": "Avan\u00e7ada" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat espanyol" }, + "expand": { + "message": "Amplia" + }, + "expand_candidates": { + "message": "amplia la llista de candidats" + }, "fi_fin_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat fin\u00e8s" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat irland\u00e8s" }, + "ignore_correction": { + "message": "Ignora la correcci\u00f3 de" + }, "il_heb_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat hebreu" }, @@ -2847,7 +2859,7 @@ "message": "Teclat roman\u00e8s" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Teclat est\u00e0ndard roman\u00e8s" }, "keyboard_russian": { "message": "Teclat rus" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat suec" }, + "settings": { + "message": "Configuraci\u00f3" + }, "shift": { "message": "maj" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostra suggeriments d'hangul" }, + "shrink_candidates": { + "message": "redueix la llista de candidats" + }, "si_slv_settings_page": { "message": "P\u00e0gina de configuraci\u00f3 del teclat eslov\u00e8" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Suprimeix les seleccionades" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Desa" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/cs/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/cs/messages.json index 2c689a8..72dffcc 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/cs/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/cs/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "P\u0159idat do osobn\u00edho slovn\u00edku" + }, "advanced": { "message": "Roz\u0161\u00ed\u0159en\u00e1 nastaven\u00ed" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Str\u00e1nka nastaven\u00ed \u0161pan\u011blsk\u00e9 kl\u00e1vesnice" }, + "expand": { + "message": "Rozbalit" + }, + "expand_candidates": { + "message": "rozbalit seznam kandid\u00e1t\u016f" + }, "fi_fin_settings_page": { "message": "Str\u00e1nka nastaven\u00ed finsk\u00e9 kl\u00e1vesnice" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Str\u00e1nka nastaven\u00ed irsk\u00e9 kl\u00e1vesnice" }, + "ignore_correction": { + "message": "Ignorovat opravu pro" + }, "il_heb_settings_page": { "message": "Str\u00e1nka nastaven\u00ed hebrejsk\u00e9 kl\u00e1vesnice" }, @@ -2847,7 +2859,7 @@ "message": "Rumunsk\u00e1 kl\u00e1vesnice" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Standardn\u00ed rumunsk\u00e1 kl\u00e1vesnice" }, "keyboard_russian": { "message": "Rusk\u00e1 kl\u00e1vesnice" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Str\u00e1nka nastaven\u00ed \u0161v\u00e9dsk\u00e9 kl\u00e1vesnice" }, + "settings": { + "message": "Nastaven\u00ed" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Zobrazovat n\u00e1vrhy korejsk\u00e9ho p\u00edsma" }, + "shrink_candidates": { + "message": "sbalit seznam kandid\u00e1t\u016f" + }, "si_slv_settings_page": { "message": "Str\u00e1nka nastaven\u00ed slovinsk\u00e9 kl\u00e1vesnice" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Odstranit vybran\u00e9" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Ulo\u017eit" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/da/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/da/messages.json index 8543fe3..f928550 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/da/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/da/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "F\u00f8j til personlig ordbog" + }, "advanced": { "message": "Avanceret" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Side med indstillinger for spansk tastatur" }, + "expand": { + "message": "Udvid" + }, + "expand_candidates": { + "message": "udvid kandidatlisten" + }, "fi_fin_settings_page": { "message": "Side med indstillinger for finsk tastatur" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Side med indstillinger for irsk tastatur" }, + "ignore_correction": { + "message": "Ignorer rettelsen af" + }, "il_heb_settings_page": { "message": "Side med indstillinger for hebraisk tastatur" }, @@ -2847,7 +2859,7 @@ "message": "Rum\u00e6nsk tastatur" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rum\u00e6nsk standardtastatur" }, "keyboard_russian": { "message": "Russisk tastatur" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Side med indstillinger for svensk tastatur" }, + "settings": { + "message": "Indstillinger" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Vis forslag p\u00e5 hangul" }, + "shrink_candidates": { + "message": "g\u00f8r kandidatlisten mindre" + }, "si_slv_settings_page": { "message": "Side med indstillinger for slovensk tastatur" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Fjern markering" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Gem" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/de/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/de/messages.json index 22eda943..9d8bf655 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/de/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/de/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "In pers\u00f6nliches W\u00f6rterbuch aufnehmen" + }, "advanced": { "message": "Erweitert" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Seite mit Einstellungen f\u00fcr spanische Tastatur" }, + "expand": { + "message": "Maximieren" + }, + "expand_candidates": { + "message": "Kandidatenliste maximieren" + }, "fi_fin_settings_page": { "message": "Seite mit Einstellungen f\u00fcr finnische Tastatur" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Seite mit Einstellungen f\u00fcr irische Tastatur" }, + "ignore_correction": { + "message": "Korrektur ignorieren f\u00fcr" + }, "il_heb_settings_page": { "message": "Seite mit Einstellungen f\u00fcr hebr\u00e4ische Tastatur" }, @@ -2847,7 +2859,7 @@ "message": "Rum\u00e4nische Tastatur" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rum\u00e4nische Standardtastatur" }, "keyboard_russian": { "message": "Russische Tastatur" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Seite mit Einstellungen f\u00fcr schwedische Tastatur" }, + "settings": { + "message": "Einstellungen" + }, "shift": { "message": "Umschalttaste" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Hangul-Vorschl\u00e4ge anzeigen" }, + "shrink_candidates": { + "message": "Kandidatenliste minimieren" + }, "si_slv_settings_page": { "message": "Seite mit Einstellungen f\u00fcr slowenische Tastatur" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Auswahl entfernen" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Speichern" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/el/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/el/messages.json index f274d422..58b4d65 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/el/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/el/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03c3\u03c4\u03bf \u03c0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03cc \u03bb\u03b5\u03be\u03b9\u03ba\u03cc" + }, "advanced": { "message": "\u03a3\u03cd\u03bd\u03b8\u03b5\u03c4\u03b5\u03c2" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03b9\u03c3\u03c0\u03b1\u03bd\u03b9\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, + "expand": { + "message": "\u0391\u03bd\u03ac\u03c0\u03c4\u03c5\u03be\u03b7" + }, + "expand_candidates": { + "message": "\u03b1\u03bd\u03ac\u03c0\u03c4\u03c5\u03be\u03b7 \u03bb\u03af\u03c3\u03c4\u03b1\u03c2 \u03c5\u03c0\u03bf\u03c8\u03ae\u03c6\u03b9\u03c9\u03bd" + }, "fi_fin_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03c6\u03b9\u03bd\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03b9\u03c1\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, + "ignore_correction": { + "message": "\u03a0\u03b1\u03c1\u03ac\u03b2\u03bb\u03b5\u03c8\u03b7 \u03b4\u03b9\u03cc\u03c1\u03b8\u03c9\u03c3\u03b7\u03c2 \u03b3\u03b9\u03b1" + }, "il_heb_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03b5\u03b2\u03c1\u03b1\u03ca\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, @@ -2847,7 +2859,7 @@ "message": "\u03a0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03bf \u03bc\u03b5 \u03c1\u03bf\u03c5\u03bc\u03b1\u03bd\u03b9\u03ba\u03bf\u03cd\u03c2 \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b5\u03c2" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u03a4\u03c5\u03c0\u03b9\u03ba\u03cc \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03bf \u03a1\u03bf\u03c5\u03bc\u03b1\u03bd\u03b9\u03ba\u03ce\u03bd" }, "keyboard_russian": { "message": "\u03a0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03cc\u03b3\u03b9\u03bf \u03bc\u03b5 \u03c1\u03c9\u03c3\u03b9\u03ba\u03bf\u03cd\u03c2 \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03b5\u03c2" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03c3\u03bf\u03c5\u03b7\u03b4\u03b9\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, + "settings": { + "message": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0395\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b7 \u03c0\u03c1\u03bf\u03c4\u03ac\u03c3\u03b5\u03c9\u03bd \u03a7\u03b1\u03bd\u03b3\u03ba\u03bf\u03cd\u03bb" }, + "shrink_candidates": { + "message": "\u03c3\u03cd\u03bc\u03c0\u03c4\u03c5\u03be\u03b7 \u03bb\u03af\u03c3\u03c4\u03b1\u03c2 \u03c5\u03c0\u03bf\u03c8\u03ae\u03c6\u03b9\u03c9\u03bd" + }, "si_slv_settings_page": { "message": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03af\u03bf\u03c5 \u03c3\u03bb\u03bf\u03b2\u03b5\u03bd\u03b9\u03ba\u03ce\u03bd \u03c7\u03b1\u03c1\u03b1\u03ba\u03c4\u03ae\u03c1\u03c9\u03bd" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u039a\u03b1\u03c4\u03ac\u03c1\u03b3\u03b7\u03c3\u03b7 \u03b5\u03c0\u03b9\u03bb\u03b5\u03b3\u03bc\u03ad\u03bd\u03c9\u03bd" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/en/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/en/messages.json index 564113a..724c42c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/en/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/en/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Add to personal dictionary" + }, "advanced": { "message": "Advanced" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Spanish Keyboard Settings Page" }, + "expand": { + "message": "Expand" + }, + "expand_candidates": { + "message": "expand candidate list" + }, "fi_fin_settings_page": { "message": "Finnish Keyboard Settings Page" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Irish Keyboard Settings Page" }, + "ignore_correction": { + "message": "Ignore correction for" + }, "il_heb_settings_page": { "message": "Hebrew Keyboard Settings Page" }, @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Swedish Keyboard Settings Page" }, + "settings": { + "message": "Settings" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Show Hangul suggestions" }, + "shrink_candidates": { + "message": "shrink candidate list" + }, "si_slv_settings_page": { "message": "Slovenian Keyboard Settings Page" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Remove Selected" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Save" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/en_GB/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/en_GB/messages.json index ecec283..90bf9183 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/en_GB/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/en_GB/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Add to personal dictionary" + }, "advanced": { "message": "Advanced" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Spanish Keyboard Settings Page" }, + "expand": { + "message": "Expand" + }, + "expand_candidates": { + "message": "expand candidate list" + }, "fi_fin_settings_page": { "message": "Finnish Keyboard Settings Page" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Irish Keyboard Settings Page" }, + "ignore_correction": { + "message": "Ignore correction for" + }, "il_heb_settings_page": { "message": "Hebrew Keyboard Settings Page" }, @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Swedish Keyboard Settings Page" }, + "settings": { + "message": "Settings" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Show Hangul suggestions" }, + "shrink_candidates": { + "message": "shrink candidate list" + }, "si_slv_settings_page": { "message": "Slovenian Keyboard Settings Page" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Remove Selected" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Save" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/es/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/es/messages.json index 112ab832..767ae62 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/es/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/es/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "A\u00f1adir a diccionario personal" + }, "advanced": { "message": "Avanzada" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado espa\u00f1ol" }, + "expand": { + "message": "Ampliar" + }, + "expand_candidates": { + "message": "mostrar lista de candidatos" + }, "fi_fin_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado fin\u00e9s" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado irland\u00e9s" }, + "ignore_correction": { + "message": "Ignorar correcci\u00f3n de" + }, "il_heb_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado hebreo" }, @@ -2847,7 +2859,7 @@ "message": "Teclado rumano" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Teclado rumano est\u00e1ndar" }, "keyboard_russian": { "message": "Teclado ruso" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado sueco" }, + "settings": { + "message": "Configuraci\u00f3n" + }, "shift": { "message": "may\u00fas" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostrar sugerencias de hangul" }, + "shrink_candidates": { + "message": "contraer lista de candidatos" + }, "si_slv_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado esloveno" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Eliminar selecci\u00f3n" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Guardar" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/es_419/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/es_419/messages.json index 84eabf2..ab90857 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/es_419/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/es_419/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Agregar a diccionario personal" + }, "advanced": { "message": "Configuraci\u00f3n avanzada" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado espa\u00f1ol" }, + "expand": { + "message": "Expandir" + }, + "expand_candidates": { + "message": "ampliar lista de candidatos" + }, "fi_fin_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado fin\u00e9s" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado irland\u00e9s" }, + "ignore_correction": { + "message": "Ignorar correcci\u00f3n de" + }, "il_heb_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado hebreo" }, @@ -2847,7 +2859,7 @@ "message": "Teclado rumano" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Teclado est\u00e1ndar rumano" }, "keyboard_russian": { "message": "Teclado ruso" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado sueco" }, + "settings": { + "message": "Configuraci\u00f3n" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostrar sugerencias en hangul" }, + "shrink_candidates": { + "message": "reducir lista de candidatos" + }, "si_slv_settings_page": { "message": "P\u00e1gina de configuraci\u00f3n del teclado esloveno" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Eliminar selecci\u00f3n" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Guardar" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/et/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/et/messages.json index 7fd017e..d45b93f 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/et/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/et/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Isiklikku s\u00f5nastikku lisamine" + }, "advanced": { "message": "T\u00e4psemad" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Hispaania klaviatuuri seadete leht" }, + "expand": { + "message": "Laienda" + }, + "expand_candidates": { + "message": "laienda kandidaatide loendit" + }, "fi_fin_settings_page": { "message": "Soome klaviatuuri seadete leht" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Iiri klaviatuuri seadete leht" }, + "ignore_correction": { + "message": "Ignoreeri parandust:" + }, "il_heb_settings_page": { "message": "Heebrea klaviatuuri seadete leht" }, @@ -2847,7 +2859,7 @@ "message": "Rumeenia klaviatuur" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumeenia standardne klaviatuur" }, "keyboard_russian": { "message": "Vene klaviatuur" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Rootsi klaviatuuri seadete leht" }, + "settings": { + "message": "Seaded" + }, "shift": { "message": "t\u00f5stuklahv" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Kuva hanguli soovitused" }, + "shrink_candidates": { + "message": "kahanda kandidaatide loendit" + }, "si_slv_settings_page": { "message": "Sloveenia klaviatuuri seadete leht" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Eemalda valitud" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Salvesta" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fa/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fa/messages.json index 9d6f584..ee2afa3 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fa/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fa/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0627\u0641\u0632\u0648\u062f\u0646 \u0628\u0647 \u0641\u0631\u0647\u0646\u06af \u0644\u063a\u062a \u0634\u062e\u0635\u06cc" + }, "advanced": { "message": "\u067e\u06cc\u0634\u0631\u0641\u062a\u0647" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0627\u0633\u067e\u0627\u0646\u06cc\u0627\u06cc\u06cc" }, + "expand": { + "message": "\u0628\u0632\u0631\u06af \u06a9\u0631\u062f\u0646" + }, + "expand_candidates": { + "message": "\u0628\u0632\u0631\u06af \u06a9\u0631\u062f\u0646 \u0641\u0647\u0631\u0633\u062a \u067e\u06cc\u0634\u0646\u0647\u0627\u062f\u0627\u062a" + }, "fi_fin_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0641\u0646\u0644\u0627\u0646\u062f\u06cc" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0627\u06cc\u0631\u0644\u0646\u062f\u06cc" }, + "ignore_correction": { + "message": "\u0646\u0627\u062f\u06cc\u062f\u0647 \u06af\u0631\u0641\u062a\u0646 \u062a\u0635\u062d\u06cc\u062d \u0628\u0631\u0627\u06cc" + }, "il_heb_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0639\u0628\u0631\u06cc" }, @@ -2847,7 +2859,7 @@ "message": "\u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0631\u0648\u0645\u0627\u0646\u06cc\u0627\u06cc\u06cc" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f \u0631\u0648\u0645\u0627\u0646\u06cc\u0627\u06cc\u06cc" }, "keyboard_russian": { "message": "\u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0631\u0648\u0633\u06cc" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0633\u0648\u0626\u062f\u06cc" }, + "settings": { + "message": "\u062a\u0646\u0638\u06cc\u0645\u0627\u062a" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0646\u0645\u0627\u06cc\u0634 \u067e\u06cc\u0634\u0646\u0647\u0627\u062f\u0627\u062a \u0647\u0627\u0646\u06af\u0648\u0644" }, + "shrink_candidates": { + "message": "\u06a9\u0648\u0686\u06a9 \u06a9\u0631\u062f\u0646 \u0641\u0647\u0631\u0633\u062a \u067e\u06cc\u0634\u0646\u0647\u0627\u062f\u0627\u062a" + }, "si_slv_settings_page": { "message": "\u0635\u0641\u062d\u0647 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u0635\u0641\u062d\u0647\u200c\u06a9\u0644\u06cc\u062f \u0627\u0633\u0644\u0648\u0648\u0646\u06cc\u0627\u06cc\u06cc" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u062d\u0630\u0641 \u0627\u0646\u062a\u062e\u0627\u0628\u200c\u0634\u062f\u0647\u200c\u0647\u0627" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0630\u062e\u06cc\u0631\u0647" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fi/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fi/messages.json index 4303d5f..3fd23275 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fi/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fi/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Lis\u00e4\u00e4 omaan sanakirjaan" + }, "advanced": { "message": "Lis\u00e4asetukset" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Espanjan n\u00e4pp\u00e4imist\u00f6n asetukset" }, + "expand": { + "message": "Laajenna" + }, + "expand_candidates": { + "message": "laajenna vaihtoehtoluettelo" + }, "fi_fin_settings_page": { "message": "Suomen n\u00e4pp\u00e4imist\u00f6n asetukset" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Irlannin iirinkielisen n\u00e4pp\u00e4imist\u00f6n asetukset" }, + "ignore_correction": { + "message": "\u00c4l\u00e4 korjaa:" + }, "il_heb_settings_page": { "message": "Hepreankielisen n\u00e4pp\u00e4imist\u00f6n asetukset" }, @@ -2847,7 +2859,7 @@ "message": "N\u00e4pp\u00e4imist\u00f6: romania" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Romanialainen vakion\u00e4pp\u00e4imist\u00f6" }, "keyboard_russian": { "message": "N\u00e4pp\u00e4imist\u00f6: ven\u00e4j\u00e4" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Ruotsin n\u00e4pp\u00e4imist\u00f6n asetukset" }, + "settings": { + "message": "Asetukset" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "N\u00e4yt\u00e4 Hangul-ehdotukset" }, + "shrink_candidates": { + "message": "pienenn\u00e4 vaihtoehtoluettelo" + }, "si_slv_settings_page": { "message": "Slovenian n\u00e4pp\u00e4imist\u00f6n asetukset" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Poista valitut" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Tallenna" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fil/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fil/messages.json index d15aad8d6..e7a294a 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fil/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fil/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Idagdag sa personal na diksyunaryo" + }, "advanced": { "message": "Advanced" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Page ng Mga Setting ng Spanish na Keyboard" }, + "expand": { + "message": "Palawakin" + }, + "expand_candidates": { + "message": "palawakin ang listahan ng kandidato" + }, "fi_fin_settings_page": { "message": "Page ng Mga Setting ng Finnish na Keyboard" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Page ng Mga Setting ng Irish na Keyboard" }, + "ignore_correction": { + "message": "Huwag pansinin ang pagwawasto para sa" + }, "il_heb_settings_page": { "message": "Page ng Mga Setting ng Hebrew na Keyboard" }, @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Page ng Mga Setting ng Swedish na Keyboard" }, + "settings": { + "message": "Mga Setting" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Ipakita ang mga suhestyon sa Hangul" }, + "shrink_candidates": { + "message": "paliitin ang listahan ng kandidato" + }, "si_slv_settings_page": { "message": "Page ng Mga Setting ng Slovenian na Keyboard" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Alisin ang Napili" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "I-save" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fr/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fr/messages.json index 59f4cd2..b8dcbab 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/fr/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/fr/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Ajouter au dictionnaire personnel" + }, "advanced": { "message": "Param\u00e8tres avanc\u00e9s" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Page des param\u00e8tres du clavier espagnol" }, + "expand": { + "message": "D\u00e9velopper" + }, + "expand_candidates": { + "message": "d\u00e9velopper la liste des propositions" + }, "fi_fin_settings_page": { "message": "Page des param\u00e8tres du clavier finnois" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Page des param\u00e8tres du clavier irlandais" }, + "ignore_correction": { + "message": "Ignorer la correction pour" + }, "il_heb_settings_page": { "message": "Page des param\u00e8tres du clavier h\u00e9breu" }, @@ -2847,7 +2859,7 @@ "message": "Clavier roumain" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Clavier roumain standard" }, "keyboard_russian": { "message": "Clavier russe" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Page des param\u00e8tres du clavier su\u00e9dois" }, + "settings": { + "message": "Param\u00e8tres" + }, "shift": { "message": "maj" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Afficher les suggestions en hang\u00fbl" }, + "shrink_candidates": { + "message": "r\u00e9duire la liste des propositions" + }, "si_slv_settings_page": { "message": "Page des param\u00e8tres du clavier slov\u00e8ne" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Supprimer la s\u00e9lection" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Enregistrer" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/gu/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/gu/messages.json index 2173ddb..dc80c641 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/gu/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/gu/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0ab5\u0acd\u0aaf\u0a95\u0acd\u0aa4\u0abf\u0a97\u0aa4 \u0ab6\u0aac\u0acd\u0aa6\u0a95\u0acb\u0ab6\u0aae\u0abe\u0a82 \u0a89\u0aae\u0ac7\u0ab0\u0acb" + }, "advanced": { "message": "\u0ab5\u0abf\u0a97\u0aa4\u0ab5\u0abe\u0ab0" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0ab8\u0acd\u0aaa\u0ac7\u0aa8\u0abf\u0ab6 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, + "expand": { + "message": "\u0ab5\u0abf\u0ab8\u0acd\u0aa4\u0ac3\u0aa4 \u0a95\u0ab0\u0acb" + }, + "expand_candidates": { + "message": "\u0a89\u0aae\u0ac7\u0aa6\u0ab5\u0abe\u0ab0\u0acb\u0aa8\u0ac0 \u0ab8\u0ac2\u0a9a\u0abf \u0ab5\u0abf\u0ab8\u0acd\u0aa4\u0ac3\u0aa4 \u0a95\u0ab0\u0acb" + }, "fi_fin_settings_page": { "message": "\u0aab\u0abf\u0aa8\u0abf\u0ab6 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0a86\u0a87\u0ab0\u0abf\u0ab6 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, + "ignore_correction": { + "message": "\u0a86 \u0aae\u0abe\u0a9f\u0ac7\u0aa8\u0abe \u0ab8\u0ac1\u0aa7\u0abe\u0ab0\u0aa8\u0ac7 \u0a85\u0ab5\u0a97\u0aa3\u0acb" + }, "il_heb_settings_page": { "message": "\u0ab9\u0ac0\u0aac\u0acd\u0ab0\u0ac1 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, @@ -2847,7 +2859,7 @@ "message": "\u0ab0\u0acb\u0aae\u0ac7\u0aa8\u0abf\u0aaf\u0aa8 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0ab0\u0acb\u0aae\u0abe\u0aa8\u0abf\u0aaf\u0aa8 \u0aae\u0abe\u0aa8\u0a95 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1" }, "keyboard_russian": { "message": "\u0ab0\u0ab6\u0abf\u0aaf\u0aa8 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0ab8\u0acd\u0ab5\u0ac0\u0aa1\u0abf\u0ab6 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, + "settings": { + "message": "\u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0ab9\u0a82\u0a97\u0ac1\u0ab2 \u0ab8\u0ac2\u0a9a\u0aa8\u0acb \u0aa6\u0ab0\u0acd\u0ab6\u0abe\u0ab5\u0acb" }, + "shrink_candidates": { + "message": "\u0a89\u0aae\u0ac7\u0aa6\u0ab5\u0abe\u0ab0\u0acb\u0aa8\u0ac0 \u0ab8\u0ac2\u0a9a\u0abf \u0ab8\u0a82\u0a95\u0acb\u0a9a\u0abf\u0aa4 \u0a95\u0ab0\u0acb" + }, "si_slv_settings_page": { "message": "\u0ab8\u0acd\u0ab2\u0acb\u0ab5\u0ac7\u0aa8\u0abf\u0aaf\u0aa8 \u0a95\u0ac0\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac3\u0ab7\u0acd\u0aa0" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0aaa\u0ab8\u0a82\u0aa6 \u0a95\u0ab0\u0ac7\u0ab2\u0ac1\u0a82 \u0aa6\u0ac2\u0ab0 \u0a95\u0ab0\u0acb" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0ab8\u0abe\u0a9a\u0ab5\u0acb" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hi/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hi/messages.json index 1c88905c..57e1f6c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hi/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hi/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0935\u094d\u092f\u0915\u094d\u0924\u093f\u0917\u0924 \u0936\u092c\u094d\u0926\u0915\u094b\u0936 \u092e\u0947\u0902 \u091c\u094b\u0921\u093c\u0947\u0902" + }, "advanced": { "message": "\u0909\u0928\u094d\u0928\u0924" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0938\u094d\u200d\u092a\u0947\u0928\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, + "expand": { + "message": "\u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0915\u0930\u0947\u0902" + }, + "expand_candidates": { + "message": "\u0909\u092e\u094d\u092e\u0940\u0926\u0935\u093e\u0930 \u0938\u0942\u091a\u0940 \u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0915\u0930\u0947\u0902" + }, "fi_fin_settings_page": { "message": "\u092b\u093c\u093f\u0928\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0906\u092f\u0930\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, + "ignore_correction": { + "message": "\u0907\u0938\u0915\u0947 \u0932\u093f\u090f \u0938\u0941\u0927\u093e\u0930 \u092a\u0930 \u0927\u094d\u092f\u093e\u0928 \u0928 \u0926\u0947\u0902" + }, "il_heb_settings_page": { "message": "\u0939\u093f\u092c\u094d\u0930\u0942 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, @@ -2847,7 +2859,7 @@ "message": "\u0930\u094b\u092e\u093e\u0928\u093f\u092f\u093e\u0908 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0930\u094b\u092e\u093e\u0928\u093f\u092f\u093e\u0908 \u092e\u093e\u0928\u0915 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" }, "keyboard_russian": { "message": "\u0930\u0942\u0938\u0940 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0938\u094d\u200d\u0935\u0940\u0921\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, + "settings": { + "message": "\u0938\u0947\u091f\u093f\u0902\u0917" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0939\u0902\u0917\u0941\u0932 \u0938\u0941\u091d\u093e\u0935 \u0926\u093f\u0916\u093e\u090f\u0902" }, + "shrink_candidates": { + "message": "\u0909\u092e\u094d\u092e\u0940\u0926\u0935\u093e\u0930 \u0938\u0942\u091a\u0940 \u091b\u094b\u091f\u0940 \u0915\u0930\u0947\u0902" + }, "si_slv_settings_page": { "message": "\u0938\u094d\u200d\u0932\u094b\u0935\u0947\u0928\u093f\u092f\u093e\u0908 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917 \u092a\u0943\u0937\u094d\u200d\u0920" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u091a\u092f\u0928\u093f\u0924 \u0915\u094b \u0928\u093f\u0915\u093e\u0932\u0947\u0902" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0938\u0939\u0947\u091c\u0947\u0902" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hr/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hr/messages.json index f2d5a57..20d6c0e 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hr/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hr/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Dodaj u osobni rje\u010dnik" + }, "advanced": { "message": "Napredno" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Stranica postavki \u0161panjolske tipkovnice" }, + "expand": { + "message": "Pro\u0161iri" + }, + "expand_candidates": { + "message": "pro\u0161iri popis kandidata" + }, "fi_fin_settings_page": { "message": "Stranica postavki finske tipkovnice" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Stranica postavki irske tipkovnice" }, + "ignore_correction": { + "message": "Zanemari ispravak za" + }, "il_heb_settings_page": { "message": "Stranica postavki hebrejske tipkovnice" }, @@ -2847,7 +2859,7 @@ "message": "Rumunjska tipkovnica" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumunjska standardna tipkovnica" }, "keyboard_russian": { "message": "Ruska tipkovnica" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Stranica postavki \u0161vedske tipkovnice" }, + "settings": { + "message": "Postavke" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Prika\u017ei prijedloge za hangul" }, + "shrink_candidates": { + "message": "smanji popis kandidata" + }, "si_slv_settings_page": { "message": "Stranica postavki slovenske tipkovnice" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Ukloni odabrano" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Spremi" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hu/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hu/messages.json index 4f49508f..3bdb3d4d 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/hu/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/hu/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Hozz\u00e1ad\u00e1s a szem\u00e9lyes sz\u00f3t\u00e1rhoz" + }, "advanced": { "message": "Halad\u00f3" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Spanyol billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, + "expand": { + "message": "Kibont\u00e1s" + }, + "expand_candidates": { + "message": "javaslati lista kibont\u00e1sa" + }, "fi_fin_settings_page": { "message": "Finn billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u00cdr billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, + "ignore_correction": { + "message": "Jav\u00edt\u00e1s mell\u0151z\u00e9se enn\u00e9l a sz\u00f3n\u00e1l:" + }, "il_heb_settings_page": { "message": "H\u00e9ber billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, @@ -2847,7 +2859,7 @@ "message": "Rom\u00e1n billenty\u0171zet" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Hagyom\u00e1nyos rom\u00e1n billenty\u0171zet" }, "keyboard_russian": { "message": "Orosz billenty\u0171zet" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Sv\u00e9d billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, + "settings": { + "message": "Be\u00e1ll\u00edt\u00e1sok" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Hanguljavaslatok megjelen\u00edt\u00e9se" }, + "shrink_candidates": { + "message": "javaslati lista \u00f6sszecsuk\u00e1sa" + }, "si_slv_settings_page": { "message": "Szlov\u00e9n billenty\u0171zet be\u00e1ll\u00edt\u00e1sainak oldala" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Kijel\u00f6lt(ek) elt\u00e1vol\u00edt\u00e1sa" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Ment\u00e9s" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/id/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/id/messages.json index 45d5077..46234451 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/id/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/id/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Tambahkan ke kamus pribadi" + }, "advanced": { "message": "Lanjutan" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Laman Setelan Keyboard Spanyol" }, + "expand": { + "message": "Luaskan" + }, + "expand_candidates": { + "message": "luaskan daftar calon" + }, "fi_fin_settings_page": { "message": "Laman Setelan Keyboard Suomi" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Laman Setelan Keyboard Irlandia" }, + "ignore_correction": { + "message": "Abaikan koreksi untuk" + }, "il_heb_settings_page": { "message": "Laman Setelan Keyboard Ibrani" }, @@ -2847,7 +2859,7 @@ "message": "Keyboard Rumania" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Keyboard standar Rumania" }, "keyboard_russian": { "message": "Keyboard Rusia" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Laman Setelan Keyboard Swensk" }, + "settings": { + "message": "Setelan" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Tampilkan saran Hangul" }, + "shrink_candidates": { + "message": "ciutkan daftar calon" + }, "si_slv_settings_page": { "message": "Laman Setelan Keyboard Sloven" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Hapus yang Dipilih" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Simpan" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/it/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/it/messages.json index 654ee0e1..b11c616 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/it/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/it/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Aggiungi al dizionario personale" + }, "advanced": { "message": "Avanzata" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Pagina Impostazioni tastiera Spagnolo" }, + "expand": { + "message": "Espandi" + }, + "expand_candidates": { + "message": "espandi elenco candidati" + }, "fi_fin_settings_page": { "message": "Pagina Impostazioni tastiera Finlandese" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Pagina Impostazioni tastiera Irlandese" }, + "ignore_correction": { + "message": "Ignora correzione di:" + }, "il_heb_settings_page": { "message": "Pagina Impostazioni tastiera Ebraico" }, @@ -2847,7 +2859,7 @@ "message": "Tastiera Rumeno" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Tastiera Rumeno standard" }, "keyboard_russian": { "message": "Tastiera Russo" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Pagina Impostazioni tastiera Svedese" }, + "settings": { + "message": "Impostazioni" + }, "shift": { "message": "maiusc" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostra suggerimenti in hangul" }, + "shrink_candidates": { + "message": "comprimi elenco candidati" + }, "si_slv_settings_page": { "message": "Pagina Impostazioni tastiera Sloveno" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Rimuovi selezionati" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Salva" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/iw/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/iw/messages.json index 5c2249f..205cc72 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/iw/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/iw/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u05d4\u05d5\u05e1\u05e3 \u05dc\u05de\u05d9\u05dc\u05d5\u05df \u05d4\u05d0\u05d9\u05e9\u05d9" + }, "advanced": { "message": "\u05de\u05ea\u05e7\u05d3\u05dd" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05e1\u05e4\u05e8\u05d3\u05d9\u05ea" }, + "expand": { + "message": "\u05d4\u05e8\u05d7\u05d1" + }, + "expand_candidates": { + "message": "\u05d4\u05e8\u05d7\u05d1 \u05d0\u05ea \u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05d4\u05e6\u05e2\u05d5\u05ea" + }, "fi_fin_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05e4\u05d9\u05e0\u05d9\u05ea" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05d0\u05d9\u05e8\u05d9\u05ea" }, + "ignore_correction": { + "message": "\u05d4\u05ea\u05e2\u05dc\u05dd \u05de\u05ea\u05d9\u05e7\u05d5\u05df \u05e9\u05dc" + }, "il_heb_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05e2\u05d1\u05e8\u05d9\u05ea" }, @@ -2847,7 +2859,7 @@ "message": "\u05de\u05e7\u05dc\u05d3\u05ea \u05e8\u05d5\u05de\u05e0\u05d9\u05ea" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u05de\u05e7\u05dc\u05d3\u05ea \u05e8\u05d5\u05de\u05e0\u05d9\u05ea \u05e8\u05d2\u05d9\u05dc\u05d4" }, "keyboard_russian": { "message": "\u05de\u05e7\u05dc\u05d3\u05ea \u05e8\u05d5\u05e1\u05d9\u05ea" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05e9\u05d5\u05d5\u05d3\u05d9\u05ea" }, + "settings": { + "message": "\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u200f\u05d4\u05e6\u05d2\u05ea \u05d4\u05e6\u05e2\u05d5\u05ea \u05d1-Hangul" }, + "shrink_candidates": { + "message": "\u05db\u05d5\u05d5\u05e5 \u05d0\u05ea \u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05d4\u05e6\u05e2\u05d5\u05ea" + }, "si_slv_settings_page": { "message": "\u05d3\u05e3 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05de\u05e7\u05dc\u05d3\u05ea \u05e1\u05dc\u05d5\u05d1\u05e0\u05d9\u05ea" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u05d4\u05e1\u05e8 \u05e2\u05e8\u05da \u05e0\u05d1\u05d7\u05e8" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u05e9\u05de\u05d5\u05e8" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ja/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ja/messages.json index eef51fbb..a1beb42 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ja/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ja/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u30e6\u30fc\u30b6\u30fc\u8f9e\u66f8\u306b\u8ffd\u52a0" + }, "advanced": { "message": "\u8a73\u7d30\u8a2d\u5b9a" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u30b9\u30da\u30a4\u30f3\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, + "expand": { + "message": "\u5c55\u958b" + }, + "expand_candidates": { + "message": "\u5019\u88dc\u306e\u6570\u3092\u5897\u3084\u3059" + }, "fi_fin_settings_page": { "message": "\u30d5\u30a3\u30f3\u30e9\u30f3\u30c9\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u30a2\u30a4\u30eb\u30e9\u30f3\u30c9\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, + "ignore_correction": { + "message": "\u6b21\u306e\u8a9e\u306f\u4fee\u6b63\u3057\u306a\u3044:" + }, "il_heb_settings_page": { "message": "\u30d8\u30d6\u30e9\u30a4\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, @@ -2847,7 +2859,7 @@ "message": "\u30eb\u30fc\u30de\u30cb\u30a2\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u30eb\u30fc\u30de\u30cb\u30a2\u8a9e\u6a19\u6e96\u30ad\u30fc\u30dc\u30fc\u30c9" }, "keyboard_russian": { "message": "\u30ed\u30b7\u30a2\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u30b9\u30a6\u30a7\u30fc\u30c7\u30f3\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, + "settings": { + "message": "\u8a2d\u5b9a" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u30cf\u30f3\u30b0\u30eb\u5019\u88dc\u8868\u793a" }, + "shrink_candidates": { + "message": "\u5019\u88dc\u306e\u6570\u3092\u6e1b\u3089\u3059" + }, "si_slv_settings_page": { "message": "\u30b9\u30ed\u30d9\u30cb\u30a2\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u30da\u30fc\u30b8" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u9078\u629e\u9805\u76ee\u3092\u524a\u9664" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u4fdd\u5b58" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/kn/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/kn/messages.json index f23a26a..d976d11f 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/kn/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/kn/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0cb5\u0cc6\u0cd6\u0caf\u0c95\u0ccd\u0ca4\u0cbf\u0c95 \u0ca8\u0cbf\u0c98\u0c82\u0c9f\u0cbf\u0c97\u0cc6 \u0cb8\u0cc6\u0cd5\u0cb0\u0cbf\u0cb8\u0cbf" + }, "advanced": { "message": "\u0cb8\u0cc1\u0ca7\u0cbe\u0cb0\u0cbf\u0ca4" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0cb8\u0ccd\u0caa\u0ccd\u0caf\u0cbe\u0ca8\u0cbf\u0cb7\u0ccd \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, + "expand": { + "message": "\u0cb5\u0cbf\u0cb8\u0ccd\u0ca4\u0cb0\u0cbf\u0cb8\u0cbf" + }, + "expand_candidates": { + "message": "\u0c85\u0cad\u0ccd\u0caf\u0cb0\u0ccd\u0ca5\u0cbf \u0caa\u0c9f\u0ccd\u0c9f\u0cbf\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0cb5\u0cbf\u0cb8\u0ccd\u0ca4\u0cb0\u0cbf\u0cb8\u0cbf" + }, "fi_fin_settings_page": { "message": "\u0cab\u0cbf\u0ca8\u0ccd\u0ca8\u0cbf\u0cb6\u0ccd \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0c90\u0cb0\u0cbf\u0cb7\u0ccd \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, + "ignore_correction": { + "message": "\u0c87\u0ca6\u0c95\u0ccd\u0c95\u0cbe\u0c97\u0cbf \u0cb8\u0cb0\u0cbf\u0caa\u0ca1\u0cbf\u0cb8\u0cc1\u0cb5\u0cbf\u0c95\u0cc6\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca8\u0cbf\u0cb0\u0ccd\u0cb2\u0c95\u0ccd\u0cb7\u0cbf\u0cb8\u0cbf" + }, "il_heb_settings_page": { "message": "\u0cb9\u0cbf\u0cac\u0ccd\u0cb0\u0cc2 \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, @@ -2847,7 +2859,7 @@ "message": "\u0cb0\u0cca\u0cae\u0cc7\u0ca8\u0cbf\u0caf\u0ca8\u0ccd \u0c95\u0cc0\u0cac\u0ccb\u0cb0\u0ccd\u0ca1\u0ccd" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0cb0\u0cc6\u0cc2\u0cae\u0cc6\u0cd5\u0ca8\u0cbf\u0caf\u0ca8\u0ccd \u0caa\u0ccd\u0cb0\u0cae\u0cbe\u0ca3\u0cbf\u0ca4 \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd" }, "keyboard_russian": { "message": "\u0cb0\u0cb7\u0ccd\u0caf\u0ca8\u0ccd \u0c95\u0cc0\u0cac\u0ccb\u0cb0\u0ccd\u0ca1\u0ccd" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0cb8\u0ccd\u0cb5\u0cbf\u0cd5\u0ca1\u0cbf\u0cb6\u0ccd \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, + "settings": { + "message": "\u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3\u0cc1" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0cb9\u0c82\u0c97\u0cc1\u0cb2\u0ccd \u0cb8\u0cb2\u0cb9\u0cc6\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca4\u0cc6\u0cc2\u0cd5\u0cb0\u0cbf\u0cb8\u0cbf" }, + "shrink_candidates": { + "message": "\u0c85\u0cad\u0ccd\u0caf\u0cb0\u0ccd\u0ca5\u0cbf \u0caa\u0c9f\u0ccd\u0c9f\u0cbf\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0c95\u0cc1\u0c97\u0ccd\u0c97\u0cbf\u0cb8\u0cbf" + }, "si_slv_settings_page": { "message": "\u0cb8\u0ccd\u0cb2\u0cc6\u0cc2\u0cd5\u0cb5\u0cc6\u0cd5\u0ca8\u0cbf\u0caf\u0ca8\u0ccd \u0c95\u0cbf\u0cd5\u0cac\u0cc6\u0cc2\u0cd5\u0cb0\u0ccd\u0ca1\u0ccd \u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0cc1\u0c9f" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0c86\u0caf\u0ccd\u0c95\u0cc6\u0cae\u0cbe\u0ca1\u0cb2\u0cbe\u0c97\u0cbf\u0cb0\u0cc1\u0cb5\u0cc1\u0ca6\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca4\u0cc6\u0c97\u0cc6\u0ca6\u0cc1\u0cb9\u0cbe\u0c95\u0cbf" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0c89\u0cb3\u0cbf\u0cb8\u0cc1" }, @@ -3282,7 +3303,7 @@ "message": "\u0ca7\u0ccd\u0cb5\u0ca8\u0cbf \u0c87\u0ca8\u0ccd\u200c\u0caa\u0cc1\u0c9f\u0ccd \u0c9f\u0cc2\u0cb2\u0ccd \u0c85\u0ca8\u0ccd\u0ca8\u0cc1 \u0c86\u0cab\u0ccd \u0cae\u0cbe\u0ca1\u0cbf" }, "voice_turn_on": { - "message": "\u0ca7\u0ccd\u0cb5\u0ca8\u0cbf \u0c87\u0ca8\u0ccd\u200c\u0caa\u0cc1\u0c9f\u0ccd \u0c9f\u0cc2\u0cb2\u0ccd \u0c85\u0ca8\u0ccd\u0ca8\u0cc1 \u0c86\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf" + "message": "\u0ca7\u0ccd\u0cb5\u0ca8\u0cbf \u0c87\u0ca8\u0ccd\u200c\u0caa\u0cc1\u0c9f\u0ccd \u0caa\u0cb0\u0cbf\u0c95\u0cb0\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1 \u0c86\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf" }, "wait": { "message": "\u0c95\u0cbe\u0caf\u0cbf\u0cb0\u0cbf"
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ko/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ko/messages.json index 9fe890d8..20a139d 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ko/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ko/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\uac1c\uc778 \uc0ac\uc804\uc5d0 \ucd94\uac00" + }, "advanced": { "message": "\uace0\uae09" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\uc2a4\ud398\uc778\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, + "expand": { + "message": "\ud3bc\uce58\uae30" + }, + "expand_candidates": { + "message": "\ud6c4\ubcf4 \ubaa9\ub85d \ud3bc\uce58\uae30" + }, "fi_fin_settings_page": { "message": "\ud540\ub780\ub4dc\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\uc544\uc77c\ub79c\ub4dc\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, + "ignore_correction": { + "message": "\uc790\ub3d9 \uc218\uc815 \uae30\ub2a5 \ubb34\uc2dc" + }, "il_heb_settings_page": { "message": "\ud788\ube0c\ub9ac\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, @@ -2847,7 +2859,7 @@ "message": "\ub8e8\ub9c8\ub2c8\uc544\uc5b4 \ud0a4\ubcf4\ub4dc" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\ub8e8\ub9c8\ub2c8\uc544 \ud45c\uc900 \ud0a4\ubcf4\ub4dc" }, "keyboard_russian": { "message": "\ub7ec\uc2dc\uc544\uc5b4 \ud0a4\ubcf4\ub4dc" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\uc2a4\uc6e8\ub374\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, + "settings": { + "message": "\uc124\uc815" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\ud55c\uae00 \ucd94\ucc9c \ud56d\ubaa9 \ud45c\uc2dc" }, + "shrink_candidates": { + "message": "\ud6c4\ubcf4 \ubaa9\ub85d \uc228\uae30\uae30" + }, "si_slv_settings_page": { "message": "\uc2ac\ub85c\ubca0\ub2c8\uc544\uc5b4 \ud0a4\ubcf4\ub4dc \uc124\uc815 \ud398\uc774\uc9c0" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\uc120\ud0dd \ud56d\ubaa9 \uc0ad\uc81c" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\uc800\uc7a5" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/lt/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/lt/messages.json index 60cdb5f9..57ebfd7 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/lt/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/lt/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Prid\u0117ti prie asmeninio \u017eodyno" + }, "advanced": { "message": "I\u0161pl\u0117stiniai" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Ispani\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, + "expand": { + "message": "I\u0161skleisti" + }, + "expand_candidates": { + "message": "i\u0161skleisti variant\u0173 s\u0105ra\u0161\u0105" + }, "fi_fin_settings_page": { "message": "Suomi\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Airi\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, + "ignore_correction": { + "message": "Ignoruoti pataisym\u0105" + }, "il_heb_settings_page": { "message": "Hebraji\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, @@ -2847,7 +2859,7 @@ "message": "Rumuni\u0161ka klaviat\u016bra" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumun\u0173 k. standartin\u0117 klaviat\u016bra" }, "keyboard_russian": { "message": "Rusi\u0161ka klaviat\u016bra" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0160vedi\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, + "settings": { + "message": "Nustatymai" + }, "shift": { "message": "klavi\u0161as \u201eshift\u201c" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Rodyti hangul pasi\u016blymus" }, + "shrink_candidates": { + "message": "sutraukti variant\u0173 s\u0105ra\u0161\u0105" + }, "si_slv_settings_page": { "message": "Slov\u0117ni\u0161kos klaviat\u016bros nustatym\u0173 puslapis" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Pa\u0161alinti pasirinktus" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "I\u0161saugoti" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/lv/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/lv/messages.json index dc4b34f..7d90fc9 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/lv/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/lv/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Pievienot personiskajai v\u0101rdn\u012bcai" + }, "advanced": { "message": "Papildu" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Sp\u0101\u0146u valodas tastat\u016bras iestat\u012bjumu lapa" }, + "expand": { + "message": "Izv\u0113rst" + }, + "expand_candidates": { + "message": "papla\u0161in\u0101t kandid\u0101tu sarakstu" + }, "fi_fin_settings_page": { "message": "Somu valodas tastat\u016bras iestat\u012bjumu lapa" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u012aru valodas tastat\u016bras iestat\u012bjumu lapa" }, + "ignore_correction": { + "message": "Ignor\u0113t labojumu v\u0101rdam" + }, "il_heb_settings_page": { "message": "Ebreju valodas tastat\u016bras iestat\u012bjumu lapa" }, @@ -2847,7 +2859,7 @@ "message": "Rum\u0101\u0146u valodas tastat\u016bra" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rum\u0101\u0146u standarta tastat\u016bra" }, "keyboard_russian": { "message": "Krievu valodas tastat\u016bra" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Zviedru valodas tastat\u016bras iestat\u012bjumu lapa" }, + "settings": { + "message": "Iestat\u012bjumi" + }, "shift": { "message": "tausti\u0146\u0161 Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "R\u0101d\u012bt ieteikumus korejie\u0161u valod\u0101" }, + "shrink_candidates": { + "message": "sa\u0161aurin\u0101t kandid\u0101tu sarakstu" + }, "si_slv_settings_page": { "message": "Slov\u0113\u0146u valodas tastat\u016bras iestat\u012bjumu lapa" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "No\u0146emt atlas\u012btos" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Saglab\u0101t" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ml/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ml/messages.json index 2d2f356..5860bc5 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ml/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ml/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0d35\u0d4d\u0d2f\u0d15\u0d4d\u0d24\u0d3f\u0d17\u0d24 \u0d28\u0d3f\u0d18\u0d23\u0d4d\u0d1f\u0d41\u0d35\u0d3f\u0d7d \u0d1a\u0d47\u0d7c\u0d15\u0d4d\u0d15\u0d41\u0d15" + }, "advanced": { "message": "\u0d35\u0d3f\u0d2a\u0d41\u0d32\u0d2e\u0d3e\u0d2f" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0d38\u0d4d\u200c\u0d2a\u0d3e\u0d28\u0d3f\u0d37\u0d4d \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, + "expand": { + "message": "\u0d35\u0d3f\u0d2a\u0d41\u0d32\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" + }, + "expand_candidates": { + "message": "\u0d15\u0d3e\u0d7b\u0d21\u0d3f\u0d21\u0d47\u0d31\u0d4d\u0d31\u0d4d \u0d32\u0d3f\u0d38\u0d4d\u200c\u0d31\u0d4d\u0d31\u0d4d \u0d35\u0d3f\u0d2a\u0d41\u0d32\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" + }, "fi_fin_settings_page": { "message": "\u0d2b\u0d3f\u0d28\u0d4d\u0d28\u0d3f\u0d37\u0d4d \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0d10\u0d31\u0d3f\u0d37\u0d4d \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, + "ignore_correction": { + "message": "\u0d0e\u0d28\u0d4d\u0d28\u0d24\u0d3f\u0d28\u0d41\u0d33\u0d4d\u0d33 \u0d24\u0d3f\u0d30\u0d41\u0d24\u0d4d\u0d24\u0d7d \u0d05\u0d35\u0d17\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" + }, "il_heb_settings_page": { "message": "\u0d39\u0d40\u0d2c\u0d4d\u0d30\u0d41 \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, @@ -2847,7 +2859,7 @@ "message": "\u0d31\u0d4a\u0d2e\u0d3e\u0d28\u0d3f\u0d2f\u0d28\u0d4d\u200d \u0d15\u0d40\u0d2c\u0d4b\u0d30\u0d4d\u200d\u0d21\u0d4d" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0d31\u0d4a\u0d2e\u0d3e\u0d28\u0d3f\u0d2f\u0d7b \u0d05\u0d1f\u0d3f\u0d38\u0d4d\u0d25\u0d3e\u0d28 \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d" }, "keyboard_russian": { "message": "\u0d31\u0d37\u0d4d\u0d2f\u0d28\u0d4d\u200d \u0d15\u0d40\u0d2c\u0d4b\u0d30\u0d4d\u200d\u0d21\u0d4d" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0d38\u0d4d\u0d35\u0d40\u0d21\u0d3f\u0d37\u0d4d \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, + "settings": { + "message": "\u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23\u0d02" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0d39\u0d02\u0d17\u0d41\u0d7d \u0d28\u0d3f\u0d7c\u0d26\u0d4d\u0d26\u0d47\u0d36\u0d19\u0d4d\u0d19\u0d7e \u0d15\u0d3e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" }, + "shrink_candidates": { + "message": "\u0d15\u0d3e\u0d7b\u0d21\u0d3f\u0d21\u0d47\u0d31\u0d4d\u0d31\u0d4d \u0d32\u0d3f\u0d38\u0d4d\u200c\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d41\u0d30\u0d41\u0d15\u0d4d\u0d15\u0d41\u0d15" + }, "si_slv_settings_page": { "message": "\u0d38\u0d4d\u200c\u0d32\u0d4b\u0d35\u0d47\u0d28\u0d3f\u0d2f\u0d7b \u0d15\u0d40\u0d2c\u0d4b\u0d7c\u0d21\u0d4d \u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23 \u0d2a\u0d47\u0d1c\u0d4d" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0d24\u0d3f\u0d30\u0d1e\u0d4d\u0d1e\u0d46\u0d1f\u0d41\u0d24\u0d4d\u0d24\u0d35 \u0d28\u0d40\u0d15\u0d4d\u0d15\u0d02\u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0d38\u0d02\u0d30\u0d15\u0d4d\u0d37\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/mr/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/mr/messages.json index 7728083..f1bd1ba 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/mr/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/mr/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0935\u0948\u092f\u0915\u094d\u0924\u093f\u0915 \u0936\u092c\u094d\u0926\u0915\u094b\u0936\u093e\u0924 \u091c\u094b\u0921\u093e" + }, "advanced": { "message": "\u092a\u094d\u0930\u0917\u0924" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0938\u094d\u092a\u0945\u0928\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, + "expand": { + "message": "\u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0915\u0930\u093e" + }, + "expand_candidates": { + "message": "\u0909\u092e\u0947\u0926\u0935\u093e\u0930 \u0938\u0942\u091a\u0940 \u0935\u093f\u0938\u094d\u0924\u0943\u0924 \u0915\u0930\u093e" + }, "fi_fin_settings_page": { "message": "\u092b\u093f\u0928\u094d\u0928\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0906\u092f\u0930\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, + "ignore_correction": { + "message": "\u092f\u093e\u0938\u093e\u0920\u0940 \u0938\u0941\u0927\u093e\u0930\u0923\u0947\u0915\u0921\u0947 \u0926\u0941\u0930\u094d\u0932\u0915\u094d\u0937 \u0915\u0930\u093e" + }, "il_heb_settings_page": { "message": "\u0939\u093f\u092c\u094d\u0930\u0942 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, @@ -2847,7 +2859,7 @@ "message": "\u0930\u094b\u092e\u093e\u0928\u093f\u092f\u0928 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0930\u094b\u092e\u0947\u0928\u093f\u092f\u0928 \u092e\u093e\u0928\u0915 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" }, "keyboard_russian": { "message": "\u0930\u0936\u093f\u092f\u0928 \u0915\u0940\u092c\u094b\u0930\u094d\u0921" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0938\u094d\u0935\u0940\u0921\u093f\u0936 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, + "settings": { + "message": "\u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0939\u0902\u0917\u0941\u0932 \u0938\u0942\u091a\u0928\u093e \u0926\u0930\u094d\u0936\u0935\u093e" }, + "shrink_candidates": { + "message": "\u0909\u092e\u0947\u0926\u0935\u093e\u0930 \u0938\u0942\u091a\u0940 \u0938\u0902\u0915\u094d\u0937\u093f\u092a\u094d\u0924 \u0915\u0930\u093e" + }, "si_slv_settings_page": { "message": "\u0938\u094d\u0932\u094b\u0935\u094d\u0939\u0947\u0928\u093f\u092f\u0928 \u0915\u0940\u092c\u094b\u0930\u094d\u0921 \u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0943\u0937\u094d\u0920" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0928\u093f\u0935\u0921\u0932\u0947\u0932\u0947 \u0915\u093e\u0922\u093e" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u091c\u0924\u0928 \u0915\u0930\u093e" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ms/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ms/messages.json index f1509eb..a8684822c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ms/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ms/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Tambahkan pada kamus peribadi" + }, "advanced": { "message": "Terperinci" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Halaman Tetapan Papan Kekunci Sepanyol" }, + "expand": { + "message": "Kembangkan" + }, + "expand_candidates": { + "message": "kembangkan senarai calon" + }, "fi_fin_settings_page": { "message": "Halaman Tetapan Papan Kekunci Finland" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Halaman Tetapan Papan Kekunci Ireland" }, + "ignore_correction": { + "message": "Abaikan pembetulan untuk" + }, "il_heb_settings_page": { "message": "Halaman Tetapan Papan Kekunci Ibrani" }, @@ -2847,7 +2859,7 @@ "message": "Papan kekunci Romania" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Papan kekunci standard Romania" }, "keyboard_russian": { "message": "Papan kekunci Rusia" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Halaman Tetapan Papan Kekunci Sweden" }, + "settings": { + "message": "Tetapan" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Tunjukkan cadangan Hangul" }, + "shrink_candidates": { + "message": "kecilkan senarai calon" + }, "si_slv_settings_page": { "message": "Halaman Tetapan Papan Kekunci Slovenia" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Alih Keluar Pilihan" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Simpan" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/nb/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/nb/messages.json index 418e3fcc..6b5ce04 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/nb/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/nb/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Legg til i den personlige ordboken" + }, "advanced": { "message": "Avansert" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Innstillinger-side for spansk tastatur" }, + "expand": { + "message": "Vis" + }, + "expand_candidates": { + "message": "vis kandidatlisten" + }, "fi_fin_settings_page": { "message": "Innstillinger-side for finsk tastatur" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Innstillinger-side for irsk tastatur" }, + "ignore_correction": { + "message": "Ignorer korrigering av" + }, "il_heb_settings_page": { "message": "Innstillinger-side for hebraisk tastatur" }, @@ -2847,7 +2859,7 @@ "message": "Rumensk tastatur" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumensk standardtastatur" }, "keyboard_russian": { "message": "Russisk tastatur" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Innstillinger-side for svensk tastatur" }, + "settings": { + "message": "Innstillinger" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Vis foresl\u00e5tte hangul-tegn" }, + "shrink_candidates": { + "message": "skjul kandidatlisten" + }, "si_slv_settings_page": { "message": "Innstillinger-side for slovensk tastatur" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Fjern valgte" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Lagre" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/nl/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/nl/messages.json index bd70257..63de460d 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/nl/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/nl/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Toevoegen aan persoonlijk woordenboek" + }, "advanced": { "message": "Geavanceerd" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Pagina met instellingen voor Spaans toetsenbord" }, + "expand": { + "message": "Uitvouwen" + }, + "expand_candidates": { + "message": "kandidatenlijst uitvouwen" + }, "fi_fin_settings_page": { "message": "Pagina met instellingen voor Fins toetsenbord" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Pagina met instellingen voor Iers toetsenbord" }, + "ignore_correction": { + "message": "Correctie negeren voor" + }, "il_heb_settings_page": { "message": "Pagina met instellingen voor Hebreeuws toetsenbord" }, @@ -2847,7 +2859,7 @@ "message": "Roemeens toetsenbord" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Standaardtoetsenbord voor Roemeens" }, "keyboard_russian": { "message": "Russisch toetsenbord" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Pagina met instellingen voor Zweeds toetsenbord" }, + "settings": { + "message": "Instellingen" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Hangul-suggesties weergeven" }, + "shrink_candidates": { + "message": "kandidatenlijst verkleinen" + }, "si_slv_settings_page": { "message": "Pagina met instellingen voor Sloveens toetsenbord" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Selectie verwijderen" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Opslaan" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pl/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pl/messages.json index b33c1f2..aa9150c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pl/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pl/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Dodaj do s\u0142ownika osobistego" + }, "advanced": { "message": "Zaawansowane" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Strona ustawie\u0144 klawiatury hiszpa\u0144skiej" }, + "expand": { + "message": "Rozwi\u0144" + }, + "expand_candidates": { + "message": "rozwi\u0144 list\u0119 sugestii" + }, "fi_fin_settings_page": { "message": "Strona ustawie\u0144 klawiatury fi\u0144skiej" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Strona ustawie\u0144 klawiatury irlandzkiej" }, + "ignore_correction": { + "message": "Ignoruj korekt\u0119" + }, "il_heb_settings_page": { "message": "Strona ustawie\u0144 klawiatury hebrajskiej" }, @@ -2847,7 +2859,7 @@ "message": "Klawiatura rumu\u0144ska" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Standardowa klawiatura rumu\u0144ska" }, "keyboard_russian": { "message": "Klawiatura rosyjska" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Strona ustawie\u0144 klawiatury szwedzkiej" }, + "settings": { + "message": "Ustawienia" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Wy\u015bwietlaj sugestie w hangulu" }, + "shrink_candidates": { + "message": "zwi\u0144 list\u0119 sugestii" + }, "si_slv_settings_page": { "message": "Strona ustawie\u0144 klawiatury s\u0142owe\u0144skiej" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Usu\u0144 zaznaczone" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Zapisz" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_BR/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_BR/messages.json index 6c63341..3b42b3c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_BR/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_BR/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Adicionar ao dicion\u00e1rio pessoal" + }, "advanced": { "message": "Avan\u00e7ado" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado espanhol" }, + "expand": { + "message": "Expandir" + }, + "expand_candidates": { + "message": "expandir lista de candidatos" + }, "fi_fin_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado finland\u00eas" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado irland\u00eas" }, + "ignore_correction": { + "message": "Ignorar corre\u00e7\u00e3o para" + }, "il_heb_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado hebraico" }, @@ -2847,7 +2859,7 @@ "message": "Teclado romeno" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Teclado romeno padr\u00e3o" }, "keyboard_russian": { "message": "Teclado russo" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado sueco" }, + "settings": { + "message": "Configura\u00e7\u00f5es" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostrar sugest\u00f5es em hangul" }, + "shrink_candidates": { + "message": "encolher lista de candidatos" + }, "si_slv_settings_page": { "message": "P\u00e1gina de configura\u00e7\u00f5es do teclado esloveno" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Remover entradas selecionadas" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Salvar" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_PT/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_PT/messages.json index 6cfe8846..d4bd96e 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_PT/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/pt_PT/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Adicionar ao dicion\u00e1rio pessoal" + }, "advanced": { "message": "Avan\u00e7ada" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado espanhol" }, + "expand": { + "message": "Expandir" + }, + "expand_candidates": { + "message": "expandir lista de candidatos" + }, "fi_fin_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado finland\u00eas" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado irland\u00eas" }, + "ignore_correction": { + "message": "Ignorar corre\u00e7\u00e3o para" + }, "il_heb_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado hebraico" }, @@ -2847,7 +2859,7 @@ "message": "Teclado romeno" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Teclado padr\u00e3o romeno" }, "keyboard_russian": { "message": "Teclado russo" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado sueco" }, + "settings": { + "message": "Defini\u00e7\u00f5es" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Mostrar sugest\u00f5es em hangul" }, + "shrink_candidates": { + "message": "reduzir lista de candidatos" + }, "si_slv_settings_page": { "message": "P\u00e1gina de defini\u00e7\u00f5es do teclado esloveno" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Remover selecionadas" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Guardar" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ro/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ro/messages.json index 585696a7..d156016c 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ro/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ro/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Adaug\u0103 \u00een dic\u021bionarul personal" + }, "advanced": { "message": "Set\u0103ri avansate" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura spaniol\u0103" }, + "expand": { + "message": "Extinde" + }, + "expand_candidates": { + "message": "extinde lista de sugestii" + }, "fi_fin_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura finlandez\u0103" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura irlandez\u0103" }, + "ignore_correction": { + "message": "Ignor\u0103 corectura pentru" + }, "il_heb_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura ebraic\u0103" }, @@ -2847,7 +2859,7 @@ "message": "Tastatur\u0103 rom\u00e2n\u0103" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Tastatur\u0103 rom\u00e2n\u0103 standard" }, "keyboard_russian": { "message": "Tastatur\u0103 rus\u0103" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura suedez\u0103" }, + "settings": { + "message": "Set\u0103ri" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Afi\u0219eaz\u0103 sugestii \u00een Hangul" }, + "shrink_candidates": { + "message": "restr\u00e2nge lista de sugestii" + }, "si_slv_settings_page": { "message": "Pagina de set\u0103ri pentru tastatura sloven\u0103" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Elimin\u0103-le pe cele selectate" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Salveaz\u0103" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ru/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ru/messages.json index c74b2f2..6dfb2d00 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ru/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ru/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c" + }, "advanced": { "message": "\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0441\u043f\u0430\u043d\u0441\u043a\u043e\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438" }, + "expand": { + "message": "\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c" + }, + "expand_candidates": { + "message": "\u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432" + }, "fi_fin_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0444\u0438\u043d\u0441\u043a\u043e\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0440\u043b\u0430\u043d\u0434\u0441\u043a\u043e\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438" }, + "ignore_correction": { + "message": "\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c:" + }, "il_heb_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438 \u043d\u0430 \u0438\u0432\u0440\u0438\u0442\u0435" }, @@ -2847,7 +2859,7 @@ "message": "\u0420\u0443\u043c\u044b\u043d\u0441\u043a\u0430\u044f \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0430" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0440\u0443\u043c\u044b\u043d\u0441\u043a\u0430\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430" }, "keyboard_russian": { "message": "\u0420\u0443\u0441\u0441\u043a\u0430\u044f \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0430" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0448\u0432\u0435\u0434\u0441\u043a\u043e\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438" }, + "settings": { + "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438 \u0434\u043b\u044f \u0445\u0430\u043d\u0433\u044b\u043b\u044f" }, + "shrink_candidates": { + "message": "\u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432" + }, "si_slv_settings_page": { "message": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043b\u043e\u0432\u0435\u043d\u0441\u043a\u043e\u0439 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043a\u0438" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sk/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sk/messages.json index 7fd376d..fb0d7f3 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sk/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sk/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Prida\u0165 do osobn\u00e9ho slovn\u00edka" + }, "advanced": { "message": "Roz\u0161\u00edren\u00e9" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Str\u00e1nka s nastaveniami \u0161panielskej kl\u00e1vesnice" }, + "expand": { + "message": "Rozbali\u0165" + }, + "expand_candidates": { + "message": "rozbali\u0165 zoznam kandid\u00e1tov" + }, "fi_fin_settings_page": { "message": "Str\u00e1nka s nastaveniami f\u00ednskej kl\u00e1vesnice" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Str\u00e1nka s nastaveniami \u00edrskej kl\u00e1vesnice" }, + "ignore_correction": { + "message": "Ignorova\u0165 opravu pre" + }, "il_heb_settings_page": { "message": "Str\u00e1nka s nastaveniami hebrejskej kl\u00e1vesnice" }, @@ -2847,7 +2859,7 @@ "message": "Rumunsk\u00e1 kl\u00e1vesnica" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumunsk\u00e1 \u0161tandardn\u00e1 kl\u00e1vesnica" }, "keyboard_russian": { "message": "Rusk\u00e1 kl\u00e1vesnica" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Str\u00e1nka s nastaveniami \u0161v\u00e9dskej kl\u00e1vesnice" }, + "settings": { + "message": "Nastavenia" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Zobrazenie n\u00e1vrhov v p\u00edsme Hangul" }, + "shrink_candidates": { + "message": "zbali\u0165 zoznam kandid\u00e1tov" + }, "si_slv_settings_page": { "message": "Str\u00e1nka s nastaveniami slovinskej kl\u00e1vesnice" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Odstr\u00e1ni\u0165 vybran\u00e9" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Ulo\u017ei\u0165" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sl/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sl/messages.json index fae3d065..f2aaca2 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sl/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sl/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Dodaj v osebni slovar" + }, "advanced": { "message": "Dodatno" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Stran z nastavitvami \u0161panske tipkovnice" }, + "expand": { + "message": "Raz\u0161iri" + }, + "expand_candidates": { + "message": "raz\u0161iri seznam kandidatov" + }, "fi_fin_settings_page": { "message": "Stran z nastavitvami finske tipkovnice" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Stran z nastavitvami irske tipkovnice" }, + "ignore_correction": { + "message": "Prezri popravek za" + }, "il_heb_settings_page": { "message": "Stran z nastavitvami hebrejske tipkovnice" }, @@ -2847,7 +2859,7 @@ "message": "Romunska tipkovnica" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Romunska standardna tipkovnica" }, "keyboard_russian": { "message": "Ruska tipkovnica" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Stran z nastavitvami \u0161vedske tipkovnice" }, + "settings": { + "message": "Nastavitve" + }, "shift": { "message": "dvigalka" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Poka\u017ei predloge za hangul" }, + "shrink_candidates": { + "message": "skr\u010di seznam kandidatov" + }, "si_slv_settings_page": { "message": "Stran z nastavitvami slovenske tipkovnice" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Odstrani izbor" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Shrani" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sr/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sr/messages.json index 7f8ae3a..54a16b3f 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sr/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sr/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0414\u043e\u0434\u0430\u0458 \u0443 \u043b\u0438\u0447\u043d\u0438 \u0440\u0435\u0447\u043d\u0438\u043a" + }, "advanced": { "message": "\u041d\u0430\u043f\u0440\u0435\u0434\u043d\u0435 \u043e\u043f\u0446\u0438\u0458\u0435" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0448\u043f\u0430\u043d\u0441\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, + "expand": { + "message": "\u041f\u0440\u043e\u0448\u0438\u0440\u0438" + }, + "expand_candidates": { + "message": "\u043f\u0440\u043e\u0448\u0438\u0440\u0438 \u043b\u0438\u0441\u0442\u0443 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430" + }, "fi_fin_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0444\u0438\u043d\u0441\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0438\u0440\u0441\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, + "ignore_correction": { + "message": "\u0417\u0430\u043d\u0435\u043c\u0430\u0440\u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u043a\u0443 \u0437\u0430" + }, "il_heb_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0445\u0435\u0431\u0440\u0435\u0458\u0441\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, @@ -2847,7 +2859,7 @@ "message": "\u0420\u0443\u043c\u0443\u043d\u0441\u043a\u0430 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0430" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0434\u043d\u0430 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0430 \u0437\u0430 \u0440\u0443\u043c\u0443\u043d\u0441\u043a\u0438" }, "keyboard_russian": { "message": "\u0420\u0443\u0441\u043a\u0430 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0430" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0448\u0432\u0435\u0434\u0441\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, + "settings": { + "message": "\u041f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0430" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u041f\u0440\u0438\u043a\u0430\u0436\u0438 \u0445\u0430\u043d\u0433\u0443\u043b \u043f\u0440\u0435\u0434\u043b\u043e\u0433\u0435" }, + "shrink_candidates": { + "message": "\u0441\u043a\u0443\u043f\u0438 \u043b\u0438\u0441\u0442\u0443 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430" + }, "si_slv_settings_page": { "message": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430 \u0441\u043b\u043e\u0432\u0435\u043d\u0430\u0447\u043a\u0435 \u0442\u0430\u0441\u0442\u0430\u0442\u0443\u0440\u0435" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0423\u043a\u043b\u043e\u043d\u0438 \u0438\u0437\u0430\u0431\u0440\u0430\u043d\u043e" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0421\u0430\u0447\u0443\u0432\u0430\u0458" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sv/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sv/messages.json index a187ae5..1bc9b29 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sv/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sv/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "L\u00e4gg till i personlig ordlista" + }, "advanced": { "message": "Avancerat" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r spanskt tangentbord" }, + "expand": { + "message": "Ut\u00f6ka" + }, + "expand_candidates": { + "message": "visa fler alternativ" + }, "fi_fin_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r finskt tangentbord" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r irl\u00e4ndskt tangentbord" }, + "ignore_correction": { + "message": "Ignorera korrigeringen av" + }, "il_heb_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r hebreiskt tangentbord" }, @@ -2847,7 +2859,7 @@ "message": "Rum\u00e4nskt tangentbord" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rum\u00e4nskt standardtangentbord" }, "keyboard_russian": { "message": "Ryskt tangentbord" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r svenskt tangentbord" }, + "settings": { + "message": "Inst\u00e4llningar" + }, "shift": { "message": "skift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Visa f\u00f6rslag med hangul-tecken" }, + "shrink_candidates": { + "message": "visa f\u00e4rre alternativ" + }, "si_slv_settings_page": { "message": "Inst\u00e4llningssidan f\u00f6r slovenskt tangentbord" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Ta bort markerade poster" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Spara" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sw/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sw/messages.json index b68a824..a1a125d 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/sw/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/sw/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Ongeza kwenye kamusi ya binafsi" + }, "advanced": { "message": "Mipangilio ya kina" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kihispania" }, + "expand": { + "message": "Panua" + }, + "expand_candidates": { + "message": "panua orodha ya wagombea" + }, "fi_fin_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kifini" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kiairishi" }, + "ignore_correction": { + "message": "Puuza marekebisho ya neno" + }, "il_heb_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kiyahudi" }, @@ -2847,7 +2859,7 @@ "message": "Kibodi ya Kiromania" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Kibodi wastani ya Kiromania" }, "keyboard_russian": { "message": "Kibodi ya Kirusi" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kiswidi" }, + "settings": { + "message": "Mipangilio" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Onyesha mapendekezo ya Hangul" }, + "shrink_candidates": { + "message": "punguza orodha ya wagombea" + }, "si_slv_settings_page": { "message": "Ukurasa wa Mipangilio ya Kibodi ya Kislovania" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Ondoa Uliochaguliwa" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Hifadhi" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ta/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ta/messages.json index 00aa57d..dcf08b3d 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/ta/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/ta/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0ba4\u0ba9\u0bbf\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f \u0b85\u0b95\u0bb0\u0bbe\u0ba4\u0bbf\u0baf\u0bbf\u0bb2\u0bcd \u0b9a\u0bc7\u0bb0\u0bcd" + }, "advanced": { "message": "\u0bae\u0bc7\u0bae\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0bb8\u0bcd\u0baa\u0bbe\u0ba9\u0bbf\u0bb7\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, + "expand": { + "message": "\u0bb5\u0bbf\u0bb0\u0bbf\u0bb5\u0bbe\u0b95\u0bcd\u0b95\u0bc1" + }, + "expand_candidates": { + "message": "\u0baa\u0bb0\u0bbf\u0ba8\u0bcd\u0ba4\u0bc1\u0bb0\u0bc8\u0baa\u0bcd \u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bc8 \u0bb5\u0bbf\u0bb0\u0bbf" + }, "fi_fin_settings_page": { "message": "\u0b83\u0baa\u0bbf\u0ba9\u0bcd\u0ba9\u0bbf\u0bb7\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0b90\u0bb0\u0bbf\u0bb7\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, + "ignore_correction": { + "message": "\u0b87\u0ba8\u0bcd\u0ba4\u0b9a\u0bcd \u0b9a\u0bca\u0bb2\u0bcd\u0bb2\u0bbf\u0ba9\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0ba4\u0bcd\u0ba4\u0bc8\u0ba4\u0bcd \u0ba4\u0bb5\u0bbf\u0bb0\u0bcd" + }, "il_heb_settings_page": { "message": "\u0bb9\u0bc0\u0baa\u0bcd\u0bb0\u0bc1 \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, @@ -2847,7 +2859,7 @@ "message": "\u0bb0\u0bcb\u0bae\u0bbe\u0ba9\u0bbf\u0baf\u0ba9\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0bb5\u0bb4\u0b95\u0bcd\u0b95\u0bae\u0bbe\u0ba9 \u0bb0\u0bcb\u0bae\u0bbe\u0ba9\u0bbf\u0baf\u0ba9\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8" }, "keyboard_russian": { "message": "\u0bb0\u0bb7\u0bcd\u0baf\u0ba9\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0bb8\u0bcd\u0bb5\u0bc0\u0b9f\u0bbf\u0bb7\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, + "settings": { + "message": "\u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd" + }, "shift": { "message": "\u0bb7\u0bbf\u0b83\u0baa\u0bcd\u0b9f\u0bc1" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0bb9\u0bbe\u0b99\u0bcd\u0b95\u0bc1\u0bb2\u0bcd \u0baa\u0bb0\u0bbf\u0ba8\u0bcd\u0ba4\u0bc1\u0bb0\u0bc8\u0b95\u0bb3\u0bc8\u0b95\u0bcd \u0b95\u0bbe\u0b9f\u0bcd\u0b9f\u0bc1" }, + "shrink_candidates": { + "message": "\u0baa\u0bb0\u0bbf\u0ba8\u0bcd\u0ba4\u0bc1\u0bb0\u0bc8\u0baa\u0bcd \u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bc8\u0b9a\u0bcd \u0b9a\u0bc1\u0bb0\u0bc1\u0b95\u0bcd\u0b95\u0bc1" + }, "si_slv_settings_page": { "message": "\u0bb8\u0bcd\u0bb2\u0bcb\u0bb5\u0bc7\u0ba9\u0bbf\u0baf\u0ba9\u0bcd \u0bb5\u0bbf\u0b9a\u0bc8\u0baa\u0bcd\u0baa\u0bb2\u0b95\u0bc8 \u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0bae\u0bcd" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0ba4\u0bc7\u0bb0\u0bcd\u0ba8\u0bcd\u0ba4\u0bc6\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0bb5\u0bb1\u0bcd\u0bb1\u0bc8 \u0b85\u0b95\u0bb1\u0bcd\u0bb1\u0bc1" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0b9a\u0bc7\u0bae\u0bbf" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/te/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/te/messages.json index ac15709..086a4ff1 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/te/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/te/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0c35\u0c4d\u0c2f\u0c15\u0c4d\u0c24\u0c3f\u0c17\u0c24 \u0c28\u0c3f\u0c18\u0c02\u0c1f\u0c41\u0c35\u0c41\u0c15\u0c3f \u0c1c\u0c4b\u0c21\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f" + }, "advanced": { "message": "\u0c05\u0c27\u0c41\u0c28\u0c3e\u0c24\u0c28\u0c02" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0c38\u0c4d\u0c2a\u0c3e\u0c28\u0c3f\u0c37\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, + "expand": { + "message": "\u0c35\u0c3f\u0c38\u0c4d\u0c24\u0c30\u0c3f\u0c02\u0c2a\u0c1c\u0c47\u0c2f\u0c3f" + }, + "expand_candidates": { + "message": "\u0c38\u0c42\u0c1a\u0c3f\u0c24 \u0c2a\u0c26\u0c02 \u0c1c\u0c3e\u0c2c\u0c3f\u0c24\u0c3e\u0c28\u0c41 \u0c35\u0c3f\u0c38\u0c4d\u0c24\u0c30\u0c3f\u0c02\u0c2a\u0c1c\u0c47\u0c2f\u0c3f" + }, "fi_fin_settings_page": { "message": "\u0c2b\u0c3f\u0c28\u0c4d\u0c28\u0c3f\u0c37\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0c10\u0c30\u0c3f\u0c37\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, + "ignore_correction": { + "message": "\u0c26\u0c40\u0c28\u0c3f \u0c26\u0c3f\u0c26\u0c4d\u0c26\u0c41\u0c2c\u0c3e\u0c1f\u0c41\u0c28\u0c3f \u0c35\u0c3f\u0c38\u0c4d\u0c2e\u0c30\u0c3f\u0c02\u0c1a\u0c41" + }, "il_heb_settings_page": { "message": "\u0c39\u0c3f\u0c2c\u0c4d\u0c30\u0c42 \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, @@ -2847,7 +2859,7 @@ "message": "\u0c30\u0c4a\u0c2e\u0c47\u0c28\u0c3f\u0c2f\u0c28\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0c30\u0c4a\u0c2e\u0c47\u0c28\u0c3f\u0c2f\u0c28\u0c4d \u0c2a\u0c4d\u0c30\u0c3e\u0c2e\u0c3e\u0c23\u0c3f\u0c15 \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d" }, "keyboard_russian": { "message": "\u0c30\u0c37\u0c4d\u0c2f\u0c28\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0c38\u0c4d\u0c35\u0c40\u0c21\u0c3f\u0c37\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, + "settings": { + "message": "\u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32\u0c41" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0c39\u0c3e\u0c02\u0c17\u0c41\u0c32\u0c4d \u0c38\u0c42\u0c1a\u0c28\u0c32\u0c28\u0c41 \u0c1a\u0c42\u0c2a\u0c41" }, + "shrink_candidates": { + "message": "\u0c38\u0c42\u0c1a\u0c3f\u0c24 \u0c2a\u0c26\u0c02 \u0c1c\u0c3e\u0c2c\u0c3f\u0c24\u0c3e\u0c28\u0c41 \u0c15\u0c41\u0c26\u0c3f\u0c02\u0c1a\u0c41" + }, "si_slv_settings_page": { "message": "\u0c38\u0c4d\u0c32\u0c4a\u0c35\u0c47\u0c28\u0c3f\u0c2f\u0c28\u0c4d \u0c15\u0c40\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d \u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c47\u0c1c\u0c40" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0c0e\u0c02\u0c1a\u0c41\u0c15\u0c41\u0c28\u0c4d\u0c28 \u0c35\u0c3e\u0c1f\u0c3f\u0c28\u0c3f \u0c24\u0c40\u0c38\u0c3f\u0c35\u0c47\u0c2f\u0c3f" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0c38\u0c47\u0c35\u0c4d \u0c1a\u0c47\u0c2f\u0c3f" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/th/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/th/messages.json index 4725a785..c433fc09 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/th/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/th/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e44\u0e1b\u0e22\u0e31\u0e07\u0e1e\u0e08\u0e19\u0e32\u0e19\u0e38\u0e01\u0e23\u0e21\u0e2a\u0e48\u0e27\u0e19\u0e15\u0e31\u0e27" + }, "advanced": { "message": "\u0e02\u0e31\u0e49\u0e19\u0e2a\u0e39\u0e07" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e2a\u0e40\u0e1b\u0e19" }, + "expand": { + "message": "\u0e02\u0e22\u0e32\u0e22" + }, + "expand_candidates": { + "message": "\u0e02\u0e22\u0e32\u0e22\u0e23\u0e32\u0e22\u0e0a\u0e37\u0e48\u0e2d\u0e1c\u0e39\u0e49\u0e2a\u0e21\u0e31\u0e04\u0e23" + }, "fi_fin_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e1f\u0e34\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e44\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c" }, + "ignore_correction": { + "message": "\u0e25\u0e30\u0e40\u0e27\u0e49\u0e19\u0e01\u0e32\u0e23\u0e41\u0e01\u0e49\u0e44\u0e02\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a" + }, "il_heb_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e2e\u0e35\u0e1a\u0e23\u0e39" }, @@ -2847,7 +2859,7 @@ "message": "\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e42\u0e23\u0e21\u0e32\u0e40\u0e19\u0e35\u0e22" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e21\u0e32\u0e15\u0e23\u0e10\u0e32\u0e19\u0e42\u0e23\u0e21\u0e32\u0e40\u0e19\u0e35\u0e22" }, "keyboard_russian": { "message": "\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e23\u0e31\u0e2a\u0e40\u0e0b\u0e35\u0e22" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e2a\u0e27\u0e35\u0e40\u0e14\u0e19" }, + "settings": { + "message": "\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u0e41\u0e2a\u0e14\u0e07\u0e04\u0e33\u0e41\u0e19\u0e30\u0e19\u0e33\u0e2d\u0e31\u0e01\u0e29\u0e23\u0e2e\u0e31\u0e19\u0e01\u0e36\u0e25" }, + "shrink_candidates": { + "message": "\u0e2b\u0e14\u0e23\u0e32\u0e22\u0e0a\u0e37\u0e48\u0e2d\u0e1c\u0e39\u0e49\u0e2a\u0e21\u0e31\u0e04\u0e23" + }, "si_slv_settings_page": { "message": "\u0e2b\u0e19\u0e49\u0e32\u0e01\u0e32\u0e23\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e41\u0e1b\u0e49\u0e19\u0e1e\u0e34\u0e21\u0e1e\u0e4c\u0e20\u0e32\u0e29\u0e32\u0e2a\u0e42\u0e25\u0e27\u0e35\u0e40\u0e19\u0e35\u0e22" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0e19\u0e33\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e2d\u0e2d\u0e01" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/tr/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/tr/messages.json index c19cdbd2..05d1d34a5 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/tr/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/tr/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Ki\u015fisel s\u00f6zl\u00fc\u011fe ekle" + }, "advanced": { "message": "Geli\u015fmi\u015f" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0130spanyolca Klavye Ayarlar\u0131 Sayfas\u0131" }, + "expand": { + "message": "Geni\u015flet" + }, + "expand_candidates": { + "message": "\u00f6neri listesini geni\u015flet" + }, "fi_fin_settings_page": { "message": "Fince Klavye Ayarlar\u0131 Sayfas\u0131" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0130rlandaca Klavye Ayarlar\u0131 Sayfas\u0131" }, + "ignore_correction": { + "message": "\u015eu kelime i\u00e7in d\u00fczeltmeyi yoksay" + }, "il_heb_settings_page": { "message": "\u0130branice Klavye Ayarlar\u0131 Sayfas\u0131" }, @@ -2847,7 +2859,7 @@ "message": "Romence klavye" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "Rumence" }, "keyboard_russian": { "message": "Rus\u00e7a klavye" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0130sve\u00e7\u00e7e Klavye Ayarlar\u0131 Sayfas\u0131" }, + "settings": { + "message": "Ayarlar" + }, "shift": { "message": "\u00fcstkrktr" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Hangul \u00f6nerilerini g\u00f6ster" }, + "shrink_candidates": { + "message": "\u00f6neri listesini daralt" + }, "si_slv_settings_page": { "message": "Slovence Klavye Ayarlar\u0131 Sayfas\u0131" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "Se\u00e7ileni Kald\u0131r" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "Kaydet" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/uk/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/uk/messages.json index 030d80c..6a1f460 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/uk/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/uk/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u0414\u043e\u0434\u0430\u0442\u0438 \u0432 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0441\u043b\u043e\u0432\u043d\u0438\u043a" + }, "advanced": { "message": "\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0456" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0456\u0441\u043f\u0430\u043d\u0441\u044c\u043a\u043e\u0457 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438" }, + "expand": { + "message": "\u0420\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438" + }, + "expand_candidates": { + "message": "\u0440\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0440\u0456\u0430\u043d\u0442\u0456\u0432" + }, "fi_fin_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0444\u0456\u043d\u0441\u044c\u043a\u043e\u0457 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0456\u0440\u043b\u0430\u043d\u0434\u0441\u044c\u043a\u043e\u0457 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438" }, + "ignore_correction": { + "message": "\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0441\u043b\u043e\u0432\u0430" + }, "il_heb_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438 \u0434\u043b\u044f \u0456\u0432\u0440\u0438\u0442\u0443" }, @@ -2847,7 +2859,7 @@ "message": "\u0420\u0443\u043c\u0443\u043d\u0441\u044c\u043a\u0430 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0430" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 \u0440\u0443\u043c\u0443\u043d\u0441\u044c\u043a\u0430 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0430" }, "keyboard_russian": { "message": "\u0420\u043e\u0441\u0456\u0439\u0441\u044c\u043a\u0430 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0430" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0448\u0432\u0435\u0434\u0441\u044c\u043a\u043e\u0457 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438" }, + "settings": { + "message": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f" + }, "shift": { "message": "Shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u043e\u043f\u043e\u0437\u0438\u0446\u0456\u0457 \u0434\u043b\u044f \u0430\u043b\u0444\u0430\u0432\u0456\u0442\u0443 \u0445\u0430\u043d\u0433\u0443\u043b" }, + "shrink_candidates": { + "message": "\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0430\u0440\u0456\u0430\u043d\u0442\u0456\u0432" + }, "si_slv_settings_page": { "message": "\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0441\u043b\u043e\u0432\u0435\u043d\u0441\u044c\u043a\u043e\u0457 \u043a\u043b\u0430\u0432\u0456\u0430\u0442\u0443\u0440\u0438" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u0412\u0438\u0434\u0430\u043b\u0438\u0442\u0438 \u0432\u0438\u0434\u0456\u043b\u0435\u043d\u0435" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/vi/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/vi/messages.json index 2ec90901..fd6ab5a 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/vi/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/vi/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "Th\u00eam v\u00e0o t\u1eeb \u0111i\u1ec3n c\u00e1 nh\u00e2n" + }, "advanced": { "message": "N\u00e2ng cao" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng T\u00e2y Ban Nha" }, + "expand": { + "message": "M\u1edf r\u1ed9ng" + }, + "expand_candidates": { + "message": "m\u1edf r\u1ed9ng danh s\u00e1ch \u1ee9ng vi\u00ean" + }, "fi_fin_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng Ph\u1ea7n Lan" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng Ai-len" }, + "ignore_correction": { + "message": "B\u1ecf qua t\u00ednh n\u0103ng s\u1eeda cho" + }, "il_heb_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng Do Th\u00e1i" }, @@ -2847,7 +2859,7 @@ "message": "B\u00e0n ph\u00edm ti\u1ebfng Rumani" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "B\u00e0n ph\u00edm chu\u1ea9n ti\u1ebfng Rumani" }, "keyboard_russian": { "message": "B\u00e0n ph\u00edm ti\u1ebfng Nga" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng Th\u1ee5y \u0110i\u1ec3n" }, + "settings": { + "message": "C\u00e0i \u0111\u1eb7t" + }, "shift": { "message": "shift" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "Hi\u1ec3n th\u1ecb g\u1ee3i \u00fd b\u1eb1ng ti\u1ebfng Hangul" }, + "shrink_candidates": { + "message": "thu nh\u1ecf danh s\u00e1ch \u1ee9ng vi\u00ean" + }, "si_slv_settings_page": { "message": "Trang c\u00e0i \u0111\u1eb7t b\u00e0n ph\u00edm ti\u1ebfng Slovenia" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "X\u00f3a m\u1ee5c \u0111\u00e3 ch\u1ecdn" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "L\u01b0u" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_CN/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_CN/messages.json index 2d333fb1..2e14fe2 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_CN/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_CN/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u6dfb\u52a0\u5230\u4e2a\u4eba\u5b57\u5178" + }, "advanced": { "message": "\u9ad8\u7ea7\u8bbe\u7f6e" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u897f\u73ed\u7259\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, + "expand": { + "message": "\u5c55\u5f00" + }, + "expand_candidates": { + "message": "\u5c55\u5f00\u5019\u9009\u5b57\u8bcd\u5217\u8868" + }, "fi_fin_settings_page": { "message": "\u82ac\u5170\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u7231\u5c14\u5170\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, + "ignore_correction": { + "message": "\u4e0d\u81ea\u52a8\u66f4\u6b63\u4ee5\u4e0b\u5b57\u8bcd\uff1a" + }, "il_heb_settings_page": { "message": "\u5e0c\u4f2f\u6765\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, @@ -2847,7 +2859,7 @@ "message": "\u7f57\u9a6c\u5c3c\u4e9a\u8bed\u952e\u76d8" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u7f57\u9a6c\u5c3c\u4e9a\u8bed\u6807\u51c6\u952e\u76d8" }, "keyboard_russian": { "message": "\u4fc4\u8bed\u952e\u76d8" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u745e\u5178\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, + "settings": { + "message": "\u8bbe\u7f6e" + }, "shift": { "message": "Shift\u952e" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u663e\u793a\u97e9\u8bed\u5efa\u8bae" }, + "shrink_candidates": { + "message": "\u6536\u8d77\u5019\u9009\u5b57\u8bcd\u5217\u8868" + }, "si_slv_settings_page": { "message": "\u65af\u6d1b\u6587\u5c3c\u4e9a\u8bed\u952e\u76d8\u8bbe\u7f6e\u9875\u9762" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u79fb\u9664\u6240\u9009\u5185\u5bb9" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u4fdd\u5b58" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_TW/messages.json b/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_TW/messages.json index 21e0a1f..4b16377 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_TW/messages.json +++ b/third_party/google_input_tools/src/chrome/os/inputview/_locales/zh_TW/messages.json
@@ -1,4 +1,7 @@ { + "add_to_personal_dictionary": { + "message": "\u52a0\u5165\u500b\u4eba\u5b57\u5178" + }, "advanced": { "message": "\u9032\u968e" }, @@ -2564,6 +2567,12 @@ "es_spa_settings_page": { "message": "\u897f\u73ed\u7259\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, + "expand": { + "message": "\u5c55\u958b" + }, + "expand_candidates": { + "message": "\u5c55\u958b\u5019\u9078\u6e05\u55ae" + }, "fi_fin_settings_page": { "message": "\u82ac\u862d\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, @@ -2621,6 +2630,9 @@ "ie_ga_settings_page": { "message": "\u611b\u723e\u862d\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, + "ignore_correction": { + "message": "\u4e0d\u66f4\u6b63\u4ee5\u4e0b\u5b57\u8a5e\uff1a" + }, "il_heb_settings_page": { "message": "\u5e0c\u4f2f\u4f86\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, @@ -2847,7 +2859,7 @@ "message": "\u7f85\u99ac\u5c3c\u4e9e\u6587\u9375\u76e4" }, "keyboard_romanian_standard": { - "message": "Romanian standard keyboard" + "message": "\u7f85\u99ac\u5c3c\u4e9e\u6587\u6a19\u6e96\u9375\u76e4" }, "keyboard_russian": { "message": "\u4fc4\u6587\u9375\u76e4" @@ -3062,6 +3074,9 @@ "se_swe_settings_page": { "message": "\u745e\u5178\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, + "settings": { + "message": "\u8a2d\u5b9a" + }, "shift": { "message": "Shift \u9375" }, @@ -3089,6 +3104,9 @@ "show_hangul_candidate": { "message": "\u986f\u793a\u97d3\u6587\u5efa\u8b70" }, + "shrink_candidates": { + "message": "\u6536\u5408\u5019\u9078\u6e05\u55ae" + }, "si_slv_settings_page": { "message": "\u65af\u6d1b\u7dad\u5c3c\u4e9e\u6587\u9375\u76e4\u8a2d\u5b9a\u9801\u9762" }, @@ -3263,6 +3281,9 @@ "user_dict_remove": { "message": "\u522a\u9664\u6240\u9078\u9805\u76ee" }, + "user_dict_reset": { + "message": "Reset All Dictionary Entries" + }, "user_dict_save": { "message": "\u5132\u5b58" },
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/adapter.js b/third_party/google_input_tools/src/chrome/os/inputview/adapter.js index c5783d8b..df41620 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/adapter.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/adapter.js
@@ -19,6 +19,7 @@ goog.require('goog.events.EventType'); goog.require('goog.object'); goog.require('i18n.input.chrome.DataSource'); +goog.require('i18n.input.chrome.inputview.GlobalFlags'); goog.require('i18n.input.chrome.inputview.ReadyState'); goog.require('i18n.input.chrome.inputview.StateType'); goog.require('i18n.input.chrome.inputview.events.EventType'); @@ -87,6 +88,17 @@ var Adapter = i18n.input.chrome.inputview.Adapter; +/** + * URL prefixes of common Google sites. + * + * @enum {string} + */ +Adapter.GoogleSites = { + // TODO: Add support for spreadsheets. + DOCS: 'https://docs.google.com/document/d' +}; + + /** @type {boolean} */ Adapter.prototype.isA11yMode = false; @@ -96,9 +108,12 @@ /** @type {boolean} */ -Adapter.prototype.showGlobeKey = false; +Adapter.prototype.isVoiceInputEnabled = true; +/** @type {boolean} */ +Adapter.prototype.showGlobeKey = false; + /** @type {string} */ Adapter.prototype.contextType = ContextType.DEFAULT; @@ -135,6 +150,7 @@ */ Adapter.prototype.onUpdateSettings_ = function(message) { this.screen = message[Name.SCREEN]; + this.queryCurrentSite(); this.contextType = /** @type {string} */ (message[Name.CONTEXT_TYPE]); // Resets the flag, since when inputview receive the update setting response, // it means the background switching is done. @@ -170,14 +186,25 @@ * @param {string} code * @param {number=} opt_keyCode The key code. * @param {!Object=} opt_spatialData . + * @param {!Object.<{ctrl: boolean, shift: boolean}>=} opt_modifiers . */ Adapter.prototype.sendKeyDownAndUpEvent = function(key, code, opt_keyCode, - opt_spatialData) { + opt_spatialData, opt_modifiers) { this.sendKeyEvent_([ this.generateKeyboardEvent_( - goog.events.EventType.KEYDOWN, key, code, opt_keyCode, opt_spatialData), + goog.events.EventType.KEYDOWN, + key, + code, + opt_keyCode, + opt_spatialData, + opt_modifiers), this.generateKeyboardEvent_( - goog.events.EventType.KEYUP, key, code, opt_keyCode, opt_spatialData) + goog.events.EventType.KEYUP, + key, + code, + opt_keyCode, + opt_spatialData, + opt_modifiers) ]); }; @@ -234,14 +261,23 @@ * @param {string} code The code. * @param {number=} opt_keyCode The key code. * @param {!Object=} opt_spatialData . + * @param {!Object.<{ctrl: boolean, shift: boolean}>=} opt_modifiers . * @return {!Object.<string, string|boolean>} * @private */ Adapter.prototype.generateKeyboardEvent_ = function( - type, key, code, opt_keyCode, opt_spatialData) { + type, key, code, opt_keyCode, opt_spatialData, opt_modifiers) { var StateType = i18n.input.chrome.inputview.StateType; var ctrl = !!this.modifierState_[StateType.CTRL]; var alt = !!this.modifierState_[StateType.ALT]; + var shift = !!this.modifierState_[StateType.SHIFT]; + + if (opt_modifiers) { + if (opt_modifiers.ctrl) + ctrl = opt_modifiers.ctrl; + if (opt_modifiers.shift) + shift = opt_modifiers.shift; + } if (ctrl || alt) { key = ''; @@ -256,7 +292,7 @@ result['altKey'] = alt; result['ctrlKey'] = ctrl; - result['shiftKey'] = !!this.modifierState_[StateType.SHIFT]; + result['shiftKey'] = shift; result['capsLock'] = !!this.modifierState_[StateType.CAPSLOCK]; return result; @@ -267,12 +303,14 @@ * Callback when surrounding text is changed. * * @param {string} text . + * @param {number} anchor . + * @param {number} focus . * @private */ -Adapter.prototype.onSurroundingTextChanged_ = function(text) { +Adapter.prototype.onSurroundingTextChanged_ = function(text, anchor, focus) { this.textBeforeCursor = text; this.dispatchEvent(new i18n.input.chrome.inputview.events. - SurroundingTextChangedEvent(this.textBeforeCursor)); + SurroundingTextChangedEvent(this.textBeforeCursor, anchor, focus)); }; @@ -311,6 +349,31 @@ /** + * True to enable gesture deletion. + * + * @return {boolean} + */ +Adapter.prototype.isGestureDeletionEnabled = function() { + // TODO: Omni bar sends wrong anchor/focus when autocompleting + // URLs. Re-enable when that is fixed. + if (this.contextType == ContextType.URL) { + return false; + } + return this.isGestureEdittingEnabled(); +}; + + +/** + * True to enable gesture editting. + * + * @return {boolean} + */ +Adapter.prototype.isGestureEdittingEnabled = function() { + return this.isExperimental; +}; + + +/** * Callback when blurs in the context. * * @private @@ -323,12 +386,55 @@ /** + * Asynchronously queries the current site. + */ +Adapter.prototype.queryCurrentSite = function() { + var adapter = this; + var criteria = {'active': true, 'lastFocusedWindow': true}; + if (chrome && chrome.tabs) { + chrome.tabs.query(criteria, function(tabs) { + tabs[0] && adapter.setCurrentSite_(tabs[0].url); + }); + } +}; + + +/** + * Sets the current context URL. + * + * @param {string} url . + * @private + */ +Adapter.prototype.setCurrentSite_ = function(url) { + if (url != this.currentSite_) { + this.currentSite_ = url; + this.dispatchEvent(new goog.events.Event( + i18n.input.chrome.inputview.events.EventType.URL_CHANGED)); + } +}; + + +/** + * Returns whether the current context is Google Documents. + * + * @return {boolean} . + */ +Adapter.prototype.isGoogleDocument = function() { + return this.currentSite_ && + this.currentSite_.lastIndexOf(Adapter.GoogleSites.DOCS) === 0; +}; + + +/** * Callback when focus on a context. * * @param {!Object<string, *>} message . * @private */ Adapter.prototype.onContextFocus_ = function(message) { + // URL might have changed. + this.queryCurrentSite(); + this.contextType = /** @type {string} */ (message[Name.CONTEXT_TYPE]); this.dispatchEvent(new goog.events.Event( i18n.input.chrome.inputview.events.EventType.CONTEXT_FOCUS)); @@ -362,6 +468,10 @@ }).bind(this)); chrome.accessibilityFeatures.spokenFeedback.onChange.addListener((function( details) { + if (!this.isChromeVoxOn && details['value']) { + this.dispatchEvent(new goog.events.Event( + i18n.input.chrome.inputview.events.EventType.REFRESH)); + } this.isChromeVoxOn = details['value']; }).bind(this)); } @@ -385,6 +495,12 @@ }).bind(this)); inputview.getInputMethodConfig((function(config) { this.isQPInputView = !!config['isNewQPInputViewEnabled']; + var voiceEnabled = config['isVoiceInputEnabled']; + if (goog.isDef(voiceEnabled)) { + this.isVoiceInputEnabled = !!voiceEnabled; + } + i18n.input.chrome.inputview.GlobalFlags.isQPInputView = + this.isQPInputView; this.readyState_.markStateReady(StateType.INPUT_METHOD_CONFIG_READY); this.maybeDispatchSettingsReadyEvent_(); }).bind(this)); @@ -606,7 +722,9 @@ this.onContextBlur_(); break; case Type.SURROUNDING_TEXT_CHANGED: - this.onSurroundingTextChanged_(request[Name.TEXT]); + this.onSurroundingTextChanged_(request[Name.TEXT], + request[Name.ANCHOR], + request[Name.FOCUS]); break; case Type.UPDATE_SETTINGS: this.onUpdateSettings_(msg);
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/common.css b/third_party/google_input_tools/src/chrome/os/inputview/common.css index 4a16f54b..1238b4d4 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/common.css +++ b/third_party/google_input_tools/src/chrome/os/inputview/common.css
@@ -225,6 +225,7 @@ width: 21px; height: 21px; } +.inputview-swipe-view, .inputview-menu-view, .inputview-altdata-view { position: fixed; @@ -237,12 +238,26 @@ 0 0 6px rgba(204, 204, 204, 0.65); cursor: default; } +.inputview-swipe-separator { + background-color: #ebebeb; + position: relative; + display: inline-block; +} .inputview-altdata-separator { height: 20px; border-left: 1px solid #ddd; position: relative; display: inline-block; } +.inputview-swipe-key { + background-color: #dddddd; + display: table-cell; + font-size: 23px; + color: black; + vertical-align: middle; + position: relative; + text-align: center; +} .inputview-altdata-key { display: table-cell; font-size: 23px; @@ -265,9 +280,13 @@ display: table-cell; height: 32px; } +.inputview-toolbar-button, .inputview-candidate-button { float: right; } +.inputview-toolbar-button.float-left { + float: left; +} .inputview-candidate { display: table-cell; font-size: 18px; @@ -279,6 +298,7 @@ .inputview-a11y .inputview-candidate { font-size: 12px; } +.inputview-toolbar-separator, .inputview-candidate-separator { border-left: 1px solid #ddd; position: relative; @@ -311,6 +331,7 @@ -webkit-box-shadow: 0 0 5px 1px #397FFB; opacity: 0.9; } +.inputview-track-cover, .inputview-altdata-cover { position: fixed; bottom: 0; @@ -319,6 +340,9 @@ opacity: 0.5; z-index: 1; } +.inputview-track-cover { + z-index: 998; +} .inputview-arrow-key { display: inline-block; height: 13.5px; @@ -369,6 +393,7 @@ height: 14.5px; } .inputview-candidate.inputview-candidate-highlight, +.inputview-toolbar-button.inputview-candidate-highlight, .inputview-element-highlight { background-color: #dddddd; } @@ -377,6 +402,10 @@ .inputview-view .inputview-special-key-bg.inputview-special-key-highlight { background-color: #cccccc; } +.inputview-swipe-separator.inputview-element-highlight, +.inputview-swipe-key.inputview-element-highlight { + background-color: #bbbbbb; +} .inputview-backspace-icon { background: transparent url('images/backspace.png'); background-size: 22.5px 13px; @@ -500,6 +529,60 @@ width: 16.5px; } +.inputview-copy-icon { + background: transparent url('images/copy.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-cut-icon { + background: transparent url('images/cut.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-paste-icon { + background: transparent url('images/paste.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-bold-icon { + background: transparent url('images/bold.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-italics-icon { + background: transparent url('images/italic.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-underline-icon { + background: transparent url('images/underline.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-select-all-icon { + background: transparent url('images/select_all.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-redo-icon { + background: transparent url('images/redo.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + +.inputview-undo-icon { + background: transparent url('images/undo.png') 0 0/17px 16.5px no-repeat; + height: 17px; + width: 16.5px; +} + /** * The following css style is for handwriting panel, * please keep it in the end of the file @@ -642,6 +725,49 @@ height: 16px; width: 40px; } +.inputview-select-knob-left, +.inputview-select-knob-right { + position: absolute; + top: 0; + margin: 0; + padding: 0; + z-index: 100; +} +.inputview-select-knob-left { + left: 0px; +} +.inputview-select-knob-right { + +} +/* Anchor to the center of the column */ +.inputview-select-knob-right > div, +.inputview-select-knob-left > div { + width: 100%; + position: relative; + height: 1px; + top: 50%; + left: 0; +} +/* Semi-circular knob */ +.inputview-select-knob-left > div > div, +.inputview-select-knob-right > div > div { + width : 100%; + height: 50px; + background-color: #dddddd; + -webkit-transform: translateY(-25px); + line-height: 50px; + color: white; + text-align: center; + font-size: medium; + font-weight: bolder; +} +.inputview-select-knob-left > div > div { + -webkit-border-radius: 0 30px 30px 0; +} +.inputview-select-knob-right > div > div { + -webkit-border-radius: 30px 0 0 30px; +} + .inputview-candidate-internal-wrapper { text-overflow: ellipsis; overflow-x: hidden;
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/config/material/emoji_data.js b/third_party/google_input_tools/src/chrome/os/inputview/config/material/emoji_data.js new file mode 100644 index 0000000..a0b6da8 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/config/material/emoji_data.js
@@ -0,0 +1,557 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.EmojiType'); +goog.require('i18n.input.chrome.inputview.SpecNodeName'); +goog.require('i18n.input.chrome.inputview.content.util'); +goog.require('i18n.input.chrome.inputview.elements.ElementType'); + +(function() { + + var viewIdPrefix = 'emoji-k-'; + var emojiKeyAmount = 27; + var util = i18n.input.chrome.inputview.content.util; + var ElementType = i18n.input.chrome.inputview.elements.ElementType; + var EmojiType = i18n.input.chrome.inputview.EmojiType; + var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; + var Css = i18n.input.chrome.inputview.Css; + + var keyCharacters = [ + // Recent + [''], + + // Hot + ['\u2665', '\ud83d\ude02', '\u263a', + '\u2764', '\ud83d\ude12', '\ud83d\ude0d', + '\ud83d\udc4c', '\ud83d\ude18', '\ud83d\ude0a', + '\ud83d\ude14', '\ud83d\ude0f', '\ud83d\ude29', + '\ud83d\ude01', '\ud83d\ude2d', '\ud83d\ude33', + '\ud83d\udc95', '\u270c', '\ud83d\udc4d', + '\ud83d\ude09', '\ud83d\udc81', '\ud83d\ude4c', + '\ud83d\ude0c', '\ud83d\ude0e', '\ud83d\ude48', + '\ud83d\ude11', '\ud83d\ude1c', '\ud83d\ude0b', + '\ud83d\ude1e', '\ud83d\ude4f', '\u270b', + '\ud83d\ude04', '\ud83d\ude4a', '\ud83d\ude15', + '\ud83d\ude21', '\ud83d\udc4f', '\ud83d\ude22', + '\ud83d\ude34', '\ud83d\udc40', '\ud83d\ude10', + '\ud83d\ude31', '\ud83d\ude2b', '\ud83d\ude1d', + '\ud83d\udc9c', '\ud83d\udc94', '\ud83d\udc8b', + '\ud83d\ude03', '\ud83d\ude2a', '\ud83d\ude23', + '\ud83d\udc99', '\ud83d\ude24', '\ud83d\udc4b', + '\ud83d\udc4a', '\ud83d\ude37', '\ud83d\ude20', + '\ud83d\ude16', '\ud83d\ude2c', '\ud83d\udc97', + '\ud83d\ude45', '\ud83d\ude08', '\ud83d\ude05', + '\ud83d\udc4e', '\ud83d\ude25', '\ud83d\ude4b', + '\ud83d\ude06', '\ud83d\ude13', '\ud83d\udcaa', + '\ud83d\udc96', '\ud83d\ude36', '\ud83d\ude1a', + '\ud83d\udc9b', '\ud83d\udc9a', '\ud83d\ude1b', + '\ud83d\udc83', '\ud83d\udc9e', '\ud83d\ude00', + '\ud83d\ude30', '\u270a', '\ud83d\udca9', + '\ud83d\udc98', '\u261d'], + + // Emotion + ['\u263a', '\ud83d\ude0a', '\ud83d\ude00', + '\ud83d\ude01', '\ud83d\ude02', '\ud83d\ude03', + '\ud83d\ude04', '\ud83d\ude05', '\ud83d\ude06', + '\ud83d\ude07', '\ud83d\ude08', '\ud83d\ude09', + '\ud83d\ude2f', '\ud83d\ude10', '\ud83d\ude11', + '\ud83d\ude15', '\ud83d\ude20', '\ud83d\ude2c', + '\ud83d\ude21', '\ud83d\ude22', '\ud83d\ude34', + '\ud83d\ude2e', '\ud83d\ude23', '\ud83d\ude24', + '\ud83d\ude25', '\ud83d\ude26', '\ud83d\ude27', + '\ud83d\ude28', '\ud83d\ude29', '\ud83d\ude30', + '\ud83d\ude1f', '\ud83d\ude31', '\ud83d\ude32', + '\ud83d\ude33', '\ud83d\ude35', '\ud83d\ude36', + '\ud83d\ude37', '\ud83d\ude1e', '\ud83d\ude12', + '\ud83d\ude0d', '\ud83d\ude1b', '\ud83d\ude1c', + '\ud83d\ude1d', '\ud83d\ude0b', '\ud83d\ude17', + '\ud83d\ude19', '\ud83d\ude18', '\ud83d\ude1a', + '\ud83d\ude0e', '\ud83d\ude2d', '\ud83d\ude0c', + '\ud83d\ude16', '\ud83d\ude14', '\ud83d\ude2a', + '\ud83d\ude0f', '\ud83d\ude13', '\ud83d\ude2b', + '\ud83d\ude4b', '\ud83d\ude4c', '\ud83d\ude4d', + '\ud83d\ude45', '\ud83d\ude46' , '\ud83d\ude47', + '\ud83d\ude4e', '\ud83d\ude4f', '\ud83d\ude3a', + '\ud83d\ude3c', '\ud83d\ude38' , '\ud83d\ude39', + '\ud83d\ude3b', '\ud83d\ude3d', '\ud83d\ude3f', + '\ud83d\ude3e', '\ud83d\ude40', '\ud83d\ude48', + '\ud83d\ude49', '\ud83d\ude4a', '\ud83d\udca9', + '\ud83d\udc76', '\ud83d\udc66', '\ud83d\udc67', + '\ud83d\udc68', '\ud83d\udc69', '\ud83d\udc74', + '\ud83d\udc75', '\ud83d\udc8f', '\ud83d\udc91', + '\ud83d\udc6a', '\ud83d\udc6b', '\ud83d\udc6c', + '\ud83d\udc6d', '\ud83d\udc64', '\ud83d\udc65', + '\ud83d\udc6e', '\ud83d\udc77', '\ud83d\udc81', + '\ud83d\udc82', '\ud83d\udc6f', '\ud83d\udc70', + '\ud83d\udc78', '\ud83c\udf85', '\ud83d\udc7c', + '\ud83d\udc71', '\ud83d\udc72', '\ud83d\udc73', + '\ud83d\udc83', '\ud83d\udc86', '\ud83d\udc87', + '\ud83d\udc85', '\ud83d\udc7b', '\ud83d\udc79', + '\ud83d\udc7a', '\ud83d\udc7d', '\ud83d\udc7e', + '\ud83d\udc7f', '\ud83d\udc80', '\ud83d\udcaa', + '\ud83d\udc40', '\ud83d\udc42', '\ud83d\udc43', + '\ud83d\udc63', '\ud83d\udc44', '\ud83d\udc45', + '\ud83d\udc8b', '\u2764', '\ud83d\udc99', + '\ud83d\udc9a', '\ud83d\udc9b', '\ud83d\udc9c', + '\ud83d\udc93', '\ud83d\udc94', '\ud83d\udc95', + '\ud83d\udc96', '\ud83d\udc97', '\ud83d\udc98', + '\ud83d\udc9d', '\ud83d\udc9e', '\ud83d\udc9f', + '\ud83d\udc4d', '\ud83d\udc4e', '\ud83d\udc4c', + '\u270a', '\u270c', '\u270b', + '\ud83d\udc4a', '\u261d', '\ud83d\udc46', + '\ud83d\udc47', '\ud83d\udc48', '\ud83d\udc49', + '\ud83d\udc4b', '\ud83d\udc4f', '\ud83d\udc50'], + + // Items + ['\ud83d\udd30', '\ud83d\udc84', '\ud83d\udc5e', + '\ud83d\udc5f', '\ud83d\udc51', '\ud83d\udc52', + '\ud83c\udfa9', '\ud83c\udf93', '\ud83d\udc53', + '\u231a', '\ud83d\udc54', '\ud83d\udc55', + '\ud83d\udc56', '\ud83d\udc57', '\ud83d\udc58', + '\ud83d\udc59', '\ud83d\udc60', '\ud83d\udc61', + '\ud83d\udc62', '\ud83d\udc5a', '\ud83d\udc5c', + '\ud83d\udcbc', '\ud83c\udf92', '\ud83d\udc5d', + '\ud83d\udc5b', '\ud83d\udcb0', '\ud83d\udcb3', + '\ud83d\udcb2', '\ud83d\udcb5', '\ud83d\udcb4', + '\ud83d\udcb6', '\ud83d\udcb7', '\ud83d\udcb8', + '\ud83d\udcb1', '\ud83d\udcb9', '\ud83d\udd2b', + '\ud83d\udd2a', '\ud83d\udca3', '\ud83d\udc89', + '\ud83d\udc8a', '\ud83d\udeac', '\ud83d\udd14', + '\ud83d\udd15', '\ud83d\udeaa', '\ud83d\udd2c', + '\ud83d\udd2d', '\ud83d\udd2e', '\ud83d\udd26', + '\ud83d\udd0b', '\ud83d\udd0c', '\ud83d\udcdc', + '\ud83d\udcd7', '\ud83d\udcd8', '\ud83d\udcd9', + '\ud83d\udcda', '\ud83d\udcd4', '\ud83d\udcd2', + '\ud83d\udcd1', '\ud83d\udcd3', '\ud83d\udcd5', + '\ud83d\udcd6', '\ud83d\udcf0', '\ud83d\udcdb', + '\ud83c\udf83', '\ud83c\udf84', '\ud83c\udf80', + '\ud83c\udf81', '\ud83c\udf82', '\ud83c\udf88', + '\ud83c\udf86', '\ud83c\udf87', '\ud83c\udf89', + '\ud83c\udf8a', '\ud83c\udf8d', '\ud83c\udf8f', + '\ud83c\udf8c', '\ud83c\udf90', '\ud83c\udf8b', + '\ud83c\udf8e', '\ud83d\udcf1', '\ud83d\udcf2', + '\ud83d\udcdf', '\u260e', '\ud83d\udcde', + '\ud83d\udce0', '\ud83d\udce6', '\u2709', + '\ud83d\udce8', '\ud83d\udce9', '\ud83d\udcea', + '\ud83d\udceb', '\ud83d\udced', '\ud83d\udcec', + '\ud83d\udcee', '\ud83d\udce4', '\ud83d\udce5', + '\ud83d\udcef', '\ud83d\udce2', '\ud83d\udce3', + '\ud83d\udce1', '\ud83d\udcac', '\ud83d\udcad', + '\u2712', '\u270f', '\ud83d\udcdd', + '\ud83d\udccf', '\ud83d\udcd0', '\ud83d\udccd', + '\ud83d\udccc', '\ud83d\udcce', '\u2702', + '\ud83d\udcba', '\ud83d\udcbb', '\ud83d\udcbd', + '\ud83d\udcbe', '\ud83d\udcbf', '\ud83d\udcc6', + '\ud83d\udcc5', '\ud83d\udcc7', '\ud83d\udccb', + '\ud83d\udcc1', '\ud83d\udcc2', '\ud83d\udcc3', + '\ud83d\udcc4', '\ud83d\udcca', '\ud83d\udcc8', + '\ud83d\udcc9', '\u26fa', '\ud83c\udfa1', + '\ud83c\udfa2', '\ud83c\udfa0', '\ud83c\udfaa', + '\ud83c\udfa8', '\ud83c\udfac', '\ud83c\udfa5', + '\ud83d\udcf7', '\ud83d\udcf9', '\ud83c\udfa6', + '\ud83c\udfad', '\ud83c\udfab', '\ud83c\udfae', + '\ud83c\udfb2', '\ud83c\udfb0', '\ud83c\udccf', + '\ud83c\udfb4', '\ud83c\udc04', '\ud83c\udfaf', + '\ud83d\udcfa', '\ud83d\udcfb', '\ud83d\udcc0', + '\ud83d\udcfc', '\ud83c\udfa7', '\ud83c\udfa4', + '\ud83c\udfb5', '\ud83c\udfb6', '\ud83c\udfbc', + '\ud83c\udfbb', '\ud83c\udfb9', '\ud83c\udfb7', + '\ud83c\udfba', '\ud83c\udfb8', '\u303d'], + + // Nature + ['\ud83d\udc15', '\ud83d\udc36', '\ud83d\udc29', + '\ud83d\udc08', '\ud83d\udc31', '\ud83d\udc00', + '\ud83d\udc01', '\ud83d\udc2d', '\ud83d\udc39', + '\ud83d\udc22', '\ud83d\udc07', '\ud83d\udc30', + '\ud83d\udc13', '\ud83d\udc14', '\ud83d\udc23', + '\ud83d\udc24', '\ud83d\udc25', '\ud83d\udc26', + '\ud83d\udc0f', '\ud83d\udc11', '\ud83d\udc10', + '\ud83d\udc3a', '\ud83d\udc03', '\ud83d\udc02', + '\ud83d\udc04', '\ud83d\udc2e', '\ud83d\udc34', + '\ud83d\udc17', '\ud83d\udc16', '\ud83d\udc37', + '\ud83d\udc3d', '\ud83d\udc38', '\ud83d\udc0d', + '\ud83d\udc3c', '\ud83d\udc27', '\ud83d\udc18', + '\ud83d\udc28', '\ud83d\udc12', '\ud83d\udc35', + '\ud83d\udc06', '\ud83d\udc2f', '\ud83d\udc3b', + '\ud83d\udc2b', '\ud83d\udc2a', '\ud83d\udc0a', + '\ud83d\udc33', '\ud83d\udc0b', '\ud83d\udc1f', + '\ud83d\udc20', '\ud83d\udc21', '\ud83d\udc19', + '\ud83d\udc1a', '\ud83d\udc2c', '\ud83d\udc0c', + '\ud83d\udc1b', '\ud83d\udc1c', '\ud83d\udc1d', + '\ud83d\udc1e', '\ud83d\udc32', '\ud83d\udc09', + '\ud83d\udc3e', '\ud83c\udf78', '\ud83c\udf7a', + '\ud83c\udf7b', '\ud83c\udf77', '\ud83c\udf79', + '\ud83c\udf76', '\u2615', '\ud83c\udf75', + '\ud83c\udf7c', '\ud83c\udf74', '\ud83c\udf68', + '\ud83c\udf67', '\ud83c\udf66', '\ud83c\udf69', + '\ud83c\udf70', '\ud83c\udf6a', '\ud83c\udf6b', + '\ud83c\udf6c', '\ud83c\udf6d', '\ud83c\udf6e', + '\ud83c\udf6f', '\ud83c\udf73', '\ud83c\udf54', + '\ud83c\udf5f', '\ud83c\udf5d', '\ud83c\udf55', + '\ud83c\udf56', '\ud83c\udf57', '\ud83c\udf64', + '\ud83c\udf63', '\ud83c\udf71', '\ud83c\udf5e', + '\ud83c\udf5c', '\ud83c\udf59', '\ud83c\udf5a', + '\ud83c\udf5b', '\ud83c\udf72', '\ud83c\udf65', + '\ud83c\udf62', '\ud83c\udf61', '\ud83c\udf58', + '\ud83c\udf60', '\ud83c\udf4c', '\ud83c\udf4e', + '\ud83c\udf4f', '\ud83c\udf4a', '\ud83c\udf4b', + '\ud83c\udf44', '\ud83c\udf45', '\ud83c\udf46', + '\ud83c\udf47', '\ud83c\udf48', '\ud83c\udf49', + '\ud83c\udf50', '\ud83c\udf51', '\ud83c\udf52', + '\ud83c\udf53', '\ud83c\udf4d', '\ud83c\udf30', + '\ud83c\udf31', '\ud83c\udf32', '\ud83c\udf33', + '\ud83c\udf34', '\ud83c\udf35', '\ud83c\udf37', + '\ud83c\udf38', '\ud83c\udf39', '\ud83c\udf40', + '\ud83c\udf41', '\ud83c\udf42', '\ud83c\udf43', + '\ud83c\udf3a', '\ud83c\udf3b', '\ud83c\udf3c', + '\ud83c\udf3d', '\ud83c\udf3e', '\ud83c\udf3f', + '\u2600', '\ud83c\udf08', '\u26c5', + '\u2601', '\ud83c\udf01', '\ud83c\udf02', + '\u2614', '\ud83d\udca7', '\u26a1', + '\ud83c\udf00', '\u2744', '\u26c4', + '\ud83c\udf19', '\ud83c\udf1e', '\ud83c\udf1d', + '\ud83c\udf1a', '\ud83c\udf1b', '\ud83c\udf1c', + '\ud83c\udf11', '\ud83c\udf12', '\ud83c\udf13', + '\ud83c\udf14', '\ud83c\udf15', '\ud83c\udf16', + '\ud83c\udf17', '\ud83c\udf18', '\ud83c\udf91', + '\ud83c\udf04', '\ud83c\udf05', '\ud83c\udf07', + '\ud83c\udf06', '\ud83c\udf03', '\ud83c\udf0c', + '\ud83c\udf09', '\ud83c\udf0a', '\ud83c\udf0b', + '\ud83c\udf0e', '\ud83c\udf0f', '\ud83c\udf0d', + '\ud83c\udf10'], + + // Places of interests + ['\ud83c\udfe0', '\ud83c\udfe1', '\ud83c\udfe2', + '\ud83c\udfe3', '\ud83c\udfe4', '\ud83c\udfe5', + '\ud83c\udfe6', '\ud83c\udfe7', '\ud83c\udfe8', + '\ud83c\udfe9', '\ud83c\udfea', '\ud83c\udfeb', + '\u26ea', '\u26f2', '\ud83c\udfec', + '\ud83c\udfef', '\ud83c\udff0', '\ud83c\udfed', + '\ud83d\uddfb', '\ud83d\uddfc', '\ud83d\uddfd', + '\ud83d\uddfe', '\ud83d\uddff', '\u2693', + '\ud83c\udfee', '\ud83d\udc88', '\ud83d\udd27', + '\ud83d\udd28', '\ud83d\udd29', '\ud83d\udebf', + '\ud83d\udec1', '\ud83d\udec0', '\ud83d\udebd', + '\ud83d\udebe', '\ud83c\udfbd', '\ud83c\udfa3', + '\ud83c\udfb1', '\ud83c\udfb3', '\u26be', + '\u26f3', '\ud83c\udfbe', '\u26bd', + '\ud83c\udfbf', '\ud83c\udfc0', '\ud83c\udfc1', + '\ud83c\udfc2', '\ud83c\udfc3', '\ud83c\udfc4', + '\ud83c\udfc6', '\ud83c\udfc7', '\ud83d\udc0e', + '\ud83c\udfc8', '\ud83c\udfc9', '\ud83c\udfca', + '\ud83d\ude82', '\ud83d\ude83', '\ud83d\ude84', + '\ud83d\ude85', '\ud83d\ude86', '\ud83d\ude87', + '\u24c2', '\ud83d\ude88', '\ud83d\ude8a', + '\ud83d\ude8b', '\ud83d\ude8c', '\ud83d\ude8d', + '\ud83d\ude8e', '\ud83d\ude8f', '\ud83d\ude90', + '\ud83d\ude91', '\ud83d\ude92', '\ud83d\ude93', + '\ud83d\ude94', '\ud83d\ude95', '\ud83d\ude96', + '\ud83d\ude97', '\ud83d\ude98', '\ud83d\ude99', + '\ud83d\ude9a', '\ud83d\ude9b', '\ud83d\ude9c', + '\ud83d\ude9d', '\ud83d\ude9e', '\ud83d\ude9f', + '\ud83d\udea0', '\ud83d\udea1', '\ud83d\udea2', + '\ud83d\udea3', '\ud83d\ude81', '\u2708', + '\ud83d\udec2', '\ud83d\udec3', '\ud83d\udec4', + '\ud83d\udec5', '\u26f5', '\ud83d\udeb2', + '\ud83d\udeb3', '\ud83d\udeb4', '\ud83d\udeb5', + '\ud83d\udeb7', '\ud83d\udeb8', '\ud83d\ude89', + '\ud83d\ude80', '\ud83d\udea4', '\ud83d\udeb6', + '\u26fd', '\ud83c\udd7f', '\ud83d\udea5', + '\ud83d\udea6', '\ud83d\udea7', '\ud83d\udea8', + '\u2668', '\ud83d\udc8c', '\ud83d\udc8d', + '\ud83d\udc8e', '\ud83d\udc90', '\ud83d\udc92'], + + // Special characters + ['\ud83d\udd1d', '\ud83d\udd19', '\ud83d\udd1b', + '\ud83d\udd1c', '\ud83d\udd1a', '\u23f3', + '\u231b', '\u23f0', '\u2648', + '\u2649', '\u264a', '\u264b', + '\u264c', '\u264d', '\u264e', + '\u264f', '\u2650', '\u2651', + '\u2652', '\u2653', '\u26ce', + '\ud83d\udd31', '\ud83d\udd2f', '\ud83d\udebb', + '\ud83d\udeae', '\ud83d\udeaf', '\ud83d\udeb0', + '\ud83d\udeb1', '\ud83c\udd70', '\ud83c\udd71', + '\ud83c\udd8e', '\ud83c\udd7e', '\ud83d\udcae', + '\ud83d\udcaf', '\ud83d\udd20', '\ud83d\udd21', + '\ud83d\udd22', '\ud83d\udd23', '\ud83d\udd24', + '\u27bf', '\ud83d\udcf6', '\ud83d\udcf3', + '\ud83d\udcf4', '\ud83d\udcf5', '\ud83d\udeb9', + '\ud83d\udeba', '\ud83d\udebc', '\u267f', + '\u267b', '\ud83d\udead', '\ud83d\udea9', + '\u26a0', '\ud83c\ude01', '\ud83d\udd1e', + '\u26d4', '\ud83c\udd92', '\ud83c\udd97', + '\ud83c\udd95', '\ud83c\udd98', '\ud83c\udd99', + '\ud83c\udd93', '\ud83c\udd96', '\ud83c\udd9a', + '\ud83c\ude32', '\ud83c\ude33', '\ud83c\ude34', + '\ud83c\ude35', '\ud83c\ude36', '\ud83c\ude37', + '\ud83c\ude38', '\ud83c\ude39', '\ud83c\ude02', + '\ud83c\ude3a', '\ud83c\ude50', '\ud83c\ude51', + '\u3299', '\u00ae', '\u00a9', + '\u2122', '\ud83c\ude1a', '\ud83c\ude2f', + '\u3297', '\u2b55', '\u274c', + '\u274e', '\u2139', '\ud83d\udeab', + '\u2705', '\u2714', '\ud83d\udd17', + '\u2734', '\u2733', '\u2795', + '\u2796', '\u2716', '\u2797', + '\ud83d\udca0', '\ud83d\udca1', '\ud83d\udca4', + '\ud83d\udca2', '\ud83d\udd25', '\ud83d\udca5', + '\ud83d\udca8', '\ud83d\udca6', '\ud83d\udcab', + '\ud83d\udd5b', '\ud83d\udd67', '\ud83d\udd50', + '\ud83d\udd5c', '\ud83d\udd51', '\ud83d\udd5d', + '\ud83d\udd52', '\ud83d\udd5e', '\ud83d\udd53', + '\ud83d\udd5f', '\ud83d\udd54', '\ud83d\udd60', + '\ud83d\udd55', '\ud83d\udd61', '\ud83d\udd56', + '\ud83d\udd62', '\ud83d\udd57', '\ud83d\udd63', + '\ud83d\udd58', '\ud83d\udd64', '\ud83d\udd59', + '\ud83d\udd65', '\ud83d\udd5a', '\ud83d\udd66', + '\u2195', '\u2b06', '\u2197', + '\u27a1', '\u2198', '\u2b07', + '\u2199', '\u2b05', '\u2196', + '\u2194', '\u2934', '\u2935', + '\u23ea', '\u23eb', '\u23ec', + '\u23e9', '\u25c0', '\u25b6', + '\ud83d\udd3d', '\ud83d\udd3c', '\u2747', + '\u2728', '\ud83d\udd34', '\ud83d\udd35', + '\u26aa', '\u26ab', '\ud83d\udd33', + '\ud83d\udd32', '\u2b50', '\ud83c\udf1f', + '\ud83c\udf20', '\u25ab', '\u25aa', + '\u25fd', '\u25fe', '\u25fb', + '\u25fc', '\u2b1c', '\u2b1b', + '\ud83d\udd38', '\ud83d\udd39', '\ud83d\udd36', + '\ud83d\udd37', '\ud83d\udd3a', '\ud83d\udd3b', + '\u2754', '\u2753', '\u2755', + '\u2757', '\u203c', '\u2049', + '\u3030', '\u27b0', '\u2660', + '\u2665', '\u2663', '\u2666', + '\ud83c\udd94', '\ud83d\udd11', '\u21a9', + '\ud83c\udd91', '\ud83d\udd0d', '\ud83d\udd12', + '\ud83d\udd13', '\u21aa', '\ud83d\udd10', + '\u2611', '\ud83d\udd18', '\ud83d\udd0e', + '\ud83d\udd16', '\ud83d\udd0f', '\ud83d\udd03', + '\ud83d\udd00', '\ud83d\udd01', '\ud83d\udd02', + '\ud83d\udd04', '\ud83d\udce7', '\ud83d\udd05', + '\ud83d\udd06', '\ud83d\udd07', '\ud83d\udd08', + '\ud83d\udd09', '\ud83d\udd0a'], + + // Emoticon + [':)', + ';-)', + ':-D', + ':P', + ':-(', + ':\'(', + ':-)', + ':-*', + ':-$', + ':-\\', + ':-[', + ':-!', + ':S', + ':O', + ':-O', + 'B-)', + 'o_O', + 'O_o', + '^O^', + '-.-', + '^_^', + '^﹏^', + '^m^', + '^/^', + '~_~', + '-_-', + '-_-||', + '>_<', + '><', + '>﹏<', + '_#', + '\#_#', + '*-*', + '(^^)', + '(^_^)', + '(^.^)', + '(^!^)', + '(^J^)', + '(^m^)', + '(^\'^)', + '(^_-)', + '(^O^)', + '(^o^)', + '(^q^)', + '(^○^)', + '(^O^;)', + '(^m^;)', + '(^Q^)', + '!(^^)!', + 'T_T', + '(ToT)', + '(T_T)', + '\@_\@', + '=.=', + '=.=!', + '=_=', + '╰_╯', + '-_-z', + '^_-', + '囧rz', + 'Orz', + '→_→', + '←_←', + '≧◇≦', + '(x_x)', + '(′o`)', + '(′ェ`)', + '(?_?)', + '(′θ`)', + '(*_*)', + '(@@)', + '⊙▽⊙', + '⊙△⊙', + '⊙_⊙', + '⊙﹏⊙', + '◑﹏◐', + '◑︿◐', + '◑__◐', + '∩__∩', + '∩﹏∩', + '(ˇˍˇ)', + '(′▽`〃)', + '(′0ノ`*)', + '(^_^;)', + '(@_@)', + '(*^^*)', + '(´・ω・`)', + '(=θωθ=)', + '(°ο°)', + '^(oo)^', + '(#^.^#)', + '(*^_^*)', + '(¯(●●)¯)', + '>"<|||', + '(′~`;)', + '(=′?`=)', + '(○’ω’○)', + 'o(≧o≦)o', + '(??_??)?', + '└(^o^)┘', + '(︶^︶)', + '(>.<*)', + '(⊙o⊙)', + '(⊙﹏⊙)', + '=^_^=', + '::>_<::', + '↖(^ω^)↗', + '~w_w~'] + ]; + var keyList = []; + var mapping = {}; + keyList.push(util.createTabBarKey('Tabbar0', EmojiType.RECENT, + Css.EMOJI_TABBAR_RECENT)); + keyList.push(util.createTabBarKey('Tabbar1', EmojiType.HOT, + Css.EMOJI_TABBAR_HOT)); + keyList.push(util.createTabBarKey('Tabbar2', EmojiType.EMOTION, + Css.EMOJI_TABBAR_EMOTION)); + keyList.push(util.createTabBarKey('Tabbar3', EmojiType.ITEMS, + Css.EMOJI_TABBAR_ITEMS)); + keyList.push(util.createTabBarKey('Tabbar4', EmojiType.NATURE, + Css.EMOJI_TABBAR_NATURE)); + keyList.push(util.createTabBarKey('Tabbar5', EmojiType.PLACES_OF_INTERESTS, + Css.EMOJI_TABBAR_PLACES_OF_INTERESTS)); + keyList.push(util.createTabBarKey('Tabbar6', + EmojiType.SPECIAL_CHARACTERS, + Css.EMOJI_TABBAR_SPECIAL_CHARACTERS)); + keyList.push(util.createTabBarKey('Tabbar7', EmojiType.EMOTICON, + Css.EMOJI_TABBAR_EMOTICON)); + + var amount = 0; + var acturalLength = 0; + for (var i = 0, len = keyCharacters.length; i < len; i++) { + acturalLength = Math.ceil(keyCharacters[i].length / emojiKeyAmount) * + emojiKeyAmount; + for (var j = 0, lenJ = keyCharacters[i].length; j < lenJ; j++) { + var spec = {}; + spec[SpecNodeName.ID] = 'emojikey' + amount; + spec[SpecNodeName.TYPE] = ElementType.EMOJI_KEY; + spec[SpecNodeName.TEXT] = keyCharacters[i][j]; + spec[SpecNodeName.IS_EMOTICON] = (i == EmojiType.EMOTICON); + var key = i18n.input.chrome.inputview.content.util.createKey(spec); + keyList.push(key); + amount++; + } + for (var j = keyCharacters[i].length; j < acturalLength; j++) { + var spec = {}; + spec[SpecNodeName.ID] = 'emojikey' + amount; + spec[SpecNodeName.TYPE] = ElementType.EMOJI_KEY; + spec[SpecNodeName.TEXT] = ''; + spec[SpecNodeName.IS_EMOTICON] = (i == EmojiType.EMOTICON); + var key = i18n.input.chrome.inputview.content.util.createKey(spec); + keyList.push(key); + amount++; + } + } + keyList.push(util.createBackspaceKey()); + keyList.push(util.createEnterKey()); + keyList.push(util.createHideKeyboardKey()); + + var tabbarLength = 1 + keyCharacters.length; + var key = []; + + // Map the tabbars. + for (var i = 0, len = keyCharacters.length; i < len; i++) { + key = keyList[i]; + mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i; + } + + // Map the emoji keys. + amount = 0; + var offset = tabbarLength + 1; + for (var i = 0, len = keyCharacters.length; i < len; i++) { + acturalLength = Math.ceil(keyCharacters[i].length / emojiKeyAmount) * + emojiKeyAmount; + for (var j = 0, lenJ = acturalLength; j < lenJ; j++) { + key = keyList[amount + len]; + mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + (amount + + offset); + amount++; + } + } + + // Map the side keys + for (var i = 0; i < 3; ++i) { + key = keyList[i + amount + keyCharacters.length]; + mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + + (i + amount + offset); + } + + amount = amount + offset + 3; + //The space row. + var tmp = util.createBackToKeyboardKey(); + keyList.push(tmp); + mapping[tmp['spec'][SpecNodeName.ID]] = viewIdPrefix + amount++; + tmp = util.createSpaceKey(); + keyList.push(tmp); + mapping[tmp['spec'][SpecNodeName.ID]] = viewIdPrefix + amount++; + tmp = util.createHideKeyboardKey(); + keyList.push(tmp); + mapping[tmp['spec'][SpecNodeName.ID]] = viewIdPrefix + amount++; + + var result = []; + result[SpecNodeName.TEXT] = keyCharacters; + result[SpecNodeName.KEY_LIST] = keyList; + result[SpecNodeName.MAPPING] = mapping; + result[SpecNodeName.LAYOUT] = 'emoji'; + result['id'] = 'emoji'; + google.ime.chrome.inputview.onConfigLoaded(result); +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/config/material/hwt_data.js b/third_party/google_input_tools/src/chrome/os/inputview/config/material/hwt_data.js new file mode 100644 index 0000000..b266bb0 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/config/material/hwt_data.js
@@ -0,0 +1,75 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.SpecNodeName'); +goog.require('i18n.input.chrome.inputview.content.util'); +goog.require('i18n.input.chrome.inputview.elements.ElementType'); + +(function() { + var util = i18n.input.chrome.inputview.content.util; + var ElementType = i18n.input.chrome.inputview.elements.ElementType; + var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; + var Css = i18n.input.chrome.inputview.Css; + + var viewIdPrefix = 'handwriting-k-'; + + var spec = {}; + spec[SpecNodeName.ID] = 'SingleQuote'; + spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY; + spec[SpecNodeName.CHARACTERS] = ['\'']; + var singleQuoteKey = util.createKey(spec); + + spec[SpecNodeName.ID] = 'Comma'; + spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY; + spec[SpecNodeName.CHARACTERS] = [',']; + var commaKey = util.createKey(spec); + + spec = {}; + spec[SpecNodeName.ID] = 'Period'; + spec[SpecNodeName.TYPE] = ElementType.CHARACTER_KEY; + spec[SpecNodeName.CHARACTERS] = ['.']; + var periodKey = util.createKey(spec); + + spec = {}; + spec[SpecNodeName.TEXT] = ''; + spec[SpecNodeName.ICON_CSS_CLASS] = Css.SPACE_ICON; + spec[SpecNodeName.TYPE] = ElementType.SPACE_KEY; + spec[SpecNodeName.ID] = 'Space'; + var spaceKey = i18n.input.chrome.inputview.content.util.createKey(spec); + + var keyList = [ + singleQuoteKey, + commaKey, + periodKey, + util.createBackToKeyboardKey(), + util.createBackspaceKey(), + util.createEnterKey(), + spaceKey, + util.createHideKeyboardKey() + ]; + + var mapping = {}; + for (var i = 0; i < keyList.length; i++) { + var key = keyList[i]; + mapping[key['spec'][SpecNodeName.ID]] = viewIdPrefix + i; + } + + var result = []; + result[SpecNodeName.KEY_LIST] = keyList; + result[SpecNodeName.MAPPING] = mapping; + result[SpecNodeName.LAYOUT] = 'handwriting'; + result[SpecNodeName.HAS_ALTGR_KEY] = false; + result['id'] = 'hwt'; + google.ime.chrome.inputview.onConfigLoaded(result); +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/config/util.js b/third_party/google_input_tools/src/chrome/os/inputview/config/util.js index 560ba12..928fd8cf 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/config/util.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/config/util.js
@@ -153,6 +153,21 @@ /** + * Create the key which leads to keyboard from emoji/hwt. + * + * @return {!Object} The back key. + */ +i18n.input.chrome.inputview.content.util.createBackToKeyboardKey = function() { + var spec = {}; + spec[SpecNodeName.ICON_CSS_CLASS] = + i18n.input.chrome.inputview.Css.BACK_TO_KEYBOARD_ICON; + spec[SpecNodeName.TYPE] = ElementType.BACK_TO_KEYBOARD; + spec[SpecNodeName.ID] = 'backToKeyboard'; + return i18n.input.chrome.inputview.content.util.createKey(spec); +}; + + +/** * Creates a ctrl key. * * @return {!Object} The ctrl key.
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/controller.js b/third_party/google_input_tools/src/chrome/os/inputview/controller.js index f0f49795..fecf7b0 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/controller.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/controller.js
@@ -24,6 +24,7 @@ goog.require('goog.i18n.bidi'); goog.require('goog.object'); goog.require('i18n.input.chrome.DataSource'); +goog.require('i18n.input.chrome.SoundController'); goog.require('i18n.input.chrome.Statistics'); goog.require('i18n.input.chrome.inputview.Adapter'); goog.require('i18n.input.chrome.inputview.CandidatesInfo'); @@ -36,7 +37,6 @@ goog.require('i18n.input.chrome.inputview.ReadyState'); goog.require('i18n.input.chrome.inputview.Settings'); goog.require('i18n.input.chrome.inputview.SizeSpec'); -goog.require('i18n.input.chrome.inputview.SoundController'); goog.require('i18n.input.chrome.inputview.SpecNodeName'); goog.require('i18n.input.chrome.inputview.StateType'); goog.require('i18n.input.chrome.inputview.SwipeDirection'); @@ -76,7 +76,7 @@ var SpecNodeName = i18n.input.chrome.inputview.SpecNodeName; var StateType = i18n.input.chrome.inputview.StateType; var content = i18n.input.chrome.inputview.elements.content; -var SoundController = i18n.input.chrome.inputview.SoundController; +var SoundController = i18n.input.chrome.SoundController; var Sounds = i18n.input.chrome.inputview.Sounds; var Type = i18n.input.chrome.message.Type; var util = i18n.input.chrome.inputview.util; @@ -116,6 +116,23 @@ this.layoutDataMap_ = {}; /** + * The element map. + * + * @private {!Object.<ElementType, !KeyCodes>} + */ + this.elementTypeToKeyCode_ = goog.object.create( + ElementType.BOLD, KeyCodes.KEY_B, + ElementType.ITALICS, KeyCodes.KEY_I, + ElementType.UNDERLINE, KeyCodes.KEY_U, + ElementType.COPY, KeyCodes.KEY_C, + ElementType.PASTE, KeyCodes.KEY_V, + ElementType.CUT, KeyCodes.KEY_X, + ElementType.SELECT_ALL, KeyCodes.KEY_A, + ElementType.REDO, KeyCodes.KEY_Y, + ElementType.UNDO, KeyCodes.KEY_Z + ); + + /** * The keyset data map. * * @type {!Object.<string, !Object>} @@ -162,14 +179,14 @@ /** @private {!i18n.input.chrome.inputview.Adapter} */ this.adapter_ = new i18n.input.chrome.inputview.Adapter(this.readyState_); + /** @private {!i18n.input.chrome.SoundController} */ + this.soundController_ = new SoundController(false); + /** @private {!i18n.input.chrome.inputview.KeyboardContainer} */ this.container_ = new i18n.input.chrome.inputview.KeyboardContainer( - this.adapter_); + this.adapter_, this.soundController_); this.container_.render(); - /** @private {!i18n.input.chrome.inputview.SoundController} */ - this.soundController_ = new SoundController(false); - /** * The context type and keyset mapping group by input method id. * key: input method id. @@ -359,6 +376,17 @@ /** + * A temporary list to track keysets have customized in material design. + * + * @private {!Array.<string>} + */ +Controller.MATERIAL_KEYSETS_ = [ + 'emoji', + 'hwt' +]; + + +/** * The active language code. * * @type {string} @@ -440,28 +468,21 @@ ], this.onPointerEvent_). listen(window, goog.events.EventType.RESIZE, this.resize). listen(this.adapter_, - i18n.input.chrome.inputview.events.EventType. - SURROUNDING_TEXT_CHANGED, - this.onSurroundingTextChanged_). + EventType.SURROUNDING_TEXT_CHANGED, this.onSurroundingTextChanged_). listen(this.adapter_, i18n.input.chrome.DataSource.EventType.CANDIDATES_BACK, this.onCandidatesBack_). - listen(this.adapter_, - i18n.input.chrome.inputview.events.EventType.CONTEXT_FOCUS, - this.onContextFocus_). - listen(this.adapter_, - i18n.input.chrome.inputview.events.EventType.CONTEXT_BLUR, - this.onContextBlur_). - listen(this.adapter_, - i18n.input.chrome.inputview.events.EventType.VISIBILITY_CHANGE, + listen(this.adapter_, EventType.URL_CHANGED, this.onURLChanged_). + listen(this.adapter_, EventType.CONTEXT_FOCUS, this.onContextFocus_). + listen(this.adapter_, EventType.CONTEXT_BLUR, this.onContextBlur_). + listen(this.adapter_, EventType.VISIBILITY_CHANGE, this.onVisibilityChange_). - listen(this.adapter_, - i18n.input.chrome.inputview.events.EventType.SETTINGS_READY, - this.onSettingsReady_). + listen(this.adapter_, EventType.SETTINGS_READY, this.onSettingsReady_). listen(this.adapter_, Type.UPDATE_SETTINGS, this.onUpdateSettings_). listen(this.adapter_, Type.FRONT_TOGGLE_LANGUAGE_STATE, this.onUpdateToggleLanguateState_). - listen(this.adapter_, Type.VOICE_STATE_CHANGE, this.onVoiceStateChange_); + listen(this.adapter_, Type.VOICE_STATE_CHANGE, this.onVoiceStateChange_). + listen(this.adapter_, EventType.REFRESH, this.onRefresh_); }; @@ -482,6 +503,16 @@ /** + * Handles the refresh event from adapter. + * + * @private + */ +Controller.prototype.onRefresh_ = function() { + window.location.reload(); +}; + + +/** * Sets the default keyset for context types. * * @param {string} newKeyset . @@ -536,6 +567,16 @@ /** + * Callback for url changed. + * + * @private + */ +Controller.prototype.onURLChanged_ = function() { + this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_()); +}; + + +/** * Callback for setting ready. * * @private @@ -561,6 +602,8 @@ if (newKeyset) { this.setDefaultKeyset_(newKeyset); } + this.container_.selectView.setVisible( + this.adapter_.isGestureEdittingEnabled()); // Loads resources in case the default keyset is changed. this.loadAllResources_(); this.maybeCreateViews_(); @@ -695,6 +738,13 @@ this.container_.altDataView.highlightItem(e.x, e.y); return; } + if (view.type == ElementType.BACKSPACE_KEY) { + if (this.container_.swipeView.isVisible() || + this.container_.swipeView.isArmed()) { + this.stopBackspaceAutoRepeat_(); + return; + } + } if (view.type == ElementType.CHARACTER_KEY) { view = /** @type {!content.CharacterKey} */ (view); @@ -780,12 +830,13 @@ 'InputMethod.VirtualKeyboard.TapCount', 1, 4095, 4096); } - if (e.type == i18n.input.chrome.inputview.events.EventType.SWIPE) { + if (e.type == EventType.SWIPE) { e = /** @type {!i18n.input.chrome.inputview.events.SwipeEvent} */ (e); this.handleSwipeAction_(view, e); } switch (view.type) { case ElementType.BACK_BUTTON: + case ElementType.BACK_TO_KEYBOARD: if (e.type == EventType.POINTER_OUT || e.type == EventType.POINTER_UP) { view.setHighlighted(false); } else if (e.type == EventType.POINTER_DOWN || @@ -897,7 +948,7 @@ return; case ElementType.VOICE_BTN: - if (e.type == EventType.CLICK) { + if (e.type == EventType.POINTER_UP) { this.container_.candidateView.switchToIcon( CandidateView.IconType.VOICE, false); this.container_.voiceView.start(); @@ -913,7 +964,33 @@ this.container_.voiceView.stop(); } return; - + case ElementType.SWIPE_VIEW: + this.stopBackspaceAutoRepeat_(); + if (e.type == EventType.POINTER_UP || + e.type == EventType.POINTER_OUT) { + this.clearUnstickyState_(); + } + return; + case ElementType.CUT: + case ElementType.COPY: + case ElementType.PASTE: + case ElementType.BOLD: + case ElementType.ITALICS: + case ElementType.UNDERLINE: + case ElementType.REDO: + case ElementType.UNDO: + case ElementType.SELECT_ALL: + view.setHighlighted(e.type == EventType.POINTER_DOWN || + e.type == EventType.POINTER_OVER); + if (e.type == EventType.POINTER_UP) { + this.adapter_.sendKeyDownAndUpEvent( + '', this.elementTypeToKeyCode_[view.type], undefined, undefined, { + ctrl: true, + alt: false, + shift: false + }); + } + return; case ElementType.SOFT_KEY_VIEW: // Delegates the events on the soft key view to its soft key. view = /** @type {!i18n.input.chrome.inputview.elements.layout. @@ -926,7 +1003,8 @@ if (view.type != ElementType.MODIFIER_KEY && !this.container_.altDataView.isVisible() && - !this.container_.menuView.isVisible()) { + !this.container_.menuView.isVisible() && + !this.container_.swipeView.isVisible()) { // The highlight of the modifier key is depending on the state instead // of the key down or up. if (e.type == EventType.POINTER_OVER || e.type == EventType.POINTER_DOWN || @@ -1012,8 +1090,9 @@ this.backspaceTick_(); } else if (e.type == EventType.POINTER_UP || e.type == EventType. POINTER_OUT) { - this.stopBackspaceAutoRepeat_(); - this.adapter_.sendKeyUpEvent('\u0008', KeyCodes.BACKSPACE); + if (!this.container_.swipeView.isVisible()) { + this.stopBackspaceAutoRepeat_(); + } } break; @@ -1075,7 +1154,8 @@ case ElementType.SPACE_KEY: key = /** @type {!content.SpaceKey} */ (softKey); var doubleSpacePeriod = this.model_.settings.doubleSpacePeriod && - this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_; + this.currentKeyset_ != Controller.HANDWRITING_VIEW_CODE_ && + this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_; if (e.type == EventType.POINTER_UP || (!doubleSpacePeriod && e.type == EventType.DOUBLE_CLICK_END)) { this.adapter_.sendKeyDownAndUpEvent(key.getCharacter(), @@ -1286,11 +1366,24 @@ this.resize(); this.container_.expandedCandidateView.close(); this.container_.menuView.hide(); + this.container_.swipeView.reset(); this.container_.altDataView.hide(); }; /** + * Returns whether the toolbar should be shown. + * + * @return {boolean} + * @private + */ +Controller.prototype.shouldShowToolBar_ = function() { + return this.adapter_.isExperimental && this.adapter_.isGoogleDocument() && + this.adapter_.contextType == ContextType.DEFAULT; +}; + + +/** * Callback when the context is changed. * * @private @@ -1501,13 +1594,15 @@ if (this.container_.currentKeysetView) { this.container_.currentKeysetView.setVisible(true); } - if (this.currentKeyset_ == Controller.HANDWRITING_VIEW_CODE_) { - this.container_.candidateView.switchToIcon( - CandidateView.IconType.BACK, true); - } else { - this.container_.candidateView.switchToIcon(CandidateView.IconType.VOICE, - this.currentKeyset_ != Controller.EMOJI_VIEW_CODE_ && - this.adapter_.isExperimental); + if (!this.adapter_.isQPInputView) { + if (this.currentKeyset_ == Controller.HANDWRITING_VIEW_CODE_ || + this.currentKeyset_ == Controller.EMOJI_VIEW_CODE_) { + this.container_.candidateView.switchToIcon( + CandidateView.IconType.BACK, true); + } else { + this.container_.candidateView.switchToIcon(CandidateView.IconType.VOICE, + this.adapter_.isVoiceInputEnabled); + } } }; @@ -1636,7 +1731,12 @@ this.contextTypeToKeysetMap_[this.currentInputMethod_][contextType] = keyset; } - this.loadResource_(keyset); + if (this.adapter_.isQPInputView && + goog.array.contains(Controller.MATERIAL_KEYSETS_, keyset)) { + this.loadResource_('m-' + keyset); + } else { + this.loadResource_(keyset); + } } }; @@ -1665,7 +1765,7 @@ } var layoutId = data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT]; - if (this.adapter_.isQPInputView && layoutId == 'compactkbd-qwerty') { + if (this.adapter_.isQPInputView) { layoutId = 'm-' + layoutId; data[i18n.input.chrome.inputview.SpecNodeName.LAYOUT] = layoutId; } @@ -1733,6 +1833,7 @@ this.container_.resize(screen.width, height, widthPercent, candidateViewHeight); + this.container_.candidateView.setToolbarVisible(this.shouldShowToolBar_()); if (this.container_.currentKeysetView) { this.isKeyboardReady = true; }
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/css.js b/third_party/google_input_tools/src/chrome/os/inputview/css.js index ca4c5da2..d08b111 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/css.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/css.js
@@ -28,6 +28,8 @@ ALTGR_CONTENT: goog.getCssName('inputview-ac'), ARROW_KEY: goog.getCssName('inputview-arrow-key'), BACKSPACE_ICON: goog.getCssName('inputview-backspace-icon'), + BACK_TO_KEYBOARD_ICON: goog.getCssName('inputview-back-to-keyboard'), + BOLD_ICON: goog.getCssName('inputview-bold-icon'), CANDIDATE: goog.getCssName('inputview-candidate'), CANDIDATES_LINE: goog.getCssName('inputview-candidates-line'), CANDIDATES_TOP_LINE: goog.getCssName('inputview-candidates-top-line'), @@ -52,6 +54,8 @@ CHECKED_MENU_LIST: goog.getCssName('inputview-checked-menu-list'), COMPACT_KEY: goog.getCssName('inputview-compact-key'), COMPACT_SWITCHER: goog.getCssName('inputview-compact-switcher'), + COPY_ICON: goog.getCssName('inputview-copy-icon'), + CUT_ICON: goog.getCssName('inputview-cut-icon'), CONTAINER: goog.getCssName('inputview-container'), DEFAULT_CONTENT: goog.getCssName('inputview-dc'), DIGIT_CHARACTER: goog.getCssName('inputview-digit-character'), @@ -90,6 +94,7 @@ EN_SWITCHER_ENGLISH: goog.getCssName('inputview-en-switcher-english'), EXPAND_CANDIDATES_ICON: goog.getCssName('inputview-expand-candidates-icon'), EXTENDED_LAYOUT_TRANSITION: goog.getCssName('inputview-extended-transition'), + FLOAT_LEFT: goog.getCssName('float-left'), FONT: goog.getCssName('inputview-font'), FONT_SMALL: goog.getCssName('inputview-font-small'), FUNCITONAL_KEY_STICKY: goog.getCssName('inputview-functional-key-sticky'), @@ -115,6 +120,7 @@ INDICATOR: goog.getCssName('inputview-indicator'), INDICATOR_BACKGROUND: goog.getCssName('inputview-indicator-background'), INLINE_DIV: goog.getCssName('inputview-inline-div'), + ITALICS_ICON: goog.getCssName('inputview-italics-icon'), JP_IME_SWITCH: goog.getCssName('inputview-jp-ime-switch'), KEY_HOLD: goog.getCssName('inputview-key-hold'), LANDSCAPE: goog.getCssName('inputview-landscape'), @@ -143,26 +149,42 @@ MODIFIER_STATE_ICON: goog.getCssName('inputview-modifier-state-icon'), PAGE_DOWN_ICON: goog.getCssName('inputview-page-down-icon'), PAGE_UP_ICON: goog.getCssName('inputview-page-up-icon'), + PASTE_ICON: goog.getCssName('inputview-paste-icon'), PINYIN: goog.getCssName('inputview-pinyin'), PORTRAIT: goog.getCssName('inputview-portrait'), + REDO_ICON: goog.getCssName('inputview-redo-icon'), REGULAR_SWITCHER: goog.getCssName('inputview-regular-switcher'), RIGHT_KEY: goog.getCssName('inputview-right-key'), + SELECT_ALL_ICON: goog.getCssName('inputview-select-all-icon'), + SELECT_KNOB_LEFT: goog.getCssName('inputview-select-knob-left'), + SELECT_KNOB_RIGHT: goog.getCssName('inputview-select-knob-right'), SHIFT_ICON: goog.getCssName('inputview-shift-icon'), SHRINK_CANDIDATES_ICON: goog.getCssName('inputview-shrink-candidates-icon'), SOFT_KEY: goog.getCssName('inputview-sk'), SOFT_KEY_VIEW: goog.getCssName('inputview-skv'), SPACE_ICON: goog.getCssName('inputview-space-icon'), SPACE_WRAPPER: goog.getCssName('inputview-space-wrapper'), + SPACE_GREY_BG: goog.getCssName('inputview-space-grey-bg'), SPECIAL_KEY_BG: goog.getCssName('inputview-special-key-bg'), SPECIAL_KEY_HIGHLIGHT: goog.getCssName('inputview-special-key-highlight'), SPECIAL_KEY_NAME: goog.getCssName('inputview-special-key-name'), + SWIPE_KEY: goog.getCssName('inputview-swipe-key'), + SWIPE_SEPARATOR: goog.getCssName('inputview-swipe-separator'), + SWIPE_VIEW: goog.getCssName('inputview-swipe-view'), SWITCHER_CHINESE: goog.getCssName('inputview-switcher-chinese'), SWITCHER_ENGLISH: goog.getCssName('inputview-switcher-english'), + SWITCHER_KEY_NAME: goog.getCssName('inputview-switcher-key-name'), TABLE_CELL: goog.getCssName('inputview-table-cell'), TAB_ICON: goog.getCssName('inputview-tab-icon'), THREE_CANDIDATES: goog.getCssName('inputview-three-candidates'), TITLE: goog.getCssName('inputview-title'), TITLE_BAR: goog.getCssName('inputview-title-bar'), + TOOLBAR_SEPARATOR: goog.getCssName('inputview-toolbar-separator'), + TOOLBAR_BUTTON: goog.getCssName('inputview-toolbar-button'), + TOOLBAR_CONTAINER: goog.getCssName('inputview-toolbar-container'), + TRACK_COVER: goog.getCssName('inputview-track-cover'), + UNDERLINE_ICON: goog.getCssName('inputview-underline-icon'), + UNDO_ICON: goog.getCssName('inputview-undo-icon'), UP_KEY: goog.getCssName('inputview-up-key'), VERTICAL_LAYOUT: goog.getCssName('inputview-vertical'), VIEW: goog.getCssName('inputview-view'),
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/backspacekey.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/backspacekey.js new file mode 100644 index 0000000..c81c3ab --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/backspacekey.js
@@ -0,0 +1,46 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.provide('i18n.input.chrome.inputview.elements.content.BackspaceKey'); + +goog.require('i18n.input.chrome.inputview.elements.content.FunctionalKey'); + + + +goog.scope(function() { + +/** + * The backspace key. + * + * @param {string} id The id. + * @param {!i18n.input.chrome.inputview.elements.ElementType} type The element + * type. + * @param {string} text The text. + * @param {string} iconCssClass The css class for the icon. + * @param {goog.events.EventTarget=} opt_eventTarget The event target. + * @param {string=} opt_textCssClass The css class for the text. + * @constructor + * @extends {i18n.input.chrome.inputview.elements.content.FunctionalKey} + */ +i18n.input.chrome.inputview.elements.content.BackspaceKey = function(id, type, + text, iconCssClass, opt_eventTarget, opt_textCssClass) { + goog.base(this, id, type, text, iconCssClass, opt_eventTarget, + opt_textCssClass); + + this.pointerConfig.longPressWithPointerUp = true; + this.pointerConfig.longPressDelay = 300; +}; +goog.inherits(i18n.input.chrome.inputview.elements.content.BackspaceKey, + i18n.input.chrome.inputview.elements.content.FunctionalKey); +}); // goog.scope +
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/candidateview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/candidateview.js index 84ce75fc..5ccc1e84 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/candidateview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/candidateview.js
@@ -20,10 +20,12 @@ goog.require('goog.object'); goog.require('goog.style'); goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.GlobalFlags'); goog.require('i18n.input.chrome.inputview.elements.Element'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); goog.require('i18n.input.chrome.inputview.elements.content.Candidate'); goog.require('i18n.input.chrome.inputview.elements.content.CandidateButton'); +goog.require('i18n.input.chrome.inputview.elements.content.ToolbarButton'); goog.require('i18n.input.chrome.message.Name'); @@ -66,18 +68,46 @@ */ this.iconButtons_ = []; - this.iconButtons_[CandidateView.IconType.BACK] = new content.CandidateButton( + this.iconButtons_[IconType.BACK] = new content.CandidateButton( '', ElementType.BACK_BUTTON, '', chrome.i18n.getMessage('HANDWRITING_BACK'), this); - this.iconButtons_[CandidateView.IconType.SHRINK_CANDIDATES] = new content. + this.iconButtons_[IconType.SHRINK_CANDIDATES] = new content. CandidateButton('', ElementType.SHRINK_CANDIDATES, Css.SHRINK_CANDIDATES_ICON, '', this); - this.iconButtons_[CandidateView.IconType.EXPAND_CANDIDATES] = new content. + + this.iconButtons_[IconType.EXPAND_CANDIDATES] = new content. CandidateButton('', ElementType.EXPAND_CANDIDATES, Css.EXPAND_CANDIDATES_ICON, '', this); - this.iconButtons_[CandidateView.IconType.VOICE] = new content. + + this.iconButtons_[IconType.VOICE] = new content. CandidateButton('', ElementType.VOICE_BTN, Css.VOICE_MIC_BAR, '', this, true); + + /** + * Toolbar buttons. + * + * @private {!Array.<!i18n.input.chrome.inputview.elements.Element>} + */ + this.toolbarButtons_ = []; + + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.UNDO, Css.UNDO_ICON, '', this, true)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.REDO, Css.REDO_ICON, '', this, true)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.BOLD, Css.BOLD_ICON, '', this, true)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.ITALICS, Css.ITALICS_ICON, '', this, true)); + this.toolbarButtons_.push(new content.ToolbarButton( + '', ElementType.UNDERLINE, Css.UNDERLINE_ICON, '', this, true)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.CUT, Css.CUT_ICON, '', this)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.COPY, Css.COPY_ICON, '', this)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.PASTE, Css.PASTE_ICON, '', this)); + this.toolbarButtons_.push(new content. + ToolbarButton('', ElementType.SELECT_ALL, Css.SELECT_ALL_ICON, '', this)); }; goog.inherits(i18n.input.chrome.inputview.elements.content.CandidateView, i18n.input.chrome.inputview.elements.Element); @@ -85,7 +115,7 @@ /** - * The icon type at the right of the candiate view. + * The icon type at the right of the candidate view. * * @enum {number} */ @@ -95,6 +125,7 @@ EXPAND_CANDIDATES: 2, VOICE: 3 }; +var IconType = CandidateView.IconType; /** @@ -132,7 +163,7 @@ /** - * true if it is showing number row. + * True if it is showing number row. * * @type {boolean} */ @@ -140,6 +171,14 @@ /** + * True if showing the toolbar row. + * + * @type {boolean} + */ +CandidateView.prototype.showingToolbar = false; + + +/** * The width for a candidate when showing in THREE_CANDIDATE mode. * * @type {number} @@ -158,6 +197,14 @@ /** + * The width of icons in the toolbar. + * + * @private {number} + */ +CandidateView.TOOLBAR_ICON_WIDTH_ = 40; + + +/** * The handwriting keyset code. * * @private {string} @@ -187,6 +234,13 @@ var dom = this.getDomHelper(); var elem = this.getElement(); + + for (var i = 0; i < this.toolbarButtons_.length; i++) { + var button = this.toolbarButtons_[i]; + button.render(elem); + button.setVisible(false); + } + this.interContainer_ = dom.createDom(TagName.DIV, Css.CANDIDATE_INTER_CONTAINER); dom.appendChild(elem, this.interContainer_); @@ -196,10 +250,16 @@ button.render(elem); button.setVisible(false); } + goog.a11y.aria.setState(/** @type {!Element} */ - (this.iconButtons_[CandidateView.IconType.VOICE].getElement()), + (this.iconButtons_[IconType.SHRINK_CANDIDATES].getElement()), goog.a11y.aria.State.LABEL, - chrome.i18n.getMessage('VOICE_TURN_ON')); + chrome.i18n.getMessage('SHRINK_CANDIDATES')); + + goog.a11y.aria.setState(/** @type {!Element} */ + (this.iconButtons_[IconType.EXPAND_CANDIDATES].getElement()), + goog.a11y.aria.State.LABEL, + chrome.i18n.getMessage('EXPAND_CANDIDATES')); }; @@ -248,12 +308,12 @@ if (candidates.length > 0) { if (showThreeCandidates) { this.addThreeCandidates_(candidates); - // Hide the voice icons. - this.switchToIcon(CandidateView.IconType.VOICE, false); } else { this.addFullCandidates_(candidates); - this.switchToIcon(CandidateView.IconType.EXPAND_CANDIDATES, - !!opt_expandable && this.candidateCount < candidates.length); + if (!this.iconButtons_[IconType.BACK].isVisible()) { + this.switchToIcon(IconType.EXPAND_CANDIDATES, + !!opt_expandable && this.candidateCount < candidates.length); + } } this.showingCandidates = true; this.showingNumberRow = false; @@ -272,10 +332,13 @@ i18n.input.chrome.inputview.Css.THREE_CANDIDATES); var num = Math.min(3, candidates.length); var dom = this.getDomHelper(); + var width = CandidateView.WIDTH_FOR_THREE_CANDIDATES_; + if (this.showingToolbar) { + width -= CandidateView.ICON_WIDTH_ / 3; + } for (var i = 0; i < num; i++) { var candidateElem = new Candidate(String(i), candidates[i], Type.CANDIDATE, - this.height, i == 1 || num == 1, CandidateView. - WIDTH_FOR_THREE_CANDIDATES_, this); + this.height, i == 1 || num == 1, width, this); candidateElem.render(this.interContainer_); } this.candidateCount = num; @@ -352,6 +415,10 @@ button.resize(CandidateView.ICON_WIDTH_, height); } + for (var i = 0; i < this.toolbarButtons_.length; i++) { + var button = this.toolbarButtons_[i]; + button.resize(CandidateView.TOOLBAR_ICON_WIDTH_, height); + } // Resets the candidates elements visibility. if (this.candidateCount > 0) { @@ -383,16 +450,34 @@ CandidateView.prototype.switchToIcon = function(type, visible) { for (var i = 0; i < this.iconButtons_.length; i++) { // Don't enable voice when focus in password box. - this.iconButtons_[i].setVisible(visible && type == i && - (type != CandidateView.IconType.VOICE || !this.candidateCount && - this.adapter_.contextType != 'password')); + this.iconButtons_[i].setVisible(false); } - // We need make default voice icon showed if the position doesn't show other - // icon. - if (!visible && this.adapter_.isExperimental && + if (visible) { + if (type != IconType.VOICE) { + this.iconButtons_[type].setVisible(true); + } else if (this.adapter_.isVoiceInputEnabled && + this.adapter_.contextType != 'password') { + this.iconButtons_[type].setVisible(true); + } + } else if (this.adapter_.isVoiceInputEnabled && + type != IconType.VOICE && this.adapter_.contextType != 'password') { - this.iconButtons_[CandidateView.IconType.VOICE].setVisible(true); + // Default to show voice icon. + this.iconButtons_[IconType.VOICE].setVisible(true); + } +}; + + +/** + * Changes the visibility of the toolbar and it's icons. + * + * @param {boolean} visible The target visibility. + */ +CandidateView.prototype.setToolbarVisible = function(visible) { + this.showingToolbar = visible; + for (var i = 0; i < this.toolbarButtons_.length; i++) { + this.toolbarButtons_[i].setVisible(visible); } }; @@ -406,12 +491,15 @@ */ CandidateView.prototype.updateByKeyset = function( keyset, isPasswordBox, isRTL) { - if (keyset == CandidateView.HANDWRITING_VIEW_CODE_) { - this.switchToIcon(CandidateView.IconType.BACK, true); - } else if (keyset != CandidateView.EMOJI_VIEW_CODE_ && !this.candidateCount && - this.adapter_.isExperimental) { - // If candidates count is greater than 0, don't show voice icon. - this.switchToIcon(CandidateView.IconType.VOICE, true); + if (!i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + if (keyset == CandidateView.HANDWRITING_VIEW_CODE_ || + keyset == CandidateView.EMOJI_VIEW_CODE_) { + this.switchToIcon(IconType.BACK, true); + } else { + this.switchToIcon(IconType.VOICE, + this.adapter_.isVoiceInputEnabled && + this.adapter_.contextType != 'password'); + } } if (isPasswordBox && keyset.indexOf('compact') != -1) { @@ -421,4 +509,13 @@ } this.interContainer_.style.direction = isRTL ? 'rtl' : 'ltr'; }; + + +/** @override */ +CandidateView.prototype.disposeInternal = function() { + goog.disposeAll(this.toolbarButtons_); + goog.disposeAll(this.iconButtons_); + + goog.base(this, 'disposeInternal'); +}; }); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/characterkey.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/characterkey.js index 6e6ec65..2c0c5f909 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/characterkey.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/characterkey.js
@@ -50,6 +50,8 @@ * @param {boolean} enableShiftRendering Whether renders two letter vertically, * it means show shift letter when in letter state, shows default letter * when in shift state, same as the altgr state. + * @param {boolean} isQpInputView Temporary flag to indicate it is in material + * design. * @param {goog.events.EventTarget=} opt_eventTarget The event target. * @constructor * @extends {i18n.input.chrome.inputview.elements.content.SoftKey} @@ -57,7 +59,7 @@ i18n.input.chrome.inputview.elements.content.CharacterKey = function(id, keyCode, characters, isLetterKey, hasAltGrCharacterInTheKeyset, alwaysRenderAltGrCharacter, stateManager, isRTL, - enableShiftRendering, opt_eventTarget) { + enableShiftRendering, isQpInputView, opt_eventTarget) { goog.base(this, id, i18n.input.chrome.inputview.elements.ElementType. CHARACTER_KEY, opt_eventTarget); @@ -117,6 +119,9 @@ /** @private {boolean} */ this.enableShiftRendering_ = enableShiftRendering; + /** @private {boolean} */ + this.isQpInputView_ = isQpInputView; + this.pointerConfig.longPressWithPointerUp = true; this.pointerConfig.longPressDelay = 500; }; @@ -164,6 +169,7 @@ CharacterKey.STATE_LIST_[i], this.stateManager_, this.enableShiftRendering_, + this.isQpInputView_, this.getCapslockCharacter_(i)); var character = new Character(this.id + '-' + i, model, this.isRTL_); this.addChild(character, true);
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/charactermodel.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/charactermodel.js index cc1aff0..01479fa 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/charactermodel.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/charactermodel.js
@@ -36,13 +36,14 @@ * @param {!i18n.input.chrome.inputview.StateManager} stateManager The state * manager. * @param {boolean} enableShiftRendering . + * @param {boolean} isQpInputView . * @param {string=} opt_capslockCharacter . * @constructor */ i18n.input.chrome.inputview.elements.content.CharacterModel = function( character, belongToLetterKey, hasAltGrCharacterInTheKeyset, alwaysRenderAltGrCharacter, stateType, stateManager, enableShiftRendering, - opt_capslockCharacter) { + isQpInputView, opt_capslockCharacter) { /** * The character. @@ -101,6 +102,9 @@ /** @private {boolean} */ this.enableShiftRendering_ = enableShiftRendering; + + /** @private {boolean} */ + this.isQpInputView_ = isQpInputView; }; var CharacterModel = i18n.input.chrome.inputview.elements.content. CharacterModel; @@ -149,10 +153,13 @@ * @return {boolean} True if the character is visible. */ CharacterModel.prototype.isVisible = function() { - var enableShiftLetter = this.enableShiftRendering_ || - this.stateManager_.hasState(StateType.SHIFT); - var enableDefaultLetter = this.enableShiftRendering_ || !this.stateManager_. - hasState(StateType.SHIFT); + var hasShift = this.stateManager_.hasState(StateType.SHIFT); + var enableShiftLetter = !this.belongToLetterKey_ || hasShift; + var enableDefaultLetter = !this.belongToLetterKey_ || !hasShift; + if (this.isQpInputView_) { + enableShiftLetter = this.enableShiftRendering_ || hasShift; + enableDefaultLetter = this.enableShiftRendering_ || !hasShift; + } if (this.stateType_ == StateType.DEFAULT) { return !this.stateManager_.hasState(StateType.ALTGR) && enableDefaultLetter; }
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/emojiview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/emojiview.js index 6c9c609e..98d6624 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/emojiview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/emojiview.js
@@ -19,9 +19,11 @@ goog.require('goog.positioning.Corner'); goog.require('goog.style'); goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.GlobalFlags'); goog.require('i18n.input.chrome.inputview.SpecNodeName'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); goog.require('i18n.input.chrome.inputview.elements.content.KeysetView'); +goog.require('i18n.input.chrome.inputview.elements.content.PageIndicator'); goog.require('i18n.input.chrome.inputview.events.EventType'); goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); @@ -172,6 +174,14 @@ /** + * The width percent to used inside the emoji panel. + * + * @private {number} + */ +EmojiView.prototype.emojiWidthPercent_ = 1; + + +/** * Whether it is a drag event. * * @private {number} @@ -260,8 +270,37 @@ /** @override */ -EmojiView.prototype.resize = function(outerWidth, outerHeight, opt_force) { - goog.base(this, 'resize', outerWidth, outerHeight, opt_force); +EmojiView.prototype.resize = function(outerWidth, outerHeight, widthPercent, + opt_force) { + if (i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + if (this.getElement() && (!!opt_force || this.outerHeight != outerHeight || + this.outerWidth != outerWidth || + this.emojiWidthPercent_ != widthPercent)) { + this.outerHeight = outerHeight; + this.outerWidth = outerWidth; + goog.style.setSize(this.getElement(), outerWidth, outerHeight); + this.emojiWidthPercent_ = widthPercent; + var marginOrPadding = Math.round((outerWidth - + outerWidth * widthPercent) / 2); + var w = outerWidth - 2 * marginOrPadding; + var tabBar = /** @type {!Element} */ ( + this.getChildViewById('tabBar').getElement()); + tabBar.style.paddingLeft = tabBar.style.paddingRight = + marginOrPadding + 'px'; + var rowsAndKeys = /** @type {!Element} */ ( + this.getChildViewById('rowsAndSideKeys').getElement()); + rowsAndKeys.style.marginLeft = rowsAndKeys.style.marginRight = + marginOrPadding + 'px'; + var spaceRow = /**@type {!Element} */ ( + this.getChildViewById('emojiSpaceRow').getElement()); + spaceRow.style.marginLeft = spaceRow.style.marginRight = + marginOrPadding + 'px'; + this.resizeRows(outerWidth, outerHeight); + } + } else { + goog.base(this, 'resize', outerWidth, outerHeight, widthPercent, + opt_force); + } // Reposition must happen before clear because it will set the width. this.repositionIndicator_(); this.clearEmojiStates(); @@ -510,8 +549,10 @@ var emojiElement = this.emojiSlider_.getElement(); var elem = this.pageIndicator_.getElement(); elem.style.width = goog.style.getSize(emojiElement).width + 'px'; + var rowsAndSideKeys = /** @type {!Element} */ ( + this.getChildViewById('rowsAndSideKeys').getElement()); var position = new goog.positioning.AnchoredViewportPosition( - this.getElement(), goog.positioning.Corner.BOTTOM_START, true); + rowsAndSideKeys, goog.positioning.Corner.BOTTOM_START, true); position.reposition(this.pageIndicator_.getElement(), goog.positioning.Corner.BOTTOM_START); };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/keysetview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/keysetview.js index 392cede..0174e0b 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/keysetview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/keysetview.js
@@ -22,6 +22,7 @@ goog.require('i18n.input.chrome.inputview.Css'); goog.require('i18n.input.chrome.inputview.SpecNodeName'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); +goog.require('i18n.input.chrome.inputview.elements.content.BackspaceKey'); goog.require('i18n.input.chrome.inputview.elements.content.CandidateButton'); goog.require('i18n.input.chrome.inputview.elements.content.CanvasView'); goog.require('i18n.input.chrome.inputview.elements.content.CharacterKey'); @@ -238,19 +239,25 @@ /** * The outer height of the view. * - * @type {number} - * @private + * @protected {number} */ -KeysetView.prototype.outerHeight_ = 0; +KeysetView.prototype.outerHeight = 0; /** * The outer width of the view. * - * @type {number} - * @private + * @protected {number} */ -KeysetView.prototype.outerWidth_ = 0; +KeysetView.prototype.outerWidth = 0; + + +/** + * The width percentage. + * + * @private {number} + */ +KeysetView.prototype.widthPercent_ = 1; /** @override */ @@ -306,33 +313,65 @@ /** + * @param {number} outerWidth . + * @param {number} outerHeight . + * @param {number} widthPercent . + * @param {boolean} force . + * @return {boolean} . + */ +KeysetView.prototype.shouldResize = function(outerWidth, outerHeight, + widthPercent, force) { + var needResize = force || (this.outerHeight != outerHeight || + this.outerWidth != outerWidth || this.widthPercent_ != widthPercent); + return !!this.getElement() && needResize; +}; + + +/** * Resizes the view. * * @param {number} outerWidth The width of the outer space. * @param {number} outerHeight The height of the outer space. + * @param {number} widthPercent The percentage of the width. * @param {boolean=} opt_force Forces to resize the view. */ -KeysetView.prototype.resize = function(outerWidth, outerHeight, opt_force) { - var needResize = !!opt_force || (this.outerHeight_ != outerHeight || - this.outerWidth_ != outerWidth); - if (this.getElement() && needResize) { - this.outerHeight_ = outerHeight; - this.outerWidth_ = outerWidth; +KeysetView.prototype.resize = function(outerWidth, outerHeight, widthPercent, + opt_force) { + if (this.shouldResize(outerWidth, outerHeight, widthPercent, !!opt_force)) { + this.outerHeight = outerHeight; + this.outerWidth = outerWidth; + this.widthPercent_ = widthPercent; var elem = this.getElement(); - goog.style.setSize(elem, outerWidth, outerHeight); - - var weightArray = []; - for (var i = 0; i < this.rows_.length; i++) { - var row = this.rows_[i]; - weightArray.push(row.getHeightInWeight()); + var margin = Math.round((outerWidth - outerWidth * widthPercent) / 2); + var w = outerWidth - 2 * margin; + if (margin > 0) { + elem.style.marginLeft = elem.style.marginRight = margin + 'px'; } + goog.style.setSize(elem, w, outerHeight); - var splitedHeight = i18n.input.chrome.inputview.util.splitValue(weightArray, - outerHeight); - for (var i = 0; i < this.rows_.length; i++) { - var row = this.rows_[i]; - row.resize(outerWidth, splitedHeight[i]); - } + this.resizeRows(w, outerHeight); + } +}; + + +/** + * Resizes the rows inside the keyset. + * + * @param {number} width . + * @param {number} height . + */ +KeysetView.prototype.resizeRows = function(width, height) { + var weightArray = []; + for (var i = 0; i < this.rows_.length; i++) { + var row = this.rows_[i]; + weightArray.push(row.getHeightInWeight()); + } + + var splitedHeight = i18n.input.chrome.inputview.util.splitValue(weightArray, + height); + for (var i = 0; i < this.rows_.length; i++) { + var row = this.rows_[i]; + row.resize(width, splitedHeight[i]); } }; @@ -413,7 +452,7 @@ } this.conditions_[name] = value; this.applyConditions(this.conditions_); - this.resize(this.outerWidth_, this.outerHeight_, true); + this.resize(this.outerWidth, this.outerHeight, this.widthPercent_, true); this.update(); }; @@ -552,9 +591,6 @@ var name = spec[SpecNodeName.NAME]; var characters = spec[SpecNodeName.CHARACTERS]; var iconCssClass = spec[SpecNodeName.ICON_CSS_CLASS]; - if (this.adapter && this.adapter.isQPInputView && iconCssClass) { - iconCssClass = iconCssClass.replace(/inputview/, 'm-inputview'); - } var textCssClass = spec[SpecNodeName.TEXT_CSS_CLASS]; var toKeyset = spec[SpecNodeName.TO_KEYSET]; var toKeysetName = spec[SpecNodeName.TO_KEYSET_NAME]; @@ -583,6 +619,8 @@ Css.EN_SWITCHER_ENGLISH); break; case ElementType.BACKSPACE_KEY: + elem = new content.BackspaceKey(id, type, name, iconCssClass); + break; case ElementType.ENTER_KEY: case ElementType.TAB_KEY: case ElementType.ARROW_UP: @@ -591,6 +629,7 @@ case ElementType.ARROW_RIGHT: case ElementType.HIDE_KEYBOARD_KEY: case ElementType.GLOBE_KEY: + case ElementType.BACK_TO_KEYBOARD: elem = new content.FunctionalKey(id, type, name, iconCssClass); break; case ElementType.TAB_BAR_KEY: @@ -643,7 +682,8 @@ var isLetterKey = i18n.input.chrome.inputview.util.isLetterKey( characters); var enableShiftRendering = false; - if (this.adapter && this.adapter.isQPInputView) { + var isQpInputView = !!this.adapter && this.adapter.isQPInputView; + if (isQpInputView) { enableShiftRendering = !!spec[SpecNodeName.ENABLE_SHIFT_RENDERING]; } elem = new content.CharacterKey(id, keyCode || 0, @@ -651,7 +691,8 @@ this.dataModel_.settings.alwaysRenderAltGrCharacter, this.dataModel_.stateManager, goog.i18n.bidi.isRtlLanguage(this.languageCode), - enableShiftRendering); + enableShiftRendering, + isQpInputView); break; case ElementType.BACK_BUTTON: @@ -732,7 +773,8 @@ * @return {boolean} . */ KeysetView.prototype.isTabStyle = function() { - return this.keyboardCode_ == 'hwt' || this.keyboardCode_ == 'emoji'; + return !i18n.input.chrome.inputview.GlobalFlags.isQPInputView && ( + this.keyboardCode_ == 'hwt' || this.keyboardCode_ == 'emoji'); };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/material/spacekey.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/material/spacekey.js index 82363f58..a927fd47 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/material/spacekey.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/material/spacekey.js
@@ -71,6 +71,9 @@ */ this.stateManager_ = stateManager; + /** @private {string} */ + this.iconCss_ = opt_iconCss || ''; + // Double click on space key may convert two spaces to a period followed by a // space. this.pointerConfig.dblClick = true; @@ -104,7 +107,13 @@ var dom = this.getDomHelper(); this.wrapper_ = dom.createDom(goog.dom.TagName.DIV, Css.SPACE_WRAPPER); dom.appendChild(this.getElement(), this.wrapper_); - goog.dom.setTextContent(this.wrapper_, this.title_); + if (this.iconCss_) { + var iconElem = dom.createDom(goog.dom.TagName.DIV, this.iconCss_); + dom.appendChild(this.wrapper_, iconElem); + } else { + goog.dom.classlist.add(this.wrapper_, Css.SPACE_GREY_BG); + goog.dom.setTextContent(this.wrapper_, this.title_); + } };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/menuview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/menuview.js index dd5ed6b3..c332665e 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/menuview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/menuview.js
@@ -15,6 +15,7 @@ goog.require('goog.a11y.aria'); goog.require('goog.a11y.aria.State'); +goog.require('goog.array'); goog.require('goog.dom.TagName'); goog.require('goog.dom.classlist'); goog.require('goog.style'); @@ -80,11 +81,20 @@ /** * The width of the popup menu. + * The total width include padding is 300px, the padding left is 41px. * * @type {number} * @private */ -MenuView.WIDTH_ = 300; +MenuView.width_ = 300; + + +/** + * The padding-left of the menu item. + * + * @private {number} + */ +MenuView.paddingLeft_ = 0; /** @@ -150,6 +160,11 @@ MenuView.prototype.show = function(key, currentKeysetId, isCompact, enableCompactLayout, currentInputMethod, inputMethods, hasHwt, enableSettings, hasEmoji) { + if (i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + // Temporary overwrites the value for material design. + MenuView.width_ = 259; + MenuView.paddingLeft_ = 41; + } var ElementType = i18n.input.chrome.inputview.elements.ElementType; var dom = this.getDomHelper(); if (key.type != ElementType.MENU_KEY) { @@ -222,7 +237,7 @@ inputMethod['name']; if (currentInputMethod == inputMethod['id']) { ariaLabel = chrome.i18n.getMessage('CURRENT_KEYBOARD_PREFIX') + - inputMethod['name']; + inputMethod['name']; } var imeItem = new MenuItem(String(i), listItem, MenuItem.Type.LIST_ITEM, ariaLabel); @@ -230,14 +245,16 @@ if (currentInputMethod == inputMethod['id']) { imeItem.check(); } - goog.style.setSize(imeItem.getElement(), MenuView.WIDTH_, + goog.style.setSize(imeItem.getElement(), + (MenuView.width_ + MenuView.paddingLeft_), MenuView.LIST_ITEM_HEIGHT_); } var containerHeight = inputMethods.length > MenuView.MAXIMAL_VISIBLE_IMES_ ? MenuView.LIST_ITEM_HEIGHT_ * MenuView.MAXIMAL_VISIBLE_IMES_ : MenuView.LIST_ITEM_HEIGHT_ * inputMethods.length; - goog.style.setSize(container, MenuView.WIDTH_, containerHeight); + goog.style.setSize(container, MenuView.width_ + MenuView.paddingLeft_, + containerHeight); dom.appendChild(this.getElement(), container); return containerHeight; @@ -293,7 +310,7 @@ chrome.i18n.getMessage('SWITCH_TO_COMPACT_LAYOUT')); } layoutSwitcherItem.render(this.getElement()); - goog.style.setSize(layoutSwitcherItem.getElement(), MenuView.WIDTH_, + goog.style.setSize(layoutSwitcherItem.getElement(), MenuView.width_, MenuView.LIST_ITEM_HEIGHT_); return MenuView.LIST_ITEM_HEIGHT_; @@ -347,15 +364,17 @@ // Sets footer itmes' width. var elems = dom.getChildren(footer); var len = elems.length; - var subWidth = Math.ceil(MenuView.WIDTH_ / len); + var subWidth = Math.ceil((MenuView.width_ + MenuView.paddingLeft_) / len); var i = 0; for (; i < len - 1; i++) { elems[i].style.width = subWidth + 'px'; } - elems[i].style.width = (MenuView.WIDTH_ - subWidth * (len - 1)) + 'px'; + elems[i].style.width = (MenuView.width_ + MenuView.paddingLeft_ - + subWidth * (len - 1)) + 'px'; dom.appendChild(this.getElement(), footer); - goog.style.setSize(footer, MenuView.WIDTH_, MenuView.LIST_ITEM_HEIGHT_); + goog.style.setSize(footer, (MenuView.width_ + MenuView.paddingLeft_), + MenuView.LIST_ITEM_HEIGHT_); return MenuView.LIST_ITEM_HEIGHT_; };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/selectview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/selectview.js new file mode 100644 index 0000000..50e8f64 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/selectview.js
@@ -0,0 +1,126 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.provide('i18n.input.chrome.inputview.elements.content.SelectView'); + +goog.require('goog.array'); +goog.require('goog.dom'); +goog.require('goog.dom.TagName'); +goog.require('goog.dom.classlist'); +goog.require('goog.math.Coordinate'); +goog.require('goog.style'); +goog.require('i18n.input.chrome.inputview.Accents'); +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.elements.Element'); +goog.require('i18n.input.chrome.inputview.elements.ElementType'); +goog.require('i18n.input.chrome.inputview.util'); + + +goog.scope(function() { +var Css = i18n.input.chrome.inputview.Css; +var ElementType = i18n.input.chrome.inputview.elements.ElementType; +var TagName = goog.dom.TagName; + + +/** + * The view for triggering select mode. + * + * @param {goog.events.EventTarget=} opt_eventTarget The parent event target. + * @constructor + * @extends {i18n.input.chrome.inputview.elements.Element} + */ +i18n.input.chrome.inputview.elements.content.SelectView = function( + opt_eventTarget) { + goog.base(this, '', ElementType.SELECT_VIEW, opt_eventTarget); +}; +goog.inherits(i18n.input.chrome.inputview.elements.content.SelectView, + i18n.input.chrome.inputview.elements.Element); +var SelectView = i18n.input.chrome.inputview.elements.content.SelectView; + + +/** + * The window that shows the left knob. + * + * @private {!Element} + */ +SelectView.prototype.left_; + + +/** + * The window that shows the right knob. + * + * @private {!Element} + */ +SelectView.prototype.right_; + + +/** + * The distance between finger to track view which will cancel the track + * view. + * + * @private {number} + */ +SelectView.WIDTH_ = 25; + + +/** @override */ +SelectView.prototype.createDom = function() { + goog.base(this, 'createDom'); + + var dom = this.getDomHelper(); + var elem = this.getElement(); + var knob = dom.createDom(TagName.DIV, undefined, dom.createTextNode('>')); + var knobContainer = dom.createDom(TagName.DIV, undefined, knob); + this.left_ = dom.createDom(TagName.DIV, Css.SELECT_KNOB_LEFT, knobContainer); + dom.appendChild(this.getElement(), this.left_); + + knob = dom.createDom(TagName.DIV, undefined, dom.createTextNode('<')); + knobContainer = dom.createDom(TagName.DIV, undefined, knob); + this.right_ = + dom.createDom(TagName.DIV, Css.SELECT_KNOB_RIGHT, knobContainer); + dom.appendChild(this.getElement(), this.right_); +}; + + +/** @override */ +SelectView.prototype.resize = function(width, height) { + goog.base(this, 'resize', width, height); + this.left_ && goog.style.setStyle(this.left_, { + 'height': height + 'px', + 'width': SelectView.WIDTH_ + 'px' + }); + this.right_ && goog.style.setStyle(this.right_, { + 'height': height + 'px', + 'width': SelectView.WIDTH_ + 'px', + 'left': width - SelectView.WIDTH_ + 'px' + }); + +}; + + +/** @override */ +SelectView.prototype.disposeInternal = function() { + goog.dispose(this.left_); + goog.dispose(this.right_); + + goog.base(this, 'disposeInternal'); +}; + + +/** @override */ +SelectView.prototype.setVisible = function(visible) { + SelectView.base(this, 'setVisible', visible); + goog.style.setElementShown(this.left_, visible); + goog.style.setElementShown(this.right_, visible); +}; +}); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/swipeview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/swipeview.js new file mode 100644 index 0000000..903fd21 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/swipeview.js
@@ -0,0 +1,788 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.provide('i18n.input.chrome.inputview.elements.content.SwipeView'); + +goog.require('goog.array'); +goog.require('goog.dom'); +goog.require('goog.dom.TagName'); +goog.require('goog.dom.classlist'); +goog.require('goog.events.EventType'); +goog.require('goog.math.Coordinate'); +goog.require('goog.style'); +goog.require('i18n.input.chrome.inputview.Accents'); +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.SwipeDirection'); +goog.require('i18n.input.chrome.inputview.elements.Element'); +goog.require('i18n.input.chrome.inputview.elements.ElementType'); +goog.require('i18n.input.chrome.inputview.events.EventType'); +goog.require('i18n.input.chrome.inputview.events.KeyCodes'); +goog.require('i18n.input.chrome.inputview.handler.PointerHandler'); +goog.require('i18n.input.chrome.inputview.util'); +goog.require('i18n.input.chrome.message.ContextType'); + + +goog.scope(function() { +var ContextType = i18n.input.chrome.message.ContextType; +var Css = i18n.input.chrome.inputview.Css; +var ElementType = i18n.input.chrome.inputview.elements.ElementType; +var EventType = i18n.input.chrome.inputview.events.EventType; +var KeyCodes = i18n.input.chrome.inputview.events.KeyCodes; +var content = i18n.input.chrome.inputview.elements.content; +var util = i18n.input.chrome.inputview.util; + + +/** + * The view for alt data. + * + * @param {!i18n.input.chrome.inputview.Adapter} adapter . + * @param {goog.events.EventTarget=} opt_eventTarget The parent event target. + * @constructor + * @extends {i18n.input.chrome.inputview.elements.Element} + */ +i18n.input.chrome.inputview.elements.content.SwipeView = function( + adapter, opt_eventTarget) { + i18n.input.chrome.inputview.elements.content.SwipeView.base( + this, 'constructor', '', ElementType.SWIPE_VIEW, opt_eventTarget); + + /** + * The inputview adapter. + * + * @private {!i18n.input.chrome.inputview.Adapter} + */ + this.adapter_ = adapter; + + + /** + * The swipe elements. + * + * @private {!Array.<!Element>} + */ + this.trackElements_ = []; + + /** + * The window that shows the swipe field. + * + * @private {Object} + */ + this.trackWindow_ = null; + + /** + * The text before the current focus. + * + * @private {string} + */ + this.surroundingText_ = ''; + + /** + * The index of focus in the surrounding text. + * + * @private {number} + */ + this.surroundingTextFocus_ = 0; + + /** + * The index of the anchor in the surrounding text. + * + * @private {number} + */ + this.surroundingTextAnchor_ = 0; + + /** + * Recent words that have been deleted. + * + * @private {Array.<string>} + */ + this.deletedWords_ = []; + + /** + * The pointer handler. + * + * @type {!i18n.input.chrome.inputview.handler.PointerHandler} + * @private + */ + this.pointerHandler_ = new i18n.input.chrome.inputview.handler. + PointerHandler(); + +}; +goog.inherits(i18n.input.chrome.inputview.elements.content.SwipeView, + i18n.input.chrome.inputview.elements.Element); +var SwipeView = i18n.input.chrome.inputview.elements.content.SwipeView; + + +/** + * The number of swipe elements. + * + * @type {number} + * @private + */ +SwipeView.LENGTH_ = 7; + + +/** + * Index of highlighted accent. Use this index to represent no highlighted + * accent. + * + * @type {number} + * @private + */ +SwipeView.INVALIDINDEX_ = -1; + + +/** + * The distance between finger to track view which will cancel the track + * view. + * + * @type {number} + * @private + */ +SwipeView.FINGER_DISTANCE_TO_CANCEL_SWIPE_ = 20; + + +/** + * The cover element. + * Note: The reason we use a separate cover element instead of the view is + * because of the opacity. We can not reassign the opacity in child element. + * + * @type {!Element} + * @private + */ +SwipeView.prototype.coverElement_; + + +/** + * The index of the alternative element which is highlighted. + * + * @type {number} + * @private + */ +SwipeView.prototype.highlightIndex_ = SwipeView.INVALIDINDEX_; + + +/** + * The key which trigger this alternative data view. + * + * @type {!i18n.input.chrome.inputview.elements.content.SoftKey} + */ +SwipeView.prototype.triggeredBy; + + +/** + * Whether finger movement is being tracked. + * + * @type {boolean} + * @private + */ +SwipeView.prototype.tracking_ = false; + + +/** + * Whether to deploy the tracker on swipe events. + * + * @type {boolean} + * @private + */ +SwipeView.prototype.armed_ = false; + + +/** + * Whether the tracker will be deployed on future swipe events. + * + * @return {boolean} + */ +SwipeView.prototype.isArmed = function() { + return this.armed_; +}; + + +/** + * Callback when surrounding text is changed. + * + * @param {!i18n.input.chrome.inputview.events.SurroundingTextChangedEvent} e . + * @private + */ +SwipeView.prototype.onSurroundingTextChanged_ = function(e) { + if (this.adapter_.isPasswordBox()) { + this.surroundingText_ = ''; + this.surroundingTextAnchor_ = this.surroundingTextFocus_ = 0; + return; + } + + this.surroundingTextAnchor_ = e.anchor; + this.surroundingTextFocus_ = e.focus; + + var text = e.text || ''; + var oldText = this.surroundingText_; + var diff = ''; + if (util.isLetterDelete(oldText, text)) { + diff = oldText.slice(-1); + } else if (util.isLetterRestore(oldText, text)) { + // Letter restore. + // Handle blink bug where ctrl+delete deletes a space and inserts + // a  . + // Convert   to ' ' and remove from delete words since blink + // did a minirestore for us. + var letter = text[text.length - 1]; + if (letter == String.fromCharCode(160) || letter == ' ') { + var lastDelete = this.deletedWords_.pop(); + var firstChar = lastDelete && lastDelete[0] || ''; + if (firstChar == String.fromCharCode(160) || firstChar == ' ') { + this.deletedWords_.push(lastDelete.slice(1)); + } + } + } else if (e.text.length == 100 || oldText.length == 100) { + // Check if a word was deleted from oldText. + var candidate = oldText.trim().split(' ').pop(); + if (util.isPossibleDelete(oldText, text, candidate)) { + var location = oldText.lastIndexOf(candidate); + var intersectingText = oldText.slice(0, location); + diff = oldText.slice(location); + } + } else { + diff = oldText.substring(text.length); + } + if (diff) { + this.deletedWords_.push(diff); + // Do not reset while swiping. + } else if (!this.isVisible()) { + this.deletedWords_ = []; + } + this.surroundingText_ = text; +}; + + +/** + * Handles the swipe action. + * + * @param {!i18n.input.chrome.inputview.events.SwipeEvent} e The swipe event. + * @private + */ +SwipeView.prototype.handleSwipeAction_ = function(e) { + var direction = e.direction; + if (this.isVisible()) { + if (e.view.type == ElementType.BACKSPACE_KEY) { + // Cache whether we were tracking. + var alreadyTracking = this.tracking_; + var changed = this.highlightItem(e.x, e.y); + // Did not move segments. + if (!changed) { + // First gesture. + if (!alreadyTracking) { + // All previous deletions count as one now. + this.deletedWords_.reverse(); + var word = this.deletedWords_.join(''); + this.deletedWords_ = [word]; + // Swiped right, cancel the deletion. + if (direction & i18n.input.chrome.inputview.SwipeDirection.RIGHT) { + word = this.deletedWords_.pop(); + if (word) + this.adapter_.commitText(word); + } + } + return; + } + + if (direction & i18n.input.chrome.inputview.SwipeDirection.LEFT) { + this.adapter_.sendKeyDownAndUpEvent( + '\u0008', KeyCodes.BACKSPACE, undefined, undefined, { + ctrl: true, + shift: false + }); + } else if (direction & i18n.input.chrome.inputview.SwipeDirection.RIGHT) { + var word = this.deletedWords_.pop(); + if (word) + this.adapter_.commitText(word); + // Restore text we deleted before the track came up, but part of the + // same gesture. + if (this.isAtOrigin()) { + word = this.deletedWords_.pop(); + if (word) + this.adapter_.commitText(word); + } + } + return; + } + if (e.view.type == ElementType.SELECT_VIEW) { + // Cache whether we were tracking as highlight may change this. + var alreadyTracking = this.tracking_; + var changed = this.highlightItem(e.x, e.y); + // First finger movement is onto the blank track. Ignore. + if (!alreadyTracking) + return; + if (!changed) + return; + var index = this.getTrackIndex(); + if (index == -1) { + console.error('Invalid track index.'); + return; + } + var selectWord = index % 2 == 1; + var code; + if (direction & i18n.input.chrome.inputview.SwipeDirection.LEFT) { + code = KeyCodes.ARROW_LEFT; + } else if (direction & i18n.input.chrome.inputview.SwipeDirection.RIGHT) { + code = KeyCodes.ARROW_RIGHT; + } else { + return; + } + // If anchor == focus we are either at the end or the start of the word + // and no selection is in place. + if (this.surroundingTextAnchor_ == this.surroundingTextFocus_) { + // Do not move carat at all, as this will either have no effect or cause + // us to splice the word. + if (!selectWord) { + return; + } + } + this.adapter_.sendKeyDownAndUpEvent( + '', code, undefined, undefined, { + ctrl: selectWord, + shift: selectWord + }); + return; + } + return; + } + + // User swiped on backspace key before swipeview was visible. + if (e.view.type == ElementType.BACKSPACE_KEY) { + if (!this.armed_) { + // Prevents reshowing the track after it is hidden as part of the same + // finger movement. + return; + } + if (e.direction & i18n.input.chrome.inputview.SwipeDirection.LEFT) { + var key = /** @type {!content.FunctionalKey} */ (e.view); + // Equiv to a longpress. + this.showDeletionTrack(key); + } + return; + } +}; + + +/** + * Handles the pointer action. + * + * @param {!i18n.input.chrome.inputview.events.PointerEvent} e . + * @private + */ +SwipeView.prototype.handlePointerAction_ = function(e) { + switch (e.view.type) { + case ElementType.BACKSPACE_KEY: + var key = /** @type {!content.FunctionalKey} */ (e.view); + if (e.type == EventType.POINTER_DOWN) { + if (this.adapter_.contextType != ContextType.URL) { + this.armed_ = true; + } + this.deletedWords_ = []; + } else if (e.type == EventType.POINTER_UP || e.type == EventType. + POINTER_OUT) { + if (!this.isVisible()) { + this.armed_ = false; + } + } else if (e.type == EventType.LONG_PRESS) { + if (this.adapter_.isGestureDeletionEnabled()) { + this.showDeletionTrack(key); + } + } + break; + case ElementType.SWIPE_VIEW: + if (e.type == EventType.POINTER_DOWN && + e.target == this.getCoverElement()) { + this.hide(); + } else if (e.type == EventType.POINTER_UP || + e.type == EventType.POINTER_OUT) { + this.hide(); + // Reset the deleted words. + this.deletedWords_ = []; + } + break; + case ElementType.SELECT_VIEW: + if (e.type == EventType.POINTER_DOWN) { + this.showSelectionTrack(e.x, e.y); + } + if (e.type == EventType.POINTER_UP) { + this.hide(); + } + break; + } +}; + +/** @override */ +SwipeView.prototype.createDom = function() { + goog.base(this, 'createDom'); + + var dom = this.getDomHelper(); + var elem = this.getElement(); + goog.dom.classlist.add(elem, i18n.input.chrome.inputview.Css.SWIPE_VIEW); + this.coverElement_ = dom.createDom(goog.dom.TagName.DIV, + i18n.input.chrome.inputview.Css.TRACK_COVER); + dom.appendChild(document.body, this.coverElement_); + goog.style.setElementShown(this.coverElement_, false); + + this.coverElement_['view'] = this; +}; + + +/** @override */ +SwipeView.prototype.enterDocument = function() { + goog.base(this, 'enterDocument'); + this.getHandler(). + listen(this.adapter_, + i18n.input.chrome.inputview.events.EventType. + SURROUNDING_TEXT_CHANGED, + this.onSurroundingTextChanged_). + listen(this.pointerHandler_, [ + EventType.SWIPE], this.handleSwipeAction_). + listen(this.pointerHandler_, [ + EventType.LONG_PRESS, + EventType.POINTER_UP, + EventType.POINTER_DOWN, + EventType.POINTER_OUT], this.handlePointerAction_); + goog.style.setElementShown(this.getElement(), false); +}; + + +/** + * Shows the swipe tracker. + * + * @param {number} x + * @param {number} y + * @param {number} width The width of a key. + * @param {number} height The height of a key. + * @param {number} firstTrackWidth The width of the first key. + * @param {number} firstSegmentWidth The width of the first buffer segment. + * @param {string=} opt_character Characters on each key. + * @param {Css=} opt_css Optional icon css class. + * @private + */ +SwipeView.prototype.showDeletionTrack_ = function(x, y, width, height, + firstTrackWidth, firstSegmentWidth, opt_character, opt_css) { + this.tracking_ = false; + goog.style.setElementShown(this.getElement(), true); + this.getDomHelper().removeChildren(this.getElement()); + // Each key except last has a separator. + var totalWidth = ((2 * SwipeView.LENGTH_) - 3) * width; + totalWidth += firstTrackWidth + firstSegmentWidth; + + this.ltr = true; + this.highlightIndex_ = 0; + if ((x + totalWidth) > screen.width) { + // If not enough space at the right, then make it to the left. + x -= totalWidth; + this.ltr = false; + this.highlightIndex_ = SwipeView.LENGTH_ - 1; + } + if (firstTrackWidth == 0) { + this.highlightIndex_ = SwipeView.INVALIDINDEX_; + } + var ltr = this.ltr; + var isFirstSegment = function(i) { + return ltr ? i == 0 : i == SwipeView.LENGTH_ - 2; + }; + var isFirstTrackPiece = function(i) { + return ltr ? i == 0 : i == SwipeView.LENGTH_ - 1; + }; + for (var i = 0; i < SwipeView.LENGTH_; i++) { + var trackWidth = isFirstTrackPiece(i) ? firstTrackWidth : width; + if (trackWidth != 0) { + var keyElem = this.addKey_(opt_character, opt_css); + goog.style.setSize(keyElem, trackWidth, height); + this.trackElements_.push(keyElem); + } + + if (i != (SwipeView.LENGTH_ - 1)) { + var segmentWidth = isFirstSegment(i) ? firstSegmentWidth : width; + this.addSeparator_(segmentWidth, height); + } + } + goog.style.setPosition(this.getElement(), x, y); + // Highlight selected element if it's index is valid. + if (this.highlightIndex_ != SwipeView.INVALIDINDEX_) { + var elem = this.trackElements_[this.highlightIndex_]; + this.setElementBackground_(elem, true); + } + goog.style.setElementShown(this.coverElement_, true); + this.triggeredBy && this.triggeredBy.setHighlighted(true); +}; + + +/** + * + * Shows the swipe tracker. + * @param {number} x + * @param {number} y + * @param {number} width The width of a key. + * @param {number} height The height of a key. + * @param {string} character Characters on each key. + * @private + */ +SwipeView.prototype.showSelectionTrack_ = function(x, y, width, height, + character) { + this.tracking_ = false; + goog.style.setElementShown(this.getElement(), true); + this.getDomHelper().removeChildren(this.getElement()); + // Each key has a separator. + var totalWidth = ((2 * SwipeView.LENGTH_)) * width; + + this.ltr = true; + this.highlightIndex_ = SwipeView.INVALIDINDEX_; + if ((x + totalWidth) > screen.width) { + // If not enough space at the right, then make it to the left. + x -= totalWidth; + this.ltr = false; + } + + for (var i = 0; i < SwipeView.LENGTH_; i++) { + var keyElem; + if (!this.ltr) { + keyElem = this.addKey_(character); + goog.style.setSize(keyElem, width, height); + this.trackElements_.push(keyElem); + } + + keyElem = this.addSeparator_(width, height); + goog.style.setSize(keyElem, width, height); + this.trackElements_.push(keyElem); + + if (this.ltr) { + keyElem = this.addKey_(character); + goog.style.setSize(keyElem, width, height); + this.trackElements_.push(keyElem); + } + } + goog.style.setPosition(this.getElement(), x, y); + goog.style.setElementShown(this.coverElement_, true); + this.triggeredBy && this.triggeredBy.setHighlighted(true); +}; + + +/** + * Shows the alt data view. + * + * @param {!i18n.input.chrome.inputview.elements.content.SoftKey} key + * The key triggered this track view. + */ +SwipeView.prototype.showDeletionTrack = function(key) { + this.triggeredBy = key; + var coordinate = goog.style.getClientPosition(key.getElement()); + if (key.type == ElementType.BACKSPACE_KEY) { + this.showDeletionTrack_( + coordinate.x + key.availableWidth, + coordinate.y, + 70, + key.availableHeight, + key.availableWidth, + 100, + undefined, + Css.BACKSPACE_ICON); + } +}; + + +/** + * Shows the selection track. + * + * @param {number} x + * @param {number} y + */ +SwipeView.prototype.showSelectionTrack = function(x, y) { + var ltr = x <= (screen.width / 2); + + this.showSelectionTrack_( + ltr ? 0 : screen.width, + Math.max(y - 35, 35), // Center track on finger press but force containment. + 70, + 70, + x > (screen.width / 2) ? '<' : '>'); +}; + + +/** + * Hides the alt data view. + */ +SwipeView.prototype.hide = function() { + this.armed_ = false; + this.trackElements_ = []; + this.tracking_ = false; + if (this.triggeredBy) + this.triggeredBy.setHighlighted(false); + goog.style.setElementShown(this.getElement(), false); + goog.style.setElementShown(this.coverElement_, false); + this.highlightIndex_ = SwipeView.INVALIDINDEX_; +}; + + +/** + * Whether the current track counter is at the first element. + * + * @return {boolean} + */ +SwipeView.prototype.isAtOrigin = function() { + return this.ltr ? this.highlightIndex_ == 0 : + this.highlightIndex_ == SwipeView.LENGTH_ - 1; +}; + + +/** + * Highlights the item according to the current coordinate of the finger. + * + * @param {number} x . + * @param {number} y . + * @return {boolean} Whether it passed into a new segment. + */ +SwipeView.prototype.highlightItem = function(x, y) { + var previousIndex = this.highlightIndex_; + for (var i = 0; i < this.trackElements_.length; i++) { + var elem = this.trackElements_[i]; + var coordinate = goog.style.getClientPosition(elem); + var size = goog.style.getSize(elem); + if (coordinate.x < x && (coordinate.x + size.width) > x) { + this.highlightIndex_ = i; + this.clearAllHighlights_(); + this.setElementBackground_(elem, true); + } + } + this.tracking_ = this.tracking_ || (previousIndex != this.highlightIndex_); + return (previousIndex != this.highlightIndex_); +}; + + +/** + * Clears all the highlights. + * + * @private + */ +SwipeView.prototype.clearAllHighlights_ = + function() { + for (var i = 0; i < this.trackElements_.length; i++) { + this.setElementBackground_(this.trackElements_[i], false); + } +}; + + +/** + * Sets the background style of the element. + * + * @param {!Element} element The element. + * @param {boolean} highlight True to highlight the element. + * @private + */ +SwipeView.prototype.setElementBackground_ = + function(element, highlight) { + if (highlight) { + goog.dom.classlist.add(element, i18n.input.chrome.inputview.Css. + ELEMENT_HIGHLIGHT); + } else { + goog.dom.classlist.remove(element, i18n.input.chrome.inputview.Css. + ELEMENT_HIGHLIGHT); + } +}; + + +/** + * Adds a alt data key into the view. + * + * @param {string=} opt_character The character. + * @param {Css=} opt_icon_css + * @return {!Element} The create key element. + * @private + */ +SwipeView.prototype.addKey_ = function(opt_character, opt_icon_css) { + var dom = this.getDomHelper(); + var character = opt_character && + i18n.input.chrome.inputview.util.getVisibleCharacter(opt_character); + var keyElem; + if (character) + keyElem = dom.createDom(goog.dom.TagName.DIV, Css.SWIPE_KEY, character); + else + keyElem = dom.createDom(goog.dom.TagName.DIV, Css.SWIPE_KEY); + if (opt_icon_css) { + var child = dom.createDom(goog.dom.TagName.DIV, opt_icon_css); + dom.appendChild(keyElem, child); + } + dom.appendChild(this.getElement(), keyElem); + return keyElem; +}; + + +/** + * Adds a separator. + * + * @param {number} width . + * @param {number} height . + * @return {Element} + * @private + */ +SwipeView.prototype.addSeparator_ = function(width, height) { + var dom = this.getDomHelper(); + var tableCell = dom.createDom(goog.dom.TagName.DIV, + i18n.input.chrome.inputview.Css.TABLE_CELL); + goog.style.setSize(tableCell, width + 'px', height + 'px'); + goog.dom.classlist.add(tableCell, Css.SWIPE_SEPARATOR); + dom.appendChild(this.getElement(), tableCell); + return tableCell; +}; + + +/** + * Gets the cover element. + * + * @return {!Element} The cover element. + */ +SwipeView.prototype.getCoverElement = function() { + return this.coverElement_; +}; + + +/** + * The current index. + * @return {number} + */ +SwipeView.prototype.getTrackIndex = function() { + if (this.highlightIndex_ == SwipeView.INVALIDINDEX_) + return SwipeView.INVALIDINDEX_; + if (this.ltr) + return this.highlightIndex_; + return this.trackElements_.length - this.highlightIndex_ - 1; +}; + + +/** @override */ +SwipeView.prototype.resize = function(width, height) { + goog.base(this, 'resize', width, height); + + goog.style.setSize(this.coverElement_, width, height); +}; + + +/** + * Resets the swipeview. + * + */ +SwipeView.prototype.reset = function() { + this.deletedWords_ = []; + this.surroundingText_ = ''; + this.hide(); +}; + + +/** @override */ +SwipeView.prototype.disposeInternal = function() { + goog.dispose(this.pointerHandler_); + + goog.base(this, 'disposeInternal'); +}; + +}); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/switcherkey.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/switcherkey.js index 978887e..9aa0fedc 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/switcherkey.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/switcherkey.js
@@ -13,12 +13,14 @@ // goog.provide('i18n.input.chrome.inputview.elements.content.SwitcherKey'); +goog.require('goog.dom.classlist'); +goog.require('i18n.input.chrome.inputview.Css'); goog.require('i18n.input.chrome.inputview.elements.content.FunctionalKey'); - goog.scope(function() { var FunctionalKey = i18n.input.chrome.inputview.elements.content.FunctionalKey; +var Css = i18n.input.chrome.inputview.Css; @@ -72,6 +74,10 @@ goog.base(this, 'createDom'); this.setAriaLabel(this.getChromeVoxMessage()); + + if (this.textElem) { + goog.dom.classlist.add(this.getElement(), Css.SWITCHER_KEY_NAME); + } };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/tabbarkey.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/tabbarkey.js index 4ee6846..84bb0b8 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/tabbarkey.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/tabbarkey.js
@@ -91,7 +91,9 @@ goog.dom.classlist.remove(this.bgElem, Css.SPECIAL_KEY_BG); goog.dom.classlist.add(this.bgElem, Css.EMOJI_TABBAR_KEY); goog.dom.classlist.add(this.iconElem, Css.EMOJI_SWITCH); - this.createSeparator_(); + if (!i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + this.createSeparator_(); + } // Sets aria label. var ariaLabel = ''; @@ -133,9 +135,11 @@ this.tableCell.style.width = this.availableWidth + 'px'; this.tableCell.style.height = this.availableHeight - this.BORDER_HEIGHT_ + 'px'; - this.sepTableCell.style.height = this.availableHeight - - this.BORDER_HEIGHT_ + 'px'; - this.separator.style.height = this.availableHeight * 0.32 + 'px'; + if (!i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + this.sepTableCell.style.height = this.availableHeight - + this.BORDER_HEIGHT_ + 'px'; + this.separator.style.height = this.availableHeight * 0.32 + 'px'; + } };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/toolbarbutton.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/toolbarbutton.js new file mode 100644 index 0000000..dec8bb2b --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/toolbarbutton.js
@@ -0,0 +1,108 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.provide('i18n.input.chrome.inputview.elements.content.ToolbarButton'); + +goog.require('goog.dom.TagName'); +goog.require('goog.dom.classlist'); +goog.require('goog.style'); +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.elements.Element'); + + + +goog.scope(function() { +var ElementType = i18n.input.chrome.inputview.elements.ElementType; +var Css = i18n.input.chrome.inputview.Css; + + + +/** + * The icon button in the Toolbar view. + * + * @param {string} id . + * @param {ElementType} type . + * @param {string} iconCss . + * @param {string} text . + * @param {!goog.events.EventTarget=} opt_eventTarget . + * @param {boolean=} opt_alignLeft . + * @constructor + * @extends {i18n.input.chrome.inputview.elements.Element} + */ +i18n.input.chrome.inputview.elements.content.ToolbarButton = function( + id, type, iconCss, text, opt_eventTarget, opt_alignLeft) { + goog.base(this, id, type, opt_eventTarget); + + /** @type {string} */ + this.text = text; + + /** @type {string} */ + this.iconCss = iconCss; + + this.alignLeft = opt_alignLeft || false; +}; +var ToolbarButton = i18n.input.chrome.inputview.elements.content. + ToolbarButton; +goog.inherits(ToolbarButton, i18n.input.chrome.inputview.elements.Element); + + +/** @type {!Element} */ +ToolbarButton.prototype.iconCell; + + +/** @override */ +ToolbarButton.prototype.createDom = function() { + goog.base(this, 'createDom'); + + var dom = this.getDomHelper(); + var elem = this.getElement(); + var css = [Css.CANDIDATE_INTER_CONTAINER, + Css.TOOLBAR_BUTTON]; + if (this.alignLeft) { + css.push(Css.FLOAT_LEFT); + } + goog.dom.classlist.addAll(elem, css); + + this.iconCell = dom.createDom(goog.dom.TagName.DIV, Css.TABLE_CELL); + dom.appendChild(elem, this.iconCell); + + var iconElem = dom.createDom(goog.dom.TagName.DIV, Css.INLINE_DIV); + if (this.iconCss) { + goog.dom.classlist.add(iconElem, this.iconCss); + } + if (this.text) { + dom.setTextContent(iconElem, this.text); + } + dom.appendChild(this.iconCell, iconElem); +}; + +/** @override */ +ToolbarButton.prototype.setHighlighted = function(highlight) { + if (highlight) { + goog.dom.classlist.add(this.getElement(), Css.CANDIDATE_HIGHLIGHT); + } else { + goog.dom.classlist.remove(this.getElement(), Css.CANDIDATE_HIGHLIGHT); + } +}; + + +/** @override */ +ToolbarButton.prototype.resize = function(width, height) { + goog.style.setSize(this.iconCell, width, height); + + goog.base(this, 'resize', width, height); +}; + + +}); // goog.scope +
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/voiceview.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/voiceview.js index 14a63a8..4681268 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/content/voiceview.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/content/voiceview.js
@@ -13,16 +13,13 @@ // goog.provide('i18n.input.chrome.inputview.elements.content.VoiceView'); -goog.require('goog.a11y.aria'); -goog.require('goog.a11y.aria.Announcer'); -goog.require('goog.a11y.aria.LivePriority'); -goog.require('goog.a11y.aria.State'); goog.require('goog.asserts'); goog.require('goog.async.Delay'); goog.require('goog.dom.TagName'); goog.require('goog.dom.classlist'); goog.require('goog.style'); goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.Sounds'); goog.require('i18n.input.chrome.inputview.elements.Element'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); goog.require('i18n.input.chrome.inputview.elements.content.FunctionalKey'); @@ -31,12 +28,11 @@ goog.scope(function() { -var Announcer = goog.a11y.aria.Announcer; var Css = i18n.input.chrome.inputview.Css; -var EventType = goog.events.EventType; var ElementType = i18n.input.chrome.inputview.elements.ElementType; var FunctionalKey = i18n.input.chrome.inputview.elements.content.FunctionalKey; var Name = i18n.input.chrome.message.Name; +var Sounds = i18n.input.chrome.inputview.Sounds; var TagName = goog.dom.TagName; var Type = i18n.input.chrome.message.Type; @@ -47,11 +43,12 @@ * * @param {goog.events.EventTarget=} opt_eventTarget The parent event target. * @param {i18n.input.chrome.inputview.Adapter=} opt_adapter . + * @param {i18n.input.chrome.SoundController=} opt_soundController . * @constructor * @extends {i18n.input.chrome.inputview.elements.Element} */ i18n.input.chrome.inputview.elements.content.VoiceView = - function(opt_eventTarget, opt_adapter) { + function(opt_eventTarget, opt_adapter, opt_soundController) { VoiceView.base(this, 'constructor', '', ElementType.VOICE_VIEW, opt_eventTarget); @@ -62,11 +59,15 @@ */ this.adapter_ = goog.asserts.assertObject(opt_adapter); + /** + * The sound controller. + * + * @private {!i18n.input.chrome.SoundController} + */ + this.soundController_ = goog.asserts.assertObject(opt_soundController); + /** @private {!goog.async.Delay} */ this.animator_ = new goog.async.Delay(this.animateMicrophoneLevel_, 0, this); - - /** @private {!Announcer} */ - this.announcer_ = new Announcer(); }; var VoiceView = i18n.input.chrome.inputview.elements.content.VoiceView; goog.inherits(VoiceView, i18n.input.chrome.inputview.elements.Element); @@ -120,23 +121,22 @@ var elem = this.getElement(); goog.dom.classlist.add(elem, Css.VOICE_VIEW); this.voicePanel_ = dom.createDom(TagName.DIV, Css.VOICE_PANEL); - this.voiceMicElem_ = dom.createDom(goog.dom.TagName.DIV, + this.voiceMicElem_ = dom.createDom(TagName.DIV, Css.VOICE_OPACITY + ' ' + Css.VOICE_MIC_ING); + this.levelElement_ = dom.createDom( - goog.dom.TagName.DIV, Css.VOICE_LEVEL); + TagName.DIV, Css.VOICE_LEVEL); dom.append(/** @type {!Node} */ (this.voicePanel_), this.voiceMicElem_, this.levelElement_); - goog.a11y.aria.setState(this.voiceMicElem_, goog.a11y.aria.State.LABEL, - chrome.i18n.getMessage('VOICE_TURN_OFF')); this.maskElem_ = dom.createDom(TagName.DIV, [Css.VOICE_MASK, Css.VOICE_OPACITY_NONE]); dom.append(/** @type {!Node} */ (elem), this.maskElem_, this.voicePanel_); - this.privacyDiv_ = dom.createDom(goog.dom.TagName.DIV, + this.privacyDiv_ = dom.createDom(TagName.DIV, Css.VOICE_PRIVACY_INFO); - var textDiv = dom.createDom(goog.dom.TagName.DIV, Css.VOICE_PRIVACY_TEXT); + var textDiv = dom.createDom(TagName.DIV, Css.VOICE_PRIVACY_TEXT); dom.setTextContent(textDiv, chrome.i18n.getMessage('VOICE_PRIVACY_INFO')); dom.appendChild(this.privacyDiv_, textDiv); @@ -169,11 +169,13 @@ * Start recognition. */ VoiceView.prototype.start = function() { + // visible -> invisible + if (!this.isVisible()) { + this.soundController_.playSound(Sounds.VOICE_RECOG_START, true); + } if (this.isPrivacyAllowed_) { this.adapter_.sendVoiceViewStateChange(true); this.animator_.start(); - this.announcer_.say(chrome.i18n.getMessage('VOICE_TURN_ON'), - goog.a11y.aria.LivePriority.ASSERTIVE); } this.setVisible(true); }; @@ -183,15 +185,18 @@ * Stop recognition. */ VoiceView.prototype.stop = function() { + // invisible -> visible + if (this.isVisible()) { + this.soundController_.playSound(Sounds.VOICE_RECOG_END, true); + } this.animator_.stop(); - this.announcer_.say(chrome.i18n.getMessage('VOICE_TURN_OFF'), - goog.a11y.aria.LivePriority.ASSERTIVE); this.setVisible(false); }; /** @override */ VoiceView.prototype.setVisible = function(visible) { + VoiceView.base(this, 'setVisible', visible); if (visible) { goog.style.setElementShown(this.voicePanel_, true); goog.dom.classlist.add(this.maskElem_, Css.VOICE_MASK_OPACITY); @@ -246,8 +251,7 @@ this.isPrivacyAllowed_ = true; this.adapter_.sendVoiceViewStateChange(true); this.animator_.start(); - this.announcer_.say(chrome.i18n.getMessage('VOICE_TURN_ON'), - goog.a11y.aria.LivePriority.ASSERTIVE); + this.soundController_.playSound(Sounds.VOICE_RECOG_START, true); goog.dom.classlist.add(this.privacyDiv_, Css.HANDWRITING_PRIVACY_INFO_HIDDEN); goog.dom.classlist.remove(this.maskElem_, Css.VOICE_OPACITY_NONE); };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/elementtype.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/elementtype.js index fdb6f37..035bfd98 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/elementtype.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/elementtype.js
@@ -65,6 +65,18 @@ EN_SWITCHER: 42, VOICE_BTN: 43, VOICE_VIEW: 44, - VOICE_PRIVACY_GOT_IT: 45 + VOICE_PRIVACY_GOT_IT: 45, + BACK_TO_KEYBOARD: 46, + BOLD: 47, + ITALICS: 48, + UNDERLINE: 49, + COPY: 50, + PASTE: 51, + CUT: 52, + SELECT_ALL: 53, + REDO: 54, + UNDO: 55, + SWIPE_VIEW: 56, + SELECT_VIEW: 57 };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/extendedlayout.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/extendedlayout.js index f13da37..b8aeac35 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/extendedlayout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/extendedlayout.js
@@ -143,7 +143,7 @@ if (this.heightInWeight_ < child.getHeightInWeight()) { this.heightInWeight_ = child.getHeightInWeight(); } - this.widthInWeight_ += child.getWidthInWeight(); + this.widthInWeight_ = child.getWidthInWeight(); } };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/handwritinglayout.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/handwritinglayout.js index eb24e72..1024ff61 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/handwritinglayout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/handwritinglayout.js
@@ -15,6 +15,7 @@ goog.require('goog.dom.classlist'); goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.GlobalFlags'); goog.require('i18n.input.chrome.inputview.elements.Element'); goog.require('i18n.input.chrome.inputview.elements.ElementType'); goog.require('i18n.input.chrome.inputview.elements.Weightable'); @@ -113,9 +114,11 @@ child.resize( Math.ceil(width * child.getWidthInWeight() / this.widthInWeight_), Math.ceil(height * child.getHeightInWeight() / this.heightInWeight_)); - // 85/140 = 0.6 - child.getElement().style.top = - Math.ceil(height * 0.6 / this.heightInWeight_); + if (!i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + // 85/140 = 0.6 + child.getElement().style.top = + Math.ceil(height * 0.6 / this.heightInWeight_); + } } }; }); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/linearlayout.js b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/linearlayout.js index f583c8e..ebcfebd 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/linearlayout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/elements/layout/linearlayout.js
@@ -119,6 +119,12 @@ LinearLayout.prototype.resize = function(width, height) { goog.base(this, 'resize', width, height); + var elem = this.getElement(); + var borderBox = goog.style.getBorderBox(elem); + var paddingBox = goog.style.getPaddingBox(elem); + var marginBox = goog.style.getMarginBox(elem); + var w = width - borderBox.left - borderBox.right - paddingBox.left - + paddingBox.right - marginBox.left - marginBox.right; var weightArray = []; for (var i = 0; i < this.getChildCount(); i++) { var child = /** @type {i18n.input.chrome.inputview.elements.Weightable} */ ( @@ -126,7 +132,7 @@ weightArray.push(child.getWidthInWeight()); } var splitedWidth = i18n.input.chrome.inputview.util.splitValue(weightArray, - width); + w); for (var i = 0; i < this.getChildCount(); i++) { var child = /** @type {i18n.input.chrome.inputview.elements.Element} */ ( this.getChildAt(i));
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/events.js b/third_party/google_input_tools/src/chrome/os/inputview/events.js index 558b60d..01dccb2 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/events.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/events.js
@@ -44,8 +44,9 @@ LONG_PRESS_END: goog.events.getUniqueId('lpe'), POINTER_DOWN: goog.events.getUniqueId('pd'), POINTER_UP: goog.events.getUniqueId('pu'), - POINTER_OVER: goog.events.getUniqueId('po'), + POINTER_OVER: goog.events.getUniqueId('pv'), POINTER_OUT: goog.events.getUniqueId('po'), + REFRESH: goog.events.getUniqueId('rf'), SETTINGS_READY: goog.events.getUniqueId('sr'), SURROUNDING_TEXT_CHANGED: goog.events.getUniqueId('stc'), SWIPE: goog.events.getUniqueId('s'), @@ -53,7 +54,8 @@ CONTEXT_FOCUS: goog.events.getUniqueId('cf'), CONTEXT_BLUR: goog.events.getUniqueId('cb'), VISIBILITY_CHANGE: goog.events.getUniqueId('vc'), - MODEL_UPDATE: goog.events.getUniqueId('mu') + MODEL_UPDATE: goog.events.getUniqueId('mu'), + URL_CHANGED: goog.events.getUniqueId('uc') }; @@ -218,14 +220,20 @@ * The event when the surrounding text is changed. * * @param {string} text The surrounding text. + * @param {number} anchor . + * @param {number} focus . * @constructor * @extends {goog.events.Event} */ -events.SurroundingTextChangedEvent = function(text) { +events.SurroundingTextChangedEvent = function(text, anchor, focus) { goog.base(this, events.EventType.SURROUNDING_TEXT_CHANGED); /** @type {string} */ this.text = text; + /** @type {number} */ + this.anchor = anchor; + /** @type {number} */ + this.focus = focus; }; goog.inherits(events.SurroundingTextChangedEvent, goog.events.Event);
diff --git a/third_party/google_input_tools/src/chrome/os/message/contenttype.js b/third_party/google_input_tools/src/chrome/os/inputview/globalflags.js similarity index 64% rename from third_party/google_input_tools/src/chrome/os/message/contenttype.js rename to third_party/google_input_tools/src/chrome/os/inputview/globalflags.js index ff20b05..b6e58765 100644 --- a/third_party/google_input_tools/src/chrome/os/message/contenttype.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/globalflags.js
@@ -1,4 +1,4 @@ -// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. // limitations under the License. // See the License for the specific language governing permissions and // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -11,22 +11,12 @@ // you may not use this file except in compliance with the License. // Licensed under the Apache License, Version 2.0 (the "License"); // -goog.provide('i18n.input.chrome.message.ContextType'); +goog.provide('i18n.input.chrome.inputview.GlobalFlags'); /** - * The message type. + * Whether input view keyboards of material design is enabled. * - * @enum {string} + * @type {boolean} */ -i18n.input.chrome.message.ContextType = { - DEFAULT: 'text', - EMAIL: 'email', - PASSWORD: 'password', - URL: 'url', - NUMBER: 'number', - PHONE: 'tel' -}; - - - +i18n.input.chrome.inputview.GlobalFlags.isQPInputView = false;
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/handler/pointerhandler.js b/third_party/google_input_tools/src/chrome/os/inputview/handler/pointerhandler.js index c89434e2..b2fceab 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/handler/pointerhandler.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/handler/pointerhandler.js
@@ -18,6 +18,7 @@ goog.require('goog.events.EventTarget'); goog.require('goog.events.EventType'); goog.require('goog.math.Coordinate'); +goog.require('i18n.input.chrome.inputview.events.PointerEvent'); goog.require('i18n.input.chrome.inputview.handler.PointerActionBundle'); goog.scope(function() { @@ -184,8 +185,8 @@ if (pointerActionBundle) { pointerActionBundle.handlePointerUp(e); } + e.preventDefault(); } - e.preventDefault(); if (pointerActionBundle && pointerActionBundle.view && pointerActionBundle.view.pointerConfig.stopEventPropagation) { e.stopPropagation();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/bold.png b/third_party/google_input_tools/src/chrome/os/inputview/images/bold.png new file mode 100644 index 0000000..8753bbd --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/bold.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/copy.png b/third_party/google_input_tools/src/chrome/os/inputview/images/copy.png new file mode 100644 index 0000000..074ea88 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/copy.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/cut.png b/third_party/google_input_tools/src/chrome/os/inputview/images/cut.png new file mode 100644 index 0000000..cd27ee1 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/cut.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/italic.png b/third_party/google_input_tools/src/chrome/os/inputview/images/italic.png new file mode 100644 index 0000000..38bc789 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/italic.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/material/arrow_down_for_floating.png b/third_party/google_input_tools/src/chrome/os/inputview/images/material/arrow_down_for_floating.png index b559e46e..3c0ccb2 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/images/material/arrow_down_for_floating.png +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/material/arrow_down_for_floating.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/paste.png b/third_party/google_input_tools/src/chrome/os/inputview/images/paste.png new file mode 100644 index 0000000..3014ad66 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/paste.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/redo.png b/third_party/google_input_tools/src/chrome/os/inputview/images/redo.png new file mode 100644 index 0000000..6534b7b --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/redo.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/select_all.png b/third_party/google_input_tools/src/chrome/os/inputview/images/select_all.png new file mode 100644 index 0000000..02a62e46 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/select_all.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/underline.png b/third_party/google_input_tools/src/chrome/os/inputview/images/underline.png new file mode 100644 index 0000000..4a0e00f4 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/underline.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/images/undo.png b/third_party/google_input_tools/src/chrome/os/inputview/images/undo.png new file mode 100644 index 0000000..818191c --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/images/undo.png Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/keyboardcontainer.js b/third_party/google_input_tools/src/chrome/os/inputview/keyboardcontainer.js index b7bc0fa0..f66841b 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/keyboardcontainer.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/keyboardcontainer.js
@@ -18,6 +18,7 @@ goog.require('goog.i18n.bidi'); goog.require('goog.ui.Container'); goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.GlobalFlags'); goog.require('i18n.input.chrome.inputview.elements.content.AltDataView'); goog.require('i18n.input.chrome.inputview.elements.content.CandidateView'); goog.require('i18n.input.chrome.inputview.elements.content.EmojiView'); @@ -25,6 +26,8 @@ goog.require('i18n.input.chrome.inputview.elements.content.HandwritingView'); goog.require('i18n.input.chrome.inputview.elements.content.KeysetView'); goog.require('i18n.input.chrome.inputview.elements.content.MenuView'); +goog.require('i18n.input.chrome.inputview.elements.content.SelectView'); +goog.require('i18n.input.chrome.inputview.elements.content.SwipeView'); goog.require('i18n.input.chrome.inputview.elements.content.VoiceView'); @@ -44,10 +47,12 @@ * The keyboard container. * * @param {!i18n.input.chrome.inputview.Adapter} adapter . + * @param {!i18n.input.chrome.SoundController} soundController . * @constructor * @extends {goog.ui.Container} */ -i18n.input.chrome.inputview.KeyboardContainer = function(adapter) { +i18n.input.chrome.inputview.KeyboardContainer = + function(adapter, soundController) { goog.base(this); /** @type {!content.CandidateView} */ @@ -57,11 +62,17 @@ /** @type {!content.AltDataView} */ this.altDataView = new content.AltDataView(this); + /** @type {!content.SwipeView} */ + this.swipeView = new content.SwipeView(adapter, this); + + /** @type {!content.SelectView} */ + this.selectView = new content.SelectView(this); + /** @type {!content.MenuView} */ this.menuView = new content.MenuView(this); /** @type {!content.VoiceView} */ - this.voiceView = new content.VoiceView(this, adapter); + this.voiceView = new content.VoiceView(this, adapter, soundController); /** @type {!content.ExpandedCandidateView} */ this.expandedCandidateView = new content.ExpandedCandidateView(this); @@ -126,6 +137,8 @@ this.candidateView.render(this.wrapperDiv_); this.getDomHelper().appendChild(elem, this.wrapperDiv_); this.altDataView.render(); + this.swipeView.render(); + this.selectView.render(); this.menuView.render(); this.voiceView.render(); this.voiceView.setVisible(false); @@ -276,15 +289,20 @@ this.candidateView.setWidthInWeight( this.currentKeysetView.getWidthInWeight()); - var candidateElem = this.candidateView.getElement(); - candidateElem.style.paddingLeft = candidateElem.style.paddingRight = - padding + 'px'; this.candidateView.resize(w, candidateViewHeight); - this.currentKeysetView.resize(w, h); - var currentKeysetViewElem = this.currentKeysetView.getElement(); - currentKeysetViewElem.style.paddingLeft = currentKeysetViewElem.style. - paddingRight = padding + 'px'; this.expandedCandidateView.resize(w, h); + if (i18n.input.chrome.inputview.GlobalFlags.isQPInputView) { + var candidateElem = this.candidateView.getElement(); + candidateElem.style.paddingLeft = candidateElem.style.paddingRight = + padding + 'px'; + this.currentKeysetView.resize(width, h, widthPercent); + var expandViewElem = this.expandedCandidateView.getElement(); + expandViewElem.style.marginLeft = expandViewElem.style.marginRight = + padding + 'px'; + } else { + this.currentKeysetView.resize(w, h, 1); + elem.style.paddingLeft = elem.style.paddingRight = padding + 'px'; + } if (this.expandedCandidateView.isVisible()) { // Closes the expanded candidate view if it's visible. // This is to avoid mis-layout issue for the expanded candidate when screen @@ -296,6 +314,8 @@ this.currentKeysetView.setVisible(true); } this.altDataView.resize(screen.width, height); + this.swipeView.resize(screen.width, height); + this.selectView.resize(screen.width, height); this.menuView.resize(screen.width, height); this.voiceView.resize(w + padding, height); }; @@ -305,6 +325,8 @@ KeyboardContainer.prototype.disposeInternal = function() { goog.dispose(this.candidateView); goog.dispose(this.altDataView); + goog.dispose(this.swipeView); + goog.dispose(this.selectView); goog.dispose(this.menuView); goog.dispose(this.voiceView); for (var key in this.keysetViewMap) {
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/emoji_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/emoji_layout.js index 6bb6482..6b83866 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/layouts/emoji_layout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/emoji_layout.js
@@ -96,17 +96,13 @@ }); keySpec = { - 'widthInWeight': 42, - 'heightInWeight': 14 - }; - baseSpec = { - 'widthInWeight': 42, + 'widthInWeight': 1.42, 'heightInWeight': 14 }; var sideKeys = util.createVerticalLayout({ 'id': 'sideKeys', 'children': [util.createKey(keySpec), util.createKey(keySpec), - util.createKey(baseSpec)] + util.createKey(keySpec)] }); var rowsAndSideKeys = util.createLinearLayout({
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/handwriting_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/handwriting_layout.js index 53b8f72..1bb0753b 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/layouts/handwriting_layout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/handwriting_layout.js
@@ -11,7 +11,6 @@ // you may not use this file except in compliance with the License. // Licensed under the Apache License, Version 2.0 (the "License"); // -goog.require('i18n.input.chrome.inputview.layouts.SpaceRow'); goog.require('i18n.input.chrome.inputview.layouts.util');
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/101kbd_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/101kbd_layout.js index a5111ef..ece6e699 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/101kbd_layout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/101kbd_layout.js
@@ -40,7 +40,7 @@ }); var data = { - 'layoutID': '101kbd', + 'layoutID': 'm-101kbd', 'widthInWeight': 15, 'children': [keyboardContainer] };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/102kbd_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/102kbd_layout.js index 8c9d914..e980db2 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/102kbd_layout.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/102kbd_layout.js
@@ -40,7 +40,7 @@ }); var data = { - 'layoutID': '102kbd', + 'layoutID': 'm-102kbd', 'widthInWeight': 15, 'children': [keyboardContainer] };
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_azerty_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_azerty_layout.js new file mode 100644 index 0000000..ba2d726 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_azerty_layout.js
@@ -0,0 +1,49 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.layouts.CompactSpaceRow'); +goog.require('i18n.input.chrome.inputview.layouts.RowsOfCompactAzerty'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + i18n.input.chrome.inputview.layouts.util.setPrefix('compactkbd-k-'); + + var topThreeRows = + i18n.input.chrome.inputview.layouts.RowsOfCompactAzerty.create(); + var spaceRow = + i18n.input.chrome.inputview.layouts.CompactSpaceRow.create(false); + + // Keyboard view. + var keyboardView = i18n.input.chrome.inputview.layouts.util.createLayoutView({ + 'id': 'keyboardView', + 'children': [topThreeRows, spaceRow], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + var keyboardContainer = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-compactkbd-azerty', + 'widthInWeight': 15, + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_nordic_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_nordic_layout.js new file mode 100644 index 0000000..586e920 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_nordic_layout.js
@@ -0,0 +1,49 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.layouts.CompactSpaceRow'); +goog.require('i18n.input.chrome.inputview.layouts.RowsOfCompactNordic'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + i18n.input.chrome.inputview.layouts.util.setPrefix('compactkbd-k-'); + + var topThreeRows = + i18n.input.chrome.inputview.layouts.RowsOfCompactNordic.create(); + var spaceRow = + i18n.input.chrome.inputview.layouts.CompactSpaceRow.create(true); + + // Keyboard view. + var keyboardView = i18n.input.chrome.inputview.layouts.util.createLayoutView({ + 'id': 'keyboardView', + 'children': [topThreeRows, spaceRow], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + var keyboardContainer = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-compactkbd-nordic', + 'widthInWeight': 15, + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_numberpad_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_numberpad_layout.js new file mode 100644 index 0000000..503aecb --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_numberpad_layout.js
@@ -0,0 +1,51 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.layouts.RowsOfNumberpad'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + i18n.input.chrome.inputview.layouts.util.keyIdPrefix = 'compactkbd-k-'; + + var rows = i18n.input.chrome.inputview.layouts.RowsOfNumberpad.create(); + + // Keyboard view. + var keyboardView = i18n.input.chrome.inputview.layouts.util.createLayoutView({ + 'id': 'keyboardView', + 'children': [rows], + 'widthPercent': 50, + 'heightPercent': 100 + }); + + var keyboardContainer = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-compactkbd-numberpad', + 'widthInWeight': 6.45, + 'children': [keyboardContainer], + 'disableCandidateView': true, + 'disableLongpress': true, + 'widthPercent' : { + 'LANDSCAPE' : 0.56, + 'PORTRAIT' : 0.56, + 'LANDSCAPE_WIDE_SCREEN': 0.56 + }}; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_zhuyin_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_zhuyin_layout.js new file mode 100644 index 0000000..12f93942 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/compactkbd_zhuyin_layout.js
@@ -0,0 +1,93 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.layouts.CompactSpaceRow'); +goog.require('i18n.input.chrome.inputview.layouts.RowsOfCompact'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + i18n.input.chrome.inputview.layouts.util.setPrefix('compactkbd-k-'); + + var topRows = + i18n.input.chrome.inputview.layouts.RowsOfCompactZhuyin.create(); + + var digitSwitcher = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1.1, + 'heightInWeight': 4 + }); + var globeOrSymbolKey = i18n.input.chrome.inputview.layouts.util.createKey({ + 'condition': i18n.input.chrome.inputview.ConditionName.SHOW_GLOBE_OR_SYMBOL, + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var menuKey = i18n.input.chrome.inputview.layouts.util.createKey({ + 'condition': i18n.input.chrome.inputview.ConditionName.SHOW_MENU, + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var comma = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var space = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 3, + 'heightInWeight': 4 + }); + var character = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var period = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var switcher = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1, + 'heightInWeight': 4 + }); + var hide = i18n.input.chrome.inputview.layouts.util.createKey({ + 'widthInWeight': 1.1, + 'heightInWeight': 4 + }); + menuKey['spec']['giveWeightTo'] = space['spec']['id']; + globeOrSymbolKey['spec']['giveWeightTo'] = space['spec']['id']; + + var spaceRow = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'spaceKeyrow', + 'children': [digitSwitcher, globeOrSymbolKey, menuKey, comma, + space, character, period, switcher, hide] + }); + + // Keyboard view. + var keyboardView = i18n.input.chrome.inputview.layouts.util.createLayoutView({ + 'id': 'keyboardView', + 'children': [topRows, spaceRow], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + var keyboardContainer = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-compactkbd-zhuyin', + 'widthInWeight': 15, + 'children': [keyboardContainer] + }; + google.ime.chrome.inputview.onLayoutLoaded(data); +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/emoji_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/emoji_layout.js new file mode 100644 index 0000000..a4fa8bc --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/emoji_layout.js
@@ -0,0 +1,140 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.Css'); +goog.require('i18n.input.chrome.inputview.elements.ElementType'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + +(function() { + var util = i18n.input.chrome.inputview.layouts.util; + var ElementType = i18n.input.chrome.inputview.elements.ElementType; + util.setPrefix('emoji-k-'); + var ids = ['recent', 'favorits', 'faces', 'emoticon', + 'symbol', 'nature', 'places', 'objects']; + // TODO: we should avoid using hard-coded number. + var pages = [1, 3, 6, 4, 6, 7, 5, 8]; + var emojiPage = {}; + var emojiList = []; + // Tab Rows + var tabRows = []; + var baseKeySpec = { + 'widthInWeight': 1, + 'heightInWeight': 1 + }; + + // The top tabbar row. + var keySequenceOf9 = util.createKeySequence(baseKeySpec, 9); + var rightKey = util.createKey({ + 'widthInWeight': 1.037, + 'heightInWeight': 1 + }); + var tabBar = util.createLinearLayout({ + 'id': 'tabBar', + 'children': [keySequenceOf9, rightKey], + 'iconCssClass': i18n.input.chrome.inputview.Css.LINEAR_LAYOUT_BORDER + }); + + // The emoji pages. + baseKeySpec = { + 'widthInWeight': 1, + 'heightInWeight': 1.67 + }; + var totalPages = 0; + for (var i = 0; i < pages.length; i++) { + totalPages += pages[i]; + } + for (var i = 0; i < totalPages; i++) { + var rows = []; + for (var j = 0; j < 3; j++) { + keySequenceOf9 = util.createKeySequence(baseKeySpec, 9); + var row = util.createLinearLayout({ + 'id': 'page-' + i + '-row-' + j, + 'children': [keySequenceOf9], + 'iconCssClass': i18n.input.chrome.inputview.Css.LINEAR_LAYOUT_BORDER + }); + rows.push(row); + } + emojiPage = util.createVerticalLayout({ + 'id': 'page-' + i, + 'children': rows + }); + emojiList.push(emojiPage); + } + var emojiRows = util.createExtendedLayout({ + 'id': 'emojiRows', + 'children': emojiList + }); + var emojiSlider = util.createVerticalLayout({ + 'id': 'emojiSlider', + 'children': [emojiRows] + }); + + // The right side keys. + baseKeySpec = { + 'widthInWeight': 1.037, + 'heightInWeight': 1.67 + }; + var sideKeys = util.createVerticalLayout({ + 'id': 'sideKeys', + 'children': [util.createKeySequence(baseKeySpec, 3)] + }); + + var rowsAndSideKeys = util.createLinearLayout({ + 'id': 'rowsAndSideKeys', + 'children': [emojiSlider, sideKeys] + }); + + var backToKeyboardKey = util.createKey({ + 'widthInWeight': 2, + 'heightInWeight': 1.67 + }); + var spaceKey = util.createKey({ + 'widthInWeight': 7, + 'heightInWeight': 1.67 + }); + var hideKeyboardKey = util.createKey({ + 'widthInWeight': 1.037, + 'heightInWeight': 1.67 + }); + var spaceRow = util.createLinearLayout({ + 'id': 'emojiSpaceRow', + 'children': [backToKeyboardKey, spaceKey, hideKeyboardKey] + }); + + var emojiView = util.createVerticalLayout({ + 'id': 'emojiView', + 'children': [tabBar, rowsAndSideKeys, spaceRow] + }); + + // Keyboard view. + var keyboardView = util.createLayoutView({ + 'id': 'keyboardView', + 'children': [emojiView], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + + var keyboardContainer = util.createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'disableCandidateView': true, + 'layoutID': 'm-emoji', + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/handwriting_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/handwriting_layout.js new file mode 100644 index 0000000..90f6ae29 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/handwriting_layout.js
@@ -0,0 +1,79 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.layouts.material.util'); + + +(function() { + var util = i18n.input.chrome.inputview.layouts.material.util; + util.setPrefix('handwriting-k-'); + + var verticalRows = []; + var baseKeySpec = { + 'widthInWeight': 1, + 'heightInWeight': 1 + }; + for (var i = 0; i < 4; i++) { + verticalRows.push(util.createKey(baseKeySpec)); + } + var leftSideColumn = util.createVerticalLayout({ + 'id': 'leftSideColumn', + 'children': verticalRows + }); + + verticalRows = []; + for (var i = 0; i < 4; i++) { + verticalRows.push(util.createKey(baseKeySpec)); + } + var rightSideColumn = util.createVerticalLayout({ + 'id': 'rightSideColumn', + 'children': verticalRows + }); + + var spec = { + 'id': 'canvasView', + 'widthInWeight': 11.2, + 'heightInWeight': 4 + }; + + var canvasView = util.createCanvasView(spec); + var panelView = util.createHandwritingLayout({ + 'id': 'panelView', + 'children': [canvasView, leftSideColumn, rightSideColumn] + }); + + // Keyboard view. + var keyboardView = util.createLayoutView({ + 'id': 'keyboardView', + 'children': [panelView], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + + var keyboardContainer = util.createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-handwriting', + 'heightPercentOfWidth': 0.275, + 'minimumHeight': 350, + 'fullHeightInWeight': 5.6, + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/jpkbd_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/jpkbd_layout.js new file mode 100644 index 0000000..962dfb4c --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/jpkbd_layout.js
@@ -0,0 +1,101 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// +goog.require('i18n.input.chrome.inputview.ConditionName'); +goog.require('i18n.input.chrome.inputview.layouts.RowsOfJP'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + var ConditionName = i18n.input.chrome.inputview.ConditionName; + var util = i18n.input.chrome.inputview.layouts.util; + i18n.input.chrome.inputview.layouts.util.setPrefix('jpkbd-k-'); + + var topFourRows = i18n.input.chrome.inputview.layouts.RowsOfJP.create(); + + // Creates the space row. + var globeKey = util.createKey({ + 'condition': ConditionName.SHOW_GLOBE_OR_SYMBOL, + 'widthInWeight': 1 + }); + var menuKey = util.createKey({ + 'condition': ConditionName.SHOW_MENU, + 'widthInWeight': 1 + }); + var ctrlKey = util.createKey({ + 'widthInWeight': 1 + }); + var altKey = util.createKey({ + 'widthInWeight': 1 + }); + + var leftIMEKey = util.createKey({'widthInWeight': 1}); + var spaceKey = util.createKey({'widthInWeight': 6}); + var rightIMEKey = util.createKey({'widthInWeight': 1}); + + // If globeKey or altGrKey is not shown, give its weight to space key. + globeKey['spec']['giveWeightTo'] = spaceKey['spec']['id']; + menuKey['spec']['giveWeightTo'] = spaceKey['spec']['id']; + + var leftKey = util.createKey({ + 'widthInWeight': 1 + }); + var rightKey = util.createKey({ + 'widthInWeight': 1 + }); + var hideKeyboardKey = util.createKey({ + 'widthInWeight': 1 + }); + + var keys = [ + globeKey, + menuKey, + ctrlKey, + altKey, + leftIMEKey, + spaceKey, + rightIMEKey, + leftKey, + rightKey, + hideKeyboardKey + ]; + + var spaceRow = util.createLinearLayout({ + 'id': 'spaceKeyrow', + 'children': keys + }); + + + // Keyboard view. + var keyboardView = i18n.input.chrome.inputview.layouts.util.createLayoutView({ + 'id': 'keyboardView', + 'children': [topFourRows, spaceRow], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + var keyboardContainer = i18n.input.chrome.inputview.layouts.util. + createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-jpkbd', + 'widthInWeight': 15, + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/kokbd_layout.js b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/kokbd_layout.js new file mode 100644 index 0000000..24869c4 --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/layouts/material/kokbd_layout.js
@@ -0,0 +1,110 @@ +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. +// limitations under the License. +// See the License for the specific language governing permissions and +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// distributed under the License is distributed on an "AS-IS" BASIS, +// Unless required by applicable law or agreed to in writing, software +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// You may obtain a copy of the License at +// you may not use this file except in compliance with the License. +// Licensed under the Apache License, Version 2.0 (the "License"); +// + +goog.require('i18n.input.chrome.inputview.ConditionName'); +goog.require('i18n.input.chrome.inputview.layouts.RowsOf101'); +goog.require('i18n.input.chrome.inputview.layouts.util'); + + +(function() { + var ConditionName = i18n.input.chrome.inputview.ConditionName; + var util = i18n.input.chrome.inputview.layouts.util; + + util.setPrefix('kokbd-k-'); + + /** + * Creates the spaceKey row. + * + * @return {!Object} The spaceKey row. + */ + var createSpaceRow = function() { + var globeKey = util.createKey({ + 'condition': ConditionName.SHOW_GLOBE_OR_SYMBOL, + 'widthInWeight': 1 + }); + var menuKey = util.createKey({ + 'condition': ConditionName.SHOW_MENU, + 'widthInWeight': 1 + }); + var ctrlKey = util.createKey({ + 'widthInWeight': 1 + }); + var altKey = util.createKey({ + 'widthInWeight': 1 + }); + // Creates the Hangja switcher key in the end and insert it before the + // Space key. + var hangjaSwitcher = util.createKey({ + 'widthInWeight': 1 + }); + var spaceKey = util.createKey({ + 'widthInWeight': 4.87 + }); + var enSwitcher = util.createKey({ + 'widthInWeight': 1, + 'condition': ConditionName.SHOW_EN_SWITCHER_KEY + }); + var altGrKey = util.createKey({ + 'widthInWeight': 1.25, + 'condition': ConditionName.SHOW_ALTGR + }); + // If globeKey or altGrKey is not shown, give its weight to space key. + globeKey['spec']['giveWeightTo'] = spaceKey['spec']['id']; + menuKey['spec']['giveWeightTo'] = spaceKey['spec']['id']; + altGrKey['spec']['giveWeightTo'] = spaceKey['spec']['id']; + hangjaSwitcher['spec']['giveWeightTo'] = spaceKey['spec']['id']; + + var leftKey = util.createKey({ + 'widthInWeight': 1.08 + }); + var rightKey = util.createKey({ + 'widthInWeight': 1.08 + }); + var hideKeyboardKey = util.createKey({ + 'widthInWeight': 1.08 + }); + var spaceKeyRow = util.createLinearLayout({ + 'id': 'spaceKeyrow', + 'children': [globeKey, menuKey, ctrlKey, altKey, hangjaSwitcher, + spaceKey, enSwitcher, altGrKey, leftKey, rightKey, + hideKeyboardKey] + }); + return spaceKeyRow; + }; + + var topFourRows = i18n.input.chrome.inputview.layouts.RowsOf101.create(); + var spaceRow = createSpaceRow(); + + // Keyboard view. + var keyboardView = util.createLayoutView({ + 'id': 'keyboardView', + 'children': [topFourRows, spaceRow], + 'widthPercent': 100, + 'heightPercent': 100 + }); + + var keyboardContainer = util.createLinearLayout({ + 'id': 'keyboardContainer', + 'children': [keyboardView] + }); + + var data = { + 'layoutID': 'm-kokbd', + 'widthInWeight': 15, + 'children': [keyboardContainer] + }; + + google.ime.chrome.inputview.onLayoutLoaded(data); + +}) ();
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/m17nmodel.js b/third_party/google_input_tools/src/chrome/os/inputview/m17nmodel.js index 3082006..645a32f 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/m17nmodel.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/m17nmodel.js
@@ -17,6 +17,7 @@ goog.require('goog.events.EventTarget'); goog.require('i18n.input.chrome.inputview.SpecNodeName'); goog.require('i18n.input.chrome.inputview.content.util'); +goog.require('i18n.input.chrome.inputview.events.ConfigLoadedEvent'); goog.require('i18n.input.chrome.vk.KeyCode'); goog.require('i18n.input.chrome.vk.Model');
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/sounds/auto_correction.wav b/third_party/google_input_tools/src/chrome/os/inputview/sounds/auto_correction.wav new file mode 100644 index 0000000..aa54b4c --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/sounds/auto_correction.wav Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_end.wav b/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_end.wav new file mode 100644 index 0000000..aa54b4c --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_end.wav Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_start.wav b/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_start.wav new file mode 100644 index 0000000..aa54b4c --- /dev/null +++ b/third_party/google_input_tools/src/chrome/os/inputview/sounds/voice_recog_start.wav Binary files differ
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/util.js b/third_party/google_input_tools/src/chrome/os/inputview/util.js index e29accd..009f54e 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/util.js +++ b/third_party/google_input_tools/src/chrome/os/inputview/util.js
@@ -329,4 +329,62 @@ return keyboardCode.replace(/\..*$/, ''); }; + +/** + * Checks that the word is a valid delete from the old to new context. + * + * @param {string} oldContext The old context. + * @param {string} newContext The new context. + * @param {string} deletionCandidate A possible word deletion. + * + * @return {boolean} Whether the deletion was valid. + */ +util.isPossibleDelete = function( + oldContext, newContext, deletionCandidate) { + // Check that deletionCandidate exists in oldContext. We don't check if it's a + // tail since our heuristic may have trimmed whitespace. + var rootEnd = oldContext.lastIndexOf(deletionCandidate); + if (rootEnd != -1) { + // Check that remaining text in root persisted in newContext. + var root = oldContext.slice(0, rootEnd); + return root == newContext.slice(-rootEnd); + } + return false; +}; + + +/** + * Checks whether a letter deletion would cause the observed context transform. + * + * @param {string} oldContext The old context. + * @param {string} newContext The new context. + * + * @return {boolean} Whether the transform is valid. + */ +util.isLetterDelete = function(oldContext, newContext) { + if (oldContext == '') { + return false; + } + // Handle buffer overflow. + if (oldContext.length == newContext.length) { + return util.isLetterDelete(oldContext, newContext.slice(1)); + } + return oldContext.length == newContext.length + 1 && + oldContext.indexOf(newContext) == 0; +}; + + +/** + * Checks whether a letter restoration would cause the observed context + * transform. + * + * @param {string} oldContext The old context. + * @param {string} newContext The new context. + * + * @return {boolean} Whether the transform is valid. + */ +util.isLetterRestore = function(oldContext, newContext) { + return util.isLetterDelete(newContext, oldContext); +}; + }); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/message/name.js b/third_party/google_input_tools/src/chrome/os/message/name.js index 83bf379d..42817612 100644 --- a/third_party/google_input_tools/src/chrome/os/message/name.js +++ b/third_party/google_input_tools/src/chrome/os/message/name.js
@@ -21,6 +21,7 @@ */ i18n.input.chrome.message.Name = { ALT_KEY: 'altKey', + ANCHOR: 'anchor', CANDIDATE: 'candidate', CANDIDATES: 'candidates', CANDIDATE_ID: 'candidateID', @@ -31,6 +32,7 @@ CTRL_KEY: 'ctrlKey', CURSOR: 'cursor', ENGINE_ID: 'engineID', + FOCUS: 'focus', HEIGHT: 'height', ID: 'id', IS_AUTOCORRECT: 'isAutoCorrect',
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/soundcontroller.js b/third_party/google_input_tools/src/chrome/os/soundcontroller.js similarity index 72% rename from third_party/google_input_tools/src/chrome/os/inputview/soundcontroller.js rename to third_party/google_input_tools/src/chrome/os/soundcontroller.js index 19b7024..7b57e3b 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/soundcontroller.js +++ b/third_party/google_input_tools/src/chrome/os/soundcontroller.js
@@ -1,4 +1,4 @@ -// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. // limitations under the License. // See the License for the specific language governing permissions and // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -11,7 +11,7 @@ // you may not use this file except in compliance with the License. // Licensed under the Apache License, Version 2.0 (the "License"); // -goog.provide('i18n.input.chrome.inputview.SoundController'); +goog.provide('i18n.input.chrome.SoundController'); goog.require('goog.Disposable'); goog.require('goog.dom'); @@ -25,40 +25,43 @@ var keyToSoundIdOnKeyRepeat = {}; + /** * Sound controller for the keyboard. * * @param {!boolean} enabled Whether sounds is enabled by default. - * @param {?number} opt_volume The default volume for sound tracks. + * @param {?number=} opt_volume The default volume for sound tracks. * @constructor * @extends {goog.Disposable} */ -i18n.input.chrome.inputview.SoundController = function(enabled, opt_volume) { +i18n.input.chrome.SoundController = function(enabled, opt_volume) { /** * Collection of all the sound pools. * - * @type {!Object.<string, !Object>} + * @private {!Object.<string, !Object>} */ this.sounds_ = {}; + /** @private {boolean} */ this.enabled_ = enabled; /** * The default volume for all audio tracks. Tracks with volume 0 will be * skipped. * - * @type {number} + * @private {number} */ this.volume_ = opt_volume || this.DEFAULT_VOLUME; - if (enabled) + if (enabled) { this.initialize(); + } }; -goog.inherits(i18n.input.chrome.inputview.SoundController, goog.Disposable); +goog.inherits(i18n.input.chrome.SoundController, goog.Disposable); -var Controller = i18n.input.chrome.inputview.SoundController; +var Controller = i18n.input.chrome.SoundController; /** @@ -73,17 +76,24 @@ Controller.prototype.DEFAULT_VOLUME = 0.6; +/** @private {boolean} */ +Controller.prototype.initialized_ = false; + + /** * Initializes the sound controller. */ Controller.prototype.initialize = function() { - for (var sound in Sounds) { + if (!this.initialized_) { + for (var sound in Sounds) { this.addSound_(Sounds[sound]); + } + keyToSoundIdOnKeyUp[ElementType.BACKSPACE_KEY] = Sounds.NONE; + keyToSoundIdOnKeyUp[ElementType.ENTER_KEY] = Sounds.RETURN; + keyToSoundIdOnKeyUp[ElementType.SPACE_KEY] = Sounds.SPACEBAR; + keyToSoundIdOnKeyRepeat[ElementType.BACKSPACE_KEY] = Sounds.DELETE; + this.initialized_ = true; } - keyToSoundIdOnKeyUp[ElementType.BACKSPACE_KEY] = Sounds.NONE; - keyToSoundIdOnKeyUp[ElementType.ENTER_KEY] = Sounds.RETURN; - keyToSoundIdOnKeyUp[ElementType.SPACE_KEY] = Sounds.SPACEBAR; - keyToSoundIdOnKeyRepeat[ElementType.BACKSPACE_KEY] = Sounds.DELETE; }; @@ -137,8 +147,19 @@ */ Controller.prototype.setEnabled = function(enabled) { this.enabled_ = enabled; - if (this.enabled_) + if (this.enabled_) { this.initialize(); + } +}; + + +/** + * Gets the flag whether sound controller is enabled or not. + * + * @return {!boolean} + */ +Controller.prototype.getEnabled = function() { + return this.enabled_; }; @@ -159,12 +180,18 @@ * Plays the specified sound. * * @param {string} soundId The id of the audio tag. - * @private + * @param {boolean=} opt_force Force to play sound whatever the enabled flags is + * turned on. */ -Controller.prototype.playSound_ = function(soundId) { +Controller.prototype.playSound = function(soundId, opt_force) { + if (opt_force) { + this.initialize(); + } // If master volume is zero, ignore the request. - if (!this.enabled_ || this.volume_ == 0 || soundId == Sounds.NONE) + if (!opt_force && !this.enabled_ || this.volume_ == 0 || + soundId == Sounds.NONE) { return; + } var pool = this.sounds_[soundId]; if (!pool) { console.error('Cannot find sound: ' + soundId); @@ -185,25 +212,25 @@ * * @param {ElementType} key The key released. */ - Controller.prototype.onKeyUp = function(key) { +Controller.prototype.onKeyUp = function(key) { var sound = keyToSoundIdOnKeyUp[key] || Sounds.STANDARD; - this.playSound_(sound); - }; + this.playSound(sound); +}; - /** +/** * On key repeat. * * @param {ElementType} key The key that is being repeated. */ - Controller.prototype.onKeyRepeat = function(key) { +Controller.prototype.onKeyRepeat = function(key) { var sound = keyToSoundIdOnKeyRepeat[key] || Sounds.NONE; - this.playSound_(sound); - }; + this.playSound(sound); +}; - /** @override */ - Controller.prototype.disposeInternal = function() { +/** @override */ +Controller.prototype.disposeInternal = function() { for (var soundId in this.sounds_) { var pool = this.sounds_[soundId]; for (var i = 0; i < pool.length; i++) { @@ -221,6 +248,6 @@ keyToSoundIdOnKeyUp = {}; keyToSoundIdOnKeyRepeat = {}; goog.base(this, 'disposeInternal'); - }; +}; }); // goog.scope
diff --git a/third_party/google_input_tools/src/chrome/os/inputview/sounds.js b/third_party/google_input_tools/src/chrome/os/sounds.js similarity index 80% rename from third_party/google_input_tools/src/chrome/os/inputview/sounds.js rename to third_party/google_input_tools/src/chrome/os/sounds.js index ea47003..e98f10fe 100644 --- a/third_party/google_input_tools/src/chrome/os/inputview/sounds.js +++ b/third_party/google_input_tools/src/chrome/os/sounds.js
@@ -1,4 +1,4 @@ -// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved. +// Copyright 2015 The ChromeOS IME Authors. All Rights Reserved. // limitations under the License. // See the License for the specific language governing permissions and // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,6 +24,9 @@ RETURN: 'keypress-return', SPACEBAR: 'keypress-spacebar', STANDARD: 'keypress-standard', - NONE: 'none' + NONE: 'none', + VOICE_RECOG_START: 'voice_recog_start', + VOICE_RECOG_END: 'voice_recog_end', + AUTO_CORRECTION: 'auto_correction' };
diff --git a/third_party/google_input_tools/src/chrome/os/statistics.js b/third_party/google_input_tools/src/chrome/os/statistics.js index 59d3761..551f96e 100644 --- a/third_party/google_input_tools/src/chrome/os/statistics.js +++ b/third_party/google_input_tools/src/chrome/os/statistics.js
@@ -80,6 +80,24 @@ /** + * Whether recording for physical keyboard specially. + * + * @private {boolean} + */ +Statistics.prototype.isPhysicalKeyboard_ = false; + + +/** + * Sets whether recording for physical keyboard. + * + * @param {boolean} isPhysicalKeyboard . + */ +Statistics.prototype.setPhysicalKeyboard = function(isPhysicalKeyboard) { + this.isPhysicalKeyboard_ = isPhysicalKeyboard; +}; + + +/** * Sets the current input method id. * * @param {string} inputMethodId . @@ -160,12 +178,15 @@ return; } + // For latin transliteration, record the logs under the name with 'Pk' which + // means Physical Keyboard. + var name = this.isPhysicalKeyboard_ ? + 'InputMethod.PkCommit.' : 'InputMethod.Commit.'; + var self = this; var record = function(suffix) { - self.recordEnum('InputMethod.Commit.Index' + suffix, - targetIndex + 1, 20); - self.recordEnum('InputMethod.Commit.Type' + suffix, - commitType, CommitTypes.MAX); + self.recordEnum(name + 'Index' + suffix, targetIndex + 1, 20); + self.recordEnum(name + 'Type' + suffix, commitType, CommitTypes.MAX); }; record('');
diff --git a/third_party/instrumented_libraries/download_build_install.py b/third_party/instrumented_libraries/download_build_install.py index 7fddba2..eb450ab 100755 --- a/third_party/instrumented_libraries/download_build_install.py +++ b/third_party/instrumented_libraries/download_build_install.py
@@ -111,10 +111,12 @@ run_shell_commands(build_and_install_in_destdir, parsed_arguments.verbose, environment) fix_rpaths(destdir) - shell_call( + run_shell_commands([ # Now move the contents of the temporary destdir to their final place. - 'cp %s/* %s/ -rdf' % (destdir, install_prefix), - parsed_arguments.verbose, environment) + # We only care for the contents of lib/. + 'mkdir -p %s/lib' % install_prefix, + 'cp %s/lib/* %s/lib/ -rdf' % (destdir, install_prefix)], + parsed_arguments.verbose, environment) def nss_make_and_copy(parsed_arguments, environment, install_prefix): @@ -176,10 +178,12 @@ (parsed_arguments.jobs, ' '.join(install_args)), parsed_arguments.verbose, environment) fix_rpaths(destdir) - shell_call([ + run_shell_commands([ # Now move the contents of the temporary destdir to their final place. - 'cp %s/* %s/ -rdf' % (destdir, install_prefix)], - parsed_arguments.verbose, environment) + # We only care for the contents of lib/. + 'mkdir -p %s/lib' % install_prefix, + 'cp %s/lib/* %s/lib/ -rdf' % (destdir, install_prefix)], + parsed_arguments.verbose, environment) def libpci3_make_install(parsed_arguments, environment, install_prefix): @@ -220,10 +224,9 @@ ' '.join(install_args + paths))], parsed_arguments.verbose, environment) fix_rpaths(destdir) - # Now move the contents of the temporary destdir to their final place. + # Now install the DSOs to their final place. run_shell_commands([ - 'cp %s/* %s/ -rd' % (destdir, install_prefix), - 'mkdir -p %s/lib/' % install_prefix, + 'mkdir -p %s/lib' % install_prefix, 'install -m 644 lib/libpci.so* %s/lib/' % install_prefix, 'ln -sf libpci.so.%s %s/lib/libpci.so.3' % (version, install_prefix)], parsed_arguments.verbose, environment)
diff --git a/third_party/instrumented_libraries/instrumented_libraries.gyp b/third_party/instrumented_libraries/instrumented_libraries.gyp index 195ce30..572846a 100644 --- a/third_party/instrumented_libraries/instrumented_libraries.gyp +++ b/third_party/instrumented_libraries/instrumented_libraries.gyp
@@ -31,6 +31,11 @@ 'target_defaults': { 'build_method': 'destdir', + # Every package must have --disable-static in configure flags to avoid + # building unnecessary static libs. Ideally we should add it here. + # Unfortunately, zlib1g doesn't support that flag and for some reason it + # can't be removed with a GYP exclusion list. So instead we add that flag + # manually to every package but zlib1g. 'extra_configure_flags': [], 'jobs': '<(instrumented_libraries_jobs)', 'package_cflags': [ @@ -178,36 +183,46 @@ { 'package_name': 'freetype', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'run_before_build': 'scripts/freetype.sh', 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libcairo2', 'dependencies=': [], - 'extra_configure_flags': ['--disable-gtk-doc'], + 'extra_configure_flags': [ + '--disable-gtk-doc', + '--disable-static', + ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libdbus-1-3', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libdbus-glib-1-2', 'dependencies=': [], - # Use system dbus-binding-tool. The just-built one is instrumented but - # doesn't have the correct RPATH, and will crash. - 'extra_configure_flags': ['--with-dbus-binding-tool=dbus-binding-tool'], + 'extra_configure_flags': [ + # Use system dbus-binding-tool. The just-built one is instrumented but + # doesn't have the correct RPATH, and will crash. + '--with-dbus-binding-tool=dbus-binding-tool', + '--disable-static', + ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libexpat1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libffi6', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { @@ -216,6 +231,7 @@ 'extra_configure_flags': [ '--disable-docs', '--sysconfdir=/etc/', + '--disable-static', # From debian/rules. '--with-add-fonts=/usr/X11R6/lib/X11/fonts,/usr/local/share/fonts', ], @@ -236,7 +252,7 @@ # From debian/rules. '--enable-noexecstack', '--enable-ld-version-script', - '--enable-static', + '--disable-static', # http://crbug.com/344505 '--disable-asm' ], @@ -249,6 +265,7 @@ '--disable-gtk-doc', '--disable-gtk-doc-html', '--disable-gtk-doc-pdf', + '--disable-static', ], 'asan_blacklist': 'blacklists/asan/libglib2.0-0.txt', 'msan_blacklist': 'blacklists/msan/libglib2.0-0.txt', @@ -258,6 +275,7 @@ { 'package_name': 'libgpg-error0', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { @@ -265,6 +283,7 @@ 'dependencies=': [], 'extra_configure_flags': [ '--enable-64bit', + '--disable-static', # TSan reports data races on debug variables. '--disable-debug', ], @@ -274,6 +293,7 @@ { 'package_name': 'libp11-kit0', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], # Required on Trusty due to autoconf version mismatch. 'run_before_build': 'scripts/autoreconf.sh', 'includes': ['standard_instrumented_package_target.gypi'], @@ -284,6 +304,7 @@ 'extra_configure_flags': [ '--enable-utf8', '--enable-unicode-properties', + '--disable-static', ], 'includes': ['standard_instrumented_package_target.gypi'], }, @@ -291,6 +312,7 @@ 'package_name': 'libpixman-1-0', 'dependencies=': [], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--disable-gtk', '--disable-silent-rules', @@ -301,12 +323,16 @@ { 'package_name': 'libpng12-0', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libx11-6', 'dependencies=': [], - 'extra_configure_flags': ['--disable-specs'], + 'extra_configure_flags': [ + '--disable-specs', + '--disable-static', + ], 'msan_blacklist': 'blacklists/msan/libx11-6.txt', # Required on Trusty due to autoconf version mismatch. 'run_before_build': 'scripts/autoreconf.sh', @@ -315,12 +341,16 @@ { 'package_name': 'libxau6', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxcb1', 'dependencies=': [], - 'extra_configure_flags': ['--disable-build-docs'], + 'extra_configure_flags': [ + '--disable-build-docs', + '--disable-static', + ], 'conditions': [ ['"<(_ubuntu_release)"=="precise"', { # Backport fix for https://bugs.freedesktop.org/show_bug.cgi?id=54671 @@ -334,33 +364,43 @@ { 'package_name': 'libxcomposite1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxcursor1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxdamage1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxdmcp6', 'dependencies=': [], - 'extra_configure_flags': ['--disable-docs'], + 'extra_configure_flags': [ + '--disable-docs', + '--disable-static', + ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxext6', 'dependencies=': [], - 'extra_configure_flags': ['--disable-specs'], + 'extra_configure_flags': [ + '--disable-specs', + '--disable-static', + ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxfixes3', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { @@ -369,38 +409,47 @@ 'extra_configure_flags': [ '--disable-specs', '--disable-docs', + '--disable-static', ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxinerama1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxrandr2', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxrender1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxss1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'libxtst6', 'dependencies=': [], - 'extra_configure_flags': ['--disable-specs'], + 'extra_configure_flags': [ + '--disable-specs', + '--disable-static', + ], 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'zlib1g', 'dependencies=': [], + # --disable-static is not supported 'patch': 'patches/zlib1g.diff', 'includes': ['standard_instrumented_package_target.gypi'], }, @@ -427,6 +476,7 @@ }], ], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--enable-x11', '--disable-hal-compat', @@ -440,6 +490,7 @@ { 'package_name': 'libasound2', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'run_before_build': 'scripts/libasound2.sh', 'includes': ['standard_instrumented_package_target.gypi'], }, @@ -449,6 +500,7 @@ 'patch': 'patches/libcups2.diff', 'jobs': 1, 'extra_configure_flags': [ + '--disable-static', # All from debian/rules. '--localedir=/usr/share/cups/locale', '--enable-slp', @@ -457,7 +509,6 @@ '--enable-gnutls', '--disable-openssl', '--enable-threads', - '--enable-static', '--enable-debug', '--enable-dbus', '--with-dbusdir=/etc/dbus-1', @@ -479,6 +530,7 @@ 'package_name': 'pango1.0', 'dependencies=': [], 'extra_configure_flags': [ + '--disable-static', # Avoid https://bugs.gentoo.org/show_bug.cgi?id=425620 '--enable-introspection=no', # Pango is normally used with dynamically loaded modules. However, @@ -492,6 +544,7 @@ { 'package_name': 'libcap2', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'build_method': 'custom_libcap', 'includes': ['standard_instrumented_package_target.gypi'], }, @@ -499,6 +552,7 @@ 'package_name': 'udev', 'dependencies=': [], 'extra_configure_flags': [ + '--disable-static', # Without this flag there's a linking step that doesn't honor LDFLAGS # and fails. # TODO(earthdok): find a better fix. @@ -511,6 +565,7 @@ 'package_name': 'libtasn1-3', 'dependencies=': [], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--enable-ld-version-script', ], @@ -520,6 +575,7 @@ 'package_name': 'libtasn1-6', 'dependencies=': [], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--enable-ld-version-script', ], @@ -528,8 +584,7 @@ { 'package_name': 'libgnome-keyring0', 'extra_configure_flags': [ - # Build static libs (from debian/rules). - '--enable-static', + '--disable-static', '--enable-tests=no', # Make the build less problematic. '--disable-introspection', @@ -542,6 +597,7 @@ 'package_name': 'libgtk2.0-0', 'package_cflags': ['-Wno-return-type'], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--prefix=/usr', '--sysconfdir=/etc', @@ -563,6 +619,7 @@ { 'package_name': 'libgdk-pixbuf2.0-0', 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--with-libjasper', '--with-x11', @@ -576,6 +633,7 @@ { 'package_name': 'libpci3', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'build_method': 'custom_libpci3', 'jobs': 1, 'includes': ['standard_instrumented_package_target.gypi'], @@ -583,6 +641,7 @@ { 'package_name': 'libdbusmenu-glib4', 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--disable-scrollkeeper', '--enable-gtk-doc', @@ -599,6 +658,7 @@ { 'package_name': 'overlay-scrollbar', 'extra_configure_flags': [ + '--disable-static', '--with-gtk=2', ], 'dependencies=': [], @@ -608,6 +668,7 @@ { 'package_name': 'libgconf-2-4', 'extra_configure_flags': [ + '--disable-static', # From debian/rules. (Even though --with-gtk=3.0 doesn't make sense.) '--with-gtk=3.0', '--disable-orbit', @@ -620,6 +681,7 @@ { 'package_name': 'libappindicator1', 'extra_configure_flags': [ + '--disable-static', # See above. '--disable-introspection', ], @@ -631,6 +693,7 @@ { 'package_name': 'libdbusmenu', 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--disable-scrollkeeper', '--with-gtk=2', @@ -645,6 +708,7 @@ { 'package_name': 'atk1.0', 'extra_configure_flags': [ + '--disable-static', # See above. '--disable-introspection', ], @@ -654,12 +718,14 @@ { 'package_name': 'libunity9', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], 'run_before_build': 'scripts/autogen.sh', 'includes': ['standard_instrumented_package_target.gypi'], }, { 'package_name': 'dee', 'extra_configure_flags': [ + '--disable-static', # See above. '--disable-introspection', ], @@ -671,6 +737,7 @@ 'package_name': 'harfbuzz', 'package_cflags': ['-Wno-c++11-narrowing'], 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--with-graphite2=yes', '--with-gobject', @@ -683,6 +750,7 @@ { 'package_name': 'brltty', 'extra_configure_flags': [ + '--disable-static', # From debian/rules. '--without-viavoice', '--without-theta', @@ -703,6 +771,7 @@ { 'package_name': 'libva1', 'dependencies=': [], + 'extra_configure_flags': ['--disable-static'], # Backport a use-after-free fix: # http://cgit.freedesktop.org/libva/diff/va/va.c?h=staging&id=d4988142a3f2256e38c5c5cdcdfc1b4f5f3c1ea9 'patch': 'patches/libva1.diff',
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index ddd6be4..0c92b5b 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn
@@ -124,70 +124,73 @@ ] } -# The list of files in libaddressinput.gypi. -gypi_values = exec_script("//build/gypi_to_gn.py", - [ rebase_path("src/cpp/libaddressinput.gypi") ], - "scope", - [ "src/cpp/libaddressinput.gypi" ]) +if (!is_android) { + # The list of files in libaddressinput.gypi. + gypi_values = exec_script("//build/gypi_to_gn.py", + [ rebase_path("src/cpp/libaddressinput.gypi") ], + "scope", + [ "src/cpp/libaddressinput.gypi" ]) -# This target provides more complicated functionality like pinging servers -# for validation rules. -# GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput -static_library("libaddressinput") { - sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp") - sources += [ - "chromium/chrome_address_validator.cc", - "chromium/chrome_metadata_source.cc", - "chromium/chrome_storage_impl.cc", - "chromium/fallback_data_store.cc", - "chromium/input_suggester.cc", - "chromium/string_compare.cc", - "chromium/trie.cc", - ] - sources -= libaddressinput_util_files - sources -= [ "src/cpp/src/util/string_compare.cc" ] + # This target provides more complicated functionality like pinging servers + # for validation rules. + # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput + static_library("libaddressinput") { + sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp") + sources += [ + "chromium/chrome_address_validator.cc", + "chromium/chrome_metadata_source.cc", + "chromium/chrome_storage_impl.cc", + "chromium/fallback_data_store.cc", + "chromium/input_suggester.cc", + "chromium/string_compare.cc", + "chromium/trie.cc", + ] + sources -= libaddressinput_util_files + sources -= [ "src/cpp/src/util/string_compare.cc" ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] - public_configs = [ ":libaddressinput_config" ] + public_configs = [ ":libaddressinput_config" ] - deps = [ - ":strings", - ":util", - "//base", - "//base:i18n", - "//third_party/icu", - "//third_party/re2", - ] -} + deps = [ + ":strings", + ":util", + "//base", + "//base:i18n", + "//third_party/icu", + "//third_party/re2", + ] + } -test("libaddressinput_unittests") { - sources = rebase_path(gypi_values.libaddressinput_test_files, ".", "src/cpp") - sources += [ - "chromium/addressinput_util_unittest.cc", - "chromium/chrome_address_validator_unittest.cc", - "chromium/chrome_metadata_source_unittest.cc", - "chromium/chrome_storage_impl_unittest.cc", - "chromium/fallback_data_store_unittest.cc", - "chromium/storage_test_runner.cc", - "chromium/string_compare_unittest.cc", - "chromium/trie_unittest.cc", - ] + test("libaddressinput_unittests") { + sources = + rebase_path(gypi_values.libaddressinput_test_files, ".", "src/cpp") + sources += [ + "chromium/addressinput_util_unittest.cc", + "chromium/chrome_address_validator_unittest.cc", + "chromium/chrome_metadata_source_unittest.cc", + "chromium/chrome_storage_impl_unittest.cc", + "chromium/fallback_data_store_unittest.cc", + "chromium/storage_test_runner.cc", + "chromium/string_compare_unittest.cc", + "chromium/trie_unittest.cc", + ] - configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] - defines = [ "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"" ] + defines = [ "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"" ] - include_dirs = [ "src/cpp/src" ] + include_dirs = [ "src/cpp/src" ] - deps = [ - ":libaddressinput", - ":strings", - "//base:prefs", - "//base/test:run_all_unittests", - "//net:test_support", - "//testing/gtest", - ] + deps = [ + ":libaddressinput", + ":strings", + "//base:prefs", + "//base/test:run_all_unittests", + "//net:test_support", + "//testing/gtest", + ] + } }
diff --git a/third_party/opus/BUILD.gn b/third_party/opus/BUILD.gn index 2905a49..244ddcd6 100644 --- a/third_party/opus/BUILD.gn +++ b/third_party/opus/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/arm.gni") +import("//testing/test.gni") # If fixed point implementation shall be used (otherwise float). use_opus_fixed_point = cpu_arch == "arm" || cpu_arch == "arm64" @@ -19,6 +20,23 @@ include_dirs = [ "src/include" ] } +config("opus_test_config") { + include_dirs = [ + "src/celt", + "src/silk", + ] + + if (is_win) { + defines = [ "inline=__inline" ] + } + if (is_android) { + libs = [ "log" ] + } + if (is_clang) { + cflags = [ "-Wno-absolute-value" ] + } +} + if (use_opus_rtcd) { action("convert_rtcd_assembler") { script = "convert_rtcd_assembler.py" @@ -143,23 +161,11 @@ ] configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - - include_dirs = [ - "src/celt", - "src/silk", + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", ] - if (is_win) { - defines = [ "inline=__inline" ] - } - if (is_android) { - libs = [ "log" ] - } - if (is_clang) { - cflags = [ "-Wno-absolute-value" ] - } - deps = [ ":opus", ] @@ -171,22 +177,82 @@ ] configs -= [ "//build/config/compiler:chromium_code" ] - configs += [ "//build/config/compiler:no_chromium_code" ] - - include_dirs = [ - "src/celt", - "src/silk", + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", ] - if (is_win) { - defines = [ "inline=__inline" ] + deps = [ + ":opus", + ] +} + +test("test_opus_api") { + sources = [ + "src/tests/test_opus_api.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", + ] + + deps = [ + ":opus", + ] +} + +test("test_opus_encode") { + sources = [ + "src/tests/test_opus_encode.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", + ] + + deps = [ + ":opus", + ] +} + +test("test_opus_decode") { + sources = [ + "src/tests/test_opus_decode.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", + ] + + # test_opus_decode passes a null pointer to opus_decode() for an argument + # marked as requiring a non-null value by the nonnull function attribute, + # and expects opus_decode() to fail. Disable the -Wnonnull option to avoid + # a compilation error if -Werror is specified. + if (is_posix) { + cflags = [ "-Wno-nonnull" ] } - if (is_android) { - libs = [ "log" ] - } - if (is_clang) { - cflags = [ "-Wno-absolute-value" ] - } + + deps = [ + ":opus", + ] +} + +test("test_opus_padding") { + sources = [ + "src/tests/test_opus_padding.c", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + ":opus_test_config", + ] deps = [ ":opus",
diff --git a/third_party/opus/opus.gyp b/third_party/opus/opus.gyp index b64f990..a4744865 100644 --- a/third_party/opus/opus.gyp +++ b/third_party/opus/opus.gyp
@@ -24,6 +24,33 @@ }], ], }, + 'target_defaults': { + 'target_conditions': [ + ['_type=="executable"', { + # All of the executable targets depend on 'opus'. Unfortunately the + # 'dependencies' block cannot be inherited via 'target_defaults'. + 'include_dirs': [ + 'src/celt', + 'src/silk', + ], + 'conditions': [ + ['OS == "win"', { + 'defines': [ + 'inline=__inline', + ], + }], + ['OS=="android"', { + 'libraries': [ + '-llog', + ], + }], + ['clang==1', { + 'cflags': [ '-Wno-absolute-value' ], + }] + ], + }], + ], + }, 'targets': [ { 'target_name': 'opus', @@ -134,30 +161,9 @@ 'dependencies': [ 'opus' ], - 'conditions': [ - ['OS == "win"', { - 'defines': [ - 'inline=__inline', - ], - }], - ['OS=="android"', { - 'link_settings': { - 'libraries': [ - '-llog', - ], - }, - }], - ['clang==1', { - 'cflags': [ '-Wno-absolute-value' ], - }] - ], 'sources': [ 'src/src/opus_compare.c', ], - 'include_dirs': [ - 'src/celt', - 'src/silk', - ], }, # target opus_compare { 'target_name': 'opus_demo', @@ -165,30 +171,63 @@ 'dependencies': [ 'opus' ], - 'conditions': [ - ['OS == "win"', { - 'defines': [ - 'inline=__inline', - ], - }], - ['OS=="android"', { - 'link_settings': { - 'libraries': [ - '-llog', - ], - }, - }], - ['clang==1', { - 'cflags': [ '-Wno-absolute-value' ], - }] - ], 'sources': [ 'src/src/opus_demo.c', ], - 'include_dirs': [ - 'src/celt', - 'src/silk', - ], }, # target opus_demo + { + 'target_name': 'test_opus_api', + 'type': 'executable', + 'dependencies': [ + 'opus' + ], + 'sources': [ + 'src/tests/test_opus_api.c', + ], + }, # target test_opus_api + { + 'target_name': 'test_opus_encode', + 'type': 'executable', + 'dependencies': [ + 'opus' + ], + 'sources': [ + 'src/tests/test_opus_encode.c', + ], + }, # target test_opus_encode + { + 'target_name': 'test_opus_decode', + 'type': 'executable', + 'dependencies': [ + 'opus' + ], + 'sources': [ + 'src/tests/test_opus_decode.c', + ], + # test_opus_decode passes a null pointer to opus_decode() for an argument + # marked as requiring a non-null value by the nonnull function attribute, + # and expects opus_decode() to fail. Disable the -Wnonnull option to avoid + # a compilation error if -Werror is specified. + 'conditions': [ + ['os_posix==1 and OS!="mac" and OS!="ios"', { + 'cflags': ['-Wno-nonnull'], + }], + ['OS=="mac" or OS=="ios"', { + 'xcode_settings': { + 'WARNING_CFLAGS': ['-Wno-nonnull'], + }, + }], + ], + }, # target test_opus_decode + { + 'target_name': 'test_opus_padding', + 'type': 'executable', + 'dependencies': [ + 'opus' + ], + 'sources': [ + 'src/tests/test_opus_padding.c', + ], + }, # target test_opus_padding ] }
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium index fdf3394..8fb3768 100644 --- a/third_party/qcms/README.chromium +++ b/third_party/qcms/README.chromium
@@ -51,5 +51,7 @@ - https://code.google.com/p/chromium/issues/detail?id=401971 - Minor variable name change: description -> description_offset - https://code.google.com/p/chromium/issues/detail?id=401971 + - Avoid divisions creating sample points in the float cube LUT builder + - https://code.google.com/p/chromium/issues/detail?id=443863 To regenerate google.patch: git diff b8456f38 src > google.patch
diff --git a/third_party/qcms/src/transform.c b/third_party/qcms/src/transform.c index 08db142b..9fd82389 100644 --- a/third_party/qcms/src/transform.c +++ b/third_party/qcms/src/transform.c
@@ -1118,28 +1118,31 @@ float* src = NULL; float* dest = NULL; float* lut = NULL; + float inverse; src = malloc(lutSize*sizeof(float)); dest = malloc(lutSize*sizeof(float)); if (src && dest) { - /* Prepare a list of points we want to sample */ + /* Prepare a list of points we want to sample: x, y, z order */ l = 0; + inverse = 1 / (float)(samples-1); for (x = 0; x < samples; x++) { for (y = 0; y < samples; y++) { for (z = 0; z < samples; z++) { - src[l++] = x / (float)(samples-1); - src[l++] = y / (float)(samples-1); - src[l++] = z / (float)(samples-1); + src[l++] = x * inverse; // r + src[l++] = y * inverse; // g + src[l++] = z * inverse; // b } } } lut = qcms_chain_transform(in, out, src, dest, lutSize); + if (lut) { - transform->r_clut = &lut[0]; - transform->g_clut = &lut[1]; - transform->b_clut = &lut[2]; + transform->r_clut = &lut[0]; // r + transform->g_clut = &lut[1]; // g + transform->b_clut = &lut[2]; // b transform->grid_size = samples; if (in_type == QCMS_DATA_RGBA_8) { transform->transform_fn = qcms_transform_data_tetra_clut_rgba; @@ -1149,8 +1152,8 @@ } } - - //XXX: qcms_modular_transform_data may return either the src or dest buffer. If so it must not be free-ed + // XXX: qcms_modular_transform_data may return the lut in either the src or the + // dest buffer. If so, it must not be free-ed. if (src && lut != src) { free(src); }
diff --git a/tools/chrome_proxy/OWNERS b/tools/chrome_proxy/OWNERS index f5c2303..b4ac2d2 100644 --- a/tools/chrome_proxy/OWNERS +++ b/tools/chrome_proxy/OWNERS
@@ -3,3 +3,4 @@ kundaji@chromium.org marq@chromium.org megjablon@chromium.org +sclittle@chromium.org
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py b/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py index 43d9397..10ed99b 100644 --- a/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py +++ b/tools/chrome_proxy/integration_tests/chrome_proxy_measurements.py
@@ -311,7 +311,7 @@ tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 300) def AddResults(self, tab, results): - self._metrics.AddResultsForHTTPToDirectFallback(tab, results) + self._metrics.AddResultsForHTTPToDirectFallback(tab, results, _TEST_SERVER) class ChromeProxyReenableAfterBypass(ChromeProxyValidation):
diff --git a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py index 63773da..f856f5ba 100644 --- a/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py +++ b/tools/chrome_proxy/integration_tests/chrome_proxy_metrics.py
@@ -307,36 +307,46 @@ results.AddValue(scalar.ScalarValue( results.current_page, 'via_fallback', 'count', via_fallback_count)) - def AddResultsForHTTPToDirectFallback(self, tab, results): + def AddResultsForHTTPToDirectFallback(self, tab, results, + fallback_response_host): via_fallback_count = 0 bypass_count = 0 responses = self.IterResponses(tab) - # The very first response should be through the HTTP fallback proxy. - fallback_resp = next(responses, None) - if not fallback_resp: - raise ChromeProxyMetricException, 'There should be at least one response.' - elif (not fallback_resp.HasChromeProxyViaHeader() or - fallback_resp.remote_port != 80): - r = fallback_resp.response - raise ChromeProxyMetricException, ( - 'Response for %s should have come through the fallback proxy.\n' - 'Reponse: remote_port=%s status=(%d, %s)\nHeaders:\n %s' % ( - r.url, str(fallback_resp.remote_port), r.status, r.status_text, - r.headers)) - else: - via_fallback_count += 1 + # The first response(s) coming from fallback_response_host should be + # through the HTTP fallback proxy. + resp = next(responses, None) + while resp and fallback_response_host in resp.response.url: + if fallback_response_host in resp.response.url: + if (not resp.HasChromeProxyViaHeader() or resp.remote_port != 80): + r = resp.response + raise ChromeProxyMetricException, ( + 'Response for %s should have come through the fallback proxy.\n' + 'Response: remote_port=%s status=(%d, %s)\nHeaders:\n %s' % ( + r.url, str(fallback_resp.remote_port), r.status, r.status_text, + r.headers)) + else: + via_fallback_count += 1 + resp = next(responses, None) - # All other responses should have been bypassed. - for resp in responses: + # All other responses should be bypassed. + while resp: if resp.HasChromeProxyViaHeader(): r = resp.response raise ChromeProxyMetricException, ( 'Response for %s should not have via header.\n' - 'Reponse: status=(%d, %s)\nHeaders:\n %s' % ( + 'Response: status=(%d, %s)\nHeaders:\n %s' % ( r.url, r.status, r.status_text, r.headers)) else: bypass_count += 1 + resp = next(responses, None) + + # At least one response should go through the http proxy and be bypassed. + if via_fallback_count == 0 or bypass_count == 0: + raise ChromeProxyMetricException( + 'There should be at least one response through the fallback proxy ' + '(actual %s) and at least one bypassed response (actual %s)' % + (via_fallback_count, bypass_count)) results.AddValue(scalar.ScalarValue( results.current_page, 'via_fallback', 'count', via_fallback_count))
diff --git a/tools/cr/cr-bash-helpers.sh b/tools/cr/cr-bash-helpers.sh index e7e7593..3fa6a8aa 100755 --- a/tools/cr/cr-bash-helpers.sh +++ b/tools/cr/cr-bash-helpers.sh
@@ -19,7 +19,12 @@ READLINK_e=("greadlink" "-e") fi -cr_base_dir=$(dirname $(${READLINK_e[@]} "${BASH_SOURCE:-$0}")) +if [[ $(uname) == "Darwin" ]]; then + cr_base_dir=$(dirname "${BASH_SOURCE:-$0}") +else + cr_base_dir=$(dirname $(${READLINK_e[@]} "${BASH_SOURCE:-$0}")) +fi + cr_main="${cr_base_dir}/main.py" cr_exec=("PYTHONDONTWRITEBYTECODE=1" "python" "${cr_main}")
diff --git a/tools/cr/cr/base/mac.py b/tools/cr/cr/base/mac.py new file mode 100644 index 0000000..5bf2276 --- /dev/null +++ b/tools/cr/cr/base/mac.py
@@ -0,0 +1,44 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""The mac specific host and platform implementation module.""" + +import os + +import cr + + +class MacHost(cr.Host): + """The implementation of Host for mac.""" + + ACTIVE = cr.Config.From( + GOOGLE_CODE='/usr/local/google/code', + ) + + def __init__(self): + super(MacHost, self).__init__() + + def Matches(self): + return cr.Platform.System() == 'Darwin' + + +class MacPlatform(cr.Platform): + """The implementation of Platform for the mac target.""" + + ACTIVE = cr.Config.From( + CR_BINARY=os.path.join('{CR_BUILD_DIR}', '{CR_BUILD_TARGET}'), + CHROME_DEVEL_SANDBOX='/usr/local/sbin/chrome-devel-sandbox', + ) + + @property + def enabled(self): + return cr.Platform.System() == 'Darwin' + + @property + def priority(self): + return 2 + + @property + def paths(self): + return ['{GOMA_DIR}']
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc index 50bdbe91..75d5fce 100644 --- a/tools/gn/command_args.cc +++ b/tools/gn/command_args.cc
@@ -245,7 +245,7 @@ "# Build arguments go here. Examples:\n" "# is_component_build = true\n" "# is_debug = false\n" - "# See \"gn args <dir_name> --list\" for available build " + "# See \"gn args <out_dir> --list\" for available build " "arguments.\n"; #if defined(OS_WIN) // Use Windows lineendings for this file since it will often open in @@ -275,13 +275,13 @@ extern const char kArgs_HelpShort[] = "args: Display or configure arguments declared by the build."; extern const char kArgs_Help[] = - "gn args [arg name]\n" + "gn args <out_dir> [--list] [--short] [--args]\n" "\n" " See also \"gn help buildargs\" for a more high-level overview of how\n" " build arguments work.\n" "\n" "Usage\n" - " gn args <dir_name>\n" + " gn args <out_dir>\n" " Open the arguments for the given build directory in an editor\n" " (as specified by the EDITOR environment variable). If the given\n" " build directory doesn't exist, it will be created and an empty\n" @@ -292,9 +292,9 @@ "\n" " Note: you can edit the build args manually by editing the file\n" " \"args.gn\" in the build directory and then running\n" - " \"gn gen <build_dir>\".\n" + " \"gn gen <out_dir>\".\n" "\n" - " gn args <dir_name> --list[=<exact_arg>] [--short]\n" + " gn args <out_dir> --list[=<exact_arg>] [--short]\n" " Lists all build arguments available in the current configuration,\n" " or, if an exact_arg is specified for the list flag, just that one\n" " build argument.\n" @@ -303,14 +303,14 @@ " comment preceeding the declaration. If --short is specified,\n" " only the names and values will be printed.\n" "\n" - " If the dir_name is specified, the build configuration will be\n" + " If the out_dir is specified, the build configuration will be\n" " taken from that build directory. The reason this is needed is that\n" " the definition of some arguments is dependent on the build\n" " configuration, so setting some values might add, remove, or change\n" " the default values for other arguments. Specifying your exact\n" " configuration allows the proper arguments to be displayed.\n" "\n" - " Instead of specifying the dir_name, you can also use the\n" + " Instead of specifying the out_dir, you can also use the\n" " command-line flag to specify the build configuration:\n" " --args=<exact list of args to use>\n" "\n" @@ -334,7 +334,7 @@ int RunArgs(const std::vector<std::string>& args) { if (args.size() != 1) { Err(Location(), "Exactly one build dir needed.", - "Usage: \"gn args <build_dir>\"\n" + "Usage: \"gn args <out_dir>\"\n" "Or see \"gn help args\" for more variants.").PrintToStdout(); return 1; }
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc index cacab84..5c0a5a9 100644 --- a/tools/gn/command_gen.cc +++ b/tools/gn/command_gen.cc
@@ -51,7 +51,7 @@ const char kGen_Help[] = "gn gen: Generate ninja files.\n" "\n" - " gn gen <output_directory>\n" + " gn gen <out_dir>\n" "\n" " Generates ninja files from the current tree and puts them in the given\n" " output directory.\n"
diff --git a/tools/gn/command_ls.cc b/tools/gn/command_ls.cc index 8aefa76..a2dc38c 100644 --- a/tools/gn/command_ls.cc +++ b/tools/gn/command_ls.cc
@@ -18,7 +18,7 @@ const char kLs_HelpShort[] = "ls: List matching targets."; const char kLs_Help[] = - "gn ls <build dir> [<label_pattern>] [--out] [--all-toolchains]\n" + "gn ls <out_dir> [<label_pattern>] [--out] [--all-toolchains]\n" "\n" " Lists all targets matching the given pattern for the given builn\n" " directory. By default, only targets in the default toolchain will\n"
diff --git a/tools/gn/command_refs.cc b/tools/gn/command_refs.cc index 39f8c10f..d75ca50 100644 --- a/tools/gn/command_refs.cc +++ b/tools/gn/command_refs.cc
@@ -204,7 +204,7 @@ const char kRefs_HelpShort[] = "refs: Find stuff referencing a target or file."; const char kRefs_Help[] = - "gn refs <build_dir> (<label_pattern>|<file>) [--files] [--tree] [--all]\n" + "gn refs <out_dir> (<label_pattern>|<file>) [--files] [--tree] [--all]\n" " [--all-toolchains]\n" "\n" " Finds reverse dependencies (which targets reference something). The\n" @@ -282,7 +282,7 @@ int RunRefs(const std::vector<std::string>& args) { if (args.size() != 2) { Err(Location(), "You're holding it wrong.", - "Usage: \"gn refs <build_dir> (<label_pattern>|<file>)\"") + "Usage: \"gn refs <out_dir> (<label_pattern>|<file>)\"") .PrintToStdout(); return 1; }
diff --git a/tools/memory_inspector/chrome_app/template/manifest.json b/tools/memory_inspector/chrome_app/template/manifest.json index b797fc0..f8bc06a 100644 --- a/tools/memory_inspector/chrome_app/template/manifest.json +++ b/tools/memory_inspector/chrome_app/template/manifest.json
@@ -1,7 +1,7 @@ { "name": "Memory Inspector", "description": "Memory inspector tool for Android", - "version": "0.1.2", + "version": "0.1.3", "manifest_version": 2, "icons": { "16": "images/icon_16.png",
diff --git a/tools/memory_inspector/memory_inspector/backends/android_backend.py b/tools/memory_inspector/memory_inspector/backends/android_backend.py index 2c4ce7cd..b80480533 100644 --- a/tools/memory_inspector/memory_inspector/backends/android_backend.py +++ b/tools/memory_inspector/memory_inspector/backends/android_backend.py
@@ -27,8 +27,8 @@ from memory_inspector.core import symbol -_SUPPORTED_32BIT_ABIS = {'armeabi': 'arm', 'armeabi-v7a': 'arm'} -_SUPPORTED_64BIT_ABIS = {'arm64-v8a': 'arm64'} +_SUPPORTED_32BIT_ABIS = {'armeabi': 'arm', 'armeabi-v7a': 'arm', 'x86': 'x86'} +_SUPPORTED_64BIT_ABIS = {'arm64-v8a': 'arm64', 'x86_64': 'x86_64'} _MEMDUMP_PREBUILT_PATH = os.path.join(constants.PREBUILTS_PATH, 'memdump-android-%(arch)s') _MEMDUMP_PATH_ON_DEVICE = '/data/local/tmp/memdump'
diff --git a/tools/memory_inspector/memory_inspector/frontends/www_server.py b/tools/memory_inspector/memory_inspector/frontends/www_server.py index d75c973..27b8484 100644 --- a/tools/memory_inspector/memory_inspector/frontends/www_server.py +++ b/tools/memory_inspector/memory_inspector/frontends/www_server.py
@@ -141,7 +141,7 @@ return _HTTP_OK, [], resp -@AjaxHandler(r'/ajax/dump/mmap/(\w+)/(\w+)/(\d+)') +@AjaxHandler(r'/ajax/dump/mmap/([^/]+)/([^/]+)/(\d+)') def _DumpMmapsForProcess(args, req_vars): # pylint: disable=W0613 """Dumps memory maps for a process. @@ -158,7 +158,7 @@ return _HTTP_OK, [], {'table': table, 'id': cache_id} -@AjaxHandler('/ajax/initialize/(\w+)/(\w+)$', 'POST') +@AjaxHandler('/ajax/initialize/([^/]+)/([^/]+)$', 'POST') def _InitializeDevice(args, req_vars): # pylint: disable=W0613 device = _GetDevice(args) if not device: @@ -258,7 +258,7 @@ 'rootBucket': first_snapshot.total.name + '/'} -@AjaxHandler(r'/ajax/profile/(\w+)/tree/(\d+)/(\d+)') +@AjaxHandler(r'/ajax/profile/([^/]+)/tree/(\d+)/(\d+)') def _GetProfileTreeDataForSnapshot(args, req_vars): # pylint: disable=W0613 """Gets the data for the tree chart for a given time and metric. @@ -296,7 +296,7 @@ return _HTTP_OK, [], resp -@AjaxHandler(r'/ajax/profile/(\w+)/time_serie/(\d+)/(.*)$') +@AjaxHandler(r'/ajax/profile/([^/]+)/time_serie/(\d+)/(.*)$') def _GetTimeSerieForSnapshot(args, req_vars): # pylint: disable=W0613 """Gets the data for the area chart for a given metric and bucket. @@ -362,7 +362,7 @@ return _HTTP_OK, [], resp -@AjaxHandler(r'/ajax/ps/(\w+)/(\w+)$') # /ajax/ps/Android/a0b1c2[?all=1] +@AjaxHandler(r'/ajax/ps/([^/]+)/([^/]+)$') # /ajax/ps/Android/a0b1c2[?all=1] def _ListProcesses(args, req_vars): # pylint: disable=W0613 """Lists processes and their CPU / mem stats. @@ -395,7 +395,7 @@ return _HTTP_OK, [], resp -@AjaxHandler(r'/ajax/stats/(\w+)/(\w+)$') # /ajax/stats/Android/a0b1c2 +@AjaxHandler(r'/ajax/stats/([^/]+)/([^/]+)$') # /ajax/stats/Android/a0b1c2 def _GetDeviceStats(args, req_vars): # pylint: disable=W0613 """Lists device CPU / mem stats. @@ -440,7 +440,7 @@ return _HTTP_OK, [], {'cpu': cpu_stats, 'mem': mem_stats} -@AjaxHandler(r'/ajax/stats/(\w+)/(\w+)/(\d+)$') # /ajax/stats/Android/a0b1c2/42 +@AjaxHandler(r'/ajax/stats/([^/]+)/([^/]+)/(\d+)$') # /ajax/stats/Android/a0/3 def _GetProcessStats(args, req_vars): # pylint: disable=W0613 """Lists CPU / mem stats for a given process (and keeps history). @@ -490,7 +490,7 @@ return _HTTP_OK, [], {'cpu': cpu_stats, 'mem': mem_stats} -@AjaxHandler(r'/ajax/settings/(\w+)/?(\w+)?$') # /ajax/settings/Android[/id] +@AjaxHandler(r'/ajax/settings/([^/]+)/?(\w+)?$') # /ajax/settings/Android[/id] def _GetDeviceOrBackendSettings(args, req_vars): # pylint: disable=W0613 backend = backends.GetBackend(args[0]) if not backend: @@ -511,7 +511,7 @@ return _HTTP_OK, [], resp -@AjaxHandler(r'/ajax/settings/(\w+)/?(\w+)?$', 'POST') +@AjaxHandler(r'/ajax/settings/([^/]+)/?(\w+)?$', 'POST') def _SetDeviceOrBackendSettings(args, req_vars): # pylint: disable=W0613 backend = backends.GetBackend(args[0]) if not backend: @@ -617,7 +617,7 @@ # /ajax/tracer/start/Android/device-id/pid -@AjaxHandler(r'/ajax/tracer/start/(\w+)/(\w+)/(\d+)', 'POST') +@AjaxHandler(r'/ajax/tracer/start/([^/]+)/([^/]+)/(\d+)', 'POST') def _StartTracer(args, req_vars): for arg in 'interval', 'count', 'traceNativeHeap': assert(arg in req_vars), 'Expecting %s argument in POST data' % arg
diff --git a/tools/memory_inspector/prebuilts/heap_dump-android-x86.sha1 b/tools/memory_inspector/prebuilts/heap_dump-android-x86.sha1 new file mode 100644 index 0000000..42039d8 --- /dev/null +++ b/tools/memory_inspector/prebuilts/heap_dump-android-x86.sha1
@@ -0,0 +1 @@ +13cfc6bf8d706c2faba9d38b0fb38e98a059d1e3 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/heap_dump-android-x86_64.sha1 b/tools/memory_inspector/prebuilts/heap_dump-android-x86_64.sha1 new file mode 100644 index 0000000..3590ca2 --- /dev/null +++ b/tools/memory_inspector/prebuilts/heap_dump-android-x86_64.sha1
@@ -0,0 +1 @@ +56847334a1a2433ae42a31bcbb0d5f962f2d5a34 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/libheap_profiler-android-x86.sha1 b/tools/memory_inspector/prebuilts/libheap_profiler-android-x86.sha1 new file mode 100644 index 0000000..edb828b --- /dev/null +++ b/tools/memory_inspector/prebuilts/libheap_profiler-android-x86.sha1
@@ -0,0 +1 @@ +efa81d9b76f78e01936e760f3c6627361791e485 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/libheap_profiler-android-x86_64.sha1 b/tools/memory_inspector/prebuilts/libheap_profiler-android-x86_64.sha1 new file mode 100644 index 0000000..45e82e1 --- /dev/null +++ b/tools/memory_inspector/prebuilts/libheap_profiler-android-x86_64.sha1
@@ -0,0 +1 @@ +28c7fc4438a22086f1fb62e214b459ae2e7406a8 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/memdump-android-x86.sha1 b/tools/memory_inspector/prebuilts/memdump-android-x86.sha1 new file mode 100644 index 0000000..528000a --- /dev/null +++ b/tools/memory_inspector/prebuilts/memdump-android-x86.sha1
@@ -0,0 +1 @@ +d286590ab11556d044bb1c82b960ef590b427fec \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/memdump-android-x86_64.sha1 b/tools/memory_inspector/prebuilts/memdump-android-x86_64.sha1 new file mode 100644 index 0000000..6f35e5d --- /dev/null +++ b/tools/memory_inspector/prebuilts/memdump-android-x86_64.sha1
@@ -0,0 +1 @@ +a8bd66274b5a8e0dc486a3ce554804dbf331e791 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/ps_ext-android-x86.sha1 b/tools/memory_inspector/prebuilts/ps_ext-android-x86.sha1 new file mode 100644 index 0000000..41f7a65d --- /dev/null +++ b/tools/memory_inspector/prebuilts/ps_ext-android-x86.sha1
@@ -0,0 +1 @@ +9ba72bd7ebb8626bf4dc130a4a777141ba204358 \ No newline at end of file
diff --git a/tools/memory_inspector/prebuilts/ps_ext-android-x86_64.sha1 b/tools/memory_inspector/prebuilts/ps_ext-android-x86_64.sha1 new file mode 100644 index 0000000..fe0d476 --- /dev/null +++ b/tools/memory_inspector/prebuilts/ps_ext-android-x86_64.sha1
@@ -0,0 +1 @@ +d328cded2aae293c9faf1d87599dbbadcc415dd2 \ No newline at end of file
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 8d2b76c..3cd2f7f6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -9016,6 +9016,13 @@ <summary>Time taken to unpack an extension, when the unpack fails.</summary> </histogram> +<histogram name="Extensions.SandboxUnpackHashCheck" enum="BooleanValidHashSum"> + <owner>ginkage@chromium.org</owner> + <summary> + Whether a CRX file hash sum was the same as in an updater manifest. + </summary> +</histogram> + <histogram name="Extensions.SandboxUnpackInitialCrxPathLength"> <owner>asargent@chromium.org</owner> <summary>Length of the initial path to the CRX to be unpacked.</summary> @@ -23283,6 +23290,13 @@ </summary> </histogram> +<histogram name="PasswordHash.CreateTime"> + <owner>mlerman@chromium.org</owner> + <summary> + Time required to create the local hash of the user's GAIA password. + </summary> +</histogram> + <histogram name="PasswordManager.AccountsPerSite"> <owner>gcasto@chromium.org</owner> <owner>vabr@chromium.org</owner> @@ -28811,6 +28825,13 @@ </summary> </histogram> +<histogram name="Renderer.LineLayoutMs" units="milliseconds"> + <owner>benjhayden@chromium.org</owner> + <summary> + Amount of time spent doing line layout during FrameView::performLayout. + </summary> +</histogram> + <histogram name="Renderer.PixelIncreaseFromTransitions"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <summary> @@ -39942,7 +39963,7 @@ <summary>Time spent in V8 compiler (full codegen).</summary> </histogram> -<histogram name="V8.CompileCacheableMicroseconds" units="microseconds"> +<histogram name="V8.CompileCacheableMicroSeconds" units="microseconds"> <owner>yangguo@chromium.org</owner> <summary> Time spent compiling a script that may be subject to caching. @@ -43675,6 +43696,11 @@ <int value="1" label="Valid"/> </enum> +<enum name="BooleanValidHashSum" type="int"> + <int value="0" label="Invalid hash sum"/> + <int value="1" label="Valid hash sum"/> +</enum> + <enum name="BooleanValidKeyExists" type="int"> <int value="0" label="No Valid Cached Key Found"/> <int value="1" label="Valid Cached Key Found"/> @@ -47250,9 +47276,9 @@ <int value="934" label="AUTOTESTPRIVATE_SETNATURALSCROLL"/> <int value="935" label="AUTOTESTPRIVATE_SETMOUSESENSITIVITY"/> <int value="936" label="AUTOTESTPRIVATE_SETPRIMARYBUTTONRIGHT"/> - <int value="937" label="COPRESENCEENDPOINTS_CREATELOCALENDPOINT"/> - <int value="938" label="COPRESENCEENDPOINTS_DESTROYLOCALENDPOINT"/> - <int value="939" label="COPRESENCEENDPOINTS_SEND"/> + <int value="937" label="DELETED_COPRESENCEENDPOINTS_CREATELOCALENDPOINT"/> + <int value="938" label="DELETED_COPRESENCEENDPOINTS_DESTROYLOCALENDPOINT"/> + <int value="939" label="DELETED_COPRESENCEENDPOINTS_SEND"/> <int value="940" label="INLINE_INSTALL_PRIVATE_INSTALL"/> <int value="941" label="LAUNCHERPAGE_SETENABLED"/> <int value="942" label="CRYPTOTOKENPRIVATE_REQUESTPERMISSION"/> @@ -47515,6 +47541,7 @@ <int value="30" label="INVALID_PATH_FOR_CATALOG"/> <int value="31" label="ERROR_SERIALIZING_CATALOG"/> <int value="32" label="ERROR_SAVING_CATALOG"/> + <int value="33" label="CRX_HASH_VERIFICATION_FAILED"/> </enum> <enum name="ExternalDeviceAction" type="int"> @@ -48263,6 +48290,7 @@ <int value="675" label="Fetch"/> <int value="676" label="FetchBodyStream"/> <int value="677" label="XMLHttpRequestAsynchronous"/> + <int value="678" label="AudioBufferSourceBufferOnce"/> </enum> <enum name="FFmpegCodecs" type="int"> @@ -50713,6 +50741,7 @@ <int value="-2008272679" label="disable-webrtc-hw-encoding"/> <int value="-2003354337" label="enable-search-button-in-omnibox-for-str-or-iip"/> + <int value="-1998927516" label="enable-md-settings"/> <int value="-1985025593" label="file-manager-enable-new-gallery"/> <int value="-1972383451" label="disable-pinch"/> <int value="-1940806558" label="enable-syncfs-directory-operation"/> @@ -50864,6 +50893,7 @@ <int value="-158549277" label="enable-embeddedsearch-api"/> <int value="-158197254" label="enable-credential-manager-api"/> <int value="-147283486" label="enable-network-portal-notification"/> + <int value="-146552997" label="enable-affiliation-based-matching"/> <int value="-102537270" label="extension-content-verification"/> <int value="-99781021" label="disable-roboto-font-ui"/> <int value="-88822940" label="ssl-version-min"/> @@ -50881,6 +50911,7 @@ Command-line flag doesn't start with two dashes. </int> <int value="27507364" label="apps-keep-chrome-alive"/> + <int value="37024318" label="disable-affiliation-based-matching"/> <int value="48159177" label="reduced-referrer-granularity"/> <int value="61205887" label="enable-text-input-focus-manager"/> <int value="79503461" label="disable-account-consistency"/> @@ -50979,6 +51010,7 @@ <int value="1221559505" label="enable-spelling-feedback-field-trial"/> <int value="1237297772" label="no-pings"/> <int value="1245889469" label="enable-surface-worker"/> + <int value="1250071868" label="disable-timezone-tracking-option"/> <int value="1257980502" label="disable-accelerated-video-decode"/> <int value="1268470658" label="disable-android-password-link"/> <int value="1279584261" label="enable-carrier-switching"/>
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml index 7fbe8ba..2f7cac2 100644 --- a/tools/metrics/rappor/rappor.xml +++ b/tools/metrics/rappor/rappor.xml
@@ -140,6 +140,38 @@ </summary> </rappor-metric> +<rappor-metric name="interstitial.malware.domain" type="COARSE_RAPPOR_TYPE"> + <owner>nparker@chromium.org</owner> + <summary> + The domain+registry of a URL that triggered a safe-browsing malware + interstitial. + </summary> +</rappor-metric> + +<rappor-metric name="interstitial.phishing.domain" type="COARSE_RAPPOR_TYPE"> + <owner>nparker@chromium.org</owner> + <summary> + The domain+registry of a URL that triggered a safe-browsing phishing + interstitial. + </summary> +</rappor-metric> + +<rappor-metric name="interstitial.harmful.domain" type="COARSE_RAPPOR_TYPE"> + <owner>nparker@chromium.org</owner> + <summary> + The domain+registry of a URL that triggered a safe-browsing UWS + interstitial. + </summary> +</rappor-metric> + +<rappor-metric name="interstitial.ssl.domain" type="COARSE_RAPPOR_TYPE"> + <owner>nparker@chromium.org</owner> + <summary> + The domain+registry of a URL that triggered an SSL interstitial. + Domains for bad-clock warnings are not reported. + </summary> +</rappor-metric> + </rappor-metrics> </rappor-configuration>
diff --git a/tools/perf/benchmarks/gpu_times.py b/tools/perf/benchmarks/gpu_times.py index 3085e0a..eaeb972 100644 --- a/tools/perf/benchmarks/gpu_times.py +++ b/tools/perf/benchmarks/gpu_times.py
@@ -27,7 +27,7 @@ get_metrics_from_flags_callback=_GetGPUTimelineMetric) -@benchmark.Enabled('android') +@benchmark.Disabled class GPUTimesKeyMobileSites(_GPUTimes): """Measures GPU timeline metric on key mobile sites.""" page_set = page_sets.KeyMobileSitesSmoothPageSet @@ -36,7 +36,7 @@ def Name(cls): return 'gpu_times.key_mobile_sites_smooth' -@benchmark.Enabled('android') +@benchmark.Disabled class GPUTimesGpuRasterizationKeyMobileSites(_GPUTimes): """Measures GPU timeline metric on key mobile sites with GPU rasterization. """
diff --git a/tools/perf_expectations/perf_expectations.json b/tools/perf_expectations/perf_expectations.json index 5a455c78..c479ba8c 100644 --- a/tools/perf_expectations/perf_expectations.json +++ b/tools/perf_expectations/perf_expectations.json
@@ -1,8 +1,8 @@ {"linux-release-64/sizes/chrome-bss/bss": {"reva": 311086, "revb": 311132, "type": "absolute", "better": "lower", "improve": 453296, "regress": 501029, "sha1": "d69fb86b"}, "linux-release-64/sizes/chrome-data/data": {"reva": 295451, "revb": 295513, "type": "absolute", "better": "lower", "improve": 4337320, "regress": 4794006, "sha1": "04b10278"}, "linux-release-64/sizes/chrome-si/initializers": {"reva": 281711, "revb": 281711, "type": "absolute", "better": "lower", "improve": 7, "regress": 7, "tolerance": 0, "sha1": "b11fc43a"}, - "linux-release-64/sizes/chrome-text/text": {"reva": 310080, "revb": 310080, "type": "absolute", "better": "lower", "improve": 94693532, "regress": 104661274, "sha1": "837f5b77"}, - "linux-release-64/sizes/chrome/chrome": {"reva": 295451, "revb": 295484, "type": "absolute", "better": "lower", "improve": 134684000, "regress": 148870193, "sha1": "6144f224"}, + "linux-release-64/sizes/chrome-text/text": {"reva": 314576, "revb": 314597, "type": "absolute", "better": "lower", "improve": 99684402, "regress": 110179552, "sha1": "dd896f5d"}, + "linux-release-64/sizes/chrome/chrome": {"reva": 314576, "revb": 314597, "type": "absolute", "better": "lower", "improve": 144357447, "regress": 159558118, "sha1": "dd048ccd"}, "linux-release-64/sizes/nacl_helper-bss/bss": {"reva": 282247, "revb": 282247, "type": "absolute", "better": "lower", "improve": 257670, "regress": 284794, "sha1": "4baf0f5e"}, "linux-release-64/sizes/nacl_helper-data/data": {"reva": 299377, "revb": 299377, "type": "absolute", "better": "lower", "improve": 209098, "regress": 231110, "sha1": "9d7262fa"}, "linux-release-64/sizes/nacl_helper-si/initializers": {"reva": 271321, "revb": 271321, "type": "absolute", "better": "lower", "improve": 5, "regress": 7, "sha1": "f29296a1"}, @@ -365,9 +365,9 @@ "linux-release/sizes/chrome-bss/bss": {"reva": 311086, "revb": 311132, "type": "absolute", "better": "lower", "improve": 318223, "regress": 351738, "sha1": "a1baf698"}, "linux-release/sizes/chrome-data/data": {"reva": 292870, "revb": 292920, "type": "absolute", "better": "lower", "improve": 2299296, "regress": 2560522, "sha1": "1ed32136"}, "linux-release/sizes/chrome-si/initializers": {"reva": 281717, "revb": 281717, "type": "absolute", "better": "lower", "improve": 8, "regress": 8, "tolerance": 0, "sha1": "b639bbc4"}, - "linux-release/sizes/chrome-text/text": {"reva": 298898, "revb": 298929, "type": "absolute", "better": "lower", "improve": 95627212, "regress": 105825515, "sha1": "39f276a0"}, + "linux-release/sizes/chrome-text/text": {"reva": 314576, "revb": 314590, "type": "absolute", "better": "lower", "improve": 102025091, "regress": 112765474, "sha1": "323b5a75"}, "linux-release/sizes/chrome-textrel/textrel": {"reva": 234134, "revb": 234142, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "sha1": "61db9eaf"}, - "linux-release/sizes/chrome/chrome": {"reva": 298898, "revb": 298929, "type": "absolute", "better": "lower", "improve": 130581651, "regress": 144461771, "sha1": "efac9219"}, + "linux-release/sizes/chrome/chrome": {"reva": 314576, "revb": 314590, "type": "absolute", "better": "lower", "improve": 138826666, "regress": 153444353, "sha1": "943c4b9d"}, "linux-release/sizes/libffmpegsumo.so-textrel/textrel": {"reva": 200467, "revb": 203456, "type": "absolute", "better": "lower", "improve": 1075, "regress": 1189, "sha1": "a10d4ea4"}, "linux-release/sizes/nacl_helper-bss/bss": {"reva": 282247, "revb": 282247, "type": "absolute", "better": "lower", "improve": 143640, "regress": 158760, "sha1": "95c4c516"}, "linux-release/sizes/nacl_helper-data/data": {"reva": 299377, "revb": 299377, "type": "absolute", "better": "lower", "improve": 107384, "regress": 118688, "sha1": "2e0b5d0c"}, @@ -383,7 +383,7 @@ "linux-release/sizes/totals-textrel/textrel": {"reva": 205083, "revb": 206071, "type": "absolute", "better": "lower", "improve": 1075, "regress": 1189, "sha1": "69d07fda"}, "mac-release/sizes/Chromium.app/Chromium.app": {"reva": 305049, "revb": 305099, "type": "absolute", "better": "lower", "improve": 150118604, "regress": 165929165, "sha1": "6133e499"}, "mac-release/sizes/Chromium/Chromium": {"reva": 165473, "revb": 165473, "type": "absolute", "better": "lower", "improve": 8132, "regress": 8988, "sha1": "8e448691"}, - "mac-release/sizes/ChromiumFramework/ChromiumFramework": {"reva": 305049, "revb": 305099, "type": "absolute", "better": "lower", "improve": 90343214, "regress": 99857361, "sha1": "d3a8505a"}, + "mac-release/sizes/ChromiumFramework/ChromiumFramework": {"reva": 314575, "revb": 314597, "type": "absolute", "better": "lower", "improve": 96029781, "regress": 106138196, "sha1": "e601ccfe"}, "mac-release/sizes/chrome-si/initializers": {"reva": 281731, "revb": 281731, "type": "absolute", "better": "lower", "improve": 0, "regress": 0, "tolerance": 0, "sha1": "01759b7f"}, "win-release/media_tests_av_perf/audio_latency/latency": {"reva": 199840, "revb": 201303, "type": "absolute", "better": "lower", "improve": 57, "regress": 69, "sha1": "169d47dd"}, "win-release/media_tests_av_perf/audio_latency/latency_bg_clip": {"reva": 199840, "revb": 201303, "type": "absolute", "better": "lower", "improve": 66, "regress": 78, "sha1": "708a71af"}, @@ -737,7 +737,7 @@ "win-release/media_tests_av_perf/ttp/Wifi_roller.webm": {"reva": 175328, "revb": 176157, "type": "absolute", "better": "lower", "improve": 906.775, "regress": 1184.925, "sha1": "d49e638f"}, "xp-release/sizes/chrome.dll/chrome.dll": {"reva": 309071, "revb": 309081, "type": "absolute", "better": "lower", "improve": 36382233, "regress": 40213018, "sha1": "af511cf1"}, "xp-release/sizes/chrome.exe/chrome.exe": {"reva": 309071, "revb": 309081, "type": "absolute", "better": "lower", "improve": 612377, "regress": 676839, "sha1": "63dbfdc5"}, - "xp-release/sizes/chrome_child.dll/chrome_child.dll": {"reva": 309071, "revb": 309220, "type": "absolute", "better": "lower", "improve": 36496051, "regress": 40345268, "sha1": "5e748540"}, + "xp-release/sizes/chrome_child.dll/chrome_child.dll": {"reva": 314576, "revb": 314588, "type": "absolute", "better": "lower", "improve": 39555993, "regress": 43720858, "sha1": "46896665"}, "xp-release/sizes/mini_installer.exe/mini_installer.exe": {"reva": 296771, "revb": 296791, "type": "absolute", "better": "lower", "improve": 32967219, "regress": 36469709, "sha1": "f4744be2"}, "xp-release/sizes/setup.exe/setup.exe": {"reva": 309071, "revb": 309081, "type": "absolute", "better": "lower", "improve": 933888, "regress": 1032192, "sha1": "a257fcad"}, "load": true
diff --git a/tools/profile_chrome/chrome_controller.py b/tools/profile_chrome/chrome_controller.py index 9f52263..d8cff46 100644 --- a/tools/profile_chrome/chrome_controller.py +++ b/tools/profile_chrome/chrome_controller.py
@@ -9,7 +9,7 @@ from profile_chrome import controllers -from pylib import pexpect +from pylib.device import device_errors from pylib.device import intent @@ -23,6 +23,7 @@ self._package_info = package_info self._categories = categories self._ring_buffer = ring_buffer + self._logcat_monitor = self._device.GetLogcatMonitor() self._trace_file = None self._trace_interval = None self._trace_memory = trace_memory @@ -31,21 +32,21 @@ re.compile(r'Logging performance trace to file') self._trace_finish_re = \ re.compile(r'Profiler finished[.] Results are in (.*)[.]') - self._device.old_interface.StartMonitoringLogcat(clear=False) def __repr__(self): return 'chrome trace' @staticmethod def GetCategories(device, package_info): - device.BroadcastIntent(intent.Intent( - action='%s.GPU_PROFILER_LIST_CATEGORIES' % package_info.package)) - try: - json_category_list = device.old_interface.WaitForLogMatch( - re.compile(r'{"traceCategoriesList(.*)'), None, timeout=5).group(0) - except pexpect.TIMEOUT: - raise RuntimeError('Performance trace category list marker not found. ' - 'Is the correct version of the browser running?') + with device.GetLogcatMonitor() as logmon: + device.BroadcastIntent(intent.Intent( + action='%s.GPU_PROFILER_LIST_CATEGORIES' % package_info.package)) + try: + json_category_list = logmon.WaitFor( + re.compile(r'{"traceCategoriesList(.*)'), timeout=5).group(0) + except device_errors.CommandTimeoutError: + raise RuntimeError('Performance trace category list marker not found. ' + 'Is the correct version of the browser running?') record_categories = set() disabled_by_default_categories = set() @@ -61,7 +62,7 @@ def StartTracing(self, interval): self._trace_interval = interval - self._device.old_interface.SyncLogCat() + self._logcat_monitor.Start() start_extras = {'categories': ','.join(self._categories)} if self._ring_buffer: start_extras['continuous'] = None @@ -70,7 +71,7 @@ extras=start_extras)) if self._trace_memory: - self._device.old_interface.EnableAdbRoot() + self._device.EnableRoot() self._device.SetProp(_HEAP_PROFILE_MMAP_PROPERTY, 1) # Chrome logs two different messages related to tracing: @@ -81,10 +82,9 @@ # The first one is printed when tracing starts and the second one indicates # that the trace file is ready to be pulled. try: - self._device.old_interface.WaitForLogMatch( - self._trace_start_re, None, timeout=5) + self._logcat_monitor.WaitFor(self._trace_start_re, timeout=5) self._is_tracing = True - except pexpect.TIMEOUT: + except device_errors.CommandTimeoutError: raise RuntimeError('Trace start marker not found. Is the correct version ' 'of the browser running?') @@ -92,8 +92,8 @@ if self._is_tracing: self._device.BroadcastIntent(intent.Intent( action='%s.GPU_PROFILER_STOP' % self._package_info.package)) - self._trace_file = self._device.old_interface.WaitForLogMatch( - self._trace_finish_re, None, timeout=120).group(1) + self._trace_file = self._logcat_monitor.WaitFor( + self._trace_finish_re, timeout=120).group(1) self._is_tracing = False if self._trace_memory: self._device.SetProp(_HEAP_PROFILE_MMAP_PROPERTY, 0)
diff --git a/tools/profile_chrome/chrome_startup_controller.py b/tools/profile_chrome/chrome_startup_controller.py index 8852cfe6..d685502 100644 --- a/tools/profile_chrome/chrome_startup_controller.py +++ b/tools/profile_chrome/chrome_startup_controller.py
@@ -16,10 +16,10 @@ self._device = device self._package_info = package_info self._cold = cold + self._logcat_monitor = self._device.GetLogcatMonitor() self._url = url self._trace_file = None self._trace_finish_re = re.compile(r' Completed startup tracing to (.*)') - self._device.old_interface.StartMonitoringLogcat(clear=False) def __repr__(self): return 'Browser Startup Trace' @@ -30,15 +30,16 @@ changer = flag_changer.FlagChanger( self._device, self._package_info.cmdline_file) changer.AddFlags(['--trace-startup']) - self._device.old_interface.CloseApplication(self._package_info.package) + self._device.ForceStop(self._package_info.package) if self._cold: - self._device.old_interface.EnableAdbRoot() + self._device.EnableRoot() cache_control.CacheControl(self._device).DropRamCaches() - self._device.old_interface.StartActivity( - package=self._package_info.package, - activity=self._package_info.activity, - data=self._url, - extras={'create_new_tab' : True}) + self._device.StartActivity( + intent.Intent( + package=self._package_info.package, + activity=self._package_info.activity, + data=self._url, + extras={'create_new_tab' : True})) def _TearDownTracing(self): changer = flag_changer.FlagChanger( @@ -47,12 +48,12 @@ def StartTracing(self, interval): self._SetupTracing() - self._device.old_interface.SyncLogCat() + self._logcat_monitor.Start() def StopTracing(self): try: - self._trace_file = self._device.old_interface.WaitForLogMatch( - self._trace_finish_re, None, timeout=10).group(1) + self._trace_file = self._logcat_monitor.WaitFor( + self._trace_finish_re).group(1) finally: self._TearDownTracing()
diff --git a/tools/telemetry/telemetry/core/backends/chrome/android_browser_finder.py b/tools/telemetry/telemetry/core/backends/chrome/android_browser_finder.py index 40e84ff..4a06c12 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/android_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/chrome/android_browser_finder.py
@@ -200,14 +200,13 @@ return possible_browsers -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Finds all the possible browsers on one device. The device is either the only device on the host platform, or |finder_options| specifies a particular device. """ - device = android_device.GetDevice(finder_options) - if not device: + if not isinstance(device, android_device.AndroidDevice): return [] android_platform = platform.GetPlatformForDevice(device, finder_options) return _FindAllPossibleBrowsers(finder_options, android_platform)
diff --git a/tools/telemetry/telemetry/core/backends/chrome/cros_browser_finder.py b/tools/telemetry/telemetry/core/backends/chrome/cros_browser_finder.py index 6c57c975..7acc298 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/cros_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/chrome/cros_browser_finder.py
@@ -16,10 +16,6 @@ from telemetry.core.backends.chrome import cros_browser_with_oobe -def _IsRunningOnCrOS(): - return platform_module.GetHostPlatform().GetOSName() == 'chromeos' - - class PossibleCrOSBrowser(possible_browser.PossibleBrowser): """A launchable CrOS browser instance.""" def __init__(self, browser_type, finder_options, cros_platform, is_guest): @@ -65,14 +61,14 @@ pass def SelectDefaultBrowser(possible_browsers): - if _IsRunningOnCrOS(): + if cros_device.IsRunningOnCrOS(): for b in possible_browsers: if b.browser_type == 'system': return b return None def CanFindAvailableBrowsers(finder_options): - return (_IsRunningOnCrOS() or + return (cros_device.IsRunningOnCrOS() or finder_options.cros_remote or cros_interface.HasSSH()) @@ -84,9 +80,12 @@ 'system-guest', ] -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Finds all available CrOS browsers, locally and remotely.""" - if _IsRunningOnCrOS(): + if not isinstance(device, cros_device.CrOSDevice): + return [] + + if cros_device.IsRunningOnCrOS(): return [PossibleCrOSBrowser('system', finder_options, platform_module.GetHostPlatform(), is_guest=False), @@ -94,16 +93,6 @@ platform_module.GetHostPlatform(), is_guest=True)] - if finder_options.cros_remote == None: - logging.debug('No --remote specified, will not probe for CrOS.') - return [] - - if not cros_interface.HasSSH(): - logging.debug('ssh not found. Cannot talk to CrOS devices.') - return [] - device = cros_device.CrOSDevice( - finder_options.cros_remote, finder_options.cros_remote_ssh_port, - finder_options.cros_ssh_identity) # Check ssh try: platform = platform_module.GetPlatformForDevice(device, finder_options)
diff --git a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder.py b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder.py index e396081..e2fba9e 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder.py
@@ -13,6 +13,7 @@ from telemetry.core import exceptions from telemetry.core import possible_browser from telemetry.core.backends.chrome import desktop_browser_backend +from telemetry.core.platform import desktop_device from telemetry.util import path @@ -113,8 +114,11 @@ 'content-shell-release_x64', 'system'] -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Finds all the desktop browsers available on this machine.""" + if not isinstance(device, desktop_device.DesktopDevice): + return [] + browsers = [] if not CanFindAvailableBrowsers():
diff --git a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder_unittest.py index 8f8dc1f2..14abe60 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome/desktop_browser_finder_unittest.py
@@ -5,6 +5,7 @@ from telemetry.core import browser_options from telemetry.core.backends.chrome import desktop_browser_finder +from telemetry.core.platform import desktop_device from telemetry.unittest_util import system_stub @@ -32,7 +33,8 @@ return self._path_stubs.os.path.files def DoFindAll(self): - return desktop_browser_finder.FindAllAvailableBrowsers(self._finder_options) + return desktop_browser_finder.FindAllAvailableBrowsers( + self._finder_options, desktop_device.DesktopDevice()) def DoFindAllTypes(self): browsers = self.DoFindAll()
diff --git a/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder.py b/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder.py index f8dd74e..771fd5eb 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder.py
@@ -14,6 +14,7 @@ from telemetry.core import possible_browser from telemetry.core.backends.chrome_inspector import inspector_backend from telemetry.core.backends.chrome import ios_browser_backend +from telemetry.core.platform import ios_device from telemetry.core.platform import ios_platform_backend @@ -66,21 +67,12 @@ return IOS_BROWSERS.values() -@decorators.Cache -def _IsIosDeviceAttached(): - devices = subprocess.check_output('system_profiler SPUSBDataType', shell=True) - for line in devices.split('\n'): - if line and re.match(r'\s*(iPod|iPhone|iPad):', line): - return True - return False - - -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Find all running iOS browsers on connected devices.""" - if not CanFindAvailableBrowsers(): + if not isinstance(device, ios_device.IOSDevice): return [] - if not _IsIosDeviceAttached(): + if not CanFindAvailableBrowsers(): return [] options = finder_options.browser_options
diff --git a/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder_unittest.py index e9e9042..e0e783fb 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome/ios_browser_finder_unittest.py
@@ -6,6 +6,7 @@ from telemetry import decorators from telemetry.core import browser_options from telemetry.core.backends.chrome import ios_browser_finder +from telemetry.core.platform import ios_device class IosBrowserFinderUnitTest(unittest.TestCase): @@ -15,7 +16,8 @@ @decorators.Enabled('ios') def testFindIosChrome(self): finder_options = browser_options.BrowserFinderOptions() - browsers = ios_browser_finder.FindAllAvailableBrowsers(finder_options) + browsers = ios_browser_finder.FindAllAvailableBrowsers( + finder_options, ios_device.IOSDevice()) self.assertTrue(browsers) for browser in browsers: self.assertEqual('ios-chrome', browser.browser_type)
diff --git a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py index 44c29a66..7b7bd9d 100644 --- a/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome_inspector/inspector_network_unittest.py
@@ -32,7 +32,8 @@ self.assertTrue(self._tab.timeline_model) return self._tab.timeline_model.GetAllEventsOfName('HTTPResponse') - @decorators.Disabled('mac', 'android') # crbug.com/449979, crbug.com/452279 + # crbug.com/449979, crbug.com/452279, crbug.com/455269 + @decorators.Disabled('mac', 'android', 'win') def testHTTPResponseTimelineRecorder(self): tests = { 'blank.html': InspectorNetworkTabTest.TestCase(),
diff --git a/tools/telemetry/telemetry/core/backends/remote/trybot_browser_finder.py b/tools/telemetry/telemetry/core/backends/remote/trybot_browser_finder.py index 2e240c9..ea7143ca 100644 --- a/tools/telemetry/telemetry/core/backends/remote/trybot_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/remote/trybot_browser_finder.py
@@ -15,12 +15,14 @@ from telemetry import decorators from telemetry.core import platform from telemetry.core import possible_browser +from telemetry.core.platform import trybot_device CHROMIUM_CONFIG_FILENAME = 'tools/run-perf-test.cfg' BLINK_CONFIG_FILENAME = 'Tools/run-perf-test.cfg' SUCCESS, NO_CHANGES, ERROR = range(3) + class PossibleTrybotBrowser(possible_browser.PossibleBrowser): """A script that sends a job to a trybot.""" @@ -34,7 +36,7 @@ raise NotImplementedError() def SupportsOptions(self, finder_options): - if (finder_options.android_device or + if ((finder_options.device and finder_options.device != 'trybot') or finder_options.chrome_root or finder_options.cros_remote or finder_options.extensions_to_load or @@ -250,7 +252,10 @@ return [] -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Find all perf trybots on tryserver.chromium.perf.""" + if not isinstance(device, trybot_device.TrybotDevice): + return [] + return [PossibleTrybotBrowser(b, finder_options) for b in FindAllBrowserTypes(finder_options)]
diff --git a/tools/telemetry/telemetry/core/backends/webdriver/webdriver_desktop_browser_finder.py b/tools/telemetry/telemetry/core/backends/webdriver/webdriver_desktop_browser_finder.py index 66b4aec..0373e1c 100644 --- a/tools/telemetry/telemetry/core/backends/webdriver/webdriver_desktop_browser_finder.py +++ b/tools/telemetry/telemetry/core/backends/webdriver/webdriver_desktop_browser_finder.py
@@ -12,6 +12,7 @@ from telemetry.core import possible_browser from telemetry.core import util from telemetry.core.backends.webdriver import webdriver_ie_backend +from telemetry.core.platform import desktop_device from telemetry.util import support_binaries # Try to import the selenium python lib which may be not available. @@ -96,8 +97,11 @@ 'https://code.google.com/p/selenium/wiki/PythonBindings.') return [] -def FindAllAvailableBrowsers(finder_options): +def FindAllAvailableBrowsers(finder_options, device): """Finds all the desktop browsers available on this machine.""" + if not isinstance(device, desktop_device.DesktopDevice): + return [] + browsers = [] if not webdriver: return browsers
diff --git a/tools/telemetry/telemetry/core/browser_finder.py b/tools/telemetry/telemetry/core/browser_finder.py index eb189af..f98317b3 100644 --- a/tools/telemetry/telemetry/core/browser_finder.py +++ b/tools/telemetry/telemetry/core/browser_finder.py
@@ -9,6 +9,7 @@ from telemetry import decorators from telemetry.core import browser_finder_exceptions +from telemetry.core import device_finder from telemetry.core.backends.chrome import android_browser_finder from telemetry.core.backends.chrome import cros_browser_finder from telemetry.core.backends.chrome import desktop_browser_finder @@ -60,17 +61,24 @@ raise browser_finder_exceptions.BrowserFinderException( '--remote requires --browser=cros-chrome or cros-chrome-guest.') + devices = [] + if options.device and options.device != 'list': + devices = device_finder.GetSpecifiedDevices(options) + else: + devices = device_finder.GetAllAvailableDevices(options) + browsers = [] default_browsers = [] - for finder in BROWSER_FINDERS: - if(options.browser_type and options.browser_type != 'any' and - options.browser_type not in finder.FindAllBrowserTypes(options)): - continue - curr_browsers = finder.FindAllAvailableBrowsers(options) - new_default_browser = finder.SelectDefaultBrowser(curr_browsers) - if new_default_browser: - default_browsers.append(new_default_browser) - browsers.extend(curr_browsers) + for device in devices: + for finder in BROWSER_FINDERS: + if(options.browser_type and options.browser_type != 'any' and + options.browser_type not in finder.FindAllBrowserTypes(options)): + continue + curr_browsers = finder.FindAllAvailableBrowsers(options, device) + new_default_browser = finder.SelectDefaultBrowser(curr_browsers) + if new_default_browser: + default_browsers.append(new_default_browser) + browsers.extend(curr_browsers) if options.browser_type == None: if default_browsers: @@ -125,6 +133,29 @@ @decorators.Cache +def GetAllAvailableBrowsers(options, device): + """Returns a list of available browsers on the device. + + Args: + options: A BrowserOptions object. + device: The target device, which can be None. + + Returns: + A list of browser instances. + + Raises: + BrowserFinderException: Options are improperly set, or an error occurred. + """ + if not device: + return [] + possible_browsers = [] + for browser_finder in BROWSER_FINDERS: + possible_browsers.extend( + browser_finder.FindAllAvailableBrowsers(options, device)) + return possible_browsers + + +@decorators.Cache def GetAllAvailableBrowserTypes(options): """Returns a list of available browser types. @@ -137,11 +168,11 @@ Raises: BrowserFinderException: Options are improperly set, or an error occurred. """ - browsers = [] - for finder in BROWSER_FINDERS: - browsers.extend(finder.FindAllAvailableBrowsers(options)) - - type_list = set([browser.browser_type for browser in browsers]) + devices = device_finder.GetAllAvailableDevices(options) + possible_browsers = [] + for device in devices: + possible_browsers.extend(GetAllAvailableBrowsers(options, device)) + type_list = set([browser.browser_type for browser in possible_browsers]) type_list = list(type_list) type_list.sort() return type_list
diff --git a/tools/telemetry/telemetry/core/browser_options.py b/tools/telemetry/telemetry/core/browser_options.py index 43e5793..3a790386 100644 --- a/tools/telemetry/telemetry/core/browser_options.py +++ b/tools/telemetry/telemetry/core/browser_options.py
@@ -12,6 +12,7 @@ from telemetry.core import browser_finder from telemetry.core import browser_finder_exceptions +from telemetry.core import device_finder from telemetry.core import platform from telemetry.core import profile_types from telemetry.core import util @@ -32,7 +33,7 @@ self.browser_type = browser_type self.browser_executable = None self.chrome_root = None - self.android_device = None + self.device = None self.cros_ssh_identity = None self.extensions_to_load = [] @@ -76,8 +77,8 @@ help='Where to look for chrome builds.' 'Defaults to searching parent dirs by default.') group.add_option('--device', - dest='android_device', - help='The android device ID to use' + dest='device', + help='The device ID to use.' 'If not specified, only 0 or 1 connected devices are supported.') group.add_option('--target-arch', dest='target_arch', @@ -159,16 +160,40 @@ else: logging.getLogger().setLevel(logging.WARNING) + if self.device == 'list': + devices = device_finder.GetAllAvailableDeviceNames(self) + print 'Available devices:' + for device in devices: + print ' ', device + sys.exit(0) + if self.browser_executable and not self.browser_type: self.browser_type = 'exact' if self.browser_type == 'list': - try: - types = browser_finder.GetAllAvailableBrowserTypes(self) - except browser_finder_exceptions.BrowserFinderException, ex: - sys.stderr.write('ERROR: ' + str(ex)) - sys.exit(1) - sys.stdout.write('Available browsers:\n') - sys.stdout.write(' %s\n' % '\n '.join(types)) + devices = [] + if self.device and self.device != 'list': + devices = device_finder.GetSpecifiedDevices(self) + else: + devices = device_finder.GetAllAvailableDevices(self) + if not devices: + sys.exit(0) + browser_types = {} + for device in devices: + try: + possible_browsers = browser_finder.GetAllAvailableBrowsers(self, + device) + browser_types[device.name] = sorted( + [browser.browser_type for browser in possible_browsers]) + except browser_finder_exceptions.BrowserFinderException as ex: + print >> sys.stderr, 'ERROR: ', ex + sys.exit(1) + print 'Available browsers:' + if len(browser_types) == 0: + print ' No devices were found.' + for device_name in sorted(browser_types.keys()): + print ' ', device_name + for browser_type in browser_types[device_name]: + print ' ', browser_type sys.exit(0) # Parse browser options.
diff --git a/tools/telemetry/telemetry/core/device_finder.py b/tools/telemetry/telemetry/core/device_finder.py new file mode 100644 index 0000000..dbe0115 --- /dev/null +++ b/tools/telemetry/telemetry/core/device_finder.py
@@ -0,0 +1,45 @@ +# 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. + +"""Finds devices that can be controlled by telemetry.""" + +import logging + +from telemetry.core.platform import android_device +from telemetry.core.platform import cros_device +from telemetry.core.platform import desktop_device +from telemetry.core.platform import ios_device +from telemetry.core.platform import trybot_device + +DEVICES = [ + android_device, + cros_device, + desktop_device, + ios_device, + trybot_device, +] + + +def GetAllAvailableDevices(options): + """Returns a list of all available devices.""" + devices = [] + for device in DEVICES: + devices.extend(device.FindAllAvailableDevices(options)) + devices.sort(key=lambda device: device.name) + return devices + + +def GetAllAvailableDeviceNames(options): + """Returns a list of all available device names.""" + devices = GetAllAvailableDevices(options) + device_names = [device.name for device in devices] + return device_names + + +def GetSpecifiedDevices(options): + """Returns the specified devices.""" + assert options.device and options.device != 'list' + devices = GetAllAvailableDevices(options) + devices = [d for d in devices if d.guid == options.device] + return devices
diff --git a/tools/telemetry/telemetry/core/platform/android_action_runner.py b/tools/telemetry/telemetry/core/platform/android_action_runner.py new file mode 100644 index 0000000..aa8eda6 --- /dev/null +++ b/tools/telemetry/telemetry/core/platform/android_action_runner.py
@@ -0,0 +1,115 @@ +# 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 time + + +class ActionNotSupported(Exception): + pass + + +class AndroidActionRunner(object): + """Provides an API for interacting with an android device. + + This makes use of functionality provided by the android input command. None + of the gestures here are guaranteed to be performant for telemetry tests and + there is no official support for this API. + + TODO(ariblue): Replace this API with a better implementation for interacting + with native components. + """ + + def __init__(self, platform_backend): + self._platform_backend = platform_backend + + def SmoothScrollBy(self, left_start_coord, top_start_coord, direction, + scroll_distance): + """Perfrom gesture to scroll down on the android device. + """ + if direction not in ['down', 'up', 'left', 'right']: + raise ActionNotSupported('Invalid scroll direction: %s' % direction) + + # This velocity is slower so that the exact distance we specify is the + # distance the page travels. + duration = scroll_distance + + # Note that the default behavior is swiping up for scrolling down. + if direction == 'down': + left_end_coord = left_start_coord + top_end_coord = top_start_coord - scroll_distance + elif direction == 'up': + left_end_coord = left_start_coord + top_end_coord = top_start_coord + scroll_distance + elif direction == 'right': + left_end_coord = left_start_coord - scroll_distance + top_end_coord = top_start_coord + elif direction == 'left': + left_end_coord = left_start_coord + scroll_distance + top_end_coord = top_start_coord + + self.InputSwipe(left_start_coord, top_start_coord, left_end_coord, + top_end_coord, duration) + + def Wait(self, seconds): + """Wait for the number of seconds specified. + + Args: + seconds: The number of seconds to wait. + """ + time.sleep(seconds) + + def InputText(self, string): + """Convert the characters of the string into key events and send to device. + + Args: + string: The string to send to the device. + """ + self._platform_backend.adb.RunShellCommand('input text %s' % string) + + def InputKeyEvent(self, key): + """Send a single key input to the device. + + Args: + key: A key code number or name that will be sent to the device + """ + self._platform_backend.adb.RunShellCommand('input keyevent %s' % key) + + def InputTap(self, x_coord, y_coord): + """Perform a tap input at the given coordinates. + + Args: + x_coord: The x coordinate of the tap event. + y_coord: The y coordinate of the tap event. + """ + self._platform_backend.adb.RunShellCommand('input tap %s %s' % (x_coord, + y_coord)) + + def InputSwipe(self, left_start_coord, top_start_coord, left_end_coord, + top_end_coord, duration): + """Perform a swipe input. + + Args: + left_start_coord: The horizontal starting coordinate of the gesture + top_start_coord: The vertical starting coordinate of the gesture + left_end_coord: The horizontal ending coordinate of the gesture + top_end_coord: The vertical ending coordinate of the gesture + duration: The length of time of the swipe in milliseconds + """ + self._platform_backend.adb.RunShellCommand( + 'input swipe %s %s %s %s %s' % (left_start_coord, top_start_coord, + left_end_coord, top_end_coord, + duration)) + + def InputPress(self): + """Perform a press input.""" + self._platform_backend.adb.RunShellCommand('input press') + + def InputRoll(self, dx, dy): + """Perform a roll input. This sends a simple zero-pressure move event. + + Args: + dx: Change in the x coordinate due to move. + dy: Change in the y coordinate due to move. + """ + self._platform_backend.adb.RunShellCommand('input roll %s %s' % (dx, dy))
diff --git a/tools/telemetry/telemetry/core/platform/android_device.py b/tools/telemetry/telemetry/core/platform/android_device.py index 73fad60..e04f2e0 100644 --- a/tools/telemetry/telemetry/core/platform/android_device.py +++ b/tools/telemetry/telemetry/core/platform/android_device.py
@@ -31,31 +31,7 @@ @classmethod def GetAllConnectedDevices(cls): - device_serials = adb_commands.GetAttachedDevices() - # The monsoon provides power for the device, so for devices with no - # real battery, we need to turn them on after the monsoon enables voltage - # output to the device. - if not device_serials: - try: - m = monsoon.Monsoon(wait=False) - m.SetUsbPassthrough(1) - m.SetVoltage(3.8) - m.SetMaxCurrent(8) - logging.warn(""" -Monsoon power monitor detected, but no Android devices. - -The Monsoon's power output has been enabled. Please now ensure that: - - 1. The Monsoon's front and back USB are connected to the host. - 2. The device is connected to the Monsoon's main and USB channels. - 3. The device is turned on. - -Waiting for device... -""") - util.WaitFor(adb_commands.GetAttachedDevices, 600) - device_serials = adb_commands.GetAttachedDevices() - except IOError: - return [] + device_serials = GetDeviceSerials() return [cls(s) for s in device_serials] @property @@ -67,6 +43,35 @@ return self._enable_performance_mode +def GetDeviceSerials(): + device_serials = adb_commands.GetAttachedDevices() + # The monsoon provides power for the device, so for devices with no + # real battery, we need to turn them on after the monsoon enables voltage + # output to the device. + if not device_serials: + try: + m = monsoon.Monsoon(wait=False) + m.SetUsbPassthrough(1) + m.SetVoltage(3.8) + m.SetMaxCurrent(8) + logging.warn(""" +Monsoon power monitor detected, but no Android devices. + +The Monsoon's power output has been enabled. Please now ensure that: + + 1. The Monsoon's front and back USB are connected to the host. + 2. The device is connected to the Monsoon's main and USB channels. + 3. The device is turned on. + +Waiting for device... +""") + util.WaitFor(adb_commands.GetAttachedDevices, 600) + device_serials = adb_commands.GetAttachedDevices() + except IOError: + return [] + return device_serials + + def GetDevice(finder_options): """Return a Platform instance for the device specified by |finder_options|.""" if not CanDiscoverDevices(): @@ -74,9 +79,9 @@ 'No adb command found. Will not try searching for Android browsers.') return None - if finder_options.android_device: + if finder_options.device and finder_options.device in GetDeviceSerials(): return AndroidDevice( - finder_options.android_device, + finder_options.device, enable_performance_mode=not finder_options.no_performance_mode) devices = AndroidDevice.GetAllConnectedDevices() @@ -121,3 +126,11 @@ return True return False + +def FindAllAvailableDevices(_): + """Returns a list of available devices. + """ + if not CanDiscoverDevices(): + return [] + else: + return AndroidDevice.GetAllConnectedDevices()
diff --git a/tools/telemetry/telemetry/core/platform/android_device_unittest.py b/tools/telemetry/telemetry/core/platform/android_device_unittest.py index ed7707a..6e7609b 100644 --- a/tools/telemetry/telemetry/core/platform/android_device_unittest.py +++ b/tools/telemetry/telemetry/core/platform/android_device_unittest.py
@@ -83,7 +83,7 @@ def testAdbPickOneDeviceReturnsDeviceInstance(self): finder_options = browser_options.BrowserFinderOptions() - finder_options.android_device = '555d14fecddddddd' # pick one + finder_options.device = '555d14fecddddddd' # pick one self._android_device_stub.adb_commands.attached_devices = [ '015d14fec128220c', '555d14fecddddddd'] device = android_device.GetDevice(finder_options) @@ -97,3 +97,44 @@ device = android_device.GetDevice(finder_options) self.assertEquals([], self._android_device_stub.logging.warnings) self.assertEquals('015d14fec128220c', device.device_id) + + +class FindAllAvailableDevicesTest(unittest.TestCase): + def setUp(self): + self._android_device_stub = system_stub.Override( + android_device, ['adb_commands', 'os', 'subprocess', 'logging']) + self._apb_stub = system_stub.Override( + android_platform_backend, ['adb_commands']) + + def tearDown(self): + self._android_device_stub.Restore() + self._apb_stub.Restore() + + def testAdbNoDeviceReturnsEmptyList(self): + finder_options = browser_options.BrowserFinderOptions() + devices = android_device.FindAllAvailableDevices(finder_options) + self.assertEquals([], self._android_device_stub.logging.warnings) + self.assertIsNotNone(devices) + self.assertEquals(len(devices), 0) + + def testAdbOneDeviceReturnsListWithOneDeviceInstance(self): + finder_options = browser_options.BrowserFinderOptions() + self._android_device_stub.adb_commands.attached_devices = ( + ['015d14fec128220c']) + devices = android_device.FindAllAvailableDevices(finder_options) + self.assertEquals([], self._android_device_stub.logging.warnings) + self.assertIsNotNone(devices) + self.assertEquals(len(devices), 1) + self.assertEquals('015d14fec128220c', devices[0].device_id) + + def testAdbMultipleDevicesReturnsListWithAllDeviceInstances(self): + finder_options = browser_options.BrowserFinderOptions() + self._android_device_stub.adb_commands.attached_devices = [ + '015d14fec128220c', '015d14fec128220d', '015d14fec128220e'] + devices = android_device.FindAllAvailableDevices(finder_options) + self.assertEquals([], self._android_device_stub.logging.warnings) + self.assertIsNotNone(devices) + self.assertEquals(len(devices), 3) + self.assertEquals(devices[0].guid, '015d14fec128220c') + self.assertEquals(devices[1].guid, '015d14fec128220d') + self.assertEquals(devices[2].guid, '015d14fec128220e')
diff --git a/tools/telemetry/telemetry/core/platform/android_platform.py b/tools/telemetry/telemetry/core/platform/android_platform.py index 6d22a7d..a5d40b7 100644 --- a/tools/telemetry/telemetry/core/platform/android_platform.py +++ b/tools/telemetry/telemetry/core/platform/android_platform.py
@@ -6,11 +6,18 @@ from telemetry.core import android_app from telemetry.core import platform from telemetry.core.backends import android_app_backend +from telemetry.core.platform import android_action_runner class AndroidPlatform(platform.Platform): def __init__(self, platform_backend): super(AndroidPlatform, self).__init__(platform_backend) + self._android_action_runner = android_action_runner.AndroidActionRunner( + platform_backend) + + @property + def android_action_runner(self): + return self._android_action_runner def LaunchAndroidApplication(self, start_intent, is_app_ready_predicate=None): """Launches an Android application given the intent.
diff --git a/tools/telemetry/telemetry/core/platform/cros_device.py b/tools/telemetry/telemetry/core/platform/cros_device.py index 4bb49ad..b4a09ac 100644 --- a/tools/telemetry/telemetry/core/platform/cros_device.py +++ b/tools/telemetry/telemetry/core/platform/cros_device.py
@@ -1,6 +1,10 @@ # 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 logging + +from telemetry.core import platform +from telemetry.core.platform import cros_interface from telemetry.core.platform import device @@ -29,3 +33,25 @@ @property def ssh_identity(self): return self._ssh_identity + + +def IsRunningOnCrOS(): + return platform.GetHostPlatform().GetOSName() == 'chromeos' + + +def FindAllAvailableDevices(options): + """Returns a list of available device types. + """ + if IsRunningOnCrOS(): + return [CrOSDevice('localhost', -1)] + + if options.cros_remote == None: + logging.debug('No --remote specified, will not probe for CrOS.') + return [] + + if not cros_interface.HasSSH(): + logging.debug('ssh not found. Cannot talk to CrOS devices.') + return [] + + return [CrOSDevice(options.cros_remote, options.cros_remote_ssh_port, + options.cros_ssh_identity)]
diff --git a/tools/telemetry/telemetry/core/platform/desktop_device.py b/tools/telemetry/telemetry/core/platform/desktop_device.py new file mode 100644 index 0000000..4d68863 --- /dev/null +++ b/tools/telemetry/telemetry/core/platform/desktop_device.py
@@ -0,0 +1,24 @@ +# 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.core import platform +from telemetry.core.platform import device + + +class DesktopDevice(device.Device): + def __init__(self): + super(DesktopDevice, self).__init__(name='desktop', guid='desktop') + + @classmethod + def GetAllConnectedDevices(cls): + return [] + + +def FindAllAvailableDevices(_): + """Returns a list of available devices. + """ + # If the host platform is Chrome OS, the device is also considered as cros. + if platform.GetHostPlatform().GetOSName() == 'chromeos': + return [] + return [DesktopDevice()] \ No newline at end of file
diff --git a/tools/telemetry/telemetry/core/platform/ios_device.py b/tools/telemetry/telemetry/core/platform/ios_device.py new file mode 100644 index 0000000..0cec05e --- /dev/null +++ b/tools/telemetry/telemetry/core/platform/ios_device.py
@@ -0,0 +1,40 @@ +# 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 re +import subprocess + +from telemetry.core import platform +from telemetry.core.platform import device + + +class IOSDevice(device.Device): + def __init__(self): + super(IOSDevice, self).__init__(name='ios', guid='ios') + + @classmethod + def GetAllConnectedDevices(cls): + return [] + + +def _IsIosDeviceAttached(): + devices = subprocess.check_output('system_profiler SPUSBDataType', shell=True) + for line in devices.split('\n'): + if line and re.match(r'\s*(iPod|iPhone|iPad):', line): + return True + return False + + +def FindAllAvailableDevices(_): + """Returns a list of available devices. + """ + # TODO(baxley): Add support for all platforms possible. Probably Linux, + # probably not Windows. + if platform.GetHostPlatform().GetOSName() != 'mac': + return [] + + if not _IsIosDeviceAttached(): + return [] + + return [IOSDevice()] \ No newline at end of file
diff --git a/tools/telemetry/telemetry/core/platform/trybot_device.py b/tools/telemetry/telemetry/core/platform/trybot_device.py new file mode 100644 index 0000000..cdb904f4 --- /dev/null +++ b/tools/telemetry/telemetry/core/platform/trybot_device.py
@@ -0,0 +1,20 @@ +# 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.core.platform import device + + +class TrybotDevice(device.Device): + def __init__(self): + super(TrybotDevice, self).__init__(name='trybot', guid='trybot') + + @classmethod + def GetAllConnectedDevices(cls): + return [] + + +def FindAllAvailableDevices(_): + """Returns a list of available devices. + """ + return [TrybotDevice()] \ No newline at end of file
diff --git a/tools/telemetry/telemetry/page/actions/action_runner.py b/tools/telemetry/telemetry/page/actions/action_runner.py index 090370d..140deab93 100644 --- a/tools/telemetry/telemetry/page/actions/action_runner.py +++ b/tools/telemetry/telemetry/page/actions/action_runner.py
@@ -130,8 +130,14 @@ timeout_in_seconds=timeout_in_seconds)) def WaitForNavigate(self, timeout_in_seconds_seconds=60): + start_time = time.time() self._tab.WaitForNavigate(timeout_in_seconds_seconds) - self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter() + + time_left_in_seconds = (start_time + timeout_in_seconds_seconds + - time.time()) + time_left_in_seconds = max(0, time_left_in_seconds) + self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter( + time_left_in_seconds) def ReloadPage(self): """Reloads the page."""
diff --git a/tools/telemetry/telemetry/page/actions/navigate.py b/tools/telemetry/telemetry/page/actions/navigate.py index cc4a0a4..a1ecb4d 100644 --- a/tools/telemetry/telemetry/page/actions/navigate.py +++ b/tools/telemetry/telemetry/page/actions/navigate.py
@@ -1,6 +1,9 @@ # 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 time + from telemetry.page.actions import page_action @@ -14,7 +17,13 @@ self._timeout_in_seconds = timeout_in_seconds def RunAction(self, tab): + start_time = time.time() tab.Navigate(self._url, self._script_to_evaluate_on_commit, self._timeout_in_seconds) - tab.WaitForDocumentReadyStateToBeInteractiveOrBetter() + + time_left_in_seconds = (start_time + self._timeout_in_seconds + - time.time()) + time_left_in_seconds = max(0, time_left_in_seconds) + tab.WaitForDocumentReadyStateToBeInteractiveOrBetter( + time_left_in_seconds)
diff --git a/tools/ubsan/blacklist.txt b/tools/ubsan/blacklist.txt index b9ab7824..5b4751fe 100644 --- a/tools/ubsan/blacklist.txt +++ b/tools/ubsan/blacklist.txt
@@ -89,6 +89,9 @@ # obj/third_party/libwebm/libwebm.a(obj/third_party/libwebm/source/libwebm.mkvmuxer.o)(.data.rel..L__unnamed_2+0x18): error: undefined reference to 'typeinfo for mkvparser::IMkvReader' src:*/third_party/libwebm/source/mkvmuxer.cpp +# obj/content/libcontent_renderer.a(obj/content/renderer/scheduler/content_renderer.renderer_scheduler_impl.o)(.data.rel..L__unnamed_399+0x18): error: undefined reference to ' typeinfo for cc::TestNowSource' +type:*TestNowSource* + ############################################################################# # UBSan seems to be emit false positives when virtual base classes are # involved, see e.g. chromium:448102
diff --git a/tools/valgrind/drmemory/suppressions.txt b/tools/valgrind/drmemory/suppressions.txt index 876d6f7..fb1861f 100644 --- a/tools/valgrind/drmemory/suppressions.txt +++ b/tools/valgrind/drmemory/suppressions.txt
@@ -461,11 +461,12 @@ name=http://crbug.com/371348 system call NtCreateSection KERNELBASE.dll!CreateFileMappingW -base.dll!base::SharedMemory::Create -base.dll!base::SharedMemory::CreateAnonymous -content.dll!content::ChildThread::AllocateSharedMemory -content.dll!content::ChildSharedBitmapManager::AllocateSharedBitmap -cc.dll!cc::ResourceProvider::CreateBitmap +*!base::SharedMemory::Create +*!base::SharedMemory::CreateAnonymous +*!content::ChildThreadImpl::AllocateSharedMemory +... +*!content::ChildSharedBitmapManager::AllocateSharedBitmap +*!cc::ResourceProvider::CreateBitmap HANDLE LEAK name=http://crbug.com/371357 @@ -711,3 +712,20 @@ KERNELBASE.dll!OpenProcess base.dll!base::Process::OpenWithExtraPriviles content.dll!content::BrowserMessageFilter::Internal::OnChannelConnected + +UNADDRESSABLE ACCESS +name=http://crbug.com/455060 +*!content::FrameAccessibility::GetParent +*!content::RenderFrameHostImpl::AccessibilityGetParentFrame +*!content::BrowserAccessibilityManager::GetDelegateFromRootManager +*!content::BrowserAccessibilityManager::OnWindowBlurred +... +*!content::RenderWidgetHostViewAura::Destroy + +UNADDRESSABLE ACCESS +name=http://crbug.com/455066 +system call NtReadFile parameter #4 +KERNELBASE.dll!ReadFile +KERNEL32.dll!ReadFile +*!net::FileStream::Context::ReadAsync +*!base::internal::RunnableAdapter<>::Run
diff --git a/tools/valgrind/drmemory/suppressions_full.txt b/tools/valgrind/drmemory/suppressions_full.txt index 2036d21..beb52f8 100644 --- a/tools/valgrind/drmemory/suppressions_full.txt +++ b/tools/valgrind/drmemory/suppressions_full.txt
@@ -1890,10 +1890,5 @@ *!testing::internal::HandleExceptionsInMethodIfSupported<> UNINITIALIZED READ -name=bug_446256 -*!`anonymous namespace'::GraphicsContextTest_trackDisplayListRecording_Test::TestBody -*!testing::internal::HandleExceptionsInMethodIfSupported<> - -UNINITIALIZED READ name=bug_399842 skia.dll!S32A_Opaque_BlitRow32_SSE4
diff --git a/tools/valgrind/gtest_exclude/unit_tests.gtest_linux.txt b/tools/valgrind/gtest_exclude/unit_tests.gtest_linux.txt index 5a8f1bc..a43a673 100644 --- a/tools/valgrind/gtest_exclude/unit_tests.gtest_linux.txt +++ b/tools/valgrind/gtest_exclude/unit_tests.gtest_linux.txt
@@ -32,6 +32,3 @@ # http://crbug.com/403533 ExtensionPathUtilTest.BasicPrettifyPathTest - -# http://crbug.com/452071 -SupervisedUserServiceExtensionTest.InstallContentPacks
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index 579b481..fea7c3b 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt
@@ -3401,10 +3401,10 @@ bug_431213 Memcheck:Leak fun:_Znw* - fun:_ZN3gin22CreateFunctionTemplateIFSsPN4mojo2js13HandleWrapperEEEEN2v85LocalINS6_16FunctionTemplateEEEPNS6_7IsolateEN4base8CallbackIT_EEi - fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIMN4mojo2js13HandleWrapperEFSsvEvE14CreateTemplateEPN2v87IsolateES6_ - fun:_ZN3gin21ObjectTemplateBuilder9SetMethodIMN4mojo2js13HandleWrapperEFSsvEEERS0_RKN4base16BasicStringPieceISsEERKT_ - fun:_ZN4mojo2js13HandleWrapper24GetObjectTemplateBuilderEPN2v87IsolateE + fun:_ZN3gin22CreateFunctionTemplateIF*LocalINS6_16FunctionTemplateEEEPNS6_7IsolateEN4base8CallbackIT_EEi + fun:_ZN3gin12_GLOBAL__N_114CallbackTraitsIMN*CreateTemplateEPN2v87IsolateES6_ + fun:_ZN3gin21ObjectTemplateBuilder9SetMethodIMN*0_RKN4base16BasicStringPieceISsEERKT_ + fun:_ZN*24GetObjectTemplateBuilderEPN2v87IsolateE } { bug_436110
diff --git a/ui/accelerometer/BUILD.gn b/ui/accelerometer/BUILD.gn deleted file mode 100644 index 4af13da..0000000 --- a/ui/accelerometer/BUILD.gn +++ /dev/null
@@ -1,21 +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("//build/config/ui.gni") - -component("accelerometer") { - output_name = "ui_accelerometer" - sources = [ - "accelerometer_types.cc", - "accelerometer_types.h", - "ui_accelerometer_export.h", - ] - - defines = [ "UI_ACCELEROMETER_IMPLEMENTATION" ] - - deps = [ - "//base", - "//ui/gfx/geometry", - ] -}
diff --git a/ui/accelerometer/DEPS b/ui/accelerometer/DEPS deleted file mode 100644 index 3490ab2..0000000 --- a/ui/accelerometer/DEPS +++ /dev/null
@@ -1,3 +0,0 @@ -include_rules = [ - "+ui/gfx/geometry/vector3d_f.h" -]
diff --git a/ui/accelerometer/ui_accelerometer.gyp b/ui/accelerometer/ui_accelerometer.gyp deleted file mode 100644 index 94fc4377..0000000 --- a/ui/accelerometer/ui_accelerometer.gyp +++ /dev/null
@@ -1,30 +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. - -{ - 'variables': { - 'chromium_code': 1, - }, - 'targets': [ - { - # GN version: //ui/accelerometer - 'target_name': 'ui_accelerometer', - 'type': '<(component)', - 'dependencies': [ - '../gfx/gfx.gyp:gfx_geometry', - ], - 'defines': [ - 'UI_ACCELEROMETER_IMPLEMENTATION', - ], - 'sources' : [ - 'accelerometer_types.cc', - 'accelerometer_types.h', - 'ui_accelerometer_export.h', - ], - 'include_dirs': [ - '../..', - ], - }, - ], -}
diff --git a/ui/accelerometer/ui_accelerometer_export.h b/ui/accelerometer/ui_accelerometer_export.h deleted file mode 100644 index 97727f5f..0000000 --- a/ui/accelerometer/ui_accelerometer_export.h +++ /dev/null
@@ -1,37 +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 UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_ -#define UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_ - -// Defines UI_ACCELEROMETER_EXPORT so that functionality implemented by the UI -// accelerometer module can be exported to consumers. - -#if defined(COMPONENT_BUILD) - -#if defined(WIN32) - -#if defined(UI_ACCELEROMETER_IMPLEMENTATION) -#define UI_ACCELEROMETER_EXPORT __declspec(dllexport) -#else -#define UI_ACCELEROMETER_EXPORT __declspec(dllimport) -#endif - -#else // !defined(WIN32) - -#if defined(UI_ACCELEROMETER_IMPLEMENTATION) -#define UI_ACCELEROMETER_EXPORT __attribute__((visibility("default"))) -#else -#define UI_ACCELEROMETER_EXPORT -#endif - -#endif - -#else // !defined(COMPONENT_BUILD) - -#define UI_ACCELEROMETER_EXPORT - -#endif - -#endif // UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_
diff --git a/ui/app_list/DEPS b/ui/app_list/DEPS index 184859b..ec495840 100644 --- a/ui/app_list/DEPS +++ b/ui/app_list/DEPS
@@ -13,4 +13,5 @@ "+ui/resources/grit/ui_resources.h", "+ui/strings/grit/ui_strings.h", "+ui/views", + "+ui/wm/core", ]
diff --git a/ui/app_list/app_list_unittests.isolate b/ui/app_list/app_list_unittests.isolate index 4ceb64d..b6576867 100644 --- a/ui/app_list/app_list_unittests.isolate +++ b/ui/app_list/app_list_unittests.isolate
@@ -22,6 +22,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../../testing/xvfb.py', @@ -59,6 +61,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index e2d3e09..f2083749 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -45,6 +45,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/views/bubble/bubble_window_targeter.h" +#include "ui/wm/core/masked_window_targeter.h" #if defined(OS_WIN) #include "ui/base/win/shell.h" #endif @@ -109,6 +110,29 @@ DISALLOW_COPY_AND_ASSIGN(AppListOverlayView); }; +#if defined(USE_AURA) +// An event targeter for the search box widget which will ignore events that +// are on the search box's shadow. +class SearchBoxWindowTargeter : public wm::MaskedWindowTargeter { + public: + explicit SearchBoxWindowTargeter(views::View* search_box) + : wm::MaskedWindowTargeter(search_box->GetWidget()->GetNativeWindow()), + search_box_(search_box) {} + ~SearchBoxWindowTargeter() override {} + + private: + // wm::MaskedWindowTargeter: + bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const override { + mask->addRect(gfx::RectToSkRect(search_box_->GetContentsBounds())); + return true; + } + + views::View* search_box_; + + DISALLOW_COPY_AND_ASSIGN(SearchBoxWindowTargeter); +}; +#endif + } // namespace // An animation observer to hide the view at the end of the animation. @@ -426,6 +450,13 @@ search_box_widget_->Init(search_box_widget_params); search_box_widget_->SetContentsView(search_box_view_); +#if defined(USE_AURA) + // Mouse events on the search box shadow should not be captured. + aura::Window* window = search_box_widget_->GetNativeWindow(); + window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( + new SearchBoxWindowTargeter(search_box_view_))); +#endif + app_list_main_view_->contents_view()->Layout(); }
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index 8c5c73a..dbb948a 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -273,10 +273,15 @@ bool AppListViewTestContext::CheckSearchBoxWidget(const gfx::Rect& expected) { ContentsView* contents_view = view_->app_list_main_view()->contents_view(); - gfx::Point point = expected.origin(); + // Adjust for the search box view's shadow. + gfx::Rect expected_with_shadow = + view_->app_list_main_view() + ->search_box_view() + ->GetViewBoundsForSearchBoxContentsBounds(expected); + gfx::Point point = expected_with_shadow.origin(); views::View::ConvertPointToScreen(contents_view, &point); - return gfx::Rect(point, expected.size()) == + return gfx::Rect(point, expected_with_shadow.size()) == view_->search_box_widget()->GetWindowBoundsInScreen(); }
diff --git a/ui/app_list/views/contents_animator.cc b/ui/app_list/views/contents_animator.cc index f4fe3986..97d3c502 100644 --- a/ui/app_list/views/contents_animator.cc +++ b/ui/app_list/views/contents_animator.cc
@@ -95,9 +95,9 @@ gfx::Rect search_box_rect = gfx::Tween::RectValueBetween(progress, search_box_from, search_box_to); - views::View* search_box = contents_view()->GetSearchBoxView(); - search_box->GetWidget()->SetBounds( - contents_view()->ConvertRectToWidget(search_box_rect)); + SearchBoxView* search_box = contents_view()->GetSearchBoxView(); + search_box->GetWidget()->SetBounds(contents_view()->ConvertRectToWidget( + search_box->GetViewBoundsForSearchBoxContentsBounds(search_box_rect))); } void ContentsAnimator::ClipSearchResultsPageToOnscreenBounds(
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index 069afa0..3de1018 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -469,8 +469,10 @@ // same as the app list widget so don't move it. views::Widget* search_box_widget = GetSearchBoxView()->GetWidget(); if (search_box_widget && search_box_widget != GetWidget()) { - search_box_widget->SetBounds( - ConvertRectToWidget(GetSearchBoxBoundsForState(GetActiveState()))); + gfx::Rect search_box_bounds = GetSearchBoxBoundsForState(GetActiveState()); + search_box_widget->SetBounds(ConvertRectToWidget( + GetSearchBoxView()->GetViewBoundsForSearchBoxContentsBounds( + search_box_bounds))); } // Immediately finish all current animations.
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 4126f0d7..b23e5dd 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -24,6 +24,8 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/shadow_border.h" namespace app_list { @@ -39,11 +41,11 @@ const int kMenuYOffsetFromButton = -4; const int kMenuXOffsetFromButton = -7; -const int kBackgroundBorderWidth = 1; -const int kBackgroundBorderBottomWidth = 1; const int kBackgroundBorderCornerRadius = 2; -const SkColor kBackgroundBorderColor = SkColorSetRGB(0xEE, 0xEE, 0xEE); -const SkColor kBackgroundBorderBottomColor = SkColorSetRGB(0xCC, 0xCC, 0xCC); + +const int kShadowBlur = 4; +const int kShadowYOffset = 2; +const SkColor kShadowColor = SkColorSetARGB(0x33, 0, 0, 0); // A background that paints a solid white rounded rect with a thin grey border. class ExperimentalSearchBoxBackground : public views::Background { @@ -58,15 +60,6 @@ SkPaint paint; paint.setFlags(SkPaint::kAntiAlias_Flag); - paint.setColor(kBackgroundBorderColor); - canvas->DrawRoundRect(bounds, kBackgroundBorderCornerRadius, paint); - bounds.Inset(kBackgroundBorderWidth, - kBackgroundBorderWidth, - kBackgroundBorderWidth, - 0); - paint.setColor(kBackgroundBorderBottomColor); - canvas->DrawRoundRect(bounds, kBackgroundBorderCornerRadius, paint); - bounds.Inset(0, 0, 0, kBackgroundBorderBottomWidth); paint.setColor(kSearchBoxBackground); canvas->DrawRoundRect(bounds, kBackgroundBorderCornerRadius, paint); } @@ -81,13 +74,19 @@ : delegate_(delegate), view_delegate_(view_delegate), model_(NULL), + content_container_(new views::View), icon_view_(NULL), back_button_(NULL), speech_button_(NULL), menu_button_(NULL), search_box_(new views::Textfield), contents_view_(NULL) { + SetLayoutManager(new views::FillLayout); + AddChildView(content_container_); + if (switches::IsExperimentalAppListEnabled()) { + SetBorder(make_scoped_ptr( + new views::ShadowBorder(kShadowBlur, kShadowColor, kShadowYOffset, 0))); back_button_ = new views::ImageButton(this); ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); back_button_->SetImage( @@ -95,16 +94,16 @@ rb.GetImageSkiaNamed(IDR_APP_LIST_FOLDER_BACK_NORMAL)); back_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); - AddChildView(back_button_); + content_container_->AddChildView(back_button_); - set_background(new ExperimentalSearchBoxBackground()); + content_container_->set_background(new ExperimentalSearchBoxBackground()); } else { set_background( views::Background::CreateSolidBackground(kSearchBoxBackground)); SetBorder( views::Border::CreateSolidSidedBorder(0, 0, 1, 0, kTopSeparatorColor)); icon_view_ = new views::ImageView; - AddChildView(icon_view_); + content_container_->AddChildView(icon_view_); } views::BoxLayout* layout = @@ -112,7 +111,7 @@ kPadding, 0, kPadding - views::Textfield::kTextPadding); - SetLayoutManager(layout); + content_container_->SetLayoutManager(layout); layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); layout->set_minimum_cross_axis_size(kPreferredHeight); @@ -123,7 +122,7 @@ search_box_->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont)); search_box_->set_placeholder_text_color(kHintTextColor); search_box_->set_controller(this); - AddChildView(search_box_); + content_container_->AddChildView(search_box_); layout->SetFlexForView(search_box_, 1); #if !defined(OS_CHROMEOS) @@ -135,7 +134,7 @@ *rb.GetImageSkiaNamed(IDR_APP_LIST_TOOLS_HOVER)); menu_button_->SetImage(views::Button::STATE_PRESSED, *rb.GetImageSkiaNamed(IDR_APP_LIST_TOOLS_PRESSED)); - AddChildView(menu_button_); + content_container_->AddChildView(menu_button_); #endif view_delegate_->GetSpeechUI()->AddObserver(this); @@ -176,6 +175,13 @@ menu_.reset(); } +gfx::Rect SearchBoxView::GetViewBoundsForSearchBoxContentsBounds( + const gfx::Rect& rect) const { + gfx::Rect view_bounds = rect; + view_bounds.Inset(GetInsets().Scale(-1)); + return view_bounds; +} + gfx::Size SearchBoxView::GetPreferredSize() const { return gfx::Size(kPreferredWidth, kPreferredHeight); } @@ -221,13 +227,6 @@ if (contents_view_ && contents_view_->visible()) handled = contents_view_->OnKeyPressed(key_event); - // Prevent Shift+Tab from locking up the whole chrome browser process. - // Explicitly capturing the Shift+Tab event here compensates for a focus - // search issue. We get away with this because there are no other focus - // targets. See http://crbug.com/438425 for details. - if (key_event.key_code() == ui::VKEY_TAB && key_event.IsShiftDown()) - handled = true; - return handled; } @@ -262,7 +261,7 @@ if (speech_button_prop) { if (!speech_button_) { speech_button_ = new views::ImageButton(this); - AddChildView(speech_button_); + content_container_->AddChildView(speech_button_); } if (view_delegate_->GetSpeechUI()->state() ==
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index f246d7d..b141da6 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -48,6 +48,11 @@ void ClearSearch(); void InvalidateMenu(); + // Returns the bounds to use for the view (including the shadow) given the + // desired bounds of the search box contents. + gfx::Rect GetViewBoundsForSearchBoxContentsBounds( + const gfx::Rect& rect) const; + views::ImageButton* back_button() { return back_button_; } views::Textfield* search_box() { return search_box_; } @@ -96,6 +101,7 @@ scoped_ptr<AppListMenuViews> menu_; + views::View* content_container_; // Owned by views hierarchy. views::ImageView* icon_view_; // Owned by views hierarchy. views::ImageButton* back_button_; // Owned by views hierarchy. views::ImageButton* speech_button_; // Owned by views hierarchy.
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index 6aec25b..01ea2d60 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -30,14 +30,13 @@ namespace { // Layout constants. -const int kTopMargin = 84; const int kInstantContainerSpacing = 11; const int kSearchBoxAndTilesSpacing = 40; const int kStartPageSearchBoxWidth = 480; // WebView constants. -const int kWebViewWidth = 500; -const int kWebViewHeight = 105; +const int kWebViewWidth = 700; +const int kWebViewHeight = 189; // Tile container constants. const size_t kNumStartPageTiles = 4; @@ -91,7 +90,7 @@ views::BoxLayout* instant_layout_manager = new views::BoxLayout( views::BoxLayout::kVertical, 0, 0, kInstantContainerSpacing); instant_layout_manager->set_inside_border_insets( - gfx::Insets(kTopMargin, 0, kSearchBoxAndTilesSpacing, 0)); + gfx::Insets(0, 0, kSearchBoxAndTilesSpacing, 0)); instant_layout_manager->set_main_axis_alignment( views::BoxLayout::MAIN_AXIS_ALIGNMENT_END); instant_layout_manager->set_cross_axis_alignment(
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index 78f12d03..edab4926 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -206,6 +206,10 @@ deps += [ "//ui/gfx/x" ] } + + if (use_ozone) { + sources += [ "test/ui_controls_factory_ozone.cc" ] + } } executable("demo") {
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index c5f3382..b16f5a50 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -531,6 +531,7 @@ } if (is_chromeos) { + deps += [ "//chromeos" ] sources -= [ "idle/idle_linux.cc" ] }
diff --git a/ui/base/cocoa/nsview_additions.h b/ui/base/cocoa/nsview_additions.h index 962d89b..a919b3b 100644 --- a/ui/base/cocoa/nsview_additions.h +++ b/ui/base/cocoa/nsview_additions.h
@@ -29,6 +29,9 @@ // Return best color for keyboard focus ring. - (NSColor*)cr_keyboardFocusIndicatorColor; +// Invoke |block| on this view and all descendants. +- (void)cr_recursivelyInvokeBlock:(void (^)(id view))block; + // Set needsDisplay for this view and all descendants. - (void)cr_recursivelySetNeedsDisplay:(BOOL)flag;
diff --git a/ui/base/cocoa/nsview_additions.mm b/ui/base/cocoa/nsview_additions.mm index fc24039..f111b14 100644 --- a/ui/base/cocoa/nsview_additions.mm +++ b/ui/base/cocoa/nsview_additions.mm
@@ -60,6 +60,12 @@ colorWithAlphaComponent:0.5 / [self cr_lineWidth]]; } +- (void)cr_recursivelyInvokeBlock:(void (^)(id view))block { + block(self); + for (NSView* subview in [self subviews]) + [subview cr_recursivelyInvokeBlock:block]; +} + - (void)cr_recursivelySetNeedsDisplay:(BOOL)flag { [self setNeedsDisplay:YES]; for (NSView* child in [self subviews])
diff --git a/ui/base/ui_base_unittests.isolate b/ui/base/ui_base_unittests.isolate index 16f6dd5f..7bc59c4 100644 --- a/ui/base/ui_base_unittests.isolate +++ b/ui/base/ui_base_unittests.isolate
@@ -31,6 +31,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../../testing/xvfb.py', @@ -69,6 +71,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ui/chromeos/BUILD.gn b/ui/chromeos/BUILD.gn index ea2fc20..7cd2171 100644 --- a/ui/chromeos/BUILD.gn +++ b/ui/chromeos/BUILD.gn
@@ -6,6 +6,8 @@ component("ui_chromeos") { sources = [ + "accelerometer/accelerometer_util.cc", + "accelerometer/accelerometer_util.h", "accessibility_types.h", "ime/candidate_view.cc", "ime/candidate_view.h",
diff --git a/ui/chromeos/accelerometer/accelerometer_util.cc b/ui/chromeos/accelerometer/accelerometer_util.cc new file mode 100644 index 0000000..9368b81 --- /dev/null +++ b/ui/chromeos/accelerometer/accelerometer_util.cc
@@ -0,0 +1,38 @@ +// 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/chromeos/accelerometer/accelerometer_util.h" + +#include <cmath> + +#include "chromeos/accelerometer/accelerometer_types.h" +#include "ui/gfx/geometry/vector3d_f.h" + +namespace { + +// The maximum deviation from the acceleration expected due to gravity for which +// the device will be considered stable: 1g. +const float kDeviationFromGravityThreshold = 1.0f; + +// The mean acceleration due to gravity on Earth in m/s^2. +const float kMeanGravity = 9.80665f; + +} // namespace + +namespace ui { + +const gfx::Vector3dF ConvertAccelerometerReadingToVector3dF( + const chromeos::AccelerometerReading& reading) { + return gfx::Vector3dF(reading.x, reading.y, reading.z); +} + +bool IsAccelerometerReadingStable(const chromeos::AccelerometerUpdate& update, + chromeos::AccelerometerSource source) { + return update.has(source) && + std::abs(ConvertAccelerometerReadingToVector3dF(update.get(source)) + .Length() - + kMeanGravity) <= kDeviationFromGravityThreshold; +} + +} // namespace ui
diff --git a/ui/chromeos/accelerometer/accelerometer_util.h b/ui/chromeos/accelerometer/accelerometer_util.h new file mode 100644 index 0000000..974fceb --- /dev/null +++ b/ui/chromeos/accelerometer/accelerometer_util.h
@@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_CHROMEOS_ACCELEROMETER_ACCELEROMETER_UTIL_H_ +#define UI_CHROMEOS_ACCELEROMETER_ACCELEROMETER_UTIL_H_ + +#include "chromeos/accelerometer/accelerometer_types.h" +#include "ui/chromeos/ui_chromeos_export.h" +#include "ui/gfx/geometry/vector3d_f.h" + +namespace ui { + +// Converts the acceleration data in |reading| into a gfx::Vector3dF. +UI_CHROMEOS_EXPORT const gfx::Vector3dF ConvertAccelerometerReadingToVector3dF( + const chromeos::AccelerometerReading& reading); + +// A reading is considered stable if its deviation from gravity is small. This +// returns false if the deviation is too high, or if |source| is not present +// in the update. +UI_CHROMEOS_EXPORT bool IsAccelerometerReadingStable( + const chromeos::AccelerometerUpdate& update, + chromeos::AccelerometerSource source); + +} // namespace ui + +#endif // UI_CHROMEOS_ACCELEROMETER_ACCELEROMETER_UTIL_H_
diff --git a/ui/chromeos/ui_chromeos.gyp b/ui/chromeos/ui_chromeos.gyp index 943f9d8a..7c5fcba 100644 --- a/ui/chromeos/ui_chromeos.gyp +++ b/ui/chromeos/ui_chromeos.gyp
@@ -66,6 +66,8 @@ 'UI_CHROMEOS_IMPLEMENTATION', ], 'sources': [ + 'accelerometer/accelerometer_util.cc', + 'accelerometer/accelerometer_util.h', 'accessibility_types.h', 'ime/candidate_view.cc', 'ime/candidate_view.h',
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index ded29924..ec36a0a 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -240,7 +240,7 @@ void OnSwapBuffersAborted(); // LayerTreeHostClient implementation. - void WillBeginMainFrame(int frame_id) override {} + void WillBeginMainFrame() override {} void DidBeginMainFrame() override {} void BeginMainFrame(const cc::BeginFrameArgs& args) override; void Layout() override;
diff --git a/ui/display/chromeos/display_configurator.cc b/ui/display/chromeos/display_configurator.cc index e6a379c1..bcfc46a 100644 --- a/ui/display/chromeos/display_configurator.cc +++ b/ui/display/chromeos/display_configurator.cc
@@ -456,6 +456,7 @@ force_configure_(false), next_display_protection_client_id_(1), display_externally_controlled_(false), + displays_suspended_(false), layout_manager_(new DisplayLayoutManagerImpl(this)), weak_ptr_factory_(this) { } @@ -856,9 +857,13 @@ // racing with the HandleSuspendReadiness message. native_display_delegate_->SyncWithServer(); } + + displays_suspended_ = true; } void DisplayConfigurator::ResumeDisplays() { + displays_suspended_ = false; + configure_timer_.Start( FROM_HERE, base::TimeDelta::FromMilliseconds(kResumeDelayMs), @@ -875,6 +880,14 @@ } void DisplayConfigurator::RunPendingConfiguration() { + // Don't do anything if the displays are currently suspended. Instead we will + // probe and reconfigure the displays if necessary in ResumeDisplays(). + if (displays_suspended_) { + VLOG(1) << "Displays are currently suspended. Not attempting to " + << "reconfigure them."; + return; + } + // Configuration task is currently running. Do not start a second // configuration. if (configuration_task_)
diff --git a/ui/display/chromeos/display_configurator.h b/ui/display/chromeos/display_configurator.h index 62afdeeb..c77b96a 100644 --- a/ui/display/chromeos/display_configurator.h +++ b/ui/display/chromeos/display_configurator.h
@@ -414,6 +414,9 @@ // Display controlled by an external entity. bool display_externally_controlled_; + // Whether the displays are currently suspended. + bool displays_suspended_; + scoped_ptr<DisplayLayoutManager> layout_manager_; scoped_ptr<UpdateDisplayConfigurationTask> configuration_task_;
diff --git a/ui/display/chromeos/display_configurator_unittest.cc b/ui/display/chromeos/display_configurator_unittest.cc index 96257b62..86b1473 100644 --- a/ui/display/chromeos/display_configurator_unittest.cc +++ b/ui/display/chromeos/display_configurator_unittest.cc
@@ -965,6 +965,54 @@ log_->GetActionsAndClear()); } +TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { + InitWithSingleOutput(); + + // The DisplayConfigurator may occasionally receive OnConfigurationChanged() + // after the displays have been suspended. This event should be ignored since + // the DisplayConfigurator will force a probe and reconfiguration of displays + // at resume time. + configurator_.SuspendDisplays(); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); + + configurator_.OnConfigurationChanged(); + EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); + + configurator_.ResumeDisplays(); + EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), + GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); + + // If a configuration task is pending when the displays are suspended, that + // task should not run either. + configurator_.OnConfigurationChanged(); + configurator_.SuspendDisplays(); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); + + EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); + + configurator_.ResumeDisplays(); + EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); + EXPECT_EQ( + JoinActions( + kGrab, + GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(), + GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), + kForceDPMS, + kUngrab, + NULL), + log_->GetActionsAndClear()); +} + TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) { DisplayConfigurator::ContentProtectionClientId client1 = configurator_.RegisterContentProtectionClient();
diff --git a/ui/events/cocoa/events_mac.mm b/ui/events/cocoa/events_mac.mm index fcc8cc9a..d21184cc 100644 --- a/ui/events/cocoa/events_mac.mm +++ b/ui/events/cocoa/events_mac.mm
@@ -160,10 +160,6 @@ [event release]; } -void IncrementTouchIdRefCount(const base::NativeEvent& native_event) { - NOTIMPLEMENTED(); -} - void ClearTouchIdIfReleased(const base::NativeEvent& native_event) { NOTIMPLEMENTED(); }
diff --git a/ui/events/devices/device_data_manager.cc b/ui/events/devices/device_data_manager.cc index 0977395e..eb96c46 100644 --- a/ui/events/devices/device_data_manager.cc +++ b/ui/events/devices/device_data_manager.cc
@@ -149,6 +149,20 @@ OnKeyboardDeviceConfigurationChanged()); } +void DeviceDataManager::OnMouseDevicesUpdated( + const std::vector<InputDevice>& devices) { + FOR_EACH_OBSERVER(InputDeviceEventObserver, + observers_, + OnMouseDeviceConfigurationChanged()); +} + +void DeviceDataManager::OnTouchpadDevicesUpdated( + const std::vector<InputDevice>& devices) { + FOR_EACH_OBSERVER(InputDeviceEventObserver, + observers_, + OnTouchpadDeviceConfigurationChanged()); +} + void DeviceDataManager::AddObserver(InputDeviceEventObserver* observer) { observers_.AddObserver(observer); }
diff --git a/ui/events/devices/device_data_manager.h b/ui/events/devices/device_data_manager.h index 7d7a0094..4896ad86 100644 --- a/ui/events/devices/device_data_manager.h +++ b/ui/events/devices/device_data_manager.h
@@ -64,6 +64,10 @@ const std::vector<TouchscreenDevice>& devices) override; void OnKeyboardDevicesUpdated( const std::vector<KeyboardDevice>& devices) override; + void OnMouseDevicesUpdated( + const std::vector<InputDevice>& devices) override; + void OnTouchpadDevicesUpdated( + const std::vector<InputDevice>& devices) override; private: static DeviceDataManager* instance_;
diff --git a/ui/events/devices/device_hotplug_event_observer.h b/ui/events/devices/device_hotplug_event_observer.h index 7219c5e..5bf5892 100644 --- a/ui/events/devices/device_hotplug_event_observer.h +++ b/ui/events/devices/device_hotplug_event_observer.h
@@ -11,6 +11,7 @@ namespace ui { +struct InputDevice; struct KeyboardDevice; struct TouchscreenDevice; @@ -20,14 +21,24 @@ virtual ~DeviceHotplugEventObserver() {} // On a hotplug event this is called with the list of available touchscreen - // devices. The set of touchscreen devices may not necessarily have changed. + // devices. The set of touchscreen devices may not have changed. virtual void OnTouchscreenDevicesUpdated( const std::vector<TouchscreenDevice>& devices) = 0; // On a hotplug event this is called with the list of available keyboard - // devices. The set of keyboard devices may not necessarily have changed. + // devices. The set of keyboard devices may not have changed. virtual void OnKeyboardDevicesUpdated( const std::vector<KeyboardDevice>& devices) = 0; + + // On a hotplug event this is called with the list of available mice. The set + // of mice may not have changed. + virtual void OnMouseDevicesUpdated( + const std::vector<InputDevice>& devices) = 0; + + // On a hotplug event this is called with the list of available touchpads. The + // set of touchpads may not have changed. + virtual void OnTouchpadDevicesUpdated( + const std::vector<InputDevice>& devices) = 0; }; } // namespace ui
diff --git a/ui/events/devices/input_device_event_observer.h b/ui/events/devices/input_device_event_observer.h index 6cee8e8..707fea2 100644 --- a/ui/events/devices/input_device_event_observer.h +++ b/ui/events/devices/input_device_event_observer.h
@@ -16,6 +16,8 @@ virtual void OnKeyboardDeviceConfigurationChanged() = 0; virtual void OnTouchscreenDeviceConfigurationChanged() = 0; + virtual void OnMouseDeviceConfigurationChanged() = 0; + virtual void OnTouchpadDeviceConfigurationChanged() = 0; }; } // namespace ui
diff --git a/ui/events/devices/x11/device_data_manager_x11.cc b/ui/events/devices/x11/device_data_manager_x11.cc index 68fdb2c..85c697a 100644 --- a/ui/events/devices/x11/device_data_manager_x11.cc +++ b/ui/events/devices/x11/device_data_manager_x11.cc
@@ -202,6 +202,7 @@ void DeviceDataManagerX11::UpdateDeviceList(Display* display) { cmt_devices_.reset(); touchpads_.reset(); + master_pointers_.clear(); for (int i = 0; i < kMaxDeviceNum; ++i) { valuator_count_[i] = 0; valuator_lookup_[i].clear(); @@ -233,6 +234,9 @@ for (int i = 0; i < info_list.count; ++i) { XIDeviceInfo* info = info_list.devices + i; + if (info->use == XIMasterPointer) + master_pointers_.push_back(info->deviceid); + // We currently handle only slave, non-keyboard devices if (info->use != XISlavePointer && info->use != XIFloatingSlave) continue;
diff --git a/ui/events/devices/x11/device_data_manager_x11.h b/ui/events/devices/x11/device_data_manager_x11.h index ec580cbd..bb5fa15 100644 --- a/ui/events/devices/x11/device_data_manager_x11.h +++ b/ui/events/devices/x11/device_data_manager_x11.h
@@ -239,6 +239,10 @@ // Returns true if |native_event| should be blocked. bool IsEventBlocked(const base::NativeEvent& native_event); + const std::vector<int>& master_pointers() const { + return master_pointers_; + } + protected: // DeviceHotplugEventObserver: void OnKeyboardDevicesUpdated( @@ -274,6 +278,9 @@ std::bitset<kMaxDeviceNum> cmt_devices_; std::bitset<kMaxDeviceNum> touchpads_; + // List of the master pointer devices. + std::vector<int> master_pointers_; + // A quick lookup table for determining if events from the XI device // should be blocked. std::bitset<kMaxDeviceNum> blocked_devices_;
diff --git a/ui/events/devices/x11/device_data_manager_x11_unittest.cc b/ui/events/devices/x11/device_data_manager_x11_unittest.cc index 22ae224..8149111 100644 --- a/ui/events/devices/x11/device_data_manager_x11_unittest.cc +++ b/ui/events/devices/x11/device_data_manager_x11_unittest.cc
@@ -39,6 +39,8 @@ void OnKeyboardDeviceConfigurationChanged() override { change_notified_ = true; } + void OnMouseDeviceConfigurationChanged() override {} + void OnTouchpadDeviceConfigurationChanged() override {} int change_notified() const { return change_notified_; } void Reset() { change_notified_ = false; }
diff --git a/ui/events/devices/x11/touch_factory_x11.cc b/ui/events/devices/x11/touch_factory_x11.cc index 1dce504..4201fa04 100644 --- a/ui/events/devices/x11/touch_factory_x11.cc +++ b/ui/events/devices/x11/touch_factory_x11.cc
@@ -201,6 +201,8 @@ XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_Motion); #if defined(OS_CHROMEOS) + // XGrabKey() must be replaced with XI2 keyboard grab if XI2 key events are + // enabled on desktop Linux. if (base::SysInfo::IsRunningOnChromeOS()) { XISetMask(mask, XI_KeyPress); XISetMask(mask, XI_KeyRelease); @@ -250,14 +252,8 @@ return id_generator_.GetGeneratedID(tracking_id); } -void TouchFactory::AcquireSlotForTrackingID(uint32 tracking_id) { - tracking_id_refcounts_[tracking_id]++; -} - void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) { - tracking_id_refcounts_[tracking_id]--; - if (tracking_id_refcounts_[tracking_id] == 0) - id_generator_.ReleaseNumber(tracking_id); + id_generator_.ReleaseNumber(tracking_id); } bool TouchFactory::IsTouchDevicePresent() { @@ -270,7 +266,6 @@ touch_events_disabled_ = false; touch_device_list_.clear(); touchscreen_ids_.clear(); - tracking_id_refcounts_.clear(); id_generator_.ResetForTest(); }
diff --git a/ui/events/devices/x11/touch_factory_x11.h b/ui/events/devices/x11/touch_factory_x11.h index cbec35f8..775b4966 100644 --- a/ui/events/devices/x11/touch_factory_x11.h +++ b/ui/events/devices/x11/touch_factory_x11.h
@@ -67,10 +67,6 @@ // isn't one already, allocates a new slot ID and sets up the mapping. int GetSlotForTrackingID(uint32 tracking_id); - // Increases the number of times |ReleaseSlotForTrackingID| needs to be called - // on a given tracking id before it will actually be released. - void AcquireSlotForTrackingID(uint32 tracking_id); - // Releases the slot ID mapping to tracking ID. void ReleaseSlotForTrackingID(uint32 tracking_id); @@ -130,10 +126,6 @@ // Touch screen <vid, pid>s. std::set<std::pair<int, int> > touchscreen_ids_; - // Maps from a tracking id to the number of times |ReleaseSlotForTrackingID| - // must be called before the tracking id is released. - std::map<uint32, int> tracking_id_refcounts_; - // Device ID of the virtual core keyboard. int virtual_core_keyboard_device_;
diff --git a/ui/events/event.cc b/ui/events/event.cc index d0966da..f8480e9 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc
@@ -526,19 +526,16 @@ radius_y_(GetTouchRadiusY(native_event)), rotation_angle_(GetTouchAngle(native_event)), force_(GetTouchForce(native_event)), - may_cause_scrolling_(false) { + may_cause_scrolling_(false), + should_remove_native_touch_id_mapping_(false) { latency()->AddLatencyNumberWithTimestamp( - INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, - 0, - 0, - base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()), - 1); - + INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, + base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()), 1); latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); - fixRotationAngle(); - if (type() == ET_TOUCH_PRESSED) - IncrementTouchIdRefCount(native_event); + FixRotationAngle(); + if (type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED) + should_remove_native_touch_id_mapping_ = true; } TouchEvent::TouchEvent(EventType type, @@ -552,7 +549,8 @@ radius_y_(0.0f), rotation_angle_(0.0f), force_(0.0f), - may_cause_scrolling_(false) { + may_cause_scrolling_(false), + should_remove_native_touch_id_mapping_(false) { latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); } @@ -572,17 +570,21 @@ radius_y_(radius_y), rotation_angle_(angle), force_(force), - may_cause_scrolling_(false) { + may_cause_scrolling_(false), + should_remove_native_touch_id_mapping_(false) { latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0); - fixRotationAngle(); + FixRotationAngle(); } TouchEvent::~TouchEvent() { // In ctor TouchEvent(native_event) we call GetTouchId() which in X11 // platform setups the tracking_id to slot mapping. So in dtor here, // if this touch event is a release event, we clear the mapping accordingly. - if (HasNativeEvent()) - ClearTouchIdIfReleased(native_event()); + if (should_remove_native_touch_id_mapping_) { + DCHECK(type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED); + if (type() == ET_TOUCH_RELEASED || type() == ET_TOUCH_CANCELLED) + ClearTouchIdIfReleased(native_event()); + } } void TouchEvent::UpdateForRootTransform( @@ -603,7 +605,7 @@ static_cast<EventResult>(result() | ER_DISABLE_SYNC_HANDLING)); } -void TouchEvent::fixRotationAngle() { +void TouchEvent::FixRotationAngle() { while (rotation_angle_ < 0) rotation_angle_ += 180; while (rotation_angle_ >= 180)
diff --git a/ui/events/event.h b/ui/events/event.h index e32e77c..4f585e9 100644 --- a/ui/events/event.h +++ b/ui/events/event.h
@@ -212,7 +212,7 @@ void StopPropagation(); bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); } - + // Marks the event as having been handled. A handled event does not reach the // next event phase. For example, if an event is handled during the pre-target // phase, then the event is dispatched to all pre-target handlers, but not to // the target or post-target handlers. @@ -225,9 +225,6 @@ Event(const base::NativeEvent& native_event, EventType type, int flags); Event(const Event& copy); void SetType(EventType type); - void set_delete_native_event(bool delete_native_event) { - delete_native_event_ = delete_native_event; - } void set_cancelable(bool cancelable) { cancelable_ = cancelable; } void set_time_stamp(const base::TimeDelta& time_stamp) { @@ -495,7 +492,8 @@ radius_y_(model.radius_y_), rotation_angle_(model.rotation_angle_), force_(model.force_), - may_cause_scrolling_(model.may_cause_scrolling_) {} + may_cause_scrolling_(model.may_cause_scrolling_), + should_remove_native_touch_id_mapping_(false) {} TouchEvent(EventType type, const gfx::PointF& location, @@ -532,6 +530,12 @@ void set_radius_x(const float r) { radius_x_ = r; } void set_radius_y(const float r) { radius_y_ = r; } + void set_should_remove_native_touch_id_mapping( + bool should_remove_native_touch_id_mapping) { + should_remove_native_touch_id_mapping_ = + should_remove_native_touch_id_mapping; + } + // Overridden from LocatedEvent. void UpdateForRootTransform( const gfx::Transform& inverted_root_transform) override; @@ -544,7 +548,7 @@ private: // Adjusts rotation_angle_ to within the acceptable range. - void fixRotationAngle(); + void FixRotationAngle(); // The identity (typically finger) of the touch starting at 0 and incrementing // for each separable additional touch that the hardware can detect. @@ -570,6 +574,12 @@ // touchmove that exceeds the platform slop region, or a touchend that // causes a fling). Defaults to false. bool may_cause_scrolling_; + + // True if this event should remove the mapping between the native + // event id and the touch_id_. This should only be the case for + // release and cancel events where the associated touch press event + // created a mapping between the native id and the touch_id_. + bool should_remove_native_touch_id_mapping_; }; // An interface that individual platforms can use to store additional data on
diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h index 2a0e699..1649bd7 100644 --- a/ui/events/event_utils.h +++ b/ui/events/event_utils.h
@@ -116,11 +116,6 @@ // Gets the touch id from a native event. EVENTS_EXPORT int GetTouchId(const base::NativeEvent& native_event); -// Increases the number of times |ClearTouchIdIfReleased| needs to be called on -// an event with a given touch id before it will actually be cleared. -EVENTS_EXPORT void IncrementTouchIdRefCount( - const base::NativeEvent& native_event); - // Clear the touch id from bookkeeping if it is a release/cancel event. EVENTS_EXPORT void ClearTouchIdIfReleased( const base::NativeEvent& native_event);
diff --git a/ui/events/events_stub.cc b/ui/events/events_stub.cc index 05b4b7f..a5a4fbd 100644 --- a/ui/events/events_stub.cc +++ b/ui/events/events_stub.cc
@@ -70,10 +70,6 @@ void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { } -void IncrementTouchIdRefCount(const base::NativeEvent& native_event) { - NOTIMPLEMENTED(); -} - void ClearTouchIdIfReleased(const base::NativeEvent& native_event) { NOTIMPLEMENTED(); }
diff --git a/ui/events/events_unittests.isolate b/ui/events/events_unittests.isolate index 024de78..c2418cbf 100644 --- a/ui/events/events_unittests.isolate +++ b/ui/events/events_unittests.isolate
@@ -21,6 +21,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../../testing/xvfb.py', @@ -58,6 +60,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ui/events/ozone/BUILD.gn b/ui/events/ozone/BUILD.gn index 8655ef4..3945e5d 100644 --- a/ui/events/ozone/BUILD.gn +++ b/ui/events/ozone/BUILD.gn
@@ -36,6 +36,8 @@ deps = [ "//base", "//base/third_party/dynamic_annotations", + "//ui/events", + "//ui/events:events_base", ] defines = [ "EVENTS_OZONE_IMPLEMENTATION" ] @@ -80,8 +82,8 @@ "evdev/input_controller_evdev.cc", "evdev/input_controller_evdev.h", "evdev/input_device_factory_evdev.cc", - "evdev/input_device_factory_evdev.cc", - "evdev/input_device_factory_evdev_proxy.h", + "evdev/input_device_factory_evdev.h", + "evdev/input_device_factory_evdev_proxy.cc", "evdev/input_device_factory_evdev_proxy.h", "evdev/input_injector_evdev.cc", "evdev/input_injector_evdev.h", @@ -103,7 +105,9 @@ ":events_ozone", ":events_ozone_layout", "//base", + "//ui/events", "//ui/events:dom4_keycode_converter", + "//ui/events:events_base", "//ui/events/devices", "//ui/events/platform", "//ui/gfx",
diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.cc b/ui/events/ozone/evdev/event_converter_evdev_impl.cc index 003da67..c401028 100644 --- a/ui/events/ozone/evdev/event_converter_evdev_impl.cc +++ b/ui/events/ozone/evdev/event_converter_evdev_impl.cc
@@ -96,6 +96,8 @@ ConvertMouseMoveEvent(input); break; case EV_SYN: + if (input.code == SYN_DROPPED) + LOG(WARNING) << "kernel dropped input events"; FlushEvents(); break; }
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc index ed201d3..11ede97 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.cc +++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -254,12 +254,16 @@ const std::vector<InputDevice>& devices) { // There's no list of mice in DeviceDataManager. input_controller_.set_has_mouse(devices.size() != 0); + DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); + observer->OnMouseDevicesUpdated(devices); } void EventFactoryEvdev::DispatchTouchpadDevicesUpdated( const std::vector<InputDevice>& devices) { // There's no list of touchpads in DeviceDataManager. input_controller_.set_has_touchpad(devices.size() != 0); + DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); + observer->OnTouchpadDevicesUpdated(devices); }
diff --git a/ui/events/ozone/evdev/event_thread_evdev.cc b/ui/events/ozone/evdev/event_thread_evdev.cc index 4666761..d6c5ffc 100644 --- a/ui/events/ozone/evdev/event_thread_evdev.cc +++ b/ui/events/ozone/evdev/event_thread_evdev.cc
@@ -6,10 +6,10 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/debug/trace_event.h" #include "base/logging.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread.h" +#include "base/trace_event/trace_event.h" #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h" #include "ui/events/ozone/evdev/input_device_factory_evdev.h" #include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index f215cd7..daaaa267 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -430,7 +430,7 @@ NotifyMouseDevicesUpdated(); if (converter.HasTouchpad()) - NotifyMouseDevicesUpdated(); + NotifyTouchpadDevicesUpdated(); } void InputDeviceFactoryEvdev::NotifyTouchscreensUpdated() {
diff --git a/ui/events/ozone/events_ozone.cc b/ui/events/ozone/events_ozone.cc index 932600d..d29f9da0 100644 --- a/ui/events/ozone/events_ozone.cc +++ b/ui/events/ozone/events_ozone.cc
@@ -86,9 +86,6 @@ void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { } -void IncrementTouchIdRefCount(const base::NativeEvent& event) { -} - void ClearTouchIdIfReleased(const base::NativeEvent& xev) { }
diff --git a/ui/events/ozone/events_ozone.gyp b/ui/events/ozone/events_ozone.gyp index 453379b..3094b75 100644 --- a/ui/events/ozone/events_ozone.gyp +++ b/ui/events/ozone/events_ozone.gyp
@@ -51,6 +51,8 @@ '../../ozone/ozone.gyp:ozone_base', '../devices/events_devices.gyp:events_devices', '../events.gyp:dom4_keycode_converter', + '../events.gyp:events', + '../events.gyp:events_base', '../platform/events_platform.gyp:events_platform', 'events_ozone', 'events_ozone_layout',
diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc index 78ecf35..6b54e58 100644 --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc
@@ -340,6 +340,8 @@ UiCallbacks callbacks; callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); + // TODO(pkotwicz): Compute the lists of mice and touchpads and send the new + // lists to DeviceHotplugEventObserver. // Parsing the device information may block, so delegate the operation to a // worker thread. Once the device information is extracted the parsed devices
diff --git a/ui/events/win/events_win.cc b/ui/events/win/events_win.cc index 98f4775..6960f46 100644 --- a/ui/events/win/events_win.cc +++ b/ui/events/win/events_win.cc
@@ -303,10 +303,6 @@ void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { } -void IncrementTouchIdRefCount(const base::NativeEvent& event) { - NOTIMPLEMENTED(); -} - void ClearTouchIdIfReleased(const base::NativeEvent& xev) { NOTIMPLEMENTED(); }
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc index 6678f01..6c83976 100644 --- a/ui/events/x/events_x.cc +++ b/ui/events/x/events_x.cc
@@ -739,18 +739,6 @@ delete event; } -void IncrementTouchIdRefCount(const base::NativeEvent& xev) { - ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance(); - double tracking_id; - if (!manager->GetEventData( - *xev, ui::DeviceDataManagerX11::DT_TOUCH_TRACKING_ID, &tracking_id)) { - return; - } - - ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); - factory->AcquireSlotForTrackingID(tracking_id); -} - void ClearTouchIdIfReleased(const base::NativeEvent& xev) { ui::EventType type = ui::EventTypeFromNative(xev); if (type == ui::ET_TOUCH_CANCELLED ||
diff --git a/ui/events/x/events_x_unittest.cc b/ui/events/x/events_x_unittest.cc index fb74424..554590a0 100644 --- a/ui/events/x/events_x_unittest.cc +++ b/ui/events/x/events_x_unittest.cc
@@ -300,54 +300,47 @@ return -1; } -TEST_F(EventsXTest, TouchEventIdRefcounting) { +TEST_F(EventsXTest, TouchEventNotRemovingFromNativeMapping) { std::vector<unsigned int> devices; devices.push_back(0); ui::SetUpTouchDevicesForTest(devices); std::vector<Valuator> valuators; - const int kTrackingId0 = 5; - const int kTrackingId1 = 7; + const int kTrackingId = 5; - // Increment ref count once for first touch. + // Two touch presses with the same tracking id. ui::ScopedXI2Event xpress0; xpress0.InitTouchEvent( - 0, XI_TouchBegin, kTrackingId0, gfx::Point(10, 10), valuators); + 0, XI_TouchBegin, kTrackingId, gfx::Point(10, 10), valuators); scoped_ptr<ui::TouchEvent> upress0(new ui::TouchEvent(xpress0)); - EXPECT_EQ(0, GetTouchIdForTrackingId(kTrackingId0)); + EXPECT_EQ(0, GetTouchIdForTrackingId(kTrackingId)); - // Increment ref count 4 times for second touch. ui::ScopedXI2Event xpress1; xpress1.InitTouchEvent( - 0, XI_TouchBegin, kTrackingId1, gfx::Point(20, 20), valuators); + 0, XI_TouchBegin, kTrackingId, gfx::Point(20, 20), valuators); + ui::TouchEvent upress1(xpress1); + EXPECT_EQ(0, GetTouchIdForTrackingId(kTrackingId)); - for (int i = 0; i < 4; ++i) { - ui::TouchEvent upress1(xpress1); - EXPECT_EQ(1, GetTouchIdForTrackingId(kTrackingId1)); - } - - ui::ScopedXI2Event xrelease1; - xrelease1.InitTouchEvent( - 0, XI_TouchEnd, kTrackingId1, gfx::Point(10, 10), valuators); - - // Decrement ref count 3 times for second touch. - for (int i = 0; i < 3; ++i) { - ui::TouchEvent urelease1(xrelease1); - EXPECT_EQ(1, GetTouchIdForTrackingId(kTrackingId1)); - } - - // This should clear the touch id of the second touch. - scoped_ptr<ui::TouchEvent> urelease1(new ui::TouchEvent(xrelease1)); - urelease1.reset(); - EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId1)); - - // This should clear the touch id of the first touch. + // The first touch release shouldn't clear the mapping from the + // tracking id. ui::ScopedXI2Event xrelease0; xrelease0.InitTouchEvent( - 0, XI_TouchEnd, kTrackingId0, gfx::Point(10, 10), valuators); - scoped_ptr<ui::TouchEvent> urelease0(new ui::TouchEvent(xrelease0)); - urelease0.reset(); - EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId0)); + 0, XI_TouchEnd, kTrackingId, gfx::Point(10, 10), valuators); + { + ui::TouchEvent urelease0(xrelease0); + urelease0.set_should_remove_native_touch_id_mapping(false); + } + EXPECT_EQ(0, GetTouchIdForTrackingId(kTrackingId)); + + // The second touch release should clear the mapping from the + // tracking id. + ui::ScopedXI2Event xrelease1; + xrelease1.InitTouchEvent( + 0, XI_TouchEnd, kTrackingId, gfx::Point(10, 10), valuators); + { + ui::TouchEvent urelease1(xrelease1); + } + EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId)); } TEST_F(EventsXTest, NumpadKeyEvents) {
diff --git a/ui/file_manager/file_manager/background/js/background.js b/ui/file_manager/file_manager/background/js/background.js index 6153ead..6f7c2e6 100644 --- a/ui/file_manager/file_manager/background/js/background.js +++ b/ui/file_manager/file_manager/background/js/background.js
@@ -326,17 +326,20 @@ * @type {Object} * @const */ -var FILE_MANAGER_WINDOW_CREATE_OPTIONS = Object.freeze({ - bounds: Object.freeze({ +var FILE_MANAGER_WINDOW_CREATE_OPTIONS = { + bounds: { left: Math.round(window.screen.availWidth * 0.1), top: Math.round(window.screen.availHeight * 0.1), width: Math.round(window.screen.availWidth * 0.8), height: Math.round(window.screen.availHeight * 0.8) - }), + }, + frame: { + color: '#1687d0' + }, minWidth: 480, minHeight: 300, hidden: true -}); +}; /** * @param {Object=} opt_appState App state.
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 d09cf7ba..2230324 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -85,6 +85,8 @@ './gear_menu_controller.js', './import_controller.js', './launch_param.js', + './metadata/content_metadata_provider.js', + './metadata/external_metadata_provider.js', './metadata/file_system_metadata_provider.js', './metadata/metadata_cache.js', './metadata/metadata_cache_item.js',
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 7f035d2..662c39f9 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
@@ -276,8 +276,11 @@ * @private */ CommandHandler.prototype.shouldIgnoreEvents_ = function() { - // Do not handle commands, when a dialog is shown. - if (this.fileManager_.document.querySelector('.cr-dialog-container.shown')) + // Do not handle commands, when a dialog is shown. Do not use querySelector + // as it's much slower, and this method is executed often. + var dialogs = this.fileManager_.document.getElementsByClassName( + 'cr-dialog-container'); + if (dialogs.length !== 0 && dialogs[0].classList.contains('shown')) return true; return false; // Do not ignore.
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js index 517f65b..ca75009 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader.js
@@ -86,7 +86,7 @@ this.endIndex_ = 0; /** - * Cursor begins from 0, and the origin in the list is beginIndex_. + * Cursor. * @type {number} * @private */ @@ -118,7 +118,7 @@ delete this.cache_[removedItem.toURL()]; } - this.cursor_ = 0; + this.cursor_ = this.beginIndex_; this.continue_(); } @@ -135,7 +135,7 @@ this.beginIndex_ = beginIndex; this.endIndex_ = endIndex; - this.cursor_ = 0; + this.cursor_ = this.beginIndex_; this.continue_(); } @@ -143,7 +143,7 @@ /** * Returns a thumbnail of an entry if it is in cache. * - * @return {!Object} If the thumbnail is not in cache, this returns null. + * @return {Object} If the thumbnail is not in cache, this returns null. */ ListThumbnailLoader.prototype.getThumbnailFromCache = function(entry) { return this.cache_[entry.toURL()] || null; @@ -160,10 +160,7 @@ return; } - var index = (this.beginIndex_ + this.cursor_) % this.dataModel_.length; - this.cursor_ += 1; - - var entry = /** @type {Entry} */ (this.dataModel_.item(index)); + var entry = /** @type {Entry} */ (this.dataModel_.item(this.cursor_++)); // If the entry is a directory, already in cache or fetching, skip it. if (entry.isDirectory ||
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html index d282aa9..ec8bb367 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.html
@@ -4,6 +4,7 @@ -- found in the LICENSE file. --> +<script src="../../../../webui/resources/js/assert.js"></script> <script src="../../../../webui/resources/js/cr.js"></script> <script src="../../../../webui/resources/js/cr/event_target.js"></script> <script src="../../../../webui/resources/js/cr/ui.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js index 5c288ce4..8392ab1 100644 --- a/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/list_thumbnail_loader_unittest.js
@@ -41,37 +41,50 @@ return canvas.toDataURL('image/jpeg', 0.5); } -/** - * Story test for list thumbnail loader. - */ -function testStory(callback) { +var listThumbnailLoader; +var getOneCallbacks; +var thumbnailLoadedEvents; +var fileListModel; +var fileSystem = new MockFileSystem('volume-id'); +var directory1 = new MockDirectoryEntry(fileSystem, '/TestDirectory'); +var entry1 = new MockEntry(fileSystem, '/Test1.jpg'); +var entry2 = new MockEntry(fileSystem, '/Test2.jpg'); +var entry3 = new MockEntry(fileSystem, '/Test3.jpg'); +var entry4 = new MockEntry(fileSystem, '/Test4.jpg'); +var entry5 = new MockEntry(fileSystem, '/Test5.jpg'); + +function setUp() { ListThumbnailLoader.NUM_OF_MAX_ACTIVE_TASKS = 2; MockThumbnailLoader.setTestImageDataUrl(generateSampleImageDataUrl(document)); - var getOneCallbacks = {}; + getOneCallbacks = {}; var metadataCache = { getOne: function(entry, type, callback) { getOneCallbacks[entry.toURL()] = callback; } }; - var fileListModel = new FileListModel(metadataCache); + fileListModel = new FileListModel(metadataCache); - var listThumbnailLoader = new ListThumbnailLoader(fileListModel, - metadataCache, document, MockThumbnailLoader); - var thumbnailLoadedEvents = []; + listThumbnailLoader = new ListThumbnailLoader(fileListModel, metadataCache, + document, MockThumbnailLoader); + + thumbnailLoadedEvents = []; listThumbnailLoader.addEventListener('thumbnailLoaded', function(event) { thumbnailLoadedEvents.push(event); }); +} - // Add 1 directory and 5 entries. - var fileSystem = new MockFileSystem('volume-id'); - var directory1 = new MockDirectoryEntry(fileSystem, '/TestDirectory'); - var entry1 = new MockEntry(fileSystem, '/Test1.jpg'); - var entry2 = new MockEntry(fileSystem, '/Test2.jpg'); - var entry3 = new MockEntry(fileSystem, '/Test3.jpg'); - var entry4 = new MockEntry(fileSystem, '/Test4.jpg'); - var entry5 = new MockEntry(fileSystem, '/Test5.jpg'); +function resolveGetOneCallback(url) { + assert(getOneCallbacks[url]); + getOneCallbacks[url](); + delete getOneCallbacks[url]; +} + +/** + * Story test for list thumbnail loader. + */ +function testStory(callback) { fileListModel.push(directory1, entry1, entry2, entry3, entry4, entry5); // Set high priority range to 0 - 2. @@ -91,9 +104,7 @@ assertArrayEquals([entry1.toURL(), entry2.toURL()], Object.keys(getOneCallbacks)); - // Resolve metadataCache.getOne for Test2.jpg. - getOneCallbacks[entry2.toURL()](); - delete getOneCallbacks[entry2.toURL()]; + resolveGetOneCallback(entry2.toURL()); reportPromise(waitUntil(function() { // Assert that thumbnailLoaded event is fired for Test2.jpg. @@ -123,9 +134,7 @@ // Set high priority range to 2 - 4. listThumbnailLoader.setHighPriorityRange(2, 4); - // Resolve metadataCache.getOne for Test1.jpg. - getOneCallbacks[entry1.toURL()](); - delete getOneCallbacks[entry1.toURL()]; + resolveGetOneCallback(entry1.toURL()); // Assert that task for (Test3.jpg) is enqueued. return waitUntil(function() { @@ -143,3 +152,18 @@ }); }), callback); } + +/** + * Do not enqueue prefetch task when high priority range is at the end of list. + */ +function testRangeIsAtTheEndOfList() { + // Set high priority range to 5 - 6. + listThumbnailLoader.setHighPriorityRange(5, 6); + + fileListModel.push(directory1, entry1, entry2, entry3, entry4, entry5); + + // Assert that a task is enqueued for entry5. + assertEquals(1, Object.keys(getOneCallbacks).length); + assertEquals('filesystem:volume-id/Test5.jpg', + Object.keys(getOneCallbacks)[0]); +}
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 new file mode 100644 index 0000000..c624065 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
@@ -0,0 +1,205 @@ +// 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. + +/** + * @typedef {{ + * thumbnailURL:(string|undefined), + * thumbnailTransform: (string|undefined) + * }} + */ +var ContentMetadata; + +/** + * @param {!MetadataProviderCache} cache + * @param {!MessagePort=} opt_messagePort Message port overriding the default + * worker port. + * @extends {NewMetadataProvider<!ContentMetadata>} + * @constructor + * @struct + */ +function ContentMetadataProvider(cache, opt_messagePort) { + NewMetadataProvider.call(this, cache, ['thumbnailURL', 'thumbnailTransform']); + + /** + * Pass all URLs to the metadata reader until we have a correct filter. + * @private {RegExp} + */ + this.urlFilter_ = /.*/; + + /** + * @private {!MessagePort} + * @const + */ + this.dispatcher_ = opt_messagePort ? + opt_messagePort : + new SharedWorker(ContentMetadataProvider.WORKER_SCRIPT).port; + this.dispatcher_.onmessage = this.onMessage_.bind(this); + this.dispatcher_.postMessage({verb: 'init'}); + this.dispatcher_.start(); + + /** + * Initialization is not complete until the Worker sends back the + * 'initialized' message. See below. + * @private {boolean} + */ + this.initialized_ = false; + + /** + * Map from Entry.toURL() to callback. + * Note that simultaneous requests for same url are handled in MetadataCache. + * @private {!Object<!string, !Array<function(Object)>>} + * @const + */ + this.callbacks_ = {}; +} + +/** + * Path of a worker script. + * @const {string} + */ +ContentMetadataProvider.WORKER_SCRIPT = + 'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' + + 'foreground/js/metadata/metadata_dispatcher.js'; + +/** + * Converts content metadata from parsers to the internal format. + * @param {Object} metadata The content metadata. + * @return {!ContentMetadata} Converted metadata. + */ +ContentMetadataProvider.convertContentMetadata = function(metadata) { + return { + thumbnailURL: metadata.thumbnailURL, + thumbnailTransform: metadata.thumbnailTransform + }; +}; + +ContentMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +/** + * @override + */ +ContentMetadataProvider.prototype.getImpl = function(requests) { + var promises = []; + for (var i = 0; i < requests.length; i++) { + promises.push(new Promise(function(request, fulfill, reject) { + this.fetch(request.entry, request.names, function(metadata) { + if (metadata) + fulfill(metadata); + else + reject(); + }); + }.bind(this, requests[i]))); + } + return Promise.all(promises); +}; + +/** + * Fetches the metadata. + * @param {Entry} entry File entry. + * @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. + */ +ContentMetadataProvider.prototype.fetch = function(entry, names, callback) { + if (entry.isDirectory) { + setTimeout(callback.bind(null, {}), 0); + return; + } + var url = entry.toURL(); + if (this.callbacks_[url]) { + this.callbacks_[url].push(callback); + } else { + this.callbacks_[url] = [callback]; + this.dispatcher_.postMessage({verb: 'request', arguments: [url]}); + } +}; + +/** + * Dispatch a message from a metadata reader to the appropriate on* method. + * @param {Object} event The event. + * @private + */ +ContentMetadataProvider.prototype.onMessage_ = function(event) { + var data = event.data; + switch (data.verb) { + case 'initialized': + this.onInitialized_(data.arguments[0]); + break; + case 'result': + this.onResult_(data.arguments[0], data.arguments[1]); + break; + case 'error': + this.onError_( + data.arguments[0], + data.arguments[1], + data.arguments[2], + data.arguments[3]); + break; + case 'log': + this.onLog_(data.arguments[0]); + break; + default: + assertNotReached(); + break; + } +}; + +/** + * Handles the 'initialized' message from the metadata reader Worker. + * @param {Object} regexp Regexp of supported urls. + * @private + */ +ContentMetadataProvider.prototype.onInitialized_ = function(regexp) { + this.urlFilter_ = regexp; + + // Tests can monitor for this state with + // ExtensionTestMessageListener listener("worker-initialized"); + // ASSERT_TRUE(listener.WaitUntilSatisfied()); + // Automated tests need to wait for this, otherwise we crash in + // browser_test cleanup because the worker process still has + // URL requests in-flight. + util.testSendMessage('worker-initialized'); + this.initialized_ = true; +}; + +/** + * Handles the 'result' message from the worker. + * @param {string} url File url. + * @param {Object} metadata The metadata. + * @private + */ +ContentMetadataProvider.prototype.onResult_ = function(url, metadata) { + var callbacks = this.callbacks_[url]; + delete this.callbacks_[url]; + for (var i = 0; i < callbacks.length; i++) { + callbacks[i]( + metadata ? + ContentMetadataProvider.convertContentMetadata(metadata) : null); + } +}; + +/** + * Handles the 'error' message from the worker. + * @param {string} url File entry. + * @param {string} step Step failed. + * @param {string} error Error description. + * @param {Object?} metadata The metadata, if available. + * @private + */ +ContentMetadataProvider.prototype.onError_ = + function(url, step, error, metadata) { + if (MetadataCache.log) // Avoid log spam by default. + console.warn('metadata: ' + url + ': ' + step + ': ' + error); + this.onResult_(url, null); +}; + +/** + * Handles the 'log' message from the worker. + * @param {Array.<*>} arglist Log arguments. + * @private + */ +ContentMetadataProvider.prototype.onLog_ = function(arglist) { + if (MetadataCache.log) // Avoid log spam by default. + console.log.apply(console, ['metadata:'].concat(arglist)); +};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.html new file mode 100644 index 0000000..8055430 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.html
@@ -0,0 +1,17 @@ +<!DOCTYPE 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. + --> +<!-- Base classes --> +<script src="metadata_cache_set.js"></script> +<script src="new_metadata_provider.js"></script> + +<!-- Others --> +<script src="../../../../../../ui/webui/resources/js/assert.js"></script> +<script src="../../../common/js/lru_cache.js"></script> +<script src="../../../common/js/unittest_util.js"></script> +<script src="metadata_cache_item.js"></script> +<script src="content_metadata_provider.js"></script> + +<script src="content_metadata_provider_unittest.js"></script>
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 new file mode 100644 index 0000000..06c9b3f --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js
@@ -0,0 +1,48 @@ +// 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"; } +}; + +function testExternalMetadataProviderBasic(callback) { + // Mocking SharedWorker's port. + var port = { + postMessage: function(message) { + if (message.verb === 'request') { + this.onmessage({ + data: { + verb: 'result', + arguments: [ + message.arguments[0], + { + thumbnailURL: message.arguments[0] + ',url', + thumbnailTransform: message.arguments[0] + ',transform' + } + ] + } + }); + } + }, + start: function() {} + }; + var cache = new MetadataProviderCache(); + var provider = new ContentMetadataProvider(cache, port); + reportPromise(provider.get( + [entryA, entryB], + ['thumbnailURL', 'thumbnailTransform']).then( + function(results) { + assertEquals(2, results.length); + assertEquals('filesystem://A,url', results[0].thumbnailURL); + assertEquals( + 'filesystem://A,transform', results[0].thumbnailTransform); + assertEquals('filesystem://B,url', results[1].thumbnailURL); + assertEquals( + 'filesystem://B,transform', results[1].thumbnailTransform); + }), 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 new file mode 100644 index 0000000..f2473b5 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider.js
@@ -0,0 +1,111 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @typedef {{ + * size: number, + * shared: (boolean|undefined), + * modificationTime: Date, + * thumbnailUrl: (string|undefined), + * externalFileUrl: (string|undefined), + * imageWidth: (number|undefined), + * imageHeight: (number|undefined), + * imageRotation: (number|undefined), + * pinned: (boolean|undefined), + * present: (boolean|undefined), + * hosted: (boolean|undefined), + * dirty: (boolean|undefined), + * availableOffline: (boolean|undefined), + * availableWhenMetered: (boolean|undefined), + * customIconUrl: string, + * contentMimeType: string, + * sharedWithMe: (boolean|undefined) + * }} + */ +var ExternalMetadata; + +/** + * Metadata provider for FileEntry#getMetadata. + * + * @param {!MetadataProviderCache} cache + * @constructor + * @extends {NewMetadataProvider<!ExternalMetadata>} + * @struct + */ +function ExternalMetadataProvider(cache) { + NewMetadataProvider.call(this, cache, [ + 'availableOffline', + 'availableWhenMetered', + 'contentMimeType', + 'customIconUrl', + 'dirty', + 'externalFileUrl', + 'hosted', + 'imageHeight', + 'imageRotation', + 'imageWidth', + 'modificationTime', + 'pinned', + 'present', + 'shared', + 'sharedWithMe', + 'size', + 'thumbnailUrl' + ]); +} + +ExternalMetadataProvider.prototype.__proto__ = NewMetadataProvider.prototype; + +/** + * @override + */ +ExternalMetadataProvider.prototype.getImpl = function(requests) { + return new Promise(function(fulfill, reject) { + var urls = []; + for (var i = 0; i < requests.length; i++) { + urls.push(requests[i].entry.toURL()); + } + chrome.fileManagerPrivate.getEntryProperties( + urls, + function(results) { + if (!chrome.runtime.lastError) + fulfill(this.convertResults_(requests, results)); + else + reject(chrome.runtime.lastError); + }.bind(this)); + }.bind(this)); +}; + +/** + * @param {!Array<!MetadataRequest>} requests + * @param {!Array<!EntryProperties>} propertiesList + * @return {!Array<!ExternalMetadata>} + */ +ExternalMetadataProvider.prototype.convertResults_ = + function(requests, propertiesList) { + var results = []; + for (var i = 0; i < propertiesList.length; i++) { + var properties = propertiesList[i]; + results.push({ + availableOffline: properties.isAvailableOffline, + availableWhenMetered: properties.isAvailableWhenMetered, + contentMimeType: properties.contentMimeType || '', + customIconUrl: properties.customIconUrl || '', + dirty: properties.isDirty, + externalFileUrl: properties.externalFileUrl, + hosted: properties.isHosted, + imageHeight: properties.imageHeight, + imageRotation: properties.imageRotation, + imageWidth: properties.imageWidth, + modificationTime: new Date(properties.lastModifiedTime), + pinned: properties.isPinned, + present: properties.isPresent, + shared: properties.shared, + sharedWithMe: properties.sharedWithMe, + size: requests[i].entry.isFile ? (properties.fileSize || 0) : -1, + thumbnailUrl: properties.thumbnailUrl + }); + } + return results; +};
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.html new file mode 100644 index 0000000..c03656c --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.html
@@ -0,0 +1,17 @@ +<!DOCTYPE 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. + --> +<!-- Base classes --> +<script src="metadata_cache_set.js"></script> +<script src="new_metadata_provider.js"></script> + +<!-- Others --> +<script src="../../../../../../ui/webui/resources/js/assert.js"></script> +<script src="../../../common/js/lru_cache.js"></script> +<script src="../../../common/js/unittest_util.js"></script> +<script src="metadata_cache_item.js"></script> +<script src="external_metadata_provider.js"></script> + +<script src="external_metadata_provider_unittest.js"></script>
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 new file mode 100644 index 0000000..2cb8e7a --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/external_metadata_provider_unittest.js
@@ -0,0 +1,49 @@ +// 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"; }, + isFile: true +}; + +var entryB = { + toURL: function() { return "filesystem://B"; }, + isFile: true +}; + +function testExternalMetadataProviderBasic(callback) { + // Mocking chrome API. + window.chrome = { + fileManagerPrivate: { + getEntryProperties: function(urls, callback) { + assertEquals('filesystem://A', urls[0]); + assertEquals('filesystem://B', urls[1]); + callback([{ + lastModifiedTime: new Date(2015, 0, 1).getTime(), + fileSize: 1024 + }, { + lastModifiedTime: new Date(2015, 1, 2).getTime(), + fileSize: 2048 + }]); + } + }, + 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); +}
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js index 0580e1d..83d3b39 100644 --- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js +++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
@@ -54,7 +54,7 @@ case ThumbnailLoader.LoadTarget.CONTENT_METADATA: if (opt_metadata.thumbnail && opt_metadata.thumbnail.url) { this.thumbnailUrl_ = opt_metadata.thumbnail.url; - this.thumbnailTransform = + this.transform_ = opt_metadata.thumbnail && opt_metadata.thumbnail.transform; this.loadTarget_ = ThumbnailLoader.LoadTarget.CONTENT_METADATA; } @@ -241,6 +241,101 @@ }; /** + * Loads thumbnail as data url. If data url of thumbnail can be fetched from + * metadata, this fetches it from it. Otherwise, this tries to load it from + * thumbnail loader. + * Compared with ThumbnailLoader.load, this method does not provide a + * functionality to fit image to a box. This method is responsible for rotating + * and flipping a thumbnail. + * + * @return {!Promise<{data:string, width:number, height:number}>} A promise + * which is resolved when data url is fetched. + */ +ThumbnailLoader.prototype.loadAsDataUrl = function() { + return new Promise(function(resolve) { + // Load by using ImageLoaderClient. + var modificationTime = this.metadata_ && + this.metadata_.filesystem && + this.metadata_.filesystem.modificationTime && + this.metadata_.filesystem.modificationTime.getTime(); + ImageLoaderClient.getInstance().load( + this.thumbnailUrl_, + resolve, + { + maxWidth: ThumbnailLoader.THUMBNAIL_MAX_WIDTH, + maxHeight: ThumbnailLoader.THUMBNAIL_MAX_HEIGHT, + cache: true, + priority: this.priority_, + timestamp: modificationTime + }); + }.bind(this)).then(function(result) { + if (!this.transform_) + return result; + else + return this.applyTransformToDataUrl_( + this.transform_, result.data, result.width, result.height); + }.bind(this)); +}; + +/** + * Applies transform to data url. + * + * @param {{scaleX:number, scaleY:number, rotate90: number}} transform + * Transform. + * @param {string} dataUrl Data url. + * @param {number} width Width. + * @param {number} height Height. + * @return {!Promise<{data:string, width:number, height:number}>} A promise + * which is resolved with dataUrl and its width and height. + * @private + */ +ThumbnailLoader.prototype.applyTransformToDataUrl_ = function( + transform, dataUrl, width, height) { + var image = new Image(); + var scaleX = this.transform_.scaleX; + var scaleY = this.transform_.scaleY; + var rotate90 = this.transform_.rotate90; + + assert(scaleX === 1 || scaleX === -1); + assert(scaleY === 1 || scaleY === -1); + assert(rotate90 === 0 || rotate90 === 1); + + return new Promise(function(resolve, reject) { + // Decode image for transformation. + image.onload = resolve; + image.onerror = reject; + image.src = dataUrl; + }).then(function() { + // Apply transform. Scale transformation should be applied before rotate + // transformation. i.e. When matrices for scale and rotate are A and B, + // transformation matrix should be BA. + var canvas = document.createElement('canvas'); + var context = canvas.getContext('2d'); + + canvas.width = rotate90 === 1 ? height : width; + canvas.height = rotate90 === 1 ? width : height; + + // Rotate 90 degree at center. + if (rotate90 === 1) { + context.translate(height, 0); + context.rotate(Math.PI / 2); + } + + // Flip X and Y. + context.translate(scaleX === -1 ? width : 0, scaleY === -1 ? height : 0); + context.scale(scaleX, scaleY); + + context.drawImage(image, 0, 0); + + return { + data: canvas.toDataURL('image/png'), + width: canvas.width, + height: canvas.height + }; + }.bind(this)); +} + +/** * Cancels loading the current image. */ ThumbnailLoader.prototype.cancel = function() {
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.html b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.html index 76374c6..a8e2aec 100644 --- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.html
@@ -3,7 +3,10 @@ -- Use of this source code is governed by a BSD-style license that can be -- found in the LICENSE file. --> +<script src="../../../../webui/resources/js/assert.js"></script> <script src="../../common/js/file_type.js"></script> <script src="../../common/js/mock_entry.js"></script> +<script src="../../common/js/unittest_util.js"></script> +<script src="../../../image_loader/image_loader_client.js"></script> <script src="thumbnail_loader.js"></script> <script src="thumbnail_loader_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js index b306b66..e9f0d04c 100644 --- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader_unittest.js
@@ -6,6 +6,26 @@ return new ThumbnailLoader(entry, null, metadata).getLoadTarget(); } +/** + * Generates a data url of a sample image for testing. + * + * @param {number} width Width. + * @param {number} height Height. + * @return {string} Data url of a sample image. + */ +function generateSampleImageDataUrl(width, height) { + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + + var context = canvas.getContext('2d'); + context.fillStyle = 'black'; + context.fillRect(0, 0, width / 2, height / 2); + context.fillRect(width / 2, height / 2, width / 2, height / 2); + + return canvas.toDataURL('image/png'); +} + function testShouldUseMetadataThumbnail() { var mockFileSystem = new MockFileSystem('volumeId'); var imageEntry = new MockEntry(mockFileSystem, '/test.jpg'); @@ -33,3 +53,108 @@ getLoadTarget( pdfEntry, {external: {thumbnailUrl: 'url', dirty: true}})); } + +function testLoadAsDataUrlFromImageClient(callback) { + ImageLoaderClient.getInstance = function() { + return { + load: function(url, callback, opt_option) { + callback({ + status: 'success', data: 'imageDataUrl', width: 32, height: 32}); + } + }; + }; + + var fileSystem = new MockFileSystem('volume-id'); + var entry = new MockEntry(fileSystem, '/Test1.jpg'); + var thumbnailLoader = new ThumbnailLoader(entry); + reportPromise(thumbnailLoader.loadAsDataUrl().then(function(result) { + assertEquals('imageDataUrl', result.data); + }), callback); +} + +function testLoadAsDataUrlFromExifThumbnail(callback) { + ImageLoaderClient.getInstance = function() { + return { + load: function(url, callback, opt_option) { + // Assert that data url is passed. + assertTrue(/^data:/i.test(url)); + callback({status: 'success', data: url, width: 32, height: 32}); + } + }; + }; + + var metadata = { + thumbnail: { + url: generateSampleImageDataUrl(32, 32) + } + }; + + var fileSystem = new MockFileSystem('volume-id'); + var entry = new MockEntry(fileSystem, '/Test1.jpg'); + var thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata); + reportPromise(thumbnailLoader.loadAsDataUrl().then(function(result) { + assertEquals(metadata.thumbnail.url, result.data); + }), callback); +} + +function testLoadAsDataUrlFromExifThumbnailRotate(callback) { + ImageLoaderClient.getInstance = function() { + return { + load: function(url, callback, opt_option) { + // Assert that data url is passed. + assertTrue(/^data:/i.test(url)); + callback({status: 'success', data: url, width: 64, height: 32}); + } + }; + }; + + var metadata = { + thumbnail: { + url: generateSampleImageDataUrl(64, 32), + transform: { + rotate90: 1, + scaleX: 1, + scaleY: -1, + } + } + }; + + var fileSystem = new MockFileSystem('volume-id'); + var entry = new MockEntry(fileSystem, '/Test1.jpg'); + var thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata); + reportPromise(thumbnailLoader.loadAsDataUrl().then(function(result) { + assertEquals(32, result.width); + assertEquals(64, result.height); + // For test image, transformed image should become equal to the following + // generated sample image. + assertEquals(generateSampleImageDataUrl(32, 64), result.data); + }), callback); +} + +function testLoadAsDataUrlFromExternal(callback) { + var externalThumbnailUrl = 'https://external-thumbnail-url/'; + var externalThumbnailDataUrl = generateSampleImageDataUrl(32, 32); + + ImageLoaderClient.getInstance = function() { + return { + load: function(url, callback, opt_option) { + assertEquals(externalThumbnailUrl, url); + callback({status: 'success', data: externalThumbnailDataUrl, + width: 32, height: 32}); + } + }; + }; + + var metadata = { + external: { + thumbnailUrl: externalThumbnailUrl + } + } + + var fileSystem = new MockFileSystem('volume-id'); + var entry = new MockEntry(fileSystem, '/Test1.jpg'); + var thumbnailLoader = new ThumbnailLoader(entry, undefined, metadata); + reportPromise(thumbnailLoader.loadAsDataUrl().then(function(result) { + assertEquals(externalThumbnailDataUrl, result.data); + }), callback); +}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js index 36a95dc..34515b2 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js +++ b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
@@ -71,7 +71,9 @@ DialogFooter.prototype = { /** - * @return {number} Selected filter index. + * @return {number} Selected filter index. The index is 1 based and 0 means + * 'any file types'. Keep the meaniing consistent with the index passed to + * chrome.fileManagerPrivate.selectFile. */ get selectedFilterIndex() { return ~~this.fileTypeSelector.value; @@ -129,13 +131,6 @@ */ DialogFooter.prototype.initFileTypeFilter = function( fileTypes, includeAllFiles) { - if (includeAllFiles) { - var option = document.createElement('option'); - option.innerText = str('ALL_FILES_FILTER'); - option.value = 0; - this.fileTypeSelector.appendChild(option); - } - for (var i = 0; i < fileTypes.length; i++) { var fileType = fileTypes[i]; var option = document.createElement('option'); @@ -171,6 +166,13 @@ this.fileTypeSelector.appendChild(option); } + if (includeAllFiles) { + var option = document.createElement('option'); + option.innerText = str('ALL_FILES_FILTER'); + option.value = 0; + this.fileTypeSelector.appendChild(option); + } + var options = this.fileTypeSelector.querySelectorAll('option'); if (options.length >= 2) { // There is in fact no choice, show the selector.
diff --git a/ui/file_manager/integration_tests/file_manager/tasks.js b/ui/file_manager/integration_tests/file_manager/tasks.js index 9e444f2..4e081ed 100644 --- a/ui/file_manager/integration_tests/file_manager/tasks.js +++ b/ui/file_manager/integration_tests/file_manager/tasks.js
@@ -178,8 +178,8 @@ // Wait for the dialog hidden, and the task is executed. var dialogHiddenPromise = itemClickedPromise.then(function() { - return remoteCall.waitForElement.bind( - remoteCall, windowId, '#default-action-dialog', null); + return remoteCall.waitForElementLost( + windowId, '#default-action-dialog', null); }); // Execute the new default task.
diff --git a/ui/gfx/screen.h b/ui/gfx/screen.h index 65d78fe..28652746 100644 --- a/ui/gfx/screen.h +++ b/ui/gfx/screen.h
@@ -76,7 +76,7 @@ // return the primary display. virtual gfx::Display GetDisplayNearestWindow(NativeView view) const = 0; - // Returns the display nearest the specified point. + // Returns the display nearest the specified point. |point| should be in DIPs. virtual gfx::Display GetDisplayNearestPoint( const gfx::Point& point) const = 0;
diff --git a/ui/gfx/screen_win.cc b/ui/gfx/screen_win.cc index d5ad22b..9210971 100644 --- a/ui/gfx/screen_win.cc +++ b/ui/gfx/screen_win.cc
@@ -136,7 +136,8 @@ } gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { - POINT initial_loc = { point.x(), point.y() }; + gfx::Point point_in_pixels = gfx::win::DIPToScreenPoint(point); + POINT initial_loc = { point_in_pixels.x(), point_in_pixels.y() }; HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST); MONITORINFOEX mi; ZeroMemory(&mi, sizeof(MONITORINFOEX));
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 5943bb6a..cd25b04 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -817,18 +817,6 @@ { 'return_type': 'void', 'names': ['glReleaseShaderCompiler'], 'arguments': 'void', }, -# Multisampling API is different in different GL versions, some require an -# explicit resolve step for renderbuffers and/or FBO texture attachments and -# some do not. Multiple alternatives might be present in a single -# implementation, which require different use of the API and may have -# different performance (explicit resolve performing worse, for example). -# So even though the function signature is the same across versions, we split -# their definitions so that the function to use can be chosen correctly at a -# higher level. -# TODO(oetuaho@nvidia.com): Some of these might still be possible to combine. -# This could also fix weirdness in the mock bindings that's caused by the same -# function name appearing multiple times. -# This is the ES3 function, which requires explicit resolve: { 'return_type': 'void', 'names': ['glRenderbufferStorageEXT', 'glRenderbufferStorage'], 'arguments': @@ -838,18 +826,11 @@ 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 'GLsizei width, GLsizei height', }, { 'return_type': 'void', - 'names': ['glRenderbufferStorageMultisampleANGLE', - 'glRenderbufferStorageMultisample'], + 'names': ['glRenderbufferStorageMultisampleANGLE'], 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 'GLsizei width, GLsizei height', }, -# In desktop GL, EXT and core versions both have an explicit resolve step, -# though desktop core GL implicitly resolves when drawing to a window. -# TODO(oetuaho@nvidia.com): Right now this function also doubles as ES2 EXT -# function, which has implicit resolve, and for which the fallback is wrong. -# Fix this. { 'return_type': 'void', - 'names': ['glRenderbufferStorageMultisampleEXT', - 'glRenderbufferStorageMultisample'], + 'names': ['glRenderbufferStorageMultisampleEXT'], 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 'GLsizei width, GLsizei height', }, { 'return_type': 'void',
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index 642190c..11383b1 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -1692,12 +1692,7 @@ } debug_fn.glRenderbufferStorageMultisampleANGLEFn = 0; - if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) { - fn.glRenderbufferStorageMultisampleANGLEFn = - reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>( - GetGLProcAddress("glRenderbufferStorageMultisample")); - DCHECK(fn.glRenderbufferStorageMultisampleANGLEFn); - } else if (ext.b_GL_ANGLE_framebuffer_multisample) { + if (ext.b_GL_ANGLE_framebuffer_multisample) { fn.glRenderbufferStorageMultisampleANGLEFn = reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>( GetGLProcAddress("glRenderbufferStorageMultisampleANGLE")); @@ -1705,13 +1700,8 @@ } debug_fn.glRenderbufferStorageMultisampleEXTFn = 0; - if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) { - fn.glRenderbufferStorageMultisampleEXTFn = - reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>( - GetGLProcAddress("glRenderbufferStorageMultisample")); - DCHECK(fn.glRenderbufferStorageMultisampleEXTFn); - } else if (ext.b_GL_EXT_multisampled_render_to_texture || - ext.b_GL_EXT_framebuffer_multisample) { + if (ext.b_GL_EXT_multisampled_render_to_texture || + ext.b_GL_EXT_framebuffer_multisample) { fn.glRenderbufferStorageMultisampleEXTFn = reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>( GetGLProcAddress("glRenderbufferStorageMultisampleEXT"));
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index 185d80964..8e84aa3 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -1829,8 +1829,8 @@ GLsizei width, GLsizei height) { MakeFunctionUnique("glRenderbufferStorageMultisample"); - interface_->RenderbufferStorageMultisampleEXT(target, samples, internalformat, - width, height); + interface_->RenderbufferStorageMultisample(target, samples, internalformat, + width, height); } void GL_BINDING_CALL
diff --git a/ui/keyboard/resources/keyboard_mojo.js b/ui/keyboard/resources/keyboard_mojo.js index 27190fa..13f02421c 100644 --- a/ui/keyboard/resources/keyboard_mojo.js +++ b/ui/keyboard/resources/keyboard_mojo.js
@@ -12,16 +12,19 @@ 'content/public/renderer/service_provider', ], function(connector, keyboard, serviceProvider) { 'use strict'; - function KeyboardImpl(kbd) { - console.log('Creating KeyboardImpl'); + function TextInputTypeObserverImpl(kbd) { + console.log('Creating TextInputTypeObserverImpl'); this.keyboard_ = kbd; mojo_api = this; + mojo_api.setTextInputTypeObserver( + connection.bindImpl(this, keyboard.TextInputTypeObserver)); } - KeyboardImpl.prototype = Object.create( + TextInputTypeObserverImpl.prototype = Object.create( keyboard.KeyboardAPI.stubClass.prototype); - KeyboardImpl.prototype.onTextInputTypeChanged = function(input_type) { + TextInputTypeObserverImpl.prototype.onTextInputTypeChanged = + function(input_type) { console.log('Text input changed: ' + input_type); input_focused_event.forEach(function(listener) { listener({type: input_type}); @@ -29,11 +32,10 @@ }; return function() { - connection = new connector.Connection( - serviceProvider.connectToService( - keyboard.KeyboardUIHandlerMojo.name), - KeyboardImpl, - keyboard.KeyboardUIHandlerMojo.proxyClass); + const KBDApi = keyboard.KeyboardUIHandlerMojo; + new TextInputObserverImpl(connection.bindHandleToProxy( + serviceProvider.connectToService(KBDApi.name), + KBDApi)); }; });
diff --git a/ui/keyboard/webui/keyboard.mojom b/ui/keyboard/webui/keyboard.mojom index 83e626b..889f75c 100644 --- a/ui/keyboard/webui/keyboard.mojom +++ b/ui/keyboard/webui/keyboard.mojom
@@ -1,5 +1,12 @@ -[Client=KeyboardAPI] +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module keyboard; + interface KeyboardUIHandlerMojo { + SetTextInputTypeObserver(TextInputTypeObserver observer); + SendKeyEvent(string? event_type, int32 char_value, int32 key_code, @@ -9,6 +16,6 @@ HideKeyboard(); }; -interface KeyboardAPI { +interface TextInputTypeObserver { OnTextInputTypeChanged(string? input_type); };
diff --git a/ui/keyboard/webui/vk_mojo_handler.cc b/ui/keyboard/webui/vk_mojo_handler.cc index 5efe763e..f40e9dbd 100644 --- a/ui/keyboard/webui/vk_mojo_handler.cc +++ b/ui/keyboard/webui/vk_mojo_handler.cc
@@ -29,6 +29,11 @@ return KeyboardController::GetInstance()->proxy()->GetInputMethod(); } +void VKMojoHandler::SetTextInputTypeObserver( + TextInputTypeObserverPtr observer) { + text_input_type_observer_ = observer.Pass(); +} + void VKMojoHandler::SendKeyEvent(const mojo::String& event_type, int32_t char_value, int32_t key_code, @@ -61,6 +66,9 @@ void VKMojoHandler::OnTextInputStateChanged( const ui::TextInputClient* text_client) { + if (!text_input_type_observer_) + return; + ui::TextInputType type = text_client ? text_client->GetTextInputType() : ui::TEXT_INPUT_TYPE_NONE; std::string type_name = "none"; @@ -106,7 +114,7 @@ type_name = "text"; break; } - binding_.client()->OnTextInputTypeChanged(type_name); + text_input_type_observer_->OnTextInputTypeChanged(type_name); } void VKMojoHandler::OnInputMethodDestroyed(
diff --git a/ui/keyboard/webui/vk_mojo_handler.h b/ui/keyboard/webui/vk_mojo_handler.h index 750120d..4afb1e1 100644 --- a/ui/keyboard/webui/vk_mojo_handler.h +++ b/ui/keyboard/webui/vk_mojo_handler.h
@@ -22,6 +22,7 @@ ui::InputMethod* GetInputMethod(); // KeyboardUIHandlerMojo: + void SetTextInputTypeObserver(TextInputTypeObserverPtr observer) override; void SendKeyEvent(const mojo::String& event_type, int32_t char_value, int32_t key_code, @@ -38,6 +39,7 @@ void OnInputMethodDestroyed(const ui::InputMethod* input_method) override; void OnShowImeIfNeeded() override; + TextInputTypeObserverPtr text_input_type_observer_; mojo::Binding<KeyboardUIHandlerMojo> binding_; DISALLOW_COPY_AND_ASSIGN(VKMojoHandler);
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js index 96f6e24..0f4a274c 100644 --- a/ui/login/account_picker/user_pod_row.js +++ b/ui/login/account_picker/user_pod_row.js
@@ -1033,9 +1033,9 @@ }, customizeUserPodPerUserType: function() { - if (this.user_.isChildUser && !this.user_.isDesktopUser) { + if (this.user_.childUser && !this.user_.isDesktopUser) { this.setUserPodIconType('child'); - } else if (this.user_.isSupervisedUser && !this.user_.isDesktopUser) { + } else if (this.user_.supervisedUser && !this.user_.isDesktopUser) { this.setUserPodIconType('supervised'); } else if (this.multiProfilesPolicyApplied) { // Mark user pod as not focusable which in addition to the grayed out @@ -1931,9 +1931,8 @@ this.nameElement.textContent = this.user.displayName; var isLockedUser = this.user.needsSignin; - var isSupervisedUser = this.user.supervisedUser; + var isLegacySupervisedUser = this.user.supervisedUser; var isChildUser = this.user.childUser; - var isLegacySupervisedUser = isSupervisedUser && !isChildUser; this.classList.toggle('locked', isLockedUser); this.classList.toggle('legacy-supervised', isLegacySupervisedUser); this.classList.toggle('child', isChildUser);
diff --git a/ui/message_center/message_center_unittests.isolate b/ui/message_center/message_center_unittests.isolate index 7ad8cc3c..74c1057b 100644 --- a/ui/message_center/message_center_unittests.isolate +++ b/ui/message_center/message_center_unittests.isolate
@@ -22,6 +22,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../../testing/xvfb.py', @@ -59,6 +61,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn index 09041824..6eedae3 100644 --- a/ui/ozone/BUILD.gn +++ b/ui/ozone/BUILD.gn
@@ -178,5 +178,6 @@ deps = [ "//base/test:test_support", "//testing/gtest", + "//ui/gfx/geometry", ] + ozone_platform_test_deps }
diff --git a/ui/ozone/demo/BUILD.gn b/ui/ozone/demo/BUILD.gn index 8e33185..fd9bfbb 100644 --- a/ui/ozone/demo/BUILD.gn +++ b/ui/ozone/demo/BUILD.gn
@@ -30,5 +30,6 @@ "//ui/gl", "//ui/ozone", "//ui/ozone/gpu", + "//ui/ozone:ozone_base", ] }
diff --git a/ui/ozone/gpu/BUILD.gn b/ui/ozone/gpu/BUILD.gn index 3906c43..b59bf374 100644 --- a/ui/ozone/gpu/BUILD.gn +++ b/ui/ozone/gpu/BUILD.gn
@@ -17,5 +17,6 @@ "//ui/gfx", "//ui/gfx/geometry", "//ui/gl", + "//ui/ozone:ozone_base", ] }
diff --git a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc index 263fdc34..9b463b9 100644 --- a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc +++ b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc
@@ -161,10 +161,19 @@ } pixmap = it->second.get(); } + return CreateImageForPixmap(pixmap, size, format, internalformat); +} + +scoped_refptr<gfx::GLImage> +GpuMemoryBufferFactoryOzoneNativeBuffer::CreateImageForPixmap( + scoped_refptr<NativePixmap> pixmap, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + unsigned internalformat) { if (pixmap->GetEGLClientBuffer()) { scoped_refptr<GLImageOzoneNativePixmap> image = new GLImageOzoneNativePixmap(size); - if (!image->Initialize(pixmap)) { + if (!image->Initialize(pixmap.get())) { return scoped_refptr<gfx::GLImage>(); } return image; @@ -172,7 +181,7 @@ if (pixmap->GetDmaBufFd() > 0) { scoped_refptr<GLImageOzoneNativePixmapDmaBuf> image = new GLImageOzoneNativePixmapDmaBuf(size, internalformat); - if (!image->Initialize(pixmap, format)) { + if (!image->Initialize(pixmap.get(), format)) { return scoped_refptr<gfx::GLImage>(); } return image;
diff --git a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h index bf98786..006a4a54 100644 --- a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h +++ b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h
@@ -13,6 +13,7 @@ #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/gpu/ozone_gpu_export.h" +#include "ui/ozone/public/native_pixmap.h" namespace gfx { class GLImage; @@ -48,6 +49,12 @@ unsigned internalformat, int client_id); + static scoped_refptr<gfx::GLImage> CreateImageForPixmap( + scoped_refptr<NativePixmap> pixmap, + const gfx::Size& size, + gfx::GpuMemoryBuffer::Format format, + unsigned internalformat); + private: BufferToPixmapMap native_pixmap_map_; base::Lock native_pixmap_map_lock_;
diff --git a/ui/ozone/gpu/ozone_gpu.gyp b/ui/ozone/gpu/ozone_gpu.gyp index 72bf156..cbc895d 100644 --- a/ui/ozone/gpu/ozone_gpu.gyp +++ b/ui/ozone/gpu/ozone_gpu.gyp
@@ -15,6 +15,7 @@ '../../gfx/gfx.gyp:gfx', '../../gfx/gfx.gyp:gfx_geometry', '../../gl/gl.gyp:gl', + '../ozone.gyp:ozone_base', ], 'defines': [ 'OZONE_GPU_IMPLEMENTATION',
diff --git a/ui/ozone/ozone.gyp b/ui/ozone/ozone.gyp index ce55e3f..4869a9e 100644 --- a/ui/ozone/ozone.gyp +++ b/ui/ozone/ozone.gyp
@@ -183,6 +183,7 @@ '../../base/base.gyp:base', '../../base/base.gyp:test_support_base', '../../testing/gtest.gyp:gtest', + '../gfx/gfx.gyp:gfx_geometry', '<@(external_ozone_platform_unittest_deps)', '<@(internal_ozone_platform_unittest_deps)', ],
diff --git a/ui/ozone/platform/caca/BUILD.gn b/ui/ozone/platform/caca/BUILD.gn index 3f0eb53..fd164f8 100644 --- a/ui/ozone/platform/caca/BUILD.gn +++ b/ui/ozone/platform/caca/BUILD.gn
@@ -22,6 +22,7 @@ "//base", "//skia", "//ui/events/ozone:events_ozone_layout", + "//ui/events/platform", "//ui/gfx/geometry", ]
diff --git a/ui/ozone/platform/caca/caca.gypi b/ui/ozone/platform/caca/caca.gypi index 7aa0d2ab..611d40b8 100644 --- a/ui/ozone/platform/caca/caca.gypi +++ b/ui/ozone/platform/caca/caca.gypi
@@ -23,6 +23,7 @@ '../../skia/skia.gyp:skia', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone_layout', + '../events/platform/events_platform.gyp:events_platform', '../gfx/gfx.gyp:gfx', '../gfx/gfx.gyp:gfx_geometry', ],
diff --git a/ui/ozone/platform/dri/BUILD.gn b/ui/ozone/platform/dri/BUILD.gn index 3a491677..f1fd02ca 100644 --- a/ui/ozone/platform/dri/BUILD.gn +++ b/ui/ozone/platform/dri/BUILD.gn
@@ -35,8 +35,6 @@ "dri_gpu_platform_support_.h", "dri_gpu_platform_support_host.cc", "dri_gpu_platform_support_host.h", - "dri_helper_thread.cc", - "dri_helper_thread.h", "dri_surface.cc", "dri_surface.h", "dri_surface_factory.cc", @@ -77,6 +75,8 @@ "scanout_buffer.h", ] + defines = [ "OZONE_IMPLEMENTATION" ] + deps = [ "//base", "//skia", @@ -85,8 +85,10 @@ "//ui/display/types", "//ui/display/util", "//ui/events", + "//ui/events/devices", "//ui/events/ozone:events_ozone_evdev", "//ui/events/ozone:events_ozone_layout", + "//ui/events/platform", "//ui/gfx", "//ui/gfx/geometry", ] @@ -116,17 +118,19 @@ "dri_surface_unittest.cc", "dri_window_delegate_impl_unittest.cc", "hardware_display_controller_unittest.cc", - "hardware_display_manager_unittest.cc", + "hardware_display_plane_manager_unittest.cc", "screen_manager_unittest.cc", "test/mock_dri_wrapper.cc", "test/mock_dri_wrapper.h", ] deps = [ - ":dri_common", "//skia", "//testing/gtest", + "//ui/ozone", ] + + public_configs = [ ":libdrm" ] } }
diff --git a/ui/ozone/platform/dri/crtc_controller.h b/ui/ozone/platform/dri/crtc_controller.h index d9e26bc..d814ba67 100644 --- a/ui/ozone/platform/dri/crtc_controller.h +++ b/ui/ozone/platform/dri/crtc_controller.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/hardware_display_plane_manager.h" #include "ui/ozone/platform/dri/overlay_plane.h" #include "ui/ozone/platform/dri/scoped_drm_types.h" @@ -25,7 +26,8 @@ // One CRTC can be paired up with one or more connectors. The simplest // configuration represents one CRTC driving one monitor, while pairing up a // CRTC with multiple connectors results in hardware mirroring. -class CrtcController : public base::SupportsWeakPtr<CrtcController> { +class OZONE_EXPORT CrtcController + : public base::SupportsWeakPtr<CrtcController> { public: CrtcController(DriWrapper* drm, uint32_t crtc, uint32_t connector); ~CrtcController();
diff --git a/ui/ozone/platform/dri/dri.gypi b/ui/ozone/platform/dri/dri.gypi index 0048f14c..96e5fc2c 100644 --- a/ui/ozone/platform/dri/dri.gypi +++ b/ui/ozone/platform/dri/dri.gypi
@@ -25,9 +25,11 @@ '../base/ui_base.gyp:ui_base', '../display/display.gyp:display_types', '../display/display.gyp:display_util', + '../events/devices/events_devices.gyp:events_devices', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone_evdev', '../events/ozone/events_ozone.gyp:events_ozone_layout', + '../events/platform/events_platform.gyp:events_platform', '../gfx/gfx.gyp:gfx', '../gfx/gfx.gyp:gfx_geometry', ], @@ -55,8 +57,6 @@ 'dri_gpu_platform_support.h', 'dri_gpu_platform_support_host.cc', 'dri_gpu_platform_support_host.h', - 'dri_helper_thread.cc', - 'dri_helper_thread.h', 'dri_surface.cc', 'dri_surface.h', 'dri_surface_factory.cc', @@ -106,7 +106,7 @@ '../../build/linux/system.gyp:libdrm', '../../skia/skia.gyp:skia', '../gfx/gfx.gyp:gfx_geometry', - 'ozone_platform_dri', + 'ozone.gyp:ozone', ], 'export_dependent_settings': [ '../../build/linux/system.gyp:libdrm',
diff --git a/ui/ozone/platform/dri/dri_buffer.h b/ui/ozone/platform/dri/dri_buffer.h index d20a1f9..9b22e751 100644 --- a/ui/ozone/platform/dri/dri_buffer.h +++ b/ui/ozone/platform/dri/dri_buffer.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkSurface.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/scanout_buffer.h" namespace ui { @@ -17,7 +18,7 @@ // 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 DriBuffer : public ScanoutBuffer { +class OZONE_EXPORT DriBuffer : public ScanoutBuffer { public: DriBuffer(DriWrapper* dri); @@ -53,7 +54,7 @@ DISALLOW_COPY_AND_ASSIGN(DriBuffer); }; -class DriBufferGenerator : public ScanoutBufferGenerator { +class OZONE_EXPORT DriBufferGenerator : public ScanoutBufferGenerator { public: DriBufferGenerator(); ~DriBufferGenerator() override;
diff --git a/ui/ozone/platform/dri/dri_gpu_platform_support.cc b/ui/ozone/platform/dri/dri_gpu_platform_support.cc index fa0923f..af7ed4df 100644 --- a/ui/ozone/platform/dri/dri_gpu_platform_support.cc +++ b/ui/ozone/platform/dri/dri_gpu_platform_support.cc
@@ -13,7 +13,6 @@ #include "ui/ozone/common/display_util.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" #include "ui/ozone/common/gpu/ozone_gpu_messages.h" -#include "ui/ozone/platform/dri/dri_helper_thread.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" @@ -32,9 +31,13 @@ class DriGpuPlatformSupportMessageFilter : public IPC::MessageFilter { public: + typedef base::Callback<void( + const scoped_refptr<base::SingleThreadTaskRunner>&)> + OnFilterAddedCallback; + DriGpuPlatformSupportMessageFilter( DriWindowDelegateManager* window_manager, - const base::Closure& on_filter_added_callback, + const OnFilterAddedCallback& on_filter_added_callback, IPC::Listener* main_thread_listener) : window_manager_(window_manager), on_filter_added_callback_(on_filter_added_callback), @@ -45,7 +48,9 @@ void OnFilterAdded(IPC::Sender* sender) override { io_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - main_thread_task_runner_->PostTask(FROM_HERE, on_filter_added_callback_); + main_thread_task_runner_->PostTask( + FROM_HERE, + base::Bind(on_filter_added_callback_, io_thread_task_runner_)); } // This code is meant to be very temporary and only as a special case to fix @@ -154,7 +159,7 @@ } DriWindowDelegateManager* window_manager_; - base::Closure on_filter_added_callback_; + OnFilterAddedCallback on_filter_added_callback_; IPC::Listener* main_thread_listener_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; @@ -174,8 +179,8 @@ screen_manager_(screen_manager), ndd_(ndd.Pass()) { filter_ = new DriGpuPlatformSupportMessageFilter( - window_manager, - base::Bind(&DriGpuPlatformSupport::OnFilterAdded, base::Unretained(this)), + window_manager, base::Bind(&DriGpuPlatformSupport::SetIOTaskRunner, + base::Unretained(this)), this); } @@ -352,14 +357,13 @@ callback.Run(); } -void DriGpuPlatformSupport::OnFilterAdded() { +void DriGpuPlatformSupport::SetIOTaskRunner( + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) { + io_task_runner_ = io_task_runner; base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); - // Only surfaceless path supports async page flips. So we only initialize the - // helper thread if we're using async page flips. - if (!helper_thread_.IsRunning() && - cmd->HasSwitch(switches::kOzoneUseSurfaceless)) { - helper_thread_.Initialize(); - drm_->InitializeTaskRunner(helper_thread_.task_runner()); + // Only surfaceless path supports async page flips. + if (cmd->HasSwitch(switches::kOzoneUseSurfaceless)) { + drm_->InitializeTaskRunner(io_task_runner_); } }
diff --git a/ui/ozone/platform/dri/dri_gpu_platform_support.h b/ui/ozone/platform/dri/dri_gpu_platform_support.h index daae2ec..23257bf 100644 --- a/ui/ozone/platform/dri/dri_gpu_platform_support.h +++ b/ui/ozone/platform/dri/dri_gpu_platform_support.h
@@ -10,13 +10,13 @@ #include "base/memory/scoped_vector.h" #include "ipc/message_filter.h" #include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/dri/dri_helper_thread.h" #include "ui/ozone/public/gpu_platform_support.h" class SkBitmap; namespace base { class FilePath; +class SingleThreadTaskRunner; } namespace gfx { @@ -77,17 +77,18 @@ void OnAddGraphicsDevice(const base::FilePath& path); void OnRemoveGraphicsDevice(const base::FilePath& path); - void OnFilterAdded(); + void SetIOTaskRunner( + const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); IPC::Sender* sender_; // Not owned. DriWrapper* drm_; // Not owned. DriWindowDelegateManager* window_manager_; // Not owned. ScreenManager* screen_manager_; // Not owned. - DriHelperThread helper_thread_; scoped_ptr<NativeDisplayDelegateDri> ndd_; ScopedVector<GpuPlatformSupport> handlers_; scoped_refptr<IPC::MessageFilter> filter_; + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; }; } // namespace ui
diff --git a/ui/ozone/platform/dri/dri_helper_thread.cc b/ui/ozone/platform/dri/dri_helper_thread.cc deleted file mode 100644 index 4ca33017..0000000 --- a/ui/ozone/platform/dri/dri_helper_thread.cc +++ /dev/null
@@ -1,23 +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/dri_helper_thread.h" - -namespace ui { - -DriHelperThread::DriHelperThread() : Thread("DriHelperThread") { -} - -DriHelperThread::~DriHelperThread() { - Stop(); -} - -void DriHelperThread::Initialize() { - DCHECK(!IsRunning()); - - if (!StartWithOptions(base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) - LOG(FATAL) << "Failed to start the IO helper thread"; -} - -} // namespace ui
diff --git a/ui/ozone/platform/dri/dri_helper_thread.h b/ui/ozone/platform/dri/dri_helper_thread.h deleted file mode 100644 index fea01d9..0000000 --- a/ui/ozone/platform/dri/dri_helper_thread.h +++ /dev/null
@@ -1,27 +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_DRI_HELPER_THREAD_H_ -#define UI_OZONE_PLATFORM_DRI_DRI_HELPER_THREAD_H_ - -#include "base/threading/thread.h" - -namespace ui { - -class DriHelperThread : public base::Thread { - public: - DriHelperThread(); - ~DriHelperThread() override; - - // Call to start the thread. This needs to be called after the GPU entered the - // sandbox. - void Initialize(); - - private: - DISALLOW_COPY_AND_ASSIGN(DriHelperThread); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_DRI_DRI_HELPER_THREAD_H_
diff --git a/ui/ozone/platform/dri/dri_surface.h b/ui/ozone/platform/dri/dri_surface.h index 9c439e3..6ba581e 100644 --- a/ui/ozone/platform/dri/dri_surface.h +++ b/ui/ozone/platform/dri/dri_surface.h
@@ -9,6 +9,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/skia_util.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/public/surface_ozone_canvas.h" class SkSurface; @@ -20,7 +21,7 @@ class DriWrapper; class HardwareDisplayController; -class DriSurface : public SurfaceOzoneCanvas { +class OZONE_EXPORT DriSurface : public SurfaceOzoneCanvas { public: DriSurface(DriWindowDelegate* window_delegate, DriWrapper* dri); ~DriSurface() override;
diff --git a/ui/ozone/platform/dri/dri_window_delegate_impl.h b/ui/ozone/platform/dri/dri_window_delegate_impl.h index 445cc4c..89de303 100644 --- a/ui/ozone/platform/dri/dri_window_delegate_impl.h +++ b/ui/ozone/platform/dri/dri_window_delegate_impl.h
@@ -9,6 +9,7 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/display_change_observer.h" #include "ui/ozone/platform/dri/dri_window_delegate.h" @@ -20,8 +21,8 @@ class HardwareDisplayController; class ScreenManager; -class DriWindowDelegateImpl : public DriWindowDelegate, - public DisplayChangeObserver { +class OZONE_EXPORT DriWindowDelegateImpl : public DriWindowDelegate, + public DisplayChangeObserver { public: DriWindowDelegateImpl(gfx::AcceleratedWidget widget, DriWrapper* drm,
diff --git a/ui/ozone/platform/dri/dri_window_delegate_manager.h b/ui/ozone/platform/dri/dri_window_delegate_manager.h index eb4f7b9..5a4ed27 100644 --- a/ui/ozone/platform/dri/dri_window_delegate_manager.h +++ b/ui/ozone/platform/dri/dri_window_delegate_manager.h
@@ -7,12 +7,13 @@ #include "base/containers/scoped_ptr_hash_map.h" #include "ui/gfx/native_widget_types.h" +#include "ui/ozone/ozone_export.h" namespace ui { class DriWindowDelegate; -class DriWindowDelegateManager { +class OZONE_EXPORT DriWindowDelegateManager { public: DriWindowDelegateManager(); ~DriWindowDelegateManager();
diff --git a/ui/ozone/platform/dri/dri_wrapper.h b/ui/ozone/platform/dri/dri_wrapper.h index 381459e..484174d 100644 --- a/ui/ozone/platform/dri/dri_wrapper.h +++ b/ui/ozone/platform/dri/dri_wrapper.h
@@ -15,6 +15,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/overlay_transform.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/hardware_display_plane_manager.h" #include "ui/ozone/platform/dri/scoped_drm_types.h" @@ -34,7 +35,7 @@ // 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 DriWrapper { +class OZONE_EXPORT DriWrapper { public: typedef base::Callback<void(unsigned int /* frame */, unsigned int /* seconds */,
diff --git a/ui/ozone/platform/dri/hardware_display_controller.h b/ui/ozone/platform/dri/hardware_display_controller.h index 0c09fce7..46254f5 100644 --- a/ui/ozone/platform/dri/hardware_display_controller.h +++ b/ui/ozone/platform/dri/hardware_display_controller.h
@@ -18,6 +18,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/hardware_display_plane_manager.h" #include "ui/ozone/platform/dri/overlay_plane.h" #include "ui/ozone/platform/dri/page_flip_observer.h" @@ -86,7 +87,7 @@ // only a subset of connectors can be active independently, showing different // framebuffers. Though, in this case, it would be possible to have all // connectors active if some use the same CRTC to mirror the display. -class HardwareDisplayController +class OZONE_EXPORT HardwareDisplayController : public base::SupportsWeakPtr<HardwareDisplayController>, public PageFlipObserver { public:
diff --git a/ui/ozone/platform/dri/hardware_display_plane.h b/ui/ozone/platform/dri/hardware_display_plane.h index 7ea4f95..e8589317 100644 --- a/ui/ozone/platform/dri/hardware_display_plane.h +++ b/ui/ozone/platform/dri/hardware_display_plane.h
@@ -9,6 +9,7 @@ #include <stdint.h> #include "base/basictypes.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/scoped_drm_types.h" namespace gfx { @@ -19,7 +20,7 @@ class DriWrapper; -class HardwareDisplayPlane { +class OZONE_EXPORT HardwareDisplayPlane { public: HardwareDisplayPlane(ScopedDrmPlanePtr plane); HardwareDisplayPlane(uint32_t plane_id, uint32_t possible_crtcs);
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager.h b/ui/ozone/platform/dri/hardware_display_plane_manager.h index d45c7b7..9839b72 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager.h +++ b/ui/ozone/platform/dri/hardware_display_plane_manager.h
@@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_vector.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/hardware_display_plane.h" #include "ui/ozone/platform/dri/overlay_plane.h" #include "ui/ozone/platform/dri/scoped_drm_types.h" @@ -27,7 +28,7 @@ // This contains the list of planes controlled by one HDC on a given DRM fd. // It is owned by the HDC and filled by the CrtcController. -struct HardwareDisplayPlaneList { +struct OZONE_EXPORT HardwareDisplayPlaneList { HardwareDisplayPlaneList(); ~HardwareDisplayPlaneList(); @@ -69,7 +70,7 @@ bool committed; }; -class HardwareDisplayPlaneManager { +class OZONE_EXPORT HardwareDisplayPlaneManager { public: HardwareDisplayPlaneManager(); virtual ~HardwareDisplayPlaneManager();
diff --git a/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h b/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h index a9cdf648..07d05c4 100644 --- a/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h +++ b/ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h
@@ -5,11 +5,13 @@ #ifndef UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_MANAGER_ATOMIC_H_ #define UI_OZONE_PLATFORM_DRI_HARDWARE_DISPLAY_PLANE_MANAGER_ATOMIC_H_ +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/hardware_display_plane_manager.h" namespace ui { -class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager { +class OZONE_EXPORT HardwareDisplayPlaneManagerLegacy + : public HardwareDisplayPlaneManager { public: HardwareDisplayPlaneManagerLegacy(); ~HardwareDisplayPlaneManagerLegacy() override;
diff --git a/ui/ozone/platform/dri/overlay_plane.h b/ui/ozone/platform/dri/overlay_plane.h index 7e8e1d5..9b566ac 100644 --- a/ui/ozone/platform/dri/overlay_plane.h +++ b/ui/ozone/platform/dri/overlay_plane.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/overlay_transform.h" +#include "ui/ozone/ozone_export.h" namespace ui { @@ -18,7 +19,7 @@ struct OverlayPlane; typedef std::vector<OverlayPlane> OverlayPlaneList; -struct OverlayPlane { +struct OZONE_EXPORT OverlayPlane { // Simpler constructor for the primary plane. explicit OverlayPlane(scoped_refptr<ScanoutBuffer> buffer);
diff --git a/ui/ozone/platform/dri/scoped_drm_types.h b/ui/ozone/platform/dri/scoped_drm_types.h index e651232..bd8b4bc 100644 --- a/ui/ozone/platform/dri/scoped_drm_types.h +++ b/ui/ozone/platform/dri/scoped_drm_types.h
@@ -6,6 +6,7 @@ #define UI_OZONE_PLATFORM_DRI_SCOPED_DRM_TYPES_H_ #include "base/memory/scoped_ptr.h" +#include "ui/ozone/ozone_export.h" typedef struct _drmModeConnector drmModeConnector; typedef struct _drmModeCrtc drmModeCrtc; @@ -20,34 +21,34 @@ namespace ui { -struct DrmResourcesDeleter { +struct OZONE_EXPORT DrmResourcesDeleter { void operator()(drmModeRes* resources) const; }; -struct DrmConnectorDeleter { +struct OZONE_EXPORT DrmConnectorDeleter { void operator()(drmModeConnector* connector) const; }; -struct DrmCrtcDeleter { +struct OZONE_EXPORT DrmCrtcDeleter { void operator()(drmModeCrtc* crtc) const; }; -struct DrmEncoderDeleter { +struct OZONE_EXPORT DrmEncoderDeleter { void operator()(drmModeEncoder* encoder) const; }; -struct DrmObjectPropertiesDeleter { +struct OZONE_EXPORT DrmObjectPropertiesDeleter { void operator()(drmModeObjectProperties* properties) const; }; -struct DrmPlaneDeleter { +struct OZONE_EXPORT DrmPlaneDeleter { void operator()(drmModePlane* plane) const; }; -struct DrmPlaneResDeleter { +struct OZONE_EXPORT DrmPlaneResDeleter { void operator()(drmModePlaneRes* plane_res) const; }; -struct DrmPropertyDeleter { +struct OZONE_EXPORT DrmPropertyDeleter { void operator()(drmModePropertyRes* property) const; }; -struct DrmPropertyBlobDeleter { +struct OZONE_EXPORT DrmPropertyBlobDeleter { void operator()(drmModePropertyBlobRes* property) const; }; -struct DrmFramebufferDeleter { +struct OZONE_EXPORT DrmFramebufferDeleter { void operator()(drmModeFB* framebuffer) const; };
diff --git a/ui/ozone/platform/dri/screen_manager.h b/ui/ozone/platform/dri/screen_manager.h index 5eaae1a..22ea14a9 100644 --- a/ui/ozone/platform/dri/screen_manager.h +++ b/ui/ozone/platform/dri/screen_manager.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" #include "base/observer_list.h" +#include "ui/ozone/ozone_export.h" #include "ui/ozone/platform/dri/display_change_observer.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" @@ -25,7 +26,7 @@ class ScanoutBufferGenerator; // Responsible for keeping track of active displays and configuring them. -class ScreenManager { +class OZONE_EXPORT ScreenManager { public: ScreenManager(DriWrapper* dri, ScanoutBufferGenerator* surface_generator); virtual ~ScreenManager();
diff --git a/ui/ozone/platform/egltest/BUILD.gn b/ui/ozone/platform/egltest/BUILD.gn index 402794af..8acf85b 100644 --- a/ui/ozone/platform/egltest/BUILD.gn +++ b/ui/ozone/platform/egltest/BUILD.gn
@@ -13,8 +13,10 @@ deps = [ ":eglplatform_shim", "//base", + "//ui/events/devices", "//ui/events/ozone:events_ozone_evdev", "//ui/events/ozone:events_ozone_layout", + "//ui/events/platform", "//ui/gfx", ] }
diff --git a/ui/ozone/platform/egltest/egltest.gypi b/ui/ozone/platform/egltest/egltest.gypi index 4c389e8..8683212 100644 --- a/ui/ozone/platform/egltest/egltest.gypi +++ b/ui/ozone/platform/egltest/egltest.gypi
@@ -21,9 +21,11 @@ 'dependencies': [ '../../base/base.gyp:base', '../../third_party/khronos/khronos.gyp:khronos_headers', + '../events/devices/events_devices.gyp:events_devices', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone_evdev', '../events/ozone/events_ozone.gyp:events_ozone_layout', + '../events/platform/events_platform.gyp:events_platform', '../gfx/gfx.gyp:gfx', 'eglplatform_shim', ],
diff --git a/ui/ozone/platform/test/BUILD.gn b/ui/ozone/platform/test/BUILD.gn index b5c1cf38..eaaa60c 100644 --- a/ui/ozone/platform/test/BUILD.gn +++ b/ui/ozone/platform/test/BUILD.gn
@@ -18,5 +18,6 @@ "//ui/base", "//ui/gfx/geometry", "//ui/events/ozone:events_ozone_layout", + "//ui/events/platform", ] }
diff --git a/ui/ozone/platform/test/test.gypi b/ui/ozone/platform/test/test.gypi index b94f091..6543334 100644 --- a/ui/ozone/platform/test/test.gypi +++ b/ui/ozone/platform/test/test.gypi
@@ -23,6 +23,7 @@ '../base/ui_base.gyp:ui_base', '../events/events.gyp:events', '../events/ozone/events_ozone.gyp:events_ozone_layout', + '../events/platform/events_platform.gyp:events_platform', '../gfx/gfx.gyp:gfx', ], 'sources': [
diff --git a/ui/strings/app_locale_settings.grd b/ui/strings/app_locale_settings.grd index 19bb7e5..5b0d951 100644 --- a/ui/strings/app_locale_settings.grd +++ b/ui/strings/app_locale_settings.grd
@@ -256,7 +256,7 @@ <if expr="chromeos"> <!-- The font name like: 'Font Name, 10' --> <message name="IDS_UI_FONT_FAMILY_CROS" use_name_for_id="true"> - Noto Sans UI, 12px + Noto Sans UI, 13px </message> <!-- The font used in Web UI (e.g. History). -->
diff --git a/ui/touch_selection/ui_touch_selection_unittests.isolate b/ui/touch_selection/ui_touch_selection_unittests.isolate index 64e0e54..691e0a6 100644 --- a/ui/touch_selection/ui_touch_selection_unittests.isolate +++ b/ui/touch_selection/ui_touch_selection_unittests.isolate
@@ -21,6 +21,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], 'files': [ '../../testing/xvfb.py', @@ -44,6 +46,8 @@ '--test-launcher-bot-mode', '--asan=<(asan)', '--lsan=<(lsan)', + '--msan=<(msan)', + '--tsan=<(tsan)', ], }, }],
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc index ae2df206..05f1868 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.cc +++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -76,10 +76,11 @@ delete obj; } -AXAuraObjCache::AXAuraObjCache() : current_id_(1) { +AXAuraObjCache::AXAuraObjCache() : current_id_(1), is_destroying_(false) { } AXAuraObjCache::~AXAuraObjCache() { + is_destroying_ = true; STLDeleteContainerPairSecondPointers(cache_.begin(), cache_.end()); cache_.clear(); }
diff --git a/ui/views/accessibility/ax_aura_obj_cache.h b/ui/views/accessibility/ax_aura_obj_cache.h index 6e5d9e8..a8316b5 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.h +++ b/ui/views/accessibility/ax_aura_obj_cache.h
@@ -52,6 +52,9 @@ // Remove a cached entry based on an id. void Remove(int32 id); + // Indicates if this object's currently being destroyed. + bool is_destroying() { return is_destroying_; } + private: friend struct DefaultSingletonTraits<AXAuraObjCache>; @@ -75,6 +78,9 @@ std::map<int32, AXAuraObjWrapper*> cache_; int32 current_id_; + // True immediately when entering this object's destructor. + bool is_destroying_; + DISALLOW_COPY_AND_ASSIGN(AXAuraObjCache); };
diff --git a/ui/views/accessibility/ax_widget_obj_wrapper.cc b/ui/views/accessibility/ax_widget_obj_wrapper.cc index 36a3143e..44fcfa8 100644 --- a/ui/views/accessibility/ax_widget_obj_wrapper.cc +++ b/ui/views/accessibility/ax_widget_obj_wrapper.cc
@@ -17,8 +17,10 @@ } AXWidgetObjWrapper::~AXWidgetObjWrapper() { - widget_->RemoveObserver(this); - widget_->RemoveRemovalsObserver(this); + if (!AXAuraObjCache::GetInstance()->is_destroying()) { + widget_->RemoveObserver(this); + widget_->RemoveRemovalsObserver(this); + } widget_ = NULL; }
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index 381f489d..17457d98 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -7,6 +7,7 @@ #include "base/run_loop.h" #include "ui/aura/scoped_window_targeter.h" #include "ui/aura/window.h" +#include "ui/events/event_handler.h" #include "ui/events/event_targeter.h" #include "ui/events/platform/platform_event_source.h" #include "ui/views/controls/menu/menu_item_view.h" @@ -186,6 +187,14 @@ controller_->exit_type_ = MenuController::EXIT_ALL; DispatchEvent(); } + + void DispatchTouch(int evtype, int id) { + ui::ScopedXI2Event touch_event; + std::vector<ui::Valuator> valuators; + touch_event.InitTouchEvent(1, evtype, id, gfx::Point(10, 10), valuators); + event_source_.Dispatch(touch_event); + DispatchEvent(); + } #endif void DispatchEvent() { @@ -266,4 +275,64 @@ } #endif +#if defined(USE_X11) + +class TestEventHandler : public ui::EventHandler { + public: + TestEventHandler() : outstanding_touches_(0) {} + + void OnTouchEvent(ui::TouchEvent* event) override { + switch(event->type()) { + case ui::ET_TOUCH_PRESSED: + outstanding_touches_++; + break; + case ui::ET_TOUCH_RELEASED: + case ui::ET_TOUCH_CANCELLED: + outstanding_touches_--; + break; + default: + break; + } + } + + int outstanding_touches() const { return outstanding_touches_; } + + private: + int outstanding_touches_; +}; + +// Tests that touch event ids are released correctly. See +// crbug.com/439051 for details. When the ids aren't managed +// correctly, we get stuck down touches. +TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { + scoped_ptr<Widget> owner(CreateOwnerWidget()); + TestEventHandler test_event_handler; + owner->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( + &test_event_handler); + + std::vector<unsigned int> devices; + devices.push_back(1); + ui::SetUpTouchDevicesForTest(devices); + + DispatchTouch(XI_TouchBegin, 0); + DispatchTouch(XI_TouchBegin, 1); + DispatchTouch(XI_TouchEnd, 0); + + message_loop()->PostTask(FROM_HERE, + base::Bind(&MenuControllerTest::DispatchTouch, + base::Unretained(this), XI_TouchEnd, 1)); + + message_loop()->PostTask( + FROM_HERE, + base::Bind(&MenuControllerTest::DispatchEscapeAndExpect, + base::Unretained(this), MenuController::EXIT_OUTERMOST)); + + RunMenu(owner.get()); + EXPECT_EQ(0, test_event_handler.outstanding_touches()); + + owner->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( + &test_event_handler); +} +#endif // defined(USE_X11) + } // namespace views
diff --git a/ui/views/controls/menu/menu_event_dispatcher_linux.cc b/ui/views/controls/menu/menu_event_dispatcher_linux.cc index 51990fd0..f61d58b 100644 --- a/ui/views/controls/menu/menu_event_dispatcher_linux.cc +++ b/ui/views/controls/menu/menu_event_dispatcher_linux.cc
@@ -75,6 +75,14 @@ should_quit = false; should_perform_default = false; break; + case ui::ET_TOUCH_RELEASED: + case ui::ET_TOUCH_CANCELLED: + // Don't allow the event copy to clear the native touch id + // mapping, or we'll lose the mapping before the initial event + // has finished being dispatched. + static_cast<ui::TouchEvent*>(ui_event.get()) + ->set_should_remove_native_touch_id_mapping(false); + break; default: break; }
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index 0bffda9..8fe27bf0 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -306,15 +306,15 @@ void WebDialogView::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { if (delegate_ && delegate_->HandleAddNewContents( - source, new_contents, disposition, initial_pos, user_gesture)) { + source, new_contents, disposition, initial_rect, user_gesture)) { return; } WebDialogWebContentsDelegate::AddNewContents( - source, new_contents, disposition, initial_pos, user_gesture, + source, new_contents, disposition, initial_rect, user_gesture, was_blocked); }
diff --git a/ui/views/controls/webview/web_dialog_view.h b/ui/views/controls/webview/web_dialog_view.h index ce69cfc..22550dd 100644 --- a/ui/views/controls/webview/web_dialog_view.h +++ b/ui/views/controls/webview/web_dialog_view.h
@@ -103,7 +103,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; void LoadingStateChanged(content::WebContents* source,
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc index 2e4ba84..e872a58b 100644 --- a/ui/views/controls/webview/webview.cc +++ b/ui/views/controls/webview/webview.cc
@@ -78,7 +78,7 @@ DCHECK(!is_embedding_fullscreen_widget_); } AttachWebContents(); - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::SetEmbedFullscreenWidgetMode(bool enable) { @@ -266,7 +266,7 @@ void WebView::RenderProcessExited(content::RenderProcessHost* host, base::TerminationStatus status, int exit_code) { - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::RenderProcessHostDestroyed(content::RenderProcessHost* host) { @@ -293,11 +293,11 @@ // WebView, content::WebContentsObserver implementation: void WebView::RenderViewReady() { - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) { - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, @@ -305,7 +305,7 @@ FocusManager* const focus_manager = GetFocusManager(); if (focus_manager && focus_manager->GetFocusedView() == this) OnFocus(); - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::WebContentsDestroyed() { @@ -313,7 +313,7 @@ observing_render_process_host_->RemoveObserver(this); observing_render_process_host_ = nullptr; } - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::DidShowFullscreenWidget(int routing_id) { @@ -332,11 +332,11 @@ } void WebView::DidAttachInterstitialPage() { - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } void WebView::DidDetachInterstitialPage() { - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } //////////////////////////////////////////////////////////////////////////////// @@ -398,14 +398,19 @@ // the same. So, do not change attachment. OnBoundsChanged(bounds()); } - NotifyMaybeTextInputClientChanged(); + NotifyMaybeTextInputClientAndAccessibilityChanged(); } -void WebView::NotifyMaybeTextInputClientChanged() { +void WebView::NotifyMaybeTextInputClientAndAccessibilityChanged() { // Update the TextInputClient as needed; see GetTextInputClient(). FocusManager* const focus_manager = GetFocusManager(); if (focus_manager) focus_manager->OnTextInputClientChanged(this); + +#if defined(OS_CHROMEOS) + if (web_contents()) + NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false); +#endif // defined OS_CHROMEOS } content::WebContents* WebView::CreateWebContents(
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h index af64b72..f97449b8 100644 --- a/ui/views/controls/webview/webview.h +++ b/ui/views/controls/webview/webview.h
@@ -149,7 +149,7 @@ void AttachWebContents(); void DetachWebContents(); void ReattachForFullscreenChange(bool enter_fullscreen); - void NotifyMaybeTextInputClientChanged(); + void NotifyMaybeTextInputClientAndAccessibilityChanged(); // Create a regular or test web contents (based on whether we're running // in a unit test or not).
diff --git a/ui/views/widget/desktop_aura/x11_pointer_grab.cc b/ui/views/widget/desktop_aura/x11_pointer_grab.cc index 1354159..26a1c1d 100644 --- a/ui/views/widget/desktop_aura/x11_pointer_grab.cc +++ b/ui/views/widget/desktop_aura/x11_pointer_grab.cc
@@ -3,8 +3,11 @@ // found in the LICENSE file. #include "base/logging.h" +#include "ui/base/x/x11_util.h" +#include "ui/events/devices/x11/device_data_manager_x11.h" #include "ui/views/widget/desktop_aura/x11_pointer_grab.h" +#include <X11/extensions/XInput2.h> #include <X11/Xlib.h> namespace views { @@ -20,10 +23,42 @@ } // namespace int GrabPointer(XID window, bool owner_events, ::Cursor cursor) { - int event_mask = PointerMotionMask | ButtonReleaseMask | ButtonPressMask; - int result = XGrabPointer(gfx::GetXDisplay(), window, owner_events, - event_mask, GrabModeAsync, GrabModeAsync, None, - cursor, CurrentTime); + int result = GrabInvalidTime; + if (ui::IsXInput2Available()) { + // Do an XInput2 pointer grab. If there is an active XInput2 pointer grab + // as a result of normal button press, XGrabPointer() will fail. + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + memset(mask, 0, sizeof(mask)); + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); + XIEventMask evmask; + evmask.mask_len = sizeof(mask); + evmask.mask = mask; + + const std::vector<int>& master_pointers = + ui::DeviceDataManagerX11::GetInstance()->master_pointers(); + for (int master_pointer : master_pointers) { + evmask.deviceid = master_pointer; + result = XIGrabDevice( + gfx::GetXDisplay(), master_pointer, window, CurrentTime, cursor, + GrabModeAsync, GrabModeAsync, owner_events, &evmask); + // Assume that the grab will succeed on either all or none of the master + // pointers. + if (result != GrabSuccess) { + // Try core pointer grab. + break; + } + } + } + + if (result != GrabSuccess) { + int event_mask = PointerMotionMask | ButtonReleaseMask | ButtonPressMask; + result = + XGrabPointer(gfx::GetXDisplay(), window, owner_events, event_mask, + GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); + } + if (result == GrabSuccess) { g_grab_window = window; g_owner_events = owner_events; @@ -38,6 +73,13 @@ void UngrabPointer() { g_grab_window = None; + if (ui::IsXInput2Available()) { + const std::vector<int>& master_pointers = + ui::DeviceDataManagerX11::GetInstance()->master_pointers(); + for (int master_pointer : master_pointers) + XIUngrabDevice(gfx::GetXDisplay(), master_pointer, CurrentTime); + } + // Try core pointer ungrab in case the XInput2 pointer ungrab failed. XUngrabPointer(gfx::GetXDisplay(), CurrentTime); }
diff --git a/ui/web_dialogs/test/test_web_contents_handler.cc b/ui/web_dialogs/test/test_web_contents_handler.cc index 4b2077d..7f8e5e5 100644 --- a/ui/web_dialogs/test/test_web_contents_handler.cc +++ b/ui/web_dialogs/test/test_web_contents_handler.cc
@@ -24,7 +24,7 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { }
diff --git a/ui/web_dialogs/test/test_web_contents_handler.h b/ui/web_dialogs/test/test_web_contents_handler.h index 691376e2..50d7592 100644 --- a/ui/web_dialogs/test/test_web_contents_handler.h +++ b/ui/web_dialogs/test/test_web_contents_handler.h
@@ -28,7 +28,7 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) override; DISALLOW_COPY_AND_ASSIGN(TestWebContentsHandler);
diff --git a/ui/web_dialogs/web_dialog_delegate.cc b/ui/web_dialogs/web_dialog_delegate.cc index 8020c55..e4895f17 100644 --- a/ui/web_dialogs/web_dialog_delegate.cc +++ b/ui/web_dialogs/web_dialog_delegate.cc
@@ -43,7 +43,7 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) { return false; }
diff --git a/ui/web_dialogs/web_dialog_delegate.h b/ui/web_dialogs/web_dialog_delegate.h index 898b0451..6d2079d 100644 --- a/ui/web_dialogs/web_dialog_delegate.h +++ b/ui/web_dialogs/web_dialog_delegate.h
@@ -120,13 +120,13 @@ // A callback to create a new tab with |new_contents|. |source| is the // WebContent where the operation originated. |disposition| controls how the - // new tab should be opened. |initial_pos| is the position of the window if a - // new window is created. |user_gesture| is true if the operation was started - // by a user gesture. Return false to use the default handler. + // new tab should be opened. |initial_rect| is the position and size of the + // window if a new window is created. |user_gesture| is true if the operation + // was started by a user gesture. Return false to use the default handler. virtual bool HandleAddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture); // A callback to control whether a WebContents will be created. Returns
diff --git a/ui/web_dialogs/web_dialog_web_contents_delegate.cc b/ui/web_dialogs/web_dialog_web_contents_delegate.cc index ea0006a..0493e415 100644 --- a/ui/web_dialogs/web_dialog_web_contents_delegate.cc +++ b/ui/web_dialogs/web_dialog_web_contents_delegate.cc
@@ -42,11 +42,11 @@ void WebDialogWebContentsDelegate::AddNewContents( WebContents* source, WebContents* new_contents, - WindowOpenDisposition disposition, const gfx::Rect& initial_pos, + WindowOpenDisposition disposition, const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) { handler_->AddNewContents(browser_context_, source, new_contents, disposition, - initial_pos, user_gesture); + initial_rect, user_gesture); } bool WebDialogWebContentsDelegate::IsPopupOrPanel(
diff --git a/ui/web_dialogs/web_dialog_web_contents_delegate.h b/ui/web_dialogs/web_dialog_web_contents_delegate.h index 00f9aa4ef..c8d4f10 100644 --- a/ui/web_dialogs/web_dialog_web_contents_delegate.h +++ b/ui/web_dialogs/web_dialog_web_contents_delegate.h
@@ -31,7 +31,7 @@ content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture) = 0; }; @@ -59,7 +59,7 @@ void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, + const gfx::Rect& initial_rect, bool user_gesture, bool* was_blocked) override; bool IsPopupOrPanel(const content::WebContents* source) const override;
diff --git a/ui/webui/resources/css/text_defaults.css b/ui/webui/resources/css/text_defaults.css index 682a8585..1af823b 100644 --- a/ui/webui/resources/css/text_defaults.css +++ b/ui/webui/resources/css/text_defaults.css
@@ -23,3 +23,7 @@ font-family: $2; font-size: $3; } + +button { + font-family: $2; +}
diff --git a/ui/webui/resources/js/cr/ui/focus_grid.js b/ui/webui/resources/js/cr/ui/focus_grid.js index 2e76ca1..4ff1635 100644 --- a/ui/webui/resources/js/cr/ui/focus_grid.js +++ b/ui/webui/resources/js/cr/ui/focus_grid.js
@@ -18,28 +18,58 @@ * focusable [focused] focusable (row: 1, col: 1) * focusable focusable focusable * - * And pressing right at this point would move the focus to: + * And pressing right or tab at this point would move the focus to: * * focusable focusable focusable * focusable focusable [focused] (row: 1, col: 2) * focusable focusable focusable * - * @param {Node=} opt_boundary Ignore focus events outside this node. - * @param {cr.ui.FocusRow.Observer=} opt_observer An observer of rows. - * @implements {cr.ui.FocusRow.Delegate} * @constructor */ - function FocusGrid(opt_boundary, opt_observer) { - /** @type {Node|undefined} */ - this.boundary_ = opt_boundary; - - /** @private {cr.ui.FocusRow.Observer|undefined} */ - this.observer_ = opt_observer; - + function FocusGrid() { /** @type {!Array.<!cr.ui.FocusRow>} */ this.rows = []; + + /** @private {!EventTracker} */ + this.eventTracker_ = new EventTracker; + this.eventTracker_.add(cr.doc, 'keydown', this.onKeydown_.bind(this)); + this.eventTracker_.add(cr.doc, 'focusin', this.onFocusin_.bind(this)); + + /** @private {cr.ui.FocusRow.Delegate} */ + this.delegate_ = new FocusGrid.RowDelegate(this); } + /** + * Row delegate to overwrite the behavior of a mouse click to deselect any row + * that wasn't clicked. + * @param {cr.ui.FocusGrid} focusGrid + * @implements {cr.ui.FocusRow.Delegate} + */ + FocusGrid.RowDelegate = function(focusGrid) { + /** @private {cr.ui.FocusGrid} */ + this.focusGrid_ = focusGrid; + }; + + FocusGrid.RowDelegate.prototype = { + /** @override */ + onKeydown: function(row, e) { return false; }, + + /** @override */ + onMousedown: function(row, e) { + // Only care about left mouse click. + if (e.button) + return false; + + // Only the clicked row should be active. + this.focusGrid_.rows.forEach(function(row) { + row.makeRowActive(row.contains(e.target)); + }); + + e.preventDefault(); + return true; + }, + }; + FocusGrid.prototype = { /** * Unregisters event handlers and removes all |this.rows|. @@ -51,22 +81,25 @@ /** * @param {EventTarget} target A target item to find in this grid. - * @return {?{row: number, col: number}} A position or null if not found. + * @return {number} The row index. -1 if not found. */ - getPositionForTarget: function(target) { + getRowIndexForTarget: function(target) { for (var i = 0; i < this.rows.length; ++i) { - for (var j = 0; j < this.rows[i].items.length; ++j) { - if (target == this.rows[i].items[j]) - return {row: i, col: j}; - } + if (this.rows[i].contains(target)) + return i; } - return null; + return -1; }, - /** @override */ - onKeydown: function(keyRow, e) { - var rowIndex = this.rows.indexOf(keyRow); - assert(rowIndex >= 0); + /** + * Handles keyboard shortcuts to move up/down in the grid. + * @param {Event} e The key event. + * @private + */ + onKeydown_: function(e) { + var rowIndex = this.getRowIndexForTarget(e.target); + if (rowIndex == -1) + return; var row = -1; @@ -79,35 +112,53 @@ else if (e.keyIdentifier == 'PageDown') row = this.rows.length - 1; - if (!this.rows[row]) - return false; - - var colIndex = keyRow.items.indexOf(e.target); - var col = Math.min(colIndex, this.rows[row].items.length - 1); - - this.rows[row].focusIndex(col); - - e.preventDefault(); - return true; - }, - - /** @override */ - onMousedown: function(row, e) { - return false; + var rowToFocus = this.rows[row]; + if (rowToFocus) { + this.ignoreFocusChange_ = true; + rowToFocus.getEquivalentElement(this.lastFocused).focus(); + e.preventDefault(); + } }, /** - * @param {!Array.<!NodeList|!Array.<!Element>>} grid A 2D array of nodes. + * Keep track of the last column that the user manually focused. + * @param {Event} The focusin event. + * @private */ - setGrid: function(grid) { - this.destroy(); + onFocusin_: function(e) { + if (this.ignoreFocusChange_) { + this.ignoreFocusChange_ = false; + return; + } - this.rows = grid.map(function(row) { - return new cr.ui.FocusRow(row, this.boundary_, this, this.observer_); - }, this); + if (this.getRowIndexForTarget(e.target) != -1) + this.lastFocused = e.target; + }, - if (!this.getPositionForTarget(document.activeElement) && this.rows[0]) - this.rows[0].activeIndex = 0; + /** + * Add a FocusRow to this grid. This needs to be called AFTER adding columns + * to the row. This is so that TAB focus can be properly enabled in the + * columns. + * @param {cr.ui.FocusRow} row The row that needs to be added to this grid. + */ + addRow: function(row) { + row.delegate = row.delegate || this.delegate_; + + if (this.rows.length == 0) { + // The first row should be active if no other row is focused. + row.makeRowActive(true); + } else if (row.contains(document.activeElement)) { + // The current row should be made active if it's the activeElement. + row.makeRowActive(true); + // Deactivate the first row. + this.rows[0].makeRowActive(false); + } else { + // All other rows should be inactive. + row.makeRowActive(false); + } + + // Add the row after its initial focus is set. + this.rows.push(row); }, };
diff --git a/ui/webui/resources/js/cr/ui/focus_outline_manager.js b/ui/webui/resources/js/cr/ui/focus_outline_manager.js index 2b5ec9fb..7f921ab 100644 --- a/ui/webui/resources/js/cr/ui/focus_outline_manager.js +++ b/ui/webui/resources/js/cr/ui/focus_outline_manager.js
@@ -58,10 +58,7 @@ * @type {boolean} */ set visible(visible) { - if (visible) - this.classList_.add(CLASS_NAME); - else - this.classList_.remove(CLASS_NAME); + this.classList_.toggle(CLASS_NAME, visible); }, get visible() { return this.classList_.contains(CLASS_NAME);
diff --git a/ui/webui/resources/js/cr/ui/focus_row.js b/ui/webui/resources/js/cr/ui/focus_row.js index 26c4c55..697cd699 100644 --- a/ui/webui/resources/js/cr/ui/focus_row.js +++ b/ui/webui/resources/js/cr/ui/focus_row.js
@@ -11,11 +11,13 @@ * * One could create a FocusRow by doing: * - * new cr.ui.FocusRow([checkboxEl, labelEl, buttonEl]) + * var focusRow = new cr.ui.FocusRow(rowBoundary, rowEl); * - * if there are references to each node or querying them from the DOM like so: + * focusRow.addFocusableElement(checkboxEl); + * focusRow.addFocusableElement(labelEl); + * focusRow.addFocusableElement(buttonEl); * - * new cr.ui.FocusRow(dialog.querySelectorAll('list input[type=checkbox]')) + * focusRow.setInitialFocusability(true); * * Pressing left cycles backward and pressing right cycles forward in item * order. Pressing Home goes to the beginning of the list and End goes to the @@ -23,57 +25,20 @@ * * If an item in this row is focused, it'll stay active (accessible via tab). * If no items in this row are focused, the row can stay active until focus - * changes to a node inside |this.boundary_|. If opt_boundary isn't - * specified, any focus change deactivates the row. + * changes to a node inside |this.boundary_|. If |boundary| isn't specified, + * any focus change deactivates the row. * - * @param {!Array.<!Element>|!NodeList} items Elements to track focus of. - * @param {Node=} opt_boundary Focus events are ignored outside of this node. - * @param {FocusRow.Delegate=} opt_delegate A delegate to handle key events. - * @param {FocusRow.Observer=} opt_observer An observer that's notified if - * this focus row is added to or removed from the focus order. * @constructor */ - function FocusRow(items, opt_boundary, opt_delegate, opt_observer) { - /** @type {!Array.<!Element>} */ - this.items = Array.prototype.slice.call(items); - assert(this.items.length > 0); - - /** @type {!Node} */ - this.boundary_ = opt_boundary || document; - - /** @private {cr.ui.FocusRow.Delegate|undefined} */ - this.delegate_ = opt_delegate; - - /** @private {cr.ui.FocusRow.Observer|undefined} */ - this.observer_ = opt_observer; - - /** @private {!EventTracker} */ - this.eventTracker_ = new EventTracker; - this.eventTracker_.add(cr.doc, 'focusin', this.onFocusin_.bind(this)); - this.eventTracker_.add(cr.doc, 'keydown', this.onKeydown_.bind(this)); - - this.items.forEach(function(item) { - if (item != document.activeElement) - item.tabIndex = -1; - - this.eventTracker_.add(item, 'mousedown', this.onMousedown_.bind(this)); - }, this); - - /** - * The index that should be actively participating in the page tab order. - * @type {number} - * @private - */ - this.activeIndex_ = this.items.indexOf(document.activeElement); - } + function FocusRow() {} /** @interface */ FocusRow.Delegate = function() {}; FocusRow.Delegate.prototype = { /** - * Called when a key is pressed while an item in |this.items| is focused. If - * |e|'s default is prevented, further processing is skipped. + * Called when a key is pressed while an item in |this.focusableElements| is + * focused. If |e|'s default is prevented, further processing is skipped. * @param {cr.ui.FocusRow} row The row that detected a keydown. * @param {Event} e * @return {boolean} Whether the event was handled. @@ -88,58 +53,89 @@ onMousedown: assertNotReached, }; - /** @interface */ - FocusRow.Observer = function() {}; - - FocusRow.Observer.prototype = { - /** - * Called when the row is activated (added to the focus order). - * @param {cr.ui.FocusRow} row The row added to the focus order. - */ - onActivate: assertNotReached, - - /** - * Called when the row is deactivated (removed from the focus order). - * @param {cr.ui.FocusRow} row The row removed from the focus order. - */ - onDeactivate: assertNotReached, - }; - FocusRow.prototype = { - get activeIndex() { - return this.activeIndex_; - }, - set activeIndex(index) { - var wasActive = this.items[this.activeIndex_]; - if (wasActive) - wasActive.tabIndex = -1; + __proto__: HTMLDivElement.prototype, - this.items.forEach(function(item) { assert(item.tabIndex == -1); }); - this.activeIndex_ = index; + /** + * Should be called in the constructor to decorate |this|. + * @param {Node} boundary Focus events are ignored outside of this node. + * @param {FocusRow.Delegate=} opt_delegate A delegate to handle key events. + */ + decorate: function(boundary, opt_delegate) { + /** @private {!Node} */ + this.boundary_ = boundary || document; - if (this.items[index]) - this.items[index].tabIndex = 0; + /** @type {cr.ui.FocusRow.Delegate|undefined} */ + this.delegate = opt_delegate; - if (!this.observer_) - return; + /** @type {Array<Element>} */ + this.focusableElements = []; - var isActive = index >= 0 && index < this.items.length; - if (isActive == !!wasActive) - return; - - if (isActive) - this.observer_.onActivate(this); - else - this.observer_.onDeactivate(this); + /** @private {!EventTracker} */ + this.eventTracker_ = new EventTracker; + this.eventTracker_.add(cr.doc, 'focusin', this.onFocusin_.bind(this)); + this.eventTracker_.add(cr.doc, 'keydown', this.onKeydown_.bind(this)); }, /** - * Focuses the item at |index|. - * @param {number} index An index to focus. Must be between 0 and - * this.items.length - 1. + * Called when the row's active state changes and it is added/removed from + * the focus order. + * @param {boolean} state Whether the row has become active or inactive. */ - focusIndex: function(index) { - this.items[index].focus(); + onActiveStateChanged: function(state) {}, + + /** + * Find the element that best matches |sampleElement|. + * @param {Element} sampleElement An element from a row of the same type + * which previously held focus. + * @return {!Element} The element that best matches sampleElement. + */ + getEquivalentElement: assertNotReached, + + /** + * Add an element to this FocusRow. No-op if |element| is not provided. + * @param {Element} element The element that should be added. + */ + addFocusableElement: function(element) { + if (!element) + return; + + assert(this.focusableElements.indexOf(element) == -1); + assert(this.contains(element)); + + this.focusableElements.push(element); + this.eventTracker_.add(element, 'mousedown', + this.onMousedown_.bind(this)); + }, + + /** + * Called when focus changes to activate/deactivate the row. Focus is + * removed from the row when |element| is not in the FocusRow. + * @param {Element} element The element that has focus. null if focus should + * be removed. + * @private + */ + onFocusChange_: function(element) { + var isActive = this.contains(element); + var wasActive = this.classList.contains('focus-row-active'); + + // Only send events if the active state is different for the row. + if (isActive != wasActive) + this.makeRowActive(isActive); + }, + + /** + * Enables/disables the tabIndex of the focusable elements in the FocusRow. + * tabIndex can be set properly. + * @param {boolean} active True if tab is allowed for this row. + */ + makeRowActive: function(active) { + this.focusableElements.forEach(function(element) { + element.tabIndex = active ? 0 : -1; + }); + + this.classList.toggle('focus-row-active', active); + this.onActiveStateChanged(active); }, /** Call this to clean up event handling before dereferencing. */ @@ -153,37 +149,38 @@ */ onFocusin_: function(e) { if (this.boundary_.contains(assertInstanceof(e.target, Node))) - this.activeIndex = this.items.indexOf(e.target); + this.onFocusChange_(e.target); }, /** - * @param {Event} e A focus event. + * Handles a keypress for an element in this FocusRow. + * @param {Event} e The keydown event. * @private */ onKeydown_: function(e) { - var item = this.items.indexOf(e.target); - if (item < 0) + if (!this.contains(e.target)) return; - if (this.delegate_ && this.delegate_.onKeydown(this, e)) + if (this.delegate && this.delegate.onKeydown(this, e)) return; + var elementIndex = this.focusableElements.indexOf(e.target); var index = -1; if (e.keyIdentifier == 'Left') - index = item + (isRTL() ? 1 : -1); + index = elementIndex + (isRTL() ? 1 : -1); else if (e.keyIdentifier == 'Right') - index = item + (isRTL() ? -1 : 1); + index = elementIndex + (isRTL() ? -1 : 1); else if (e.keyIdentifier == 'Home') index = 0; else if (e.keyIdentifier == 'End') - index = this.items.length - 1; + index = this.focusableElements.length - 1; - if (!this.items[index]) - return; - - this.focusIndex(index); - e.preventDefault(); + var elementToFocus = this.focusableElements[index]; + if (elementToFocus) { + this.getEquivalentElement(elementToFocus).focus(); + e.preventDefault(); + } }, /** @@ -191,11 +188,14 @@ * @private */ onMousedown_: function(e) { - if (this.delegate_ && this.delegate_.onMousedown(this, e)) + if (this.delegate && this.delegate.onMousedown(this, e)) return; - if (!e.button) - this.activeIndex = this.items.indexOf(e.currentTarget); + // Only accept the left mouse click. + if (!e.button) { + // Focus this row if the target is one of the elements in this row. + this.onFocusChange_(e.target); + } }, };
diff --git a/ui/webui/resources/polymer_resources.grdp b/ui/webui/resources/polymer_resources.grdp index ad7f86a..aa844d98 100644 --- a/ui/webui/resources/polymer_resources.grdp +++ b/ui/webui/resources/polymer_resources.grdp
@@ -54,6 +54,9 @@ <structure name="IDR_POLYMER_CORE_ICONS_CORE_ICONS_HTML" file="../../../third_party/polymer/components-chromium/core-icons/core-icons.html" type="chrome_html" /> + <structure name="IDR_POLYMER_CORE_ICONS_IMAGE_ICONS_HTML" + file="../../../third_party/polymer/components-chromium/core-icons/image-icons.html" + type="chrome_html" /> <structure name="IDR_POLYMER_CORE_ICONSET_CORE_ICONSET_EXTRACTED_JS" file="../../../third_party/polymer/components-chromium/core-iconset/core-iconset-extracted.js" type="chrome_html" />
diff --git a/webkit/DEPS b/webkit/DEPS index 72dbfae..9eae709 100644 --- a/webkit/DEPS +++ b/webkit/DEPS
@@ -1,6 +1,7 @@ # Do NOT add chrome to the list below. We shouldn't be including files from # src/chrome in src/webkit. include_rules = [ + "+cc/blink", "+cc/output", "+gpu/GLES2", "+gpu/blink",
diff --git a/webkit/common/gpu/context_provider_in_process.cc b/webkit/common/gpu/context_provider_in_process.cc index a12493c..7eb90a9 100644 --- a/webkit/common/gpu/context_provider_in_process.cc +++ b/webkit/common/gpu/context_provider_in_process.cc
@@ -4,8 +4,6 @@ #include "webkit/common/gpu/context_provider_in_process.h" -#include <set> - #include "base/bind.h" #include "base/callback_helpers.h" #include "base/strings/stringprintf.h"
diff --git a/webkit/common/gpu/context_provider_in_process.h b/webkit/common/gpu/context_provider_in_process.h index e3c9ea1..0ab7542 100644 --- a/webkit/common/gpu/context_provider_in_process.h +++ b/webkit/common/gpu/context_provider_in_process.h
@@ -11,7 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" -#include "webkit/common/gpu/context_provider_web_context.h" +#include "cc/blink/context_provider_web_context.h" #include "webkit/common/gpu/webkit_gpu_export.h" namespace blink { class WebGraphicsContext3D; } @@ -25,7 +25,7 @@ class GrContextForWebGraphicsContext3D; class WEBKIT_GPU_EXPORT ContextProviderInProcess - : NON_EXPORTED_BASE(public ContextProviderWebContext) { + : NON_EXPORTED_BASE(public cc_blink::ContextProviderWebContext) { public: static scoped_refptr<ContextProviderInProcess> Create( scoped_ptr<gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl> @@ -43,7 +43,7 @@ const std::string& debug_name); ~ContextProviderInProcess() override; - // ContextProviderWebContext: + // cc_blink::ContextProviderWebContext: blink::WebGraphicsContext3D* WebContext3D() override; // cc::ContextProvider: