diff --git a/DEPS b/DEPS index e8af060..a516c3a 100644 --- a/DEPS +++ b/DEPS
@@ -138,11 +138,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '6a07591a5577b63893dc4018a7c54fc4bb28dbb2', + 'skia_revision': '09f5aedf2cc886296641658fdb800ced1e7f0b7e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '2cb25737c9eb7893ac752674e75d400b4419f67c', + 'v8_revision': 'ddbb5499b8722f494df8daa5b5e21e3f5e2b6f64', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -150,7 +150,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': 'f7106d16306ae3a98a37100ee028b5aaeca63586', + 'angle_revision': 'c104b2d24a6f0593d5bf5ccce4b594e644a5abcb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -158,7 +158,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': '8fa6a209221b41c841c6b646bc4c55825c20682f', + 'pdfium_revision': '8e6dcdbee832eca11a20f234216146ecb4884d0b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -201,7 +201,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '3d4e56f8f4efe9b095c61a4c10d11c20eeaa63f0', + 'catapult_revision': '5b31e690a48d5f7a8ba38825a603a57bca282038', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -273,7 +273,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '839053b90c7718b9162a123ce040117d2d223cc3', + 'dawn_revision': 'c2750abd0c62608f0ebed44aae3716257e8dec41', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -807,7 +807,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '09fad2edc8250ba00e3a4c20447e10104d205292', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a3fa5283c9f7561d1e53a3dc009ea76b45ab68bb', 'condition': 'checkout_linux', }, @@ -832,7 +832,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cd28c22b7b65a63da1120592adb73c2ec6e9954a', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c38806be7188121ad4778fb07ad396213fe69c94', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1182,7 +1182,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '7f727d4068ec466c3b1f3ba5f178fe2f58f1d1d7', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '9e68bfc4b622e1d509f5767cd715cf059215eb43', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1350,7 +1350,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '85b8ce2ab95bea71bebd5238f86df04183ac4025', + Var('webrtc_git') + '/src.git' + '@' + '114e8bb7a68f239b5611f71414ca99058ae02464', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1391,7 +1391,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@261cefc6693a5217e6f9af7b05b762c1cee2a433', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@64bd50cc7d890d38cafa0c0b81da34bcdc79b40d', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_metrics_service_client.cc b/android_webview/browser/aw_metrics_service_client.cc index c37f068..d98a0a9c 100644 --- a/android_webview/browser/aw_metrics_service_client.cc +++ b/android_webview/browser/aw_metrics_service_client.cc
@@ -5,27 +5,20 @@ #include "android_webview/browser/aw_metrics_service_client.h" #include <jni.h> -#include <stdint.h> -#include <utility> -#include <vector> +#include <cstdint> +#include <memory> #include "android_webview/browser/aw_feature_list.h" #include "android_webview/browser/aw_metrics_log_uploader.h" #include "android_webview/common/aw_switches.h" #include "android_webview/jni/AwMetricsServiceClient_jni.h" -#include "base/android/build_info.h" #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/guid.h" #include "base/hash/hash.h" #include "base/i18n/rtl.h" #include "base/lazy_instance.h" -#include "base/path_service.h" #include "base/strings/string16.h" -#include "base/task/post_task.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/enabled_state_provider.h" #include "components/metrics/gpu/gpu_metrics_provider.h" @@ -35,12 +28,10 @@ #include "components/metrics/metrics_state_manager.h" #include "components/metrics/net/network_metrics_provider.h" #include "components/metrics/ui/screen_info_metrics_provider.h" -#include "components/metrics/url_constants.h" #include "components/metrics/version_utils.h" #include "components/prefs/pref_service.h" #include "components/version_info/android/channel_getter.h" #include "components/version_info/version_info.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/network_service_instance.h" namespace android_webview { @@ -49,14 +40,6 @@ namespace { -const int kUploadIntervalMinutes = 30; - -// A GUID in text form is composed of 32 hex digits and 4 hyphens. -const size_t kGuidSize = 32 + 4; -// The legacy file where WebView used to store the client ID, before it was -// moved to prefs. -const char* const kGuidFileName = "metrics_guid"; - // Callbacks for metrics::MetricsStateManager::Create. Store/LoadClientInfo // allow Windows Chrome to back up ClientInfo. They're no-ops for WebView. @@ -87,57 +70,27 @@ return hash < UINT32_MAX / 50u; } -// Load the client ID from the legacy file, if any, store it in |id|, and then -// delete the file. -// TODO(crbug/939002): Remove this after ~all clients have migrated the ID. -void LoadLegacyClientId(std::unique_ptr<std::string>* id) { - base::FilePath path; - if (!internal::GetLegacyClientIdPath(&path)) - return; - std::string contents; - if (base::ReadFileToStringWithMaxSize(path, &contents, kGuidSize)) { - if (base::IsValidGUID(contents)) - *id = std::make_unique<std::string>(std::move(contents)); - } - base::DeleteFile(path, /*recursive=*/false); -} - -std::unique_ptr<::metrics::MetricsService> CreateMetricsService( - ::metrics::MetricsStateManager* state_manager, - ::metrics::MetricsServiceClient* client, +std::unique_ptr<metrics::MetricsService> CreateMetricsService( + metrics::MetricsStateManager* state_manager, + metrics::MetricsServiceClient* client, PrefService* prefs) { auto service = - std::make_unique<::metrics::MetricsService>(state_manager, client, prefs); + std::make_unique<metrics::MetricsService>(state_manager, client, prefs); service->RegisterMetricsProvider( - std::make_unique<::metrics::NetworkMetricsProvider>( + std::make_unique<metrics::NetworkMetricsProvider>( content::CreateNetworkConnectionTrackerAsyncGetter())); service->RegisterMetricsProvider( - std::make_unique<::metrics::GPUMetricsProvider>()); + std::make_unique<metrics::GPUMetricsProvider>()); service->RegisterMetricsProvider( - std::make_unique<::metrics::ScreenInfoMetricsProvider>()); + std::make_unique<metrics::ScreenInfoMetricsProvider>()); service->RegisterMetricsProvider( - std::make_unique<::metrics::CallStackProfileMetricsProvider>()); + std::make_unique<metrics::CallStackProfileMetricsProvider>()); service->InitializeMetricsRecordingState(); return service; } } // namespace -namespace internal { - -// Get the path to the file where WebView used to store the client ID, before -// it was moved to prefs. Return true/false on success/failure. -// TODO(crbug/939002): Remove this after ~all clients have migrated the ID. -bool GetLegacyClientIdPath(base::FilePath* path) { - base::FilePath dir; - if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &dir)) - return false; - *path = dir.Append(FILE_PATH_LITERAL(kGuidFileName)); - return true; -} - -} // namespace internal - // static AwMetricsServiceClient* AwMetricsServiceClient::GetInstance() { AwMetricsServiceClient* client = g_lazy_instance_.Pointer(); @@ -150,7 +103,6 @@ void AwMetricsServiceClient::Initialize(PrefService* pref_service) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(pref_service_ == nullptr); // Initialize should only happen once. DCHECK(!init_finished_); pref_service_ = pref_service; @@ -160,11 +112,8 @@ base::BindRepeating(&StoreClientInfo), base::BindRepeating(&LoadClientInfo)); - base::PostTaskWithTraitsAndReply( - FROM_HERE, {base::MayBlock()}, - base::BindOnce(&LoadLegacyClientId, &legacy_client_id_), - base::BindOnce(&AwMetricsServiceClient::InitializeWithClientId, - base::Unretained(this))); + init_finished_ = true; + MaybeStartMetrics(); } void AwMetricsServiceClient::MaybeStartMetrics() { @@ -223,7 +172,7 @@ void AwMetricsServiceClient::SetMetricsClientId(const std::string& client_id) {} int32_t AwMetricsServiceClient::GetProduct() { - return ::metrics::ChromeUserMetricsExtension::ANDROID_WEBVIEW; + return metrics::ChromeUserMetricsExtension::ANDROID_WEBVIEW; } std::string AwMetricsServiceClient::GetApplicationLocale() { @@ -255,17 +204,17 @@ base::StringPiece mime_type, metrics::MetricsLogUploader::MetricServiceType service_type, const metrics::MetricsLogUploader::UploadCallback& on_upload_complete) { - // |server_url|, |insecure_server_url| and |mime_type| are unused because - // WebView uses the platform logging mechanism instead of the normal UMA - // server. - return std::unique_ptr<::metrics::MetricsLogUploader>( - new AwMetricsLogUploader(on_upload_complete)); + // |server_url|, |insecure_server_url|, and |mime_type| are unused because + // WebView sends metrics to the platform logging mechanism rather than to + // Chrome's metrics server. + return std::make_unique<AwMetricsLogUploader>(on_upload_complete); } base::TimeDelta AwMetricsServiceClient::GetStandardUploadInterval() { // The platform logging mechanism is responsible for upload frequency; this - // just specifies how frequently to provide logs to the platform. - return base::TimeDelta::FromMinutes(kUploadIntervalMinutes); + // just specifies how frequently to provide logs to the platform. 30 minutes + // was chosen arbitrarily. + return base::TimeDelta::FromMinutes(30); } std::string AwMetricsServiceClient::GetAppPackageName() { @@ -280,20 +229,6 @@ return std::string(); } -void AwMetricsServiceClient::InitializeWithClientId() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!init_finished_); - - if (legacy_client_id_) { - pref_service_->SetString(metrics::prefs::kMetricsClientID, - *legacy_client_id_); - legacy_client_id_.reset(); - } - - init_finished_ = true; - MaybeStartMetrics(); -} - bool AwMetricsServiceClient::IsInSample() { // Called in MaybeStartMetrics(), after metrics_service_ is created. return ::android_webview::IsInSample(metrics_service_->GetClientId());
diff --git a/android_webview/browser/aw_metrics_service_client.h b/android_webview/browser/aw_metrics_service_client.h index fb145dc..fda24ae 100644 --- a/android_webview/browser/aw_metrics_service_client.h +++ b/android_webview/browser/aw_metrics_service_client.h
@@ -18,21 +18,12 @@ class PrefService; -namespace base { -class FilePath; -} - namespace metrics { class MetricsStateManager; } namespace android_webview { -// Exposed for testing. -namespace internal { -bool GetLegacyClientIdPath(base::FilePath* path); -} - // AwMetricsServiceClient is a singleton which manages WebView metrics // collection. // @@ -44,17 +35,12 @@ // SetHaveMetricsConsent(). The last is recorded in |is_in_sample_|. // // Metrics are pseudonymously identified by a randomly-generated "client ID". -// WebView stores this in the app's data directory. There's a different such -// directory for each user, for each app, on each device. So the ID should be -// unique per (device, app, user) tuple. -// -// The client ID should be stored in prefs. But as a vestige from before WebView -// persisted prefs across runs, it may be stored in a separate file named -// "metrics_guid". If such a file is found, it should be deleted and the ID -// moved into prefs. +// WebView stores this in prefs, written to the app's data directory. There's a +// different such directory for each user, for each app, on each device. So the +// ID should be unique per (device, app, user) tuple. // // To avoid the appearance that we're doing anything sneaky, the client ID -// should only be created or persisted when neither the user nor the app have +// should only be created and retained when neither the user nor the app have // opted out. Otherwise, the presence of the ID could give the impression that // metrics were being collected. // @@ -62,43 +48,36 @@ // // startup // │ -// ├──────────────────────────┐ -// │ ▼ -// ▼ query GMS for consent -// Initialize() │ -// │ │ -// ▼ │ -// LoadLegacyClientId() │ -// │ │ -// ▼ │ -// InitializeWithClientId() ▼ -// │ SetHaveMetricsConsent() -// │ │ -// │ ┌────────────────────────┘ +// ├────────────┐ +// │ ▼ +// │ query GMS for consent +// ▼ │ +// Initialize() │ +// │ ▼ +// │ SetHaveMetricsConsent() +// │ │ +// │ ┌──────────┘ // ▼ ▼ // MaybeStartMetrics() // │ // ▼ // MetricsService::Start() // -// LoadLegacyClientId() is the only function in this diagram that happens off -// the UI thread. It checks for the legacy metrics_guid file. If it contains a -// client ID, it stores the ID in |legacy_client_id_|. Then it deletes the file. -// Once ~all clients have deleted the file, LoadLegacyClientId() can be removed, -// and Initialize() and InitializeWithClientId() can be merged. -// -// Querying GMS is slow, so SetHaveMetricsConsent() typically happens after -// InitializeWithClientId(). But it may happen before Initialize(), or between -// Initialize() and InitializeWithClientId(). +// All the named functions in this diagram happen on the UI thread. Querying GMS +// happens in the background, and the result is posted back to the UI thread, to +// SetHaveMetricsConsent(). Querying GMS is slow, so SetHaveMetricsConsent() +// typically happens after Initialize(), but it may happen before. // // Each path sets a flag, |init_finished_| or |set_consent_finished_|, to show // that path has finished, and then calls MaybeStartMetrics(). When -// MaybeStartMetrics() is called the second time, it sees both flags true, -// meaning we have both the client ID (if any) and the user/app opt-out status. +// MaybeStartMetrics() is called the first time, it sees only one flag is true, +// and does nothing. When MaybeStartMetrics() is called the second time, it +// decides whether to start metrics. // -// If consent is granted, MaybeStartMetrics() then determines sampling by -// hashing the ID (generating a new ID if there was none), and may then enable -// metrics. Otherwise, it clears the client ID. +// If consent was granted, MaybeStartMetrics() determines sampling by hashing +// the client ID (generating a new ID if there was none). If this client is in +// the sample, it then calls MetricsService::Start(). If consent was not +// granted, MaybeStartMetrics() instead clears the client ID, if any. class AwMetricsServiceClient : public metrics::MetricsServiceClient, public metrics::EnabledStateProvider { friend struct base::LazyInstanceTraitsBase<AwMetricsServiceClient>; @@ -138,18 +117,11 @@ std::string GetAppPackageName() override; protected: - // virtual for testing - virtual void InitializeWithClientId(); - virtual bool IsInSample(); + virtual bool IsInSample(); // virtual for testing private: void MaybeStartMetrics(); - // Temporarily stores a client ID loaded from the legacy file, to pass it from - // LoadLegacyClientId() to InitializeWithClientId(). - // TODO(crbug/939002): Remove this after ~all clients have migrated the ID. - std::unique_ptr<std::string> legacy_client_id_; - std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_; std::unique_ptr<metrics::MetricsService> metrics_service_; PrefService* pref_service_ = nullptr;
diff --git a/android_webview/browser/aw_metrics_service_client_unittest.cc b/android_webview/browser/aw_metrics_service_client_unittest.cc index 0f1844b..0066f92 100644 --- a/android_webview/browser/aw_metrics_service_client_unittest.cc +++ b/android_webview/browser/aw_metrics_service_client_unittest.cc
@@ -4,13 +4,9 @@ #include "android_webview/browser/aw_metrics_service_client.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "base/path_service.h" #include "base/run_loop.h" -#include "base/test/scoped_path_override.h" #include "base/test/scoped_task_environment.h" #include "base/test/test_simple_task_runner.h" #include "components/metrics/metrics_pref_names.h" @@ -23,21 +19,13 @@ // For client ID format, see: // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) -const char kValidClientId[] = "01234567-89ab-40cd-80ef-0123456789ab"; -const char kInvalidClientId[] = "foo"; +const char kTestClientId[] = "01234567-89ab-40cd-80ef-0123456789ab"; class TestClient : public AwMetricsServiceClient { public: TestClient() {} ~TestClient() override {} - void RunUntilInitialized() { - if (init_finished_) - return; - run_loop_.Run(); - ASSERT_TRUE(init_finished_); - } - bool IsRecordingActive() { auto* service = GetMetricsService(); if (service) @@ -46,18 +34,9 @@ } protected: - void InitializeWithClientId() override { - AwMetricsServiceClient::InitializeWithClientId(); - init_finished_ = true; - run_loop_.Quit(); - } - bool IsInSample() override { return true; } private: - base::RunLoop run_loop_; - bool init_finished_ = false; - DISALLOW_COPY_AND_ASSIGN(TestClient); }; @@ -70,7 +49,6 @@ std::unique_ptr<TestClient> CreateAndInitTestClient(PrefService* prefs) { auto client = std::make_unique<TestClient>(); client->Initialize(prefs); - client->RunUntilInitialized(); return client; } @@ -98,9 +76,8 @@ auto client = std::make_unique<TestClient>(); client->SetHaveMetricsConsent(true); client->Initialize(prefs.get()); - client->RunUntilInitialized(); ASSERT_TRUE(client->IsRecordingActive()); - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); + ASSERT_TRUE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); } TEST_F(AwMetricsServiceClientTest, TestSetConsentFalseBeforeInit) { @@ -108,29 +85,8 @@ auto client = std::make_unique<TestClient>(); client->SetHaveMetricsConsent(false); client->Initialize(prefs.get()); - client->RunUntilInitialized(); ASSERT_FALSE(client->IsRecordingActive()); - ASSERT_FALSE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); -} - -TEST_F(AwMetricsServiceClientTest, TestSetConsentTrueDuringInit) { - auto prefs = CreateTestPrefs(); - auto client = std::make_unique<TestClient>(); - client->Initialize(prefs.get()); - client->SetHaveMetricsConsent(true); - client->RunUntilInitialized(); - ASSERT_TRUE(client->IsRecordingActive()); - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); -} - -TEST_F(AwMetricsServiceClientTest, TestSetConsentFalseDuringInit) { - auto prefs = CreateTestPrefs(); - auto client = std::make_unique<TestClient>(); - client->Initialize(prefs.get()); - client->SetHaveMetricsConsent(false); - client->RunUntilInitialized(); - ASSERT_FALSE(client->IsRecordingActive()); - ASSERT_FALSE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); + ASSERT_FALSE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); } TEST_F(AwMetricsServiceClientTest, TestSetConsentTrueAfterInit) { @@ -138,7 +94,7 @@ auto client = CreateAndInitTestClient(prefs.get()); client->SetHaveMetricsConsent(true); ASSERT_TRUE(client->IsRecordingActive()); - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); + ASSERT_TRUE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); } TEST_F(AwMetricsServiceClientTest, TestSetConsentFalseAfterInit) { @@ -146,72 +102,27 @@ auto client = CreateAndInitTestClient(prefs.get()); client->SetHaveMetricsConsent(false); ASSERT_FALSE(client->IsRecordingActive()); - ASSERT_FALSE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); + ASSERT_FALSE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); } // If there is already a valid client ID, it should be reused. -TEST_F(AwMetricsServiceClientTest, TestKeepValidClientId) { +TEST_F(AwMetricsServiceClientTest, TestKeepExistingClientId) { auto prefs = CreateTestPrefs(); - prefs->SetString(::metrics::prefs::kMetricsClientID, kValidClientId); + prefs->SetString(metrics::prefs::kMetricsClientID, kTestClientId); auto client = CreateAndInitTestClient(prefs.get()); client->SetHaveMetricsConsent(true); ASSERT_TRUE(client->IsRecordingActive()); - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); - ASSERT_EQ(kValidClientId, - prefs->GetString(::metrics::prefs::kMetricsClientID)); + ASSERT_TRUE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); + ASSERT_EQ(kTestClientId, prefs->GetString(metrics::prefs::kMetricsClientID)); } TEST_F(AwMetricsServiceClientTest, TestSetConsentFalseClearsClientId) { auto prefs = CreateTestPrefs(); - prefs->SetString(::metrics::prefs::kMetricsClientID, kValidClientId); + prefs->SetString(metrics::prefs::kMetricsClientID, kTestClientId); auto client = CreateAndInitTestClient(prefs.get()); client->SetHaveMetricsConsent(false); ASSERT_FALSE(client->IsRecordingActive()); - ASSERT_FALSE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); -} - -// TODO(crbug/939002): Remove this after ~all clients have migrated the ID. -TEST_F(AwMetricsServiceClientTest, TestLoadAndDeleteLegacyClientId) { - // Write a valid client ID to the legacy client ID file. - base::ScopedPathOverride app_data_override(base::DIR_ANDROID_APP_DATA); - base::FilePath legacy_file_path; - ASSERT_TRUE(internal::GetLegacyClientIdPath(&legacy_file_path)); - constexpr int len = base::size(kValidClientId) - 1; - ASSERT_EQ(len, base::WriteFile(legacy_file_path, kValidClientId, len)); - - // Exercise AwMetricsServiceClient. - auto prefs = CreateTestPrefs(); - auto client = CreateAndInitTestClient(prefs.get()); - client->SetHaveMetricsConsent(true); - ASSERT_TRUE(client->IsRecordingActive()); - // The valid ID should have been stored in prefs. - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); - ASSERT_EQ(kValidClientId, - prefs->GetString(::metrics::prefs::kMetricsClientID)); - // The legacy file should have been deleted. - ASSERT_FALSE(base::PathExists(legacy_file_path)); -} - -// TODO(crbug/939002): Remove this after ~all clients have migrated the ID. -TEST_F(AwMetricsServiceClientTest, TestDeleteInvalidLegacyClientId) { - // Write an invalid client ID to the legacy client ID file. - base::ScopedPathOverride app_data_override(base::DIR_ANDROID_APP_DATA); - base::FilePath legacy_file_path; - ASSERT_TRUE(internal::GetLegacyClientIdPath(&legacy_file_path)); - constexpr int len = base::size(kInvalidClientId) - 1; - ASSERT_EQ(len, base::WriteFile(legacy_file_path, kInvalidClientId, len)); - - // Exercise AwMetricsServiceClient. - auto prefs = CreateTestPrefs(); - auto client = CreateAndInitTestClient(prefs.get()); - client->SetHaveMetricsConsent(true); - ASSERT_TRUE(client->IsRecordingActive()); - // A new ID should have been generated and stored in prefs. - ASSERT_TRUE(prefs->HasPrefPath(::metrics::prefs::kMetricsClientID)); - ASSERT_NE(kInvalidClientId, - prefs->GetString(::metrics::prefs::kMetricsClientID)); - // The legacy file should have been deleted. - ASSERT_FALSE(base::PathExists(legacy_file_path)); + ASSERT_FALSE(prefs->HasPrefPath(metrics::prefs::kMetricsClientID)); } } // namespace android_webview
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 02d2311..09daa9b 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -960,6 +960,8 @@ "system/unified/page_indicator_view.h", "system/unified/quiet_mode_feature_pod_controller.cc", "system/unified/quiet_mode_feature_pod_controller.h", + "system/unified/rounded_label_button.cc", + "system/unified/rounded_label_button.h", "system/unified/sign_out_button.cc", "system/unified/sign_out_button.h", "system/unified/top_shortcut_button.cc", @@ -1641,6 +1643,7 @@ "keyboard/ash_keyboard_controller_unittest.cc", "keyboard/virtual_keyboard_controller_unittest.cc", "keyboard/virtual_keyboard_unittest.cc", + "kiosk_next/kiosk_next_home_controller_unittest.cc", "kiosk_next/kiosk_next_shell_controller_unittest.cc", "kiosk_next/kiosk_next_shell_test_util.cc", "kiosk_next/kiosk_next_shell_test_util.h",
diff --git a/ash/app_list/views/search_result_tile_item_view.cc b/ash/app_list/views/search_result_tile_item_view.cc index 06b5527..662f9f0 100644 --- a/ash/app_list/views/search_result_tile_item_view.cc +++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -205,7 +205,8 @@ title_->SetMultiLine( (result()->display_type() == ash::SearchResultDisplayType::kTile || (IsSuggestedAppTile() && !show_in_apps_page_)) && - result()->result_type() == ash::SearchResultType::kInstalledApp); + (result()->result_type() == ash::SearchResultType::kInstalledApp || + result()->result_type() == ash::SearchResultType::kArcAppShortcut)); // If the new icon is null, it's being decoded asynchronously. Not updating it // now to prevent flickering from showing an empty icon while decoding.
diff --git a/ash/kiosk_next/kiosk_next_home_controller.cc b/ash/kiosk_next/kiosk_next_home_controller.cc index 90b20e1e..c881428 100644 --- a/ash/kiosk_next/kiosk_next_home_controller.cc +++ b/ash/kiosk_next/kiosk_next_home_controller.cc
@@ -11,13 +11,18 @@ #include "ash/screen_util.h" #include "ash/shell.h" #include "ash/wm/container_finder.h" +#include "ash/wm/overview/overview_controller.h" +#include "ash/wm/toplevel_window_event_handler.h" +#include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" #include "base/logging.h" #include "ui/aura/window.h" +#include "ui/base/hit_test.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/screen.h" +#include "ui/events/event_target.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/transform.h" @@ -111,10 +116,12 @@ Shell::Get()->screen_orientation_controller()->LockOrientationForWindow( home_screen_window_, OrientationLockType::kLandscape); + Shell::Get()->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem); } void KioskNextHomeController::OnWillRemoveWindow(aura::Window* window) { DCHECK_EQ(home_screen_window_, window); + Shell::Get()->RemovePreTargetHandler(this); home_screen_window_ = nullptr; } @@ -123,4 +130,30 @@ home_screen_container_ = nullptr; } +void KioskNextHomeController::OnGestureEvent(ui::GestureEvent* event) { + if (event->type() != ui::EventType::ET_GESTURE_SCROLL_BEGIN) + return; + + aura::Window* target = static_cast<aura::Window*>(event->target()); + int component = wm::GetNonClientComponent(target, event->location()); + + aura::Window* new_target = + ToplevelWindowEventHandler::GetTargetForClientAreaGesture(event, target); + + if (new_target) + target = new_target; + + if (target != home_screen_container_ && target != home_screen_window_) + return; + + if (component == HTCLIENT) { + event->SetHandled(); + event->StopPropagation(); + + auto* overview_controller = Shell::Get()->overview_controller(); + if (!overview_controller->InOverviewSession()) + overview_controller->ToggleOverview(); + } +} + } // namespace ash
diff --git a/ash/kiosk_next/kiosk_next_home_controller.h b/ash/kiosk_next/kiosk_next_home_controller.h index aed0000..6aec00c 100644 --- a/ash/kiosk_next/kiosk_next_home_controller.h +++ b/ash/kiosk_next/kiosk_next_home_controller.h
@@ -10,15 +10,22 @@ #include "base/macros.h" #include "ui/aura/window_observer.h" #include "ui/display/display_observer.h" +#include "ui/events/event_handler.h" + +namespace ui { +class GestureEvent; +} namespace ash { // KioskNextHomeController manages the Home window for the Kiosk Next shell. -// TODO(michaelpg): Manage gestures on the Home window, such as dragging down -// from the top for Overview mode. +// TODO(michaelpg): Show a slide-down animation when opening Overview. +// TODO(michaelpg): Suppress tap events in the Kiosk Next Home window when a +// gesture event triggers Overview this way. class ASH_EXPORT KioskNextHomeController : public HomeScreenDelegate, public display::DisplayObserver, - public aura::WindowObserver { + public aura::WindowObserver, + public ui::EventHandler { public: KioskNextHomeController(); ~KioskNextHomeController() override; @@ -39,11 +46,14 @@ void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override; - // WindowObserver: + // aura::WindowObserver: void OnWindowAdded(aura::Window* new_window) override; void OnWillRemoveWindow(aura::Window* window) override; void OnWindowDestroying(aura::Window* window) override; + // ui::EventHandler: + void OnGestureEvent(ui::GestureEvent* event) override; + private: aura::Window* home_screen_container_ = nullptr; aura::Window* home_screen_window_ = nullptr;
diff --git a/ash/kiosk_next/kiosk_next_home_controller_unittest.cc b/ash/kiosk_next/kiosk_next_home_controller_unittest.cc new file mode 100644 index 0000000..2cd7c988 --- /dev/null +++ b/ash/kiosk_next/kiosk_next_home_controller_unittest.cc
@@ -0,0 +1,116 @@ +// Copyright 2019 The Chromium 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 "ash/kiosk_next/kiosk_next_home_controller.h" + +#include "ash/home_screen/home_screen_controller.h" +#include "ash/kiosk_next/kiosk_next_shell_test_util.h" +#include "ash/kiosk_next/mock_kiosk_next_shell_client.h" +#include "ash/public/cpp/app_types.h" +#include "ash/public/cpp/ash_features.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/wm/overview/overview_controller.h" +#include "ash/wm/window_state.h" +#include "base/test/scoped_feature_list.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/window_types.h" +#include "ui/aura/test/test_window_delegate.h" +#include "ui/base/hit_test.h" +#include "ui/events/test/event_generator.h" + +namespace ash { +namespace { + +class KioskNextHomeControllerTest : public AshTestBase { + public: + KioskNextHomeControllerTest() = default; + ~KioskNextHomeControllerTest() override = default; + + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(features::kKioskNextShell); + set_start_session(false); + AshTestBase::SetUp(); + client_ = BindMockKioskNextShellClient(); + LogInKioskNextUser(GetSessionControllerClient()); + SetUpHomeWindow(); + } + + void TearDown() override { + home_screen_window_.reset(); + AshTestBase::TearDown(); + client_.reset(); + } + + void SetUpHomeWindow() { + auto* delegate = + aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(); + + home_screen_window_.reset( + CreateTestWindowInShellWithDelegate(delegate, 0, gfx::Rect())); + home_screen_window_->SetProperty(aura::client::kAppType, + static_cast<int>(AppType::CHROME_APP)); + home_screen_window_->set_owned_by_parent(false); + Shell::GetContainer(Shell::GetPrimaryRootWindow(), + kShellWindowId_HomeScreenContainer) + ->AddChild(home_screen_window_.get()); + + auto* window_state = wm::GetWindowState(home_screen_window_.get()); + window_state->Maximize(); + home_screen_window_->Show(); + } + + // TestWindowDelegate always returns its |window_component_| when + // TestWindowDelegate::GetNonClientComponent(const gfx::Point& point) is + // called, regardless of the location. Therefore individual tests have to set + // the |window_component_|. KioskNextHomeController's event handler starts + // overview only if the window component which the gesture event touches is + // HTCLIENT. + void SetWindowComponent(int component) { + auto* delegate = static_cast<aura::test::TestWindowDelegate*>( + home_screen_window_->delegate()); + delegate->set_window_component(component); + } + + protected: + std::unique_ptr<aura::Window> home_screen_window_; + std::unique_ptr<MockKioskNextShellClient> client_; + base::test::ScopedFeatureList scoped_feature_list_; + + private: + DISALLOW_COPY_AND_ASSIGN(KioskNextHomeControllerTest); +}; + +TEST_F(KioskNextHomeControllerTest, CheckWindows) { + auto* kiosk_next_home_controller = + Shell::Get()->home_screen_controller()->delegate(); + + EXPECT_EQ(kiosk_next_home_controller->GetHomeScreenWindow(), + home_screen_window_.get()); +} + +TEST_F(KioskNextHomeControllerTest, TestGestureToOverview) { + SetWindowComponent(HTCLIENT); + + ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); + + generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 20), + base::TimeDelta::FromMilliseconds(10), 10); + + EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession()); +} + +TEST_F(KioskNextHomeControllerTest, TestGestureToNoOverview) { + SetWindowComponent(HTNOWHERE); + + ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); + + generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 20), + base::TimeDelta::FromMilliseconds(10), 10); + + EXPECT_FALSE(Shell::Get()->overview_controller()->InOverviewSession()); +} + +} // namespace +} // namespace ash
diff --git a/ash/system/message_center/unified_message_center_view.cc b/ash/system/message_center/unified_message_center_view.cc index 5ecd365..103083b 100644 --- a/ash/system/message_center/unified_message_center_view.cc +++ b/ash/system/message_center/unified_message_center_view.cc
@@ -16,7 +16,7 @@ #include "ash/system/message_center/unified_message_list_view.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_popup_utils.h" -#include "ash/system/unified/sign_out_button.h" +#include "ash/system/unified/rounded_label_button.h" #include "ash/system/unified/unified_system_tray_model.h" #include "ash/system/unified/unified_system_tray_view.h" #include "base/metrics/user_metrics.h"
diff --git a/ash/system/unified/notification_hidden_view.cc b/ash/system/unified/notification_hidden_view.cc index f766bcf..128bcd03b 100644 --- a/ash/system/unified/notification_hidden_view.cc +++ b/ash/system/unified/notification_hidden_view.cc
@@ -10,7 +10,7 @@ #include "ash/system/message_center/ash_message_center_lock_screen_controller.h" #include "ash/system/message_center/message_center_controller.h" #include "ash/system/tray/tray_constants.h" -#include "ash/system/unified/sign_out_button.h" +#include "ash/system/unified/rounded_label_button.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ash/system/unified/rounded_label_button.cc b/ash/system/unified/rounded_label_button.cc new file mode 100644 index 0000000..02ed15ca --- /dev/null +++ b/ash/system/unified/rounded_label_button.cc
@@ -0,0 +1,85 @@ +// Copyright 2019 The Chromium 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 "ash/system/unified/rounded_label_button.h" + +#include "ash/system/tray/tray_constants.h" +#include "ash/system/tray/tray_popup_utils.h" +#include "ui/gfx/canvas.h" +#include "ui/views/animation/ink_drop.h" +#include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/ink_drop_mask.h" +#include "ui/views/animation/ink_drop_ripple.h" +#include "ui/views/border.h" +#include "ui/views/view_class_properties.h" + +namespace ash { + +RoundedLabelButton::RoundedLabelButton(views::ButtonListener* listener, + const base::string16& text) + : views::LabelButton(listener, text) { + SetEnabledTextColors(kUnifiedMenuTextColor); + SetHorizontalAlignment(gfx::ALIGN_CENTER); + SetBorder(views::CreateEmptyBorder(gfx::Insets())); + label()->SetSubpixelRenderingEnabled(false); + label()->SetFontList(views::Label::GetDefaultFontList().Derive( + 1, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM)); + TrayPopupUtils::ConfigureTrayPopupButton(this); + + auto path = std::make_unique<SkPath>(); + path->addRoundRect(gfx::RectToSkRect(gfx::Rect(CalculatePreferredSize())), + kTrayItemSize / 2, kTrayItemSize / 2); + SetProperty(views::kHighlightPathKey, path.release()); +} + +RoundedLabelButton::~RoundedLabelButton() = default; + +gfx::Size RoundedLabelButton::CalculatePreferredSize() const { + return gfx::Size(label()->GetPreferredSize().width() + kTrayItemSize, + kTrayItemSize); +} + +int RoundedLabelButton::GetHeightForWidth(int width) const { + return kTrayItemSize; +} + +void RoundedLabelButton::PaintButtonContents(gfx::Canvas* canvas) { + gfx::Rect rect(GetContentsBounds()); + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(kUnifiedMenuButtonColor); + flags.setStyle(cc::PaintFlags::kFill_Style); + canvas->DrawRoundRect(rect, kTrayItemSize / 2, flags); + + views::LabelButton::PaintButtonContents(canvas); +} + +std::unique_ptr<views::InkDrop> RoundedLabelButton::CreateInkDrop() { + return TrayPopupUtils::CreateInkDrop(this); +} + +std::unique_ptr<views::InkDropRipple> RoundedLabelButton::CreateInkDropRipple() + const { + return TrayPopupUtils::CreateInkDropRipple( + TrayPopupInkDropStyle::FILL_BOUNDS, this, + GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); +} + +std::unique_ptr<views::InkDropHighlight> +RoundedLabelButton::CreateInkDropHighlight() const { + return TrayPopupUtils::CreateInkDropHighlight( + TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); +} + +std::unique_ptr<views::InkDropMask> RoundedLabelButton::CreateInkDropMask() + const { + return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(), + kTrayItemSize / 2); +} + +const char* RoundedLabelButton::GetClassName() const { + return "RoundedLabelButton"; +} + +} // namespace ash
diff --git a/ash/system/unified/rounded_label_button.h b/ash/system/unified/rounded_label_button.h new file mode 100644 index 0000000..add7cc5 --- /dev/null +++ b/ash/system/unified/rounded_label_button.h
@@ -0,0 +1,42 @@ +// Copyright 2019 The Chromium 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 ASH_SYSTEM_UNIFIED_ROUNDED_LABEL_BUTTON_H_ +#define ASH_SYSTEM_UNIFIED_ROUNDED_LABEL_BUTTON_H_ + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "ui/views/controls/button/label_button.h" + +namespace views { +class ButtonListener; +} // namespace views + +namespace ash { + +// LabelButton that has a rounded shape with a Material Design ink drop. +class RoundedLabelButton : public views::LabelButton { + public: + RoundedLabelButton(views::ButtonListener* listener, + const base::string16& text); + ~RoundedLabelButton() override; + + // views::LabelButton: + gfx::Size CalculatePreferredSize() const override; + int GetHeightForWidth(int width) const override; + void PaintButtonContents(gfx::Canvas* canvas) override; + std::unique_ptr<views::InkDrop> CreateInkDrop() override; + std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; + std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() + const override; + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; + const char* GetClassName() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(RoundedLabelButton); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_UNIFIED_ROUNDED_LABEL_BUTTON_H_
diff --git a/ash/system/unified/sign_out_button.cc b/ash/system/unified/sign_out_button.cc index fa8cd08c..bf23fc8 100644 --- a/ash/system/unified/sign_out_button.cc +++ b/ash/system/unified/sign_out_button.cc
@@ -6,86 +6,10 @@ #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_popup_utils.h" #include "ash/system/user/login_status.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/gfx/canvas.h" -#include "ui/views/animation/flood_fill_ink_drop_ripple.h" -#include "ui/views/animation/ink_drop_highlight.h" -#include "ui/views/animation/ink_drop_impl.h" -#include "ui/views/animation/ink_drop_mask.h" -#include "ui/views/border.h" -#include "ui/views/view_class_properties.h" namespace ash { -RoundedLabelButton::RoundedLabelButton(views::ButtonListener* listener, - const base::string16& text) - : views::LabelButton(listener, text) { - SetEnabledTextColors(kUnifiedMenuTextColor); - SetHorizontalAlignment(gfx::ALIGN_CENTER); - SetBorder(views::CreateEmptyBorder(gfx::Insets())); - label()->SetSubpixelRenderingEnabled(false); - label()->SetFontList(views::Label::GetDefaultFontList().Derive( - 1, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM)); - TrayPopupUtils::ConfigureTrayPopupButton(this); - - auto path = std::make_unique<SkPath>(); - path->addRoundRect(gfx::RectToSkRect(gfx::Rect(CalculatePreferredSize())), - kTrayItemSize / 2, kTrayItemSize / 2); - SetProperty(views::kHighlightPathKey, path.release()); -} - -RoundedLabelButton::~RoundedLabelButton() = default; - -gfx::Size RoundedLabelButton::CalculatePreferredSize() const { - return gfx::Size(label()->GetPreferredSize().width() + kTrayItemSize, - kTrayItemSize); -} - -int RoundedLabelButton::GetHeightForWidth(int width) const { - return kTrayItemSize; -} - -void RoundedLabelButton::PaintButtonContents(gfx::Canvas* canvas) { - gfx::Rect rect(GetContentsBounds()); - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setColor(kUnifiedMenuButtonColor); - flags.setStyle(cc::PaintFlags::kFill_Style); - canvas->DrawRoundRect(rect, kTrayItemSize / 2, flags); - - views::LabelButton::PaintButtonContents(canvas); -} - -std::unique_ptr<views::InkDrop> RoundedLabelButton::CreateInkDrop() { - return TrayPopupUtils::CreateInkDrop(this); -} - -std::unique_ptr<views::InkDropRipple> RoundedLabelButton::CreateInkDropRipple() - const { - return TrayPopupUtils::CreateInkDropRipple( - TrayPopupInkDropStyle::FILL_BOUNDS, this, - GetInkDropCenterBasedOnLastEvent(), kUnifiedMenuIconColor); -} - -std::unique_ptr<views::InkDropHighlight> -RoundedLabelButton::CreateInkDropHighlight() const { - return TrayPopupUtils::CreateInkDropHighlight( - TrayPopupInkDropStyle::FILL_BOUNDS, this, kUnifiedMenuIconColor); -} - -std::unique_ptr<views::InkDropMask> RoundedLabelButton::CreateInkDropMask() - const { - return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(), - kTrayItemSize / 2); -} - -const char* RoundedLabelButton::GetClassName() const { - return "RoundedLabelButton"; -} - SignOutButton::SignOutButton(views::ButtonListener* listener) : RoundedLabelButton(listener, user::GetLocalizedSignOutStringForStatus(
diff --git a/ash/system/unified/sign_out_button.h b/ash/system/unified/sign_out_button.h index 501b9e4..dff18ae2 100644 --- a/ash/system/unified/sign_out_button.h +++ b/ash/system/unified/sign_out_button.h
@@ -5,32 +5,15 @@ #ifndef ASH_SYSTEM_UNIFIED_SIGN_OUT_BUTTON_H_ #define ASH_SYSTEM_UNIFIED_SIGN_OUT_BUTTON_H_ -#include "ui/views/controls/button/label_button.h" +#include "ash/system/unified/rounded_label_button.h" +#include "base/macros.h" + +namespace views { +class ButtonListener; +} // namespace views namespace ash { -// LabelButton that has rounded shape with Material Design ink drop. -class RoundedLabelButton : public views::LabelButton { - public: - RoundedLabelButton(views::ButtonListener* listener, - const base::string16& text); - ~RoundedLabelButton() override; - - // views::LabelButton: - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int width) const override; - void PaintButtonContents(gfx::Canvas* canvas) override; - std::unique_ptr<views::InkDrop> CreateInkDrop() override; - std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; - std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() - const override; - std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; - const char* GetClassName() const override; - - private: - DISALLOW_COPY_AND_ASSIGN(RoundedLabelButton); -}; - // Sign out button shown in TopShortcutView with TopShortcutButtons. // Shows the label like "Sign out", "Exit guest", etc. depending on the session // status. Not visible when not signed in.
diff --git a/ash/wm/desks/OWNERS b/ash/wm/desks/OWNERS new file mode 100644 index 0000000..111b3ba --- /dev/null +++ b/ash/wm/desks/OWNERS
@@ -0,0 +1 @@ +afakhry@chromium.org
diff --git a/ash/wm/desks/desk.cc b/ash/wm/desks/desk.cc index 7d933aa..adc51fe 100644 --- a/ash/wm/desks/desk.cc +++ b/ash/wm/desks/desk.cc
@@ -12,10 +12,34 @@ #include "ash/wm/window_state.h" #include "ash/wm/window_transient_descendant_iterator.h" #include "ash/wm/window_util.h" +#include "ash/wm/workspace/backdrop_controller.h" +#include "ash/wm/workspace/workspace_layout_manager.h" +#include "ash/wm/workspace_controller.h" #include "ui/wm/core/window_util.h" namespace ash { +namespace { + +void UpdateBackdropController(aura::Window* desk_container) { + auto* workspace_controller = GetWorkspaceController(desk_container); + DCHECK(workspace_controller); + WorkspaceLayoutManager* layout_manager = + workspace_controller->layout_manager(); + BackdropController* backdrop_controller = + layout_manager->backdrop_controller(); + backdrop_controller->OnDeskContentChanged(); +} + +// Returns true if |window| can be managed by the desk, and therefore can be +// moved out of the desk when the desk is removed. +bool CanMoveWindowOutOfDeskContainer(aura::Window* window) { + // TODO(afakhry): Is there a better way to filter windows? + return CanIncludeWindowInMruList(window); +} + +} // namespace + class DeskContainerObserver : public aura::WindowObserver { public: DeskContainerObserver(Desk* owner, aura::Window* container) @@ -62,7 +86,12 @@ } Desk::~Desk() { - DCHECK(windows_.empty()) << "DesksController should remove my windows first."; + for (auto* window : windows_) { + DCHECK(!CanMoveWindowOutOfDeskContainer(window)) + << "DesksController should remove this desk's application windows " + "first."; + window->RemoveObserver(this); + } for (auto& observer : observers_) { observers_.RemoveObserver(&observer); @@ -173,10 +202,18 @@ auto target_desk_throttled = target_desk->GetScopedNotifyContentChangedDisabler(); - for (auto* window : windows_) - MoveWindowToDeskInternal(window, target_desk); + auto iter = windows_.begin(); + while (iter != windows_.end()) { + aura::Window* window = *iter; + // Do not move non-desk windows. + if (!CanMoveWindowOutOfDeskContainer(window)) { + ++iter; + continue; + } - windows_.clear(); + MoveWindowToDeskInternal(window, target_desk); + iter = windows_.erase(iter); + } } NotifyContentChanged(); @@ -237,13 +274,25 @@ if (!should_notify_content_changed_) return; + // Update the backdrop availability and visibility first before notifying + // observers. + UpdateDeskBackdrops(); + for (auto& observer : observers_) observer.OnContentChanged(); } +void Desk::UpdateDeskBackdrops() { + for (auto* root : Shell::GetAllRootWindows()) + UpdateBackdropController(GetDeskContainerForRoot(root)); +} + void Desk::MoveWindowToDeskInternal(aura::Window* window, Desk* target_desk) { DCHECK(windows_.contains(window)); + DCHECK(CanMoveWindowOutOfDeskContainer(window)) + << "Non-desk windows are not allowed to move out of the container."; + window->RemoveObserver(this); // Add the window to the target desk before reparenting such that when the
diff --git a/ash/wm/desks/desk.h b/ash/wm/desks/desk.h index 2e38fb2..98d0cbe 100644 --- a/ash/wm/desks/desk.h +++ b/ash/wm/desks/desk.h
@@ -92,6 +92,10 @@ void NotifyContentChanged(); + // Updates the backdrop availability and visibility on the containers (on all + // roots) associated with this desk. + void UpdateDeskBackdrops(); + private: void MoveWindowToDeskInternal(aura::Window* window, Desk* target_desk);
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index a7e61ad..234c65f 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -204,6 +204,13 @@ available_container_ids_.push(removed_desk->container_id()); + // Avoid having stale backdrop state as a desk is removed while in overview + // mode, since the backdrop controller won't update the backdrop window as + // the removed desk's windows move out from the container. Therefore, we need + // to update it manually. + if (in_overview) + removed_desk->UpdateDeskBackdrops(); + DCHECK_LE(available_container_ids_.size(), desks_util::kMaxNumberOfDesks); }
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 5af15a0f..8694d4b 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -22,12 +22,18 @@ #include "ash/wm/overview/overview_item.h" #include "ash/wm/overview/overview_session.h" #include "ash/wm/splitview/split_view_drag_indicators.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" +#include "ash/wm/workspace/backdrop_controller.h" +#include "ash/wm/workspace/workspace_layout_manager.h" +#include "ash/wm/workspace_controller.h" #include "base/stl_util.h" #include "base/test/scoped_feature_list.h" #include "ui/aura/client/window_parenting_client.h" +#include "ui/compositor_extra/shadow.h" #include "ui/events/test/event_generator.h" +#include "ui/wm/core/shadow_controller.h" #include "ui/wm/core/window_util.h" namespace ash { @@ -106,6 +112,15 @@ event_generator->ReleaseLeftButton(); } +BackdropController* GetDeskBackdropController(const Desk* desk, + aura::Window* root) { + auto* workspace_controller = + GetWorkspaceController(desk->GetDeskContainerForRoot(root)); + WorkspaceLayoutManager* layout_manager = + workspace_controller->layout_manager(); + return layout_manager->backdrop_controller(); +} + // Defines an observer to test DesksController notifications. class TestObserver : public DesksController::Observer { public: @@ -867,12 +882,20 @@ wm::ActivateWindow(window.get()); EXPECT_EQ(window.get(), wm::GetActiveWindow()); + ui::Shadow* shadow = ::wm::ShadowController::GetShadowForWindow(window.get()); + ASSERT_TRUE(shadow); + ASSERT_TRUE(shadow->layer()); + EXPECT_TRUE(shadow->layer()->GetTargetVisibility()); + auto* overview_controller = Shell::Get()->overview_controller(); overview_controller->ToggleOverview(); EXPECT_TRUE(overview_controller->InOverviewSession()); auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); EXPECT_EQ(1u, overview_grid->size()); + // While in overview mode, the window's shadow is hidden. + EXPECT_FALSE(shadow->layer()->GetTargetVisibility()); + auto* overview_session = overview_controller->overview_session(); auto* overview_item = overview_session->GetOverviewItemForWindow(window.get()); @@ -907,6 +930,10 @@ EXPECT_TRUE(overview_session->no_windows_widget_for_testing()); EXPECT_TRUE(desk_2->windows().contains(window.get())); EXPECT_FALSE(overview_grid->drop_target_widget()); + + // After the window is dropped onto another desk, its shadow should be + // restored properly. + EXPECT_TRUE(shadow->layer()->GetTargetVisibility()); } TEST_F(DesksTest, DragWindowToNonMiniViewPoints) { @@ -1032,6 +1059,130 @@ EXPECT_EQ(nullptr, wm::GetActiveWindow()); } +TEST_F(DesksTest, TabletModeBackdrops) { + auto* controller = DesksController::Get(); + controller->NewDesk(); + ASSERT_EQ(2u, controller->desks().size()); + const Desk* desk_1 = controller->desks()[0].get(); + const Desk* desk_2 = controller->desks()[1].get(); + + auto window = CreateTestWindow(gfx::Rect(0, 0, 250, 100)); + wm::ActivateWindow(window.get()); + EXPECT_EQ(window.get(), wm::GetActiveWindow()); + + // Enter tablet mode and expect that the backdrop is created only for desk_1, + // since it's the one that has a window in it. + // Avoid TabletModeController::OnGetSwitchStates() from disabling tablet mode. + base::RunLoop().RunUntilIdle(); + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); + auto* desk_1_backdrop_controller = + GetDeskBackdropController(desk_1, Shell::GetPrimaryRootWindow()); + auto* desk_2_backdrop_controller = + GetDeskBackdropController(desk_2, Shell::GetPrimaryRootWindow()); + ASSERT_TRUE(desk_1_backdrop_controller->backdrop_window()); + EXPECT_TRUE(desk_1_backdrop_controller->backdrop_window()->IsVisible()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()); + + // Enter overview and expect that the backdrop is still present for desk_1 but + // hidden. + auto* overview_controller = Shell::Get()->overview_controller(); + overview_controller->ToggleOverview(); + EXPECT_TRUE(overview_controller->InOverviewSession()); + ASSERT_TRUE(desk_1_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()->IsVisible()); + + auto* overview_grid = GetOverviewGridForRoot(Shell::GetPrimaryRootWindow()); + EXPECT_EQ(1u, overview_grid->size()); + + auto* overview_session = overview_controller->overview_session(); + auto* overview_item = + overview_session->GetOverviewItemForWindow(window.get()); + ASSERT_TRUE(overview_item); + const auto* desks_bar_view = overview_grid->GetDesksBarViewForTesting(); + ASSERT_TRUE(desks_bar_view); + + // Now drag it to desk_2's mini_view, so that it moves to desk_2. Expect that + // desk_1's backdrop is destroyed, while created (but still hidden) for + // desk_2. + auto* desk_2_mini_view = desks_bar_view->mini_views()[1].get(); + EXPECT_EQ(desk_2, desk_2_mini_view->desk()); + DragItemToPoint(overview_item, + desk_2_mini_view->GetBoundsInScreen().CenterPoint(), + GetEventGenerator()); + EXPECT_TRUE(overview_controller->InOverviewSession()); + EXPECT_TRUE(desk_2->windows().contains(window.get())); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); + ASSERT_TRUE(desk_2_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()->IsVisible()); + + // Exit overview, and expect that desk_2's backdrop remains hidden since the + // desk is not activated yet. + overview_controller->ToggleOverview( + OverviewSession::EnterExitOverviewType::kImmediateExit); + EXPECT_FALSE(overview_controller->InOverviewSession()); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); + ASSERT_TRUE(desk_2_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()->IsVisible()); + + // Activate desk_2 and expect that its backdrop is now visible. + ActivateDesk(desk_2); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); + ASSERT_TRUE(desk_2_backdrop_controller->backdrop_window()); + EXPECT_TRUE(desk_2_backdrop_controller->backdrop_window()->IsVisible()); + + // No backdrops after exiting tablet mode. + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()); +} + +TEST_F(DesksTest, TabletModeDesksCreationRemovalCycle) { + auto window = CreateTestWindow(gfx::Rect(0, 0, 250, 100)); + wm::ActivateWindow(window.get()); + EXPECT_EQ(window.get(), wm::GetActiveWindow()); + + // Enter tablet mode. Avoid TabletModeController::OnGetSwitchStates() from + // disabling tablet mode. + base::RunLoop().RunUntilIdle(); + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); + + auto* overview_controller = Shell::Get()->overview_controller(); + overview_controller->ToggleOverview(); + EXPECT_TRUE(overview_controller->InOverviewSession()); + auto* desks_controller = DesksController::Get(); + + // Create and remove desks in a cycle while in overview mode. Expect as the + // containers are reused for new desks, their backdrop state are always + // correct, and there are no crashes as desks are removed. + for (size_t i = 0; i < 2 * desks_util::kMaxNumberOfDesks; ++i) { + desks_controller->NewDesk(); + ASSERT_EQ(2u, desks_controller->desks().size()); + const Desk* desk_1 = desks_controller->desks()[0].get(); + const Desk* desk_2 = desks_controller->desks()[1].get(); + auto* desk_1_backdrop_controller = + GetDeskBackdropController(desk_1, Shell::GetPrimaryRootWindow()); + auto* desk_2_backdrop_controller = + GetDeskBackdropController(desk_2, Shell::GetPrimaryRootWindow()); + { + SCOPED_TRACE("Check backdrops after desk creation"); + ASSERT_TRUE(desk_1_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()->IsVisible()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()); + } + // Remove the active desk, and expect that now desk_2 should have a hidden + // backdrop, while the container of the removed desk_1 should have none. + desks_controller->RemoveDesk(desk_1); + { + SCOPED_TRACE("Check backdrops after desk removal"); + EXPECT_TRUE(desk_2->is_active()); + EXPECT_TRUE(DoesActiveDeskContainWindow(window.get())); + EXPECT_FALSE(desk_1_backdrop_controller->backdrop_window()); + ASSERT_TRUE(desk_2_backdrop_controller->backdrop_window()); + EXPECT_FALSE(desk_2_backdrop_controller->backdrop_window()->IsVisible()); + } + } +} + class DesksWithSplitViewTest : public AshTestBase { public: DesksWithSplitViewTest() = default;
diff --git a/ash/wm/mru_window_tracker.cc b/ash/wm/mru_window_tracker.cc index e69d9c24..7be9e7f 100644 --- a/ash/wm/mru_window_tracker.cc +++ b/ash/wm/mru_window_tracker.cc
@@ -69,13 +69,6 @@ return window->CanFocus(); } -// A predicate that determines whether |window| can be included in the MRU -// window list. -bool CanIncludeWindowInMruList(aura::Window* window) { - return ::wm::CanActivateWindow(window) && - !wm::GetWindowState(window)->IsPip(); -} - // A predicate that determines whether |window| can be included in the list // built for cycling through windows (alt + tab). bool CanIncludeWindowInCycleList(aura::Window* window) { @@ -176,6 +169,11 @@ } // namespace +bool CanIncludeWindowInMruList(aura::Window* window) { + return ::wm::CanActivateWindow(window) && + !wm::GetWindowState(window)->IsPip(); +} + ////////////////////////////////////////////////////////////////////////////// // MruWindowTracker, public:
diff --git a/ash/wm/mru_window_tracker.h b/ash/wm/mru_window_tracker.h index b77e250..3f28ca1 100644 --- a/ash/wm/mru_window_tracker.h +++ b/ash/wm/mru_window_tracker.h
@@ -24,6 +24,10 @@ kActiveDesk, }; +// A predicate that determines whether |window| can be included in the MRU +// window list. +bool CanIncludeWindowInMruList(aura::Window* window); + // Maintains a most recently used list of windows. This is used for window // cycling using Alt+Tab and overview mode. class ASH_EXPORT MruWindowTracker : public ::wm::ActivationChangeObserver,
diff --git a/ash/wm/overview/cleanup_animation_observer_unittest.cc b/ash/wm/overview/cleanup_animation_observer_unittest.cc index 6e80b49..1dde603 100644 --- a/ash/wm/overview/cleanup_animation_observer_unittest.cc +++ b/ash/wm/overview/cleanup_animation_observer_unittest.cc
@@ -33,7 +33,6 @@ } // OverviewDelegate: - void EndOverview() override {} void AddExitAnimationObserver( std::unique_ptr<DelayedAnimationObserver> animation_observer) override { animation_observer->SetOwner(this);
diff --git a/ash/wm/overview/delayed_animation_observer_impl_unittest.cc b/ash/wm/overview/delayed_animation_observer_impl_unittest.cc index 0ce1d2a8..00076b8 100644 --- a/ash/wm/overview/delayed_animation_observer_impl_unittest.cc +++ b/ash/wm/overview/delayed_animation_observer_impl_unittest.cc
@@ -27,7 +27,6 @@ ~TestOverviewDelegate() override = default; // OverviewDelegate: - void EndOverview() override {} void AddExitAnimationObserver( std::unique_ptr<DelayedAnimationObserver> animation_observer) override { animation_observer->SetOwner(this);
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index d89d22d..eba82c0 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -393,6 +393,49 @@ return true; } +// TODO(flackr): Make OverviewController observe the activation of +// windows, so we can remove OverviewDelegate. +// TODO(sammiequon): Refactor to use a single entry point for overview. +void OverviewController::EndOverview() { + if (!InOverviewSession()) + return; + + if (!occlusion_tracker_pauser_) + PauseOcclusionTracker(); + + if (!start_animations_.empty()) + OnStartingAnimationComplete(/*canceled=*/true); + start_animations_.clear(); + + overview_session_->set_is_shutting_down(true); + // Do not show mask and show during overview shutdown. + overview_session_->UpdateMaskAndShadow(); + + for (auto& observer : observers_) + observer.OnOverviewModeEnding(overview_session_.get()); + overview_session_->Shutdown(); + +#if DCHECK_IS_ON() + const auto enter_exit_type = overview_session_->enter_exit_overview_type(); + if (enter_exit_type == + OverviewSession::EnterExitOverviewType::kImmediateExit && + !delayed_animations_.empty()) { + // Immediate exit type implies no delayed exit animations at all, if we get + // here then this is a bug. + NOTREACHED(); + } +#endif + + // Don't delete |overview_session_| yet since the stack is still using it. + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, + overview_session_.release()); + last_overview_session_time_ = base::Time::Now(); + for (auto& observer : observers_) + observer.OnOverviewModeEnded(); + if (delayed_animations_.empty()) + OnEndingAnimationComplete(/*canceled=*/false); +} + bool OverviewController::InOverviewSession() const { return overview_session_ && !overview_session_->is_shutting_down(); } @@ -539,49 +582,6 @@ weak_ptr_factory_.GetWeakPtr())); } -// TODO(flackr): Make OverviewController observe the activation of -// windows, so we can remove OverviewDelegate. -// TODO(sammiequon): Refactor to use a single entry point for overview. -void OverviewController::EndOverview() { - if (!InOverviewSession()) - return; - - if (!occlusion_tracker_pauser_) - PauseOcclusionTracker(); - - if (!start_animations_.empty()) - OnStartingAnimationComplete(/*canceled=*/true); - start_animations_.clear(); - - overview_session_->set_is_shutting_down(true); - // Do not show mask and show during overview shutdown. - overview_session_->UpdateMaskAndShadow(); - - for (auto& observer : observers_) - observer.OnOverviewModeEnding(overview_session_.get()); - overview_session_->Shutdown(); - -#if DCHECK_IS_ON() - const auto enter_exit_type = overview_session_->enter_exit_overview_type(); - if (enter_exit_type == - OverviewSession::EnterExitOverviewType::kImmediateExit && - !delayed_animations_.empty()) { - // Immediate exit type implies no delayed exit animations at all, if we get - // here then this is a bug. - NOTREACHED(); - } -#endif - - // Don't delete |overview_session_| yet since the stack is still using it. - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, - overview_session_.release()); - last_overview_session_time_ = base::Time::Now(); - for (auto& observer : observers_) - observer.OnOverviewModeEnded(); - if (delayed_animations_.empty()) - OnEndingAnimationComplete(/*canceled=*/false); -} - void OverviewController::AddExitAnimationObserver( std::unique_ptr<DelayedAnimationObserver> animation_observer) { // No delayed animations should be created when overview mode is set to exit
diff --git a/ash/wm/overview/overview_controller.h b/ash/wm/overview/overview_controller.h index d86b7fa5..74991a1 100644 --- a/ash/wm/overview/overview_controller.h +++ b/ash/wm/overview/overview_controller.h
@@ -35,6 +35,8 @@ bool ToggleOverview(OverviewSession::EnterExitOverviewType type = OverviewSession::EnterExitOverviewType::kNormal); + void EndOverview(); + // Returns true if overview mode is active. bool InOverviewSession() const; @@ -71,7 +73,6 @@ void DelayedUpdateMaskAndShadow(); // OverviewDelegate: - void EndOverview() override; void AddExitAnimationObserver( std::unique_ptr<DelayedAnimationObserver> animation) override; void RemoveAndDestroyExitAnimationObserver(
diff --git a/ash/wm/overview/overview_delegate.h b/ash/wm/overview/overview_delegate.h index 451a08e..0d9dda4 100644 --- a/ash/wm/overview/overview_delegate.h +++ b/ash/wm/overview/overview_delegate.h
@@ -12,11 +12,9 @@ namespace ash { class DelayedAnimationObserver; -// Implement this class to handle the selection event from OverviewSession. +// Implement this class to handle adding and removing animation observers. class ASH_EXPORT OverviewDelegate { public: - virtual void EndOverview() = 0; - // Passes ownership of |animation_observer| to |this| delegate. virtual void AddExitAnimationObserver( std::unique_ptr<DelayedAnimationObserver> animation_observer) = 0;
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 6195a49..d7cfc1b 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -143,6 +143,10 @@ return bounds; } +void EndOverview() { + Shell::Get()->overview_controller()->EndOverview(); +} + } // namespace OverviewSession::OverviewSession(OverviewDelegate* delegate) @@ -337,10 +341,6 @@ } } -void OverviewSession::CancelSelection() { - delegate_->EndOverview(); -} - void OverviewSession::OnGridEmpty(OverviewGrid* grid) { size_t index = 0; // If there are no longer any items on any of the grids, shutdown, @@ -376,7 +376,7 @@ Move(LEFT, true); } if (grid_list_.empty()) - CancelSelection(); + EndOverview(); else PositionWindows(/*animate=*/false); } @@ -685,7 +685,7 @@ // Cancel overview session and do not restore focus when active window is // set to nullptr. This happens when removing a display. ResetFocusRestoreWindow(false); - CancelSelection(); + EndOverview(); return; } @@ -723,7 +723,7 @@ if (iter != windows.end()) selected_item_ = iter->get(); - CancelSelection(); + EndOverview(); } aura::Window* OverviewSession::GetOverviewFocusWindow() { @@ -753,7 +753,7 @@ void OverviewSession::OnDisplayRemoved(const display::Display& display) { // TODO(flackr): Keep window selection active on remaining displays. - CancelSelection(); + EndOverview(); } void OverviewSession::OnDisplayMetricsChanged(const display::Display& display, @@ -800,7 +800,7 @@ if (wm::IsSwitchableContainer(new_window->parent()) && !::wm::GetTransientParent(new_window)) { // The new window is in one of the switchable containers, abort overview. - CancelSelection(); + EndOverview(); return; } } @@ -833,7 +833,7 @@ // Cancel overview unless we're in single split mode with no overview // windows. if (!(IsEmpty() && shell->split_view_controller()->InSplitViewMode())) - CancelSelection(); + EndOverview(); break; case ui::VKEY_UP: num_key_presses_++; @@ -888,7 +888,7 @@ void OverviewSession::OnShellDestroying() { // Cancel selection will call |Shutodnw()|, which will remove observer. - CancelSelection(); + EndOverview(); } void OverviewSession::OnSplitViewStateChanged(SplitViewState previous_state, @@ -913,7 +913,7 @@ if (state == SplitViewState::kBothSnapped || unsnappable_window_activated || (Shell::Get()->split_view_controller()->InClamshellSplitViewMode() && IsEmpty())) { - CancelSelection(); + EndOverview(); return; }
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 105fa0f3..c523c429 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -109,9 +109,6 @@ // Perform cleanup that cannot be done in the destructor. void Shutdown(); - // Cancels window selection. - void CancelSelection(); - // Called when the last overview item from a grid is deleted. void OnGridEmpty(OverviewGrid* grid);
diff --git a/ash/wm/toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc index 1dedbab3..491dd17 100644 --- a/ash/wm/toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.cc
@@ -37,65 +37,6 @@ // window from the top of the screen in tablet mode. constexpr int kDragStartTopEdgeInset = 8; -// Returns the toplevel window that should be dragged for a gesture event that -// occurs in the HTCLIENT area of a window. Returns null if there shouldn't be -// special casing for this HTCLIENT area gesture. This is used to drag app -// windows which are fullscreened/maximized in tablet mode from the top of the -// screen, which don't have a window frame. -aura::Window* GetTargetForClientAreaGesture(ui::GestureEvent* event, - aura::Window* target) { - if (event->type() != ui::ET_GESTURE_SCROLL_BEGIN) - return nullptr; - - views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(target); - if (!widget) - return nullptr; - - aura::Window* toplevel = widget->GetNativeWindow(); - - if (!Shell::Get() - ->tablet_mode_controller() - ->IsTabletModeWindowManagerEnabled()) { - return nullptr; - } - wm::WindowState* window_state = wm::GetWindowState(toplevel); - if (!window_state || - (!window_state->IsMaximized() && !window_state->IsFullscreen() && - !window_state->IsSnapped())) { - return nullptr; - } - - if (toplevel->GetProperty(aura::client::kAppType) == - static_cast<int>(AppType::BROWSER)) { - return nullptr; - } - - if (event->details().scroll_y_hint() < 0) - return nullptr; - - const gfx::Point location_in_screen = - event->target()->GetScreenLocation(*event); - const gfx::Rect work_area_bounds = - display::Screen::GetScreen() - ->GetDisplayNearestWindow(static_cast<aura::Window*>(event->target())) - .work_area(); - - gfx::Rect hit_bounds_in_screen(work_area_bounds); - hit_bounds_in_screen.set_height(kDragStartTopEdgeInset); - - // There may be a bezel sensor off screen logically above - // |hit_bounds_in_screen|. Handles the ET_GESTURE_SCROLL_BEGIN event - // triggered in the bezel area too. - bool in_bezel = location_in_screen.y() < hit_bounds_in_screen.y() && - location_in_screen.x() >= hit_bounds_in_screen.x() && - location_in_screen.x() < hit_bounds_in_screen.right(); - - if (hit_bounds_in_screen.Contains(location_in_screen) || in_bezel) - return toplevel; - - return nullptr; -} - // Returns whether |window| can be moved via a two finger drag given // the hittest results of the two fingers. bool CanStartTwoFingerMove(aura::Window* window, @@ -558,6 +499,61 @@ CompleteDrag(DragResult::REVERT); } +aura::Window* ToplevelWindowEventHandler::GetTargetForClientAreaGesture( + ui::GestureEvent* event, + aura::Window* target) { + if (event->type() != ui::ET_GESTURE_SCROLL_BEGIN) + return nullptr; + + views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(target); + if (!widget) + return nullptr; + + aura::Window* toplevel = widget->GetNativeWindow(); + + if (!Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled()) { + return nullptr; + } + wm::WindowState* window_state = wm::GetWindowState(toplevel); + if (!window_state || + (!window_state->IsMaximized() && !window_state->IsFullscreen() && + !window_state->IsSnapped())) { + return nullptr; + } + + if (toplevel->GetProperty(aura::client::kAppType) == + static_cast<int>(AppType::BROWSER)) { + return nullptr; + } + + if (event->details().scroll_y_hint() < 0) + return nullptr; + + const gfx::Point location_in_screen = + event->target()->GetScreenLocation(*event); + const gfx::Rect work_area_bounds = + display::Screen::GetScreen() + ->GetDisplayNearestWindow(static_cast<aura::Window*>(event->target())) + .work_area(); + + gfx::Rect hit_bounds_in_screen(work_area_bounds); + hit_bounds_in_screen.set_height(kDragStartTopEdgeInset); + + // There may be a bezel sensor off screen logically above + // |hit_bounds_in_screen|. Handles the ET_GESTURE_SCROLL_BEGIN event + // triggered in the bezel area too. + bool in_bezel = location_in_screen.y() < hit_bounds_in_screen.y() && + location_in_screen.x() >= hit_bounds_in_screen.x() && + location_in_screen.x() < hit_bounds_in_screen.right(); + + if (hit_bounds_in_screen.Contains(location_in_screen) || in_bezel) + return toplevel; + + return nullptr; +} + ::wm::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop( aura::Window* source, const gfx::Vector2d& drag_offset,
diff --git a/ash/wm/toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h index a9c48be..b3a85f0 100644 --- a/ash/wm/toplevel_window_event_handler.h +++ b/ash/wm/toplevel_window_event_handler.h
@@ -89,6 +89,14 @@ // Returns true if there is a drag in progress. bool is_drag_in_progress() const { return window_resizer_.get() != nullptr; } + // Returns the toplevel window that should be dragged for a gesture event that + // occurs in the HTCLIENT area of a window. Returns null if there shouldn't be + // special casing for this HTCLIENT area gesture. This is used to drag app + // windows which are fullscreened/maximized in tablet mode from the top of the + // screen, which don't have a window frame. + static aura::Window* GetTargetForClientAreaGesture(ui::GestureEvent* event, + aura::Window* target); + // Returns the window that is currently handling gesture events and its // location. aura::Window* gesture_target() { return gesture_target_; }
diff --git a/ash/wm/wm_shadow_controller_delegate.cc b/ash/wm/wm_shadow_controller_delegate.cc index 6ea4f9f..ca72bd0 100644 --- a/ash/wm/wm_shadow_controller_delegate.cc +++ b/ash/wm/wm_shadow_controller_delegate.cc
@@ -5,6 +5,7 @@ #include "ash/wm/wm_shadow_controller_delegate.h" #include "ash/shell.h" +#include "ash/wm/desks/desks_util.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_session.h" #include "ash/wm/splitview/split_view_controller.h" @@ -35,8 +36,14 @@ OverviewSession* overview_session = overview_controller->overview_session(); // InOverviewSession() being true implies |overview_session| exists. DCHECK(overview_session); - if (overview_session->IsWindowInOverview(window)) + // The window may be still in overview mode, but it belongs to a non-active + // desk, as it has just been dragged and dropped onto a non-active desk's + // mini_view. In this case, we shouldn't disable its shadow, so that it may + // restored properly. + if (desks_util::BelongsToActiveDesk(const_cast<aura::Window*>(window)) && + overview_session->IsWindowInOverview(window)) { return false; + } } // The shadow state will be updated when the window is added to a parent.
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc index eb292da..706d5bf 100644 --- a/ash/wm/workspace/backdrop_controller.cc +++ b/ash/wm/workspace/backdrop_controller.cc
@@ -68,6 +68,11 @@ DISALLOW_COPY_AND_ASSIGN(BackdropEventHandler); }; +bool InOverviewSession() { + OverviewController* overview_controller = Shell::Get()->overview_controller(); + return overview_controller && overview_controller->InOverviewSession(); +} + } // namespace BackdropController::BackdropController(aura::Window* container) @@ -114,6 +119,15 @@ UpdateBackdrop(); } +void BackdropController::OnDeskContentChanged() { + // Desk content changes may result in the need to update the backdrop even + // when overview is active, since the mini_view should show updated content. + // Example: when the last window needing backdrop is moved to another desk, + // the backdrop should be destroyed from the source desk, while created for + // the target desk, and the mini_views of both desks should be updated. + UpdateBackdropInternal(); +} + void BackdropController::SetBackdropDelegate( std::unique_ptr<BackdropDelegate> delegate) { delegate_ = std::move(delegate); @@ -121,46 +135,11 @@ } void BackdropController::UpdateBackdrop() { - // No need to continue update for recursive calls or in overview mode. - OverviewController* overview_controller = Shell::Get()->overview_controller(); - if (pause_update_ || - (overview_controller && overview_controller->InOverviewSession())) { - return; - } - - aura::Window* window = GetTopmostWindowWithBackdrop(); - if (!window) { - // Destroy the backdrop since no suitable window was found. - Hide(/*destroy=*/true); - return; - } - // We are changing the order of windows which will cause recursion. - base::AutoReset<bool> lock(&pause_update_, true); - EnsureBackdropWidget(); - UpdateAccessibilityMode(); - - if (window == backdrop_window_ && backdrop_->IsVisible()) { - Layout(); - return; - } - if (window->GetRootWindow() != backdrop_window_->GetRootWindow()) + // Skip updating while overview mode is active, since the backdrop is hidden. + if (pause_update_ || InOverviewSession()) return; - // Update the animation type of |backdrop_window_| based on current top most - // window with backdrop. - SetBackdropAnimationType(wm::GetWindowState(window)->CanMaximize() - ? wm::WINDOW_VISIBILITY_ANIMATION_TYPE_STEP_END - : ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); - - Show(); - - SetBackdropAnimationType(::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); - - // Since the backdrop needs to be immediately behind the window and the - // stacking functions only guarantee a "it's above or below", we need - // to re-arrange the two windows twice. - container_->StackChildAbove(backdrop_window_, window); - container_->StackChildAbove(window, backdrop_window_); + UpdateBackdropInternal(); } aura::Window* BackdropController::GetTopmostWindowWithBackdrop() { @@ -244,6 +223,45 @@ UpdateBackdrop(); } +void BackdropController::UpdateBackdropInternal() { + // Skip the recursive updates. + if (pause_update_) + return; + + // We are either destroying the backdrop widget or changing the order of + // windows which will cause recursion. + base::AutoReset<bool> lock(&pause_update_, true); + aura::Window* window = GetTopmostWindowWithBackdrop(); + if (!window) { + // Destroy the backdrop since no suitable window was found. + Hide(/*destroy=*/true); + return; + } + + EnsureBackdropWidget(); + UpdateAccessibilityMode(); + + if (window == backdrop_window_ && backdrop_->IsVisible()) { + Layout(); + return; + } + if (window->GetRootWindow() != backdrop_window_->GetRootWindow()) + return; + + // Update the animation type of |backdrop_window_| based on current top most + // window with backdrop. + SetBackdropAnimationType(wm::GetWindowState(window)->CanMaximize() + ? wm::WINDOW_VISIBILITY_ANIMATION_TYPE_STEP_END + : ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); + + Show(); + + SetBackdropAnimationType(::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); + + // Backdrop needs to be immediately behind the window. + container_->StackChildBelow(backdrop_window_, window); +} + void BackdropController::EnsureBackdropWidget() { if (backdrop_) return; @@ -311,7 +329,11 @@ void BackdropController::Show() { Layout(); - backdrop_->Show(); + + // When overview is active, the backdrop should never be shown. However, it + // must be laid out, since it should show up properly in the mini_views. + if (!InOverviewSession()) + backdrop_->Show(); } void BackdropController::Hide(bool destroy, bool animate) {
diff --git a/ash/wm/workspace/backdrop_controller.h b/ash/wm/workspace/backdrop_controller.h index a2aaf0c..24a64fa 100644 --- a/ash/wm/workspace/backdrop_controller.h +++ b/ash/wm/workspace/backdrop_controller.h
@@ -55,6 +55,10 @@ void OnPostWindowStateTypeChange(); void OnDisplayMetricsChanged(); + // Called when the desk content is changed in order to update the state of the + // backdrop even if overview mode is active. + void OnDeskContentChanged(); + void SetBackdropDelegate(std::unique_ptr<BackdropDelegate> delegate); // Update the visibility of, and restack the backdrop relative to @@ -89,6 +93,8 @@ private: friend class WorkspaceControllerTestApi; + void UpdateBackdropInternal(); + void EnsureBackdropWidget(); void UpdateAccessibilityMode();
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index 16e9785..ec40c3d 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -99,16 +99,10 @@ #endif #if defined(OS_CHROMEOS) - // /proc/<pid>/totmaps is a syscall that returns memory summary statistics for - // the process. - // totmaps is a Linux specific concept, currently only being used on ChromeOS. - // Do not attempt to extend this to other platforms. - // struct TotalsSummary { - size_t private_clean_kb; - size_t private_dirty_kb; size_t swap_kb; }; + // Returns memory stats for the process. BASE_EXPORT TotalsSummary GetTotalsSummary() const; #endif
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc index 0c119bd..d4dc92c 100644 --- a/base/process/process_metrics_linux.cc +++ b/base/process/process_metrics_linux.cc
@@ -308,61 +308,9 @@ #endif #if defined(OS_CHROMEOS) -// Private, Shared and Proportional working set sizes are obtained from -// /proc/<pid>/totmaps ProcessMetrics::TotalsSummary ProcessMetrics::GetTotalsSummary() const { - // The format of /proc/<pid>/totmaps is: - // - // Rss: 6120 kB - // Pss: 3335 kB - // Shared_Clean: 1008 kB - // Shared_Dirty: 4012 kB - // Private_Clean: 4 kB - // Private_Dirty: 1096 kB - // Referenced: XXX kB - // Anonymous: XXX kB - // AnonHugePages: XXX kB - // Swap: XXX kB - // Locked: XXX kB ProcessMetrics::TotalsSummary summary = {}; - - const size_t kPrivate_CleanIndex = (4 * 3) + 1; - const size_t kPrivate_DirtyIndex = (5 * 3) + 1; - const size_t kSwapIndex = (9 * 3) + 1; - - std::string totmaps_data; - { - FilePath totmaps_file = internal::GetProcPidDir(process_).Append("totmaps"); - ThreadRestrictions::ScopedAllowIO allow_io; - bool ret = ReadFileToString(totmaps_file, &totmaps_data); - if (!ret || totmaps_data.length() == 0) - return summary; - } - - std::vector<std::string> totmaps_fields = SplitString( - totmaps_data, kWhitespaceASCII, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); - - DCHECK_EQ("Private_Clean:", totmaps_fields[kPrivate_CleanIndex - 1]); - DCHECK_EQ("Private_Dirty:", totmaps_fields[kPrivate_DirtyIndex - 1]); - DCHECK_EQ("Swap:", totmaps_fields[kSwapIndex-1]); - - int private_clean_kb = 0; - int private_dirty_kb = 0; - int swap_kb = 0; - bool success = true; - success &= - StringToInt(totmaps_fields[kPrivate_CleanIndex], &private_clean_kb); - success &= - StringToInt(totmaps_fields[kPrivate_DirtyIndex], &private_dirty_kb); - success &= StringToInt(totmaps_fields[kSwapIndex], &swap_kb); - - if (!success) - return summary; - - summary.private_clean_kb = private_clean_kb; - summary.private_dirty_kb = private_dirty_kb; - summary.swap_kb = swap_kb; - + summary.swap_kb = GetVmSwapBytes() >> 10; return summary; } #endif
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 675182b..b093ea1 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -799,7 +799,10 @@ tests_to_retry_.insert(result.full_name); } - results_tracker_.AddTestResult(result); + // There are no results for this tests, + // most likley due to another test failing in the same batch. + if (result.status != TestResult::TEST_SKIPPED) + results_tracker_.AddTestResult(result); // TODO(phajdan.jr): Align counter (padding). std::string status_line(StringPrintf("[%zu/%zu] %s ", test_finished_count_, @@ -826,11 +829,8 @@ // We just printed a status line, reset the watchdog timer. watchdog_timer_.Reset(); - // Do not waste time on timeouts. We include tests with unknown results here - // because sometimes (e.g. hang in between unit tests) that's how a timeout - // gets reported. - if (result.status == TestResult::TEST_TIMEOUT || - result.status == TestResult::TEST_UNKNOWN) { + // Do not waste time on timeouts. + if (result.status == TestResult::TEST_TIMEOUT) { test_broken_count_++; } if (!force_run_broken_tests_ && test_broken_count_ >= broken_threshold_) { @@ -1381,15 +1381,6 @@ // Number of retries in this iteration. size_t retry_count = 0; while (!tests_to_retry_.empty() && retry_count < retry_limit_) { - if (!force_run_broken_tests_ && - tests_to_retry_.size() >= broken_threshold_) { - fprintf(stdout, "Too many failing tests (%zu), skipping retries.\n", - tests_to_retry_.size()); - fflush(stdout); - - results_tracker_.AddGlobalTag("BROKEN_TEST_SKIPPED_RETRIES"); - return false; - } std::vector<std::string> test_names(tests_to_retry_.begin(), tests_to_retry_.end()); tests_to_retry_.clear();
diff --git a/base/test/launcher/test_launcher_nacl_nonsfi.cc b/base/test/launcher/test_launcher_nacl_nonsfi.cc index 53bdb4f..43cf899 100644 --- a/base/test/launcher/test_launcher_nacl_nonsfi.cc +++ b/base/test/launcher/test_launcher_nacl_nonsfi.cc
@@ -124,12 +124,6 @@ return cmd_line; } - void RelaunchTests(base::TestLauncher* test_launcher, - const std::vector<std::string>& test_names, - int launch_flags) override { - RunUnitTestsBatch(test_launcher, this, test_names, launch_flags); - } - base::FilePath test_path_; };
diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc index 2e63baa..b965736 100644 --- a/base/test/launcher/unit_test_launcher.cc +++ b/base/test/launcher/unit_test_launcher.cc
@@ -208,139 +208,138 @@ } #endif // defined(OS_WIN) -// Interprets test results and reports to the test launcher. Returns true -// on success. -bool ProcessTestResults( - TestLauncher* test_launcher, - const std::vector<std::string>& test_names, - const base::FilePath& output_file, - const std::string& output, - int exit_code, - bool was_timeout, - std::vector<std::string>* tests_to_relaunch) { +// Called if there are no test results, populates results with UNKNOWN results. +// If There is only one test, will try to determine status by exit_code and +// was_timeout. +void ProcessMissingTestResults(const std::vector<std::string>& test_names, + const std::string& output, + bool was_timeout, + bool exit_code, + std::vector<TestResult>* results) { + // We do not have reliable details about test results (parsing test + // stdout is known to be unreliable). + fprintf(stdout, + "Failed to get out-of-band test success data, " + "dumping full stdio below:\n%s\n", + output.c_str()); + fflush(stdout); + + // There is only one test and no results. + // Try to determine status by exit code. + if (test_names.size() == 1) { + const std::string& test_name = test_names.front(); + TestResult test_result; + test_result.full_name = test_name; + + if (was_timeout) { + test_result.status = TestResult::TEST_TIMEOUT; + } else if (exit_code != 0) { + test_result.status = TestResult::TEST_FAILURE; + } else { + // It's strange case when test executed successfully, + // but we failed to read machine-readable report for it. + test_result.status = TestResult::TEST_UNKNOWN; + } + + results->push_back(test_result); + return; + } + for (auto& test_name : test_names) { + TestResult test_result; + test_result.full_name = test_name; + test_result.status = TestResult::TEST_SKIPPED; + results->push_back(test_result); + } +} + +// Interprets test results and reports to the test launcher. +void ProcessTestResults(TestLauncher* test_launcher, + const std::vector<std::string>& test_names, + const base::FilePath& output_file, + const std::string& output, + int exit_code, + bool was_timeout) { std::vector<TestResult> test_results; bool crashed = false; bool have_test_results = ProcessGTestOutput(output_file, &test_results, &crashed); - bool called_any_callback = false; - - if (have_test_results) { - // TODO(phajdan.jr): Check for duplicates and mismatches between - // the results we got from XML file and tests we intended to run. - std::map<std::string, TestResult> results_map; - for (const auto& i : test_results) - results_map[i.full_name] = i; - - bool had_interrupted_test = false; - - // Results to be reported back to the test launcher. - std::vector<TestResult> final_results; - - for (const auto& i : test_names) { - if (ContainsKey(results_map, i)) { - TestResult test_result = results_map[i]; - if (test_result.status == TestResult::TEST_CRASH) { - had_interrupted_test = true; - - if (was_timeout) { - // Fix up the test status: we forcibly kill the child process - // after the timeout, so from XML results it looks just like - // a crash. - test_result.status = TestResult::TEST_TIMEOUT; - } - } else if (test_result.status == TestResult::TEST_SUCCESS || - test_result.status == TestResult::TEST_FAILURE) { - // We run multiple tests in a batch with a timeout applied - // to the entire batch. It is possible that with other tests - // running quickly some tests take longer than the per-test timeout. - // For consistent handling of tests independent of order and other - // factors, mark them as timing out. - if (test_result.elapsed_time > - TestTimeouts::test_launcher_timeout()) { - test_result.status = TestResult::TEST_TIMEOUT; - } - } - test_result.output_snippet = GetTestOutputSnippet(test_result, output); - final_results.push_back(test_result); - } else if (had_interrupted_test) { - tests_to_relaunch->push_back(i); - } else { - // TODO(phajdan.jr): Explicitly pass the info that the test didn't - // run for a mysterious reason. - LOG(ERROR) << "no test result for " << i; - TestResult test_result; - test_result.full_name = i; - test_result.status = TestResult::TEST_UNKNOWN; - test_result.output_snippet = GetTestOutputSnippet(test_result, output); - final_results.push_back(test_result); - } - } - - // TODO(phajdan.jr): Handle the case where processing XML output - // indicates a crash but none of the test results is marked as crashing. - - if (final_results.empty()) - return false; - - bool has_non_success_test = false; - for (const auto& i : final_results) { - if (i.status != TestResult::TEST_SUCCESS) { - has_non_success_test = true; - break; - } - } - - if (!has_non_success_test && exit_code != 0) { - // This is a bit surprising case: all tests are marked as successful, - // but the exit code was not zero. This can happen e.g. under memory - // tools that report leaks this way. Mark all tests as a failure on exit, - // and for more precise info they'd need to be retried serially. - for (auto& i : final_results) - i.status = TestResult::TEST_FAILURE_ON_EXIT; - } - - for (auto& i : final_results) { - // Fix the output snippet after possible changes to the test result. - i.output_snippet = GetTestOutputSnippet(i, output); - test_launcher->OnTestFinished(i); - called_any_callback = true; - } - } else { - fprintf(stdout, - "Failed to get out-of-band test success data, " - "dumping full stdio below:\n%s\n", - output.c_str()); - fflush(stdout); - - // We do not have reliable details about test results (parsing test - // stdout is known to be unreliable). - if (test_names.size() == 1) { - // There is only one test. Try to determine status by exit code. - const std::string& test_name = test_names.front(); - TestResult test_result; - test_result.full_name = test_name; - - if (was_timeout) { - test_result.status = TestResult::TEST_TIMEOUT; - } else if (exit_code != 0) { - test_result.status = TestResult::TEST_FAILURE; - } else { - // It's strange case when test executed successfully, - // but we failed to read machine-readable report for it. - test_result.status = TestResult::TEST_UNKNOWN; - } - + if (!have_test_results) { + ProcessMissingTestResults(test_names, output, was_timeout, exit_code, + &test_results); + for (auto& test_result : test_results) test_launcher->OnTestFinished(test_result); - called_any_callback = true; + return; + } + + // TODO(phajdan.jr): Check for duplicates and mismatches between + // the results we got from XML file and tests we intended to run. + std::map<std::string, TestResult> results_map; + for (const auto& i : test_results) + results_map[i.full_name] = i; + + // Results to be reported back to the test launcher. + std::vector<TestResult> final_results; + + for (const auto& i : test_names) { + if (ContainsKey(results_map, i)) { + TestResult test_result = results_map[i]; + if (test_result.status == TestResult::TEST_CRASH) { + if (was_timeout) { + // Fix up the test status: we forcibly kill the child process + // after the timeout, so from XML results it looks just like + // a crash. + test_result.status = TestResult::TEST_TIMEOUT; + } + } else if (test_result.status == TestResult::TEST_SUCCESS || + test_result.status == TestResult::TEST_FAILURE) { + // We run multiple tests in a batch with a timeout applied + // to the entire batch. It is possible that with other tests + // running quickly some tests take longer than the per-test timeout. + // For consistent handling of tests independent of order and other + // factors, mark them as timing out. + if (test_result.elapsed_time > TestTimeouts::test_launcher_timeout()) { + test_result.status = TestResult::TEST_TIMEOUT; + } + } + test_result.output_snippet = GetTestOutputSnippet(test_result, output); + final_results.push_back(test_result); } else { - // There is more than one test. Retry them individually. - for (const std::string& test_name : test_names) - tests_to_relaunch->push_back(test_name); + // TODO(phajdan.jr): Explicitly pass the info that the test didn't + // run for a mysterious reason. + LOG(ERROR) << "no test result for " << i; + TestResult test_result; + test_result.full_name = i; + test_result.status = TestResult::TEST_SKIPPED; + test_result.output_snippet = GetTestOutputSnippet(test_result, output); + final_results.push_back(test_result); + } + } + // TODO(phajdan.jr): Handle the case where processing XML output + // indicates a crash but none of the test results is marked as crashing. + + bool has_non_success_test = false; + for (const auto& i : final_results) { + if (i.status != TestResult::TEST_SUCCESS) { + has_non_success_test = true; + break; } } - return called_any_callback; + if (!has_non_success_test && exit_code != 0) { + // This is a bit surprising case: all tests are marked as successful, + // but the exit code was not zero. This can happen e.g. under memory + // tools that report leaks this way. Mark all tests as a failure on exit, + // and for more precise info they'd need to be retried serially. + for (auto& i : final_results) + i.status = TestResult::TEST_FAILURE_ON_EXIT; + } + + for (auto& i : final_results) { + // Fix the output snippet after possible changes to the test result. + i.output_snippet = GetTestOutputSnippet(i, output); + test_launcher->OnTestFinished(i); + } } class UnitTestProcessLifetimeObserver : public ProcessLifetimeObserver { @@ -418,14 +417,8 @@ bool was_timeout, const std::string& output) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::vector<std::string> tests_to_relaunch; ProcessTestResults(test_launcher(), test_names(), output_file(), output, - exit_code, was_timeout, &tests_to_relaunch); - - if (!tests_to_relaunch.empty()) { - platform_delegate()->RelaunchTests(test_launcher(), tests_to_relaunch, - launch_flags()); - } + exit_code, was_timeout); // The temporary file's directory is also temporary. DeleteFile(output_file().DirName(), true); @@ -471,17 +464,8 @@ bool was_timeout, const std::string& output) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::vector<std::string> tests_to_relaunch; - bool called_any_callbacks = - ProcessTestResults(test_launcher(), test_names(), output_file(), output, - exit_code, was_timeout, &tests_to_relaunch); - - // There is only one test, there cannot be other tests to relaunch - // due to a crash. - DCHECK(tests_to_relaunch.empty()); - - // There is only one test, we should have called back with its result. - DCHECK(called_any_callbacks); + ProcessTestResults(test_launcher(), test_names(), output_file(), output, + exit_code, was_timeout); // The temporary file's directory is also temporary. DeleteFile(output_file().DirName(), true); @@ -666,19 +650,6 @@ return std::string(); } -void DefaultUnitTestPlatformDelegate::RelaunchTests( - TestLauncher* test_launcher, - const std::vector<std::string>& test_names, - int launch_flags) { - // Relaunch requested tests in parallel, but only use single - // test per batch for more precise results (crashes, etc). - for (const std::string& test_name : test_names) { - std::vector<std::string> batch; - batch.push_back(test_name); - RunUnitTestsBatch(test_launcher, this, batch, launch_flags); - } -} - UnitTestLauncherDelegate::UnitTestLauncherDelegate( UnitTestPlatformDelegate* platform_delegate, size_t batch_limit,
diff --git a/base/test/launcher/unit_test_launcher.h b/base/test/launcher/unit_test_launcher.h index 32ba25d..595923ac 100644 --- a/base/test/launcher/unit_test_launcher.h +++ b/base/test/launcher/unit_test_launcher.h
@@ -78,11 +78,6 @@ // no wrapper. virtual std::string GetWrapperForChildGTestProcess() = 0; - // Relaunch tests, e.g. after a crash. - virtual void RelaunchTests(TestLauncher* test_launcher, - const std::vector<std::string>& test_names, - int launch_flags) = 0; - protected: ~UnitTestPlatformDelegate() = default; }; @@ -111,10 +106,6 @@ std::string GetWrapperForChildGTestProcess() override; - void RelaunchTests(TestLauncher* test_launcher, - const std::vector<std::string>& test_names, - int launch_flags) override; - ScopedTempDir temp_dir_; DISALLOW_COPY_AND_ASSIGN(DefaultUnitTestPlatformDelegate);
diff --git a/build/android/constant_pool_refs_to_keep_rules.py b/build/android/constant_pool_refs_to_keep_rules.py index 7a06efc5..b2452d7 100644 --- a/build/android/constant_pool_refs_to_keep_rules.py +++ b/build/android/constant_pool_refs_to_keep_rules.py
@@ -19,6 +19,17 @@ # system APIs and are already included in ProGuard configs. _IGNORED_PACKAGES = ['java', 'android', 'org.w3c', 'org.xml', 'dalvik'] +# Classes in _WHITELIST_PACKAGES are support libraries compiled into chrome +# that must bypass the _IGNORED_PACKAGES. +_WHITELIST_PACKAGES = ['android.support'] + +# TODO(https://crbug.com/968769): Filter may be too broad. +# Classes in _DFM_FEATURES will be excluded from "keep all members" rule. +_DFM_FEATURES = [ + 'org.chromium.chrome.autofill_assistant', 'org.chromium.chrome.tab_ui', + 'org.chromium.chrome.browser.tasks.tab_management', 'org.chromium.chrome.vr' +] + # Mapping for translating Java bytecode type identifiers to source code type # identifiers. _TYPE_IDENTIFIER_MAP = { @@ -91,6 +102,22 @@ dep_refs[class_name] = [keep_entry] +def should_include_class_path(class_path): + """ Check whether a class_path should be added as keep rule. + Conditions: + - Class is auto-generated (Lambdas/Nested, for example $) + - Class is not in a DFM Module + - Class is not in a black/white listed package + """ + nested_class = '$' in class_path + not_in_dfm = all(not class_path.startswith(f) for f in _DFM_FEATURES) + allowed_packages = not (any( + class_path.startswith(p) + for p in _IGNORED_PACKAGES) and all(not class_path.startswith(p) + for p in _WHITELIST_PACKAGES)) + return nested_class or (not_in_dfm and allowed_packages) + + def main(argv): dep_refs = defaultdict(list) extended_and_implemented_classes = set() @@ -109,8 +136,10 @@ with open(args.input_file, 'r') as constant_pool_refs: for line in constant_pool_refs: line = line.rstrip().replace('/', '.') - # Ignore any references specified by the list of _IGNORED_PACKAGES. - if any(line.startswith(package) for package in _IGNORED_PACKAGES): + # Ignore any references specified by the list of + # _IGNORED_PACKAGES and not in _WHITELIST_PACKAGES. + if (any(line.startswith(p) for p in _IGNORED_PACKAGES) + and all(not line.startswith(p) for p in _WHITELIST_PACKAGES)): continue reflist = line.split(',') @@ -139,6 +168,11 @@ if class_name.startswith('['): continue + # Ignore R(esources) files that are from the same module. + if ('$' in class_name + and any(class_name.startswith(f) for f in _DFM_FEATURES)): + continue + # If member_info starts with '(', member is a method, otherwise member # is a field. # Format keep entries as per ProGuard documentation @@ -151,6 +185,18 @@ return_type = '' else: return_type = translate_single_type(return_type)[0] + + # Include types of function arguments. + for arg_type in args_list: + if should_include_class_path(arg_type): + extended_and_implemented_classes.add(arg_type) + + # Include the actual class when it's a constructor. + if member_name == '<init>': + if should_include_class_path(class_name): + extended_and_implemented_classes.add(class_name) + continue + keep_entry = '%s %s(%s);' % (return_type, member_name, ', '.join(args_list)) else: @@ -162,14 +208,14 @@ with open(args.output_file, 'w') as keep_rules: # Write super classes and implemented interfaces to keep rules. for super_class in sorted(extended_and_implemented_classes): - keep_rules.write( - '-keep,allowobfuscation class %s { *; }\n' % (super_class.rstrip())) + keep_rules.write('-keep class %s { *; }\n' % (super_class.rstrip())) keep_rules.write('\n') # Write all other class references to keep rules. for c in sorted(dep_refs.iterkeys()): + if c in extended_and_implemented_classes: + continue class_keeps = '\n '.join(dep_refs[c]) - keep_rules.write( - '-keep,allowobfuscation class %s {\n %s\n}\n' % (c, class_keeps)) + keep_rules.write('-keep class %s {\n %s\n}\n' % (c, class_keeps)) keep_rules.write('\n')
diff --git a/build/android/constant_pool_refs_to_keep_rules_test.py b/build/android/constant_pool_refs_to_keep_rules_test.py new file mode 100644 index 0000000..6f281e2 --- /dev/null +++ b/build/android/constant_pool_refs_to_keep_rules_test.py
@@ -0,0 +1,91 @@ +# Copyright 2019 The Chromium 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 +import re +import os + + +class TestProguardRuleGeneration(unittest.TestCase): + """ + This script is used to test a ProGuard keep rules for the purposes + of maintaining compatibility between async DFMs and synchronously + proguarded modules. + + The rules are often generated by constant_pool_refs_to_keep_rules.py + + This test can be run manually. Example: + python build/android/constant_pool_refs_to_keep_rules_test.py -v + """ + + # Make sure this variable is set accordingly. + # It should point to a proguard file. + PROGUARD_FILE_PATH = os.path.join( + os.path.dirname(__file__), + "../../chrome/android/features/tab_ui/proguard_async.flags") + + def test_TabUI_HasRules(self): + """ + Ensures that a few of the rules used in tabs_ui module are included. + Although this is far from 100% deterministic, these rules are + created by code that exercise different parts of the rule generation code. + """ + + rules = set() + with open(self.PROGUARD_FILE_PATH, 'r') as proguard_rules: + for line in proguard_rules: + if line.startswith('-keep'): + rule = re.search('class (.+?) {', line).group(1) + rules.add(rule) + + # The following rules test most of the use cases for + # rules that can be added automatically. + self.assertIn('org.chromium.ui.modelutil.PropertyModel', rules) + self.assertIn('org.chromium.ui.modelutil.PropertyModel', rules) + self.assertIn('org.chromium.ui.modelutil.PropertyKey', rules) + self.assertIn('org.chromium.chrome.browser.toolbar.ToolbarManager', rules) + self.assertIn('org.chromium.base.Supplier', rules) + self.assertIn('android.support.v7.widget.helper.ItemTouchHelper', rules) + self.assertIn( + 'android.support.v7.widget.helper.ItemTouchHelper$SimpleCallback', + rules) + self.assertIn('android.support.v7.widget.helper.ItemTouchHelper$Callback', + rules) + self.assertIn('android.support.v4.content.ContextCompat', rules) + self.assertIn('android.support.v7.widget.GridLayoutManager', rules) + self.assertIn('android.support.v4.content.res.ResourcesCompat', rules) + self.assertIn( + 'org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter', rules) + self.assertIn('android.support.v7.widget.RecyclerView$ViewHolder', rules) + self.assertIn('android.support.v7.widget.RecyclerView', rules) + self.assertIn('org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase', rules) + self.assertIn('org.chromium.ui.modelutil.RecyclerViewAdapter', rules) + + # The following rules need to be added manually. + self.assertNotIn( + 'org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager' + + '$FullscreenListener$$CC', rules) + self.assertNotIn( + 'org.chromium.chrome.browser.widget.bottomsheet.BottomSheet' + + '$BottomSheetContent$$CC', rules) + self.assertNotIn('org.chromium.ui.widget.RoundedCornerImageView', rules) + self.assertNotIn( + 'android.support.v4.graphics.drawable.RoundedBitmapDrawable', rules) + + def test_TabUI_HasNoDuplicateRules(self): + """ + Ensures that there are no duplicate keep rules + """ + + rules = set() + with open(self.PROGUARD_FILE_PATH, 'r') as proguard_rules: + for line in proguard_rules: + if line.startswith('-keep'): + rule = re.search('class (.+?) {', line).group(1) + self.assertNotIn(rule, rules) + rules.add(rule) + + +if __name__ == '__main__': + unittest.main()
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 5b476a2..9508d9c 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -4353,9 +4353,11 @@ build_config = _module.build_config repackage_classes = "ap${_async_package_number}" - # Pass mapping file of synchronous proguarding run to async module proguarding - # runs to preserve compatibility. - apply_mapping = _sync_proguard_mapping_path + # TODO(https://crbug.com/952858): R8 currently doesn't handle + # applying mapping files. + # Pass mapping file of synchronous proguarding run to async + # module proguarding runs to preserve compatibility. + # apply_mapping = _sync_proguard_mapping_path deps = [ _module.module_target,
diff --git a/chrome/VERSION b/chrome/VERSION index 4968a2b..e878b53f 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=77 MINOR=0 -BUILD=3810 +BUILD=3813 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index db75a65..2239c19 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -12,6 +12,7 @@ import("//chrome/android/chrome_public_apk_tmpl.gni") import( "//chrome/android/features/autofill_assistant/autofill_assistant_module_tmpl.gni") +import("//chrome/android/features/tab_ui/buildflags.gni") import("//chrome/android/features/tab_ui/tab_management_java_sources.gni") import("//chrome/android/features/tab_ui/tab_ui_module_tmpl.gni") import("//chrome/android/features/vr/public_vr_java_sources.gni") @@ -475,6 +476,12 @@ "//chrome/android/features/vr/proguard_async_manual.flags", ] } + if (async_tab_ui) { + proguard_configs += [ + "//chrome/android/features/tab_ui/proguard_async.flags", + "//chrome/android/features/tab_ui/proguard_async_manual.flags", + ] + } processor_args_javac = [ "dagger.fastInit=enabled" ] } @@ -491,6 +498,10 @@ if (disable_autofill_assistant_dfm) { deps += [ "//chrome/android/features/autofill_assistant:java" ] } + + if (disable_tab_ui_dfm) { + deps += [ "//chrome/android/features/tab_ui:java" ] + } } # This is a list of all base module jni headers. New features should add their @@ -2342,6 +2353,15 @@ }, ] } + if (!disable_tab_ui_dfm) { + extra_modules += [ + { + name = "tab_ui" + module_target = ":${target_name}__tab_ui_bundle_module" + proguard_async = async_tab_ui + }, + ] + } } }
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index aa68923..c785aa3 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1464,6 +1464,7 @@ "java/src/org/chromium/chrome/browser/suggestions/TileGroup.java", "java/src/org/chromium/chrome/browser/suggestions/TileGroupDelegateImpl.java", "java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java", + "java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java", "java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java", "java/src/org/chromium/chrome/browser/survey/SurveyController.java", "java/src/org/chromium/chrome/browser/sync/GoogleServiceAuthError.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 5d4bbee7..3668ba2 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -183,6 +183,7 @@ "junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java", "junit/src/org/chromium/chrome/browser/tasks/EngagementTimeUtilTest.java", "junit/src/org/chromium/chrome/browser/tasks/JourneyManagerTest.java", + "junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java", "junit/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java", "junit/src/org/chromium/chrome/browser/usage_stats/EventTrackerTest.java", "junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 2919c64a..07a858e2 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -255,10 +255,7 @@ deps += [ ":$_unwind_asset" ] } - deps += [ - "//chrome/android:chrome_all_java", - "//chrome/android/features/tab_ui:java", - ] + deps += [ "//chrome/android:chrome_all_java" ] if (!defined(version_code)) { if (_is_trichrome) {
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index abf0a89..7780b92 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/android/rules.gni") +import("//chrome/android/features/tab_ui/buildflags.gni") import("//chrome/common/features.gni") android_resources("java_resources") { @@ -14,6 +15,10 @@ } android_library("java") { + # Add this flag to prevent build hooks to be included in this module + # as it's already included in the base module + no_build_hooks = true + java_files = [ "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java", @@ -73,4 +78,8 @@ "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//ui/android:ui_java", ] + + if (async_tab_ui) { + proguard_configs = [ "//base/android/proguard/chromium_code.flags" ] + } }
diff --git a/chrome/android/features/tab_ui/buildflags.gni b/chrome/android/features/tab_ui/buildflags.gni new file mode 100644 index 0000000..0637699 --- /dev/null +++ b/chrome/android/features/tab_ui/buildflags.gni
@@ -0,0 +1,11 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Controls the feature being a DFM or not. + disable_tab_ui_dfm = true + + # Whether to create tab_ui module as an asynchronous DFM. + async_tab_ui = false +}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java index 757354dc..21ee7c3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherCoordinator.java
@@ -85,8 +85,10 @@ mMediator::getCreateGroupButtonOnClickListener, gridCardOnClickListenerProvider, compositorViewHolder, compositorViewHolder.getDynamicResourceLoader(), true, org.chromium.chrome.tab_ui.R.layout.grid_tab_switcher_layout, COMPONENT_NAME); - HistoryNavigationLayout navigation = - compositorViewHolder.findViewById(R.id.history_navigation); + + HistoryNavigationLayout navigation = compositorViewHolder.findViewById( + org.chromium.chrome.tab_ui.R.id.history_navigation); + navigation.setNavigationDelegate(HistoryNavigationDelegate.createForTabSwitcher( context, backPress, tabModelSelector::getCurrentTab)); mContainerViewChangeProcessor = PropertyModelChangeProcessor.create(containerViewModel, @@ -113,6 +115,7 @@ @Override public void postHiding() { + mTabGridCoordinator.postHiding(); mMediator.postHiding(); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java index 47c8ed0d..e543812 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogParent.java
@@ -75,7 +75,7 @@ mDialogContainerView = new LinearLayout(context); mDialogContainerView.setLayoutParams(mContainerParams); mDialogContainerView.setBackgroundColor(ApiCompatibilityUtils.getColor( - context.getResources(), R.color.modern_primary_color)); + context.getResources(), org.chromium.chrome.R.color.modern_primary_color)); mDialogContainerView.setOrientation(LinearLayout.VERTICAL); mScrimView = new ScrimView(context, null, backgroundView); mPopupWindow = new PopupWindow(backgroundView, 0, 0);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java index 9b1bba9..ab77adc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java
@@ -39,8 +39,8 @@ this.thumbnail = itemView.findViewById(R.id.tab_thumbnail); this.title = itemView.findViewById(R.id.tab_title); // TODO(yuezhanggg): Remove this when the strip is properly tinted. (crbug/939915) - title.setTextColor( - ContextCompat.getColor(itemView.getContext(), R.color.default_text_color_dark)); + title.setTextColor(ContextCompat.getColor( + itemView.getContext(), org.chromium.chrome.R.color.default_text_color_dark)); this.favicon = itemView.findViewById(R.id.tab_favicon); this.closeButton = itemView.findViewById(R.id.close_button); this.createGroupButton = itemView.findViewById(R.id.create_group_button); @@ -49,8 +49,8 @@ if (sCloseButtonBitmapWeakRef == null || sCloseButtonBitmapWeakRef.get() == null) { int closeButtonSize = (int) itemView.getResources().getDimension(R.dimen.tab_grid_close_button_size); - Bitmap bitmap = - BitmapFactory.decodeResource(itemView.getResources(), R.drawable.btn_close); + Bitmap bitmap = BitmapFactory.decodeResource( + itemView.getResources(), org.chromium.chrome.R.drawable.btn_close); sCloseButtonBitmapWeakRef = new WeakReference<>( Bitmap.createScaledBitmap(bitmap, closeButtonSize, closeButtonSize, true)); bitmap.recycle();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 551bee06..09ad36d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -97,14 +97,11 @@ @Override public void willCloseTab(Tab tab, boolean animate) { if (!mIsTabGroupUiVisible) return; - Tab currentTab = mTabModelSelector.getCurrentTab(); - if (currentTab == null) mResetHandler.resetSheetWithListOfTabs(null); - int tabsCount = mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .getRelatedTabList(currentTab.getId()) - .size(); + List<Tab> group = mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getRelatedTabList(tab.getId()); - mIsClosingAGroup = tabsCount == 0; + mIsClosingAGroup = group.size() == 0; } @Override
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 6564eaf55..73e27002 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -196,6 +196,10 @@ mRecyclerView.prepareOverview(); } + void postHiding() { + mRecyclerView.postHiding(); + } + /** * Destroy any members that needs clean up. */
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index b84ca82..7951ff3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -340,6 +340,9 @@ instanceof TabGroupModelFilter) { mTabGroupObserver = new TabGroupModelFilter.Observer() { @Override + public void didMergeTabToGroup(Tab movedTab, int selectedTabIdInGroup) {} + + @Override public void didMoveWithinGroup( Tab movedTab, int tabModelOldIndex, int tabModelNewIndex) { int curPosition = mModel.indexFromId(movedTab.getId()); @@ -522,9 +525,8 @@ mModel.get(i).set(TabProperties.IS_SELECTED, isSelected); if (mThumbnailProvider != null && isSelected) { - // TODO(crbug.com/964406): should force update but it's too slow. - ThumbnailFetcher callback = - new ThumbnailFetcher(mThumbnailProvider, tab, false); + // TODO(crbug.com/968829): make force updating faster. + ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, tab, true); mModel.get(i).set(TabProperties.THUMBNAIL_FETCHER, callback); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java index 361a7e9..98e0c9f6 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java
@@ -194,14 +194,18 @@ mFadeOutAnimator = null; setVisibility(View.INVISIBLE); mListener.finishedHiding(); - - if (mDynamicView != null) mDynamicView.dropCachedBitmap(); } }); mFadeOutAnimator.start(); if (!animate) mFadeOutAnimator.end(); } + void postHiding() { + if (mDynamicView != null) { + mDynamicView.dropCachedBitmap(); + } + } + private void endAllAnimations() { if (mFadeInAnimator != null) { mFadeInAnimator.end();
diff --git a/chrome/android/features/tab_ui/proguard_async.flags b/chrome/android/features/tab_ui/proguard_async.flags new file mode 100644 index 0000000..a5c42ce --- /dev/null +++ b/chrome/android/features/tab_ui/proguard_async.flags
@@ -0,0 +1,1034 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +-keep class android.content.res.Resources$Theme { *; } + +-keep class android.support.v7.widget.GridLayoutManager { *; } + +-keep class android.support.v7.widget.LinearLayoutManager { *; } + +-keep class android.support.v7.widget.RecyclerView { *; } + +-keep class android.support.v7.widget.RecyclerView$Adapter { *; } + +-keep class android.support.v7.widget.RecyclerView$LayoutManager { *; } + +-keep class android.support.v7.widget.RecyclerView$ViewHolder { *; } + +-keep class android.support.v7.widget.helper.ItemTouchHelper { *; } + +-keep class android.support.v7.widget.helper.ItemTouchHelper$Callback { *; } + +-keep class android.support.v7.widget.helper.ItemTouchHelper$SimpleCallback { *; } + +-keep class android.view.View$OnClickListener { *; } + +-keep class android.widget.PopupWindow$OnDismissListener { *; } + +-keep class boolean { *; } + +-keep class float { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$anim { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$animator { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$array { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$attr { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$bool { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$color { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$dimen { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$drawable { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$font { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$fraction { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$id { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$integer { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$layout { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$menu { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$mipmap { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$plurals { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$string { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$style { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$styleable { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$transition { *; } + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R$xml { *; } + +-keep class gen._chrome._android._monochrome_public_bundle__tab_ui_bundle_module__compile_resources.srcjar.R$dimen { *; } + +-keep class gen._chrome._android._monochrome_public_bundle__tab_ui_bundle_module__compile_resources.srcjar.R$drawable { *; } + +-keep class gen._chrome._android._monochrome_public_bundle__tab_ui_bundle_module__compile_resources.srcjar.R$id { *; } + +-keep class gen._chrome._android._monochrome_public_bundle__tab_ui_bundle_module__compile_resources.srcjar.R$layout { *; } + +-keep class int { *; } + +-keep class int[] { *; } + +-keep class long { *; } + +-keep class null { *; } + +-keep class org.apache.http.conn.scheme.LayeredSocketFactory { *; } + +-keep class org.apache.http.conn.scheme.SocketFactory { *; } + +-keep class org.apache.http.conn.ssl.AbstractVerifier { *; } + +-keep class org.apache.http.conn.ssl.X509HostnameVerifier { *; } + +-keep class org.apache.http.params.CoreConnectionPNames { *; } + +-keep class org.chromium.base.Callback { *; } + +-keep class org.chromium.base.ObserverList { *; } + +-keep class org.chromium.base.Supplier { *; } + +-keep class org.chromium.base.task.TaskTraits { *; } + +-keep class org.chromium.chrome.browser.ThemeColorProvider { *; } + +-keep class org.chromium.chrome.browser.ThemeColorProvider$ThemeColorObserver { *; } + +-keep class org.chromium.chrome.browser.ThemeColorProvider$TintObserver { *; } + +-keep class org.chromium.chrome.browser.compositor.CompositorViewHolder { *; } + +-keep class org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver { *; } + +-keep class org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior { *; } + +-keep class org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior$OverviewModeObserver { *; } + +-keep class org.chromium.chrome.browser.compositor.layouts.content.TabContentManager { *; } + +-keep class org.chromium.chrome.browser.favicon.FaviconHelper { *; } + +-keep class org.chromium.chrome.browser.favicon.FaviconHelper$FaviconImageCallback { *; } + +-keep class org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager { *; } + +-keep class org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager$FullscreenListener { *; } + +-keep class org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate { *; } + +-keep class org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher { *; } + +-keep class org.chromium.chrome.browser.lifecycle.Destroyable { *; } + +-keep class org.chromium.chrome.browser.lifecycle.LifecycleObserver { *; } + +-keep class org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver { *; } + +-keep class org.chromium.chrome.browser.profiles.Profile { *; } + +-keep class org.chromium.chrome.browser.tab.EmptyTabObserver { *; } + +-keep class org.chromium.chrome.browser.tab.Tab { *; } + +-keep class org.chromium.chrome.browser.tab.TabObserver { *; } + +-keep class org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver { *; } + +-keep class org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabCreatorManager { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabList { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabModel { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabModelObserver { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelector { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver { *; } + +-keep class org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils$1 { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcher { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcher$GridController { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator$ResetHandler { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator$ResetHandler { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetMediator$ResetHandler { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetViewBinder$ViewHolder { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUi { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator$ResetHandler { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$CreateGroupButtonProvider { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$GridCardOnClickListenerProvider { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$IphProvider { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$ThumbnailProvider { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TitleProvider { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView$VisibilityListener { *; } + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate { *; } + +-keep class org.chromium.chrome.browser.toolbar.ToolbarManager { *; } + +-keep class org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator$BottomControlsVisibilityController { *; } + +-keep class org.chromium.chrome.browser.widget.ScrimView { *; } + +-keep class org.chromium.chrome.browser.widget.ScrimView$ScrimObserver { *; } + +-keep class org.chromium.chrome.browser.widget.ScrimView$ScrimParams { *; } + +-keep class org.chromium.chrome.browser.widget.ScrimView$StatusBarScrimDelegate { *; } + +-keep class org.chromium.chrome.browser.widget.bottomsheet.BottomSheet$BottomSheetContent { *; } + +-keep class org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController { *; } + +-keep class org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver { *; } + +-keep class org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver { *; } + +-keep class org.chromium.chrome.browser.widget.textbubble.TextBubble { *; } + +-keep class org.chromium.components.feature_engagement.Tracker { *; } + +-keep class org.chromium.content_public.browser.LoadUrlParams { *; } + +-keep class org.chromium.ui.modelutil.ListModelBase { *; } + +-keep class org.chromium.ui.modelutil.PropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyKey[] { *; } + +-keep class org.chromium.ui.modelutil.PropertyListModel { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$Builder { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$ReadableBooleanPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$ReadableFloatPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$ReadableIntPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$ReadableObjectPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$WritableFloatPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey { *; } + +-keep class org.chromium.ui.modelutil.PropertyModelChangeProcessor$ViewBinder { *; } + +-keep class org.chromium.ui.modelutil.PropertyObservable { *; } + +-keep class org.chromium.ui.modelutil.RecyclerViewAdapter { *; } + +-keep class org.chromium.ui.modelutil.RecyclerViewAdapter$Delegate { *; } + +-keep class org.chromium.ui.modelutil.RecyclerViewAdapter$ViewHolderFactory { *; } + +-keep class org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase { *; } + +-keep class org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase$ItemViewTypeCallback { *; } + +-keep class org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase$ViewBinder { *; } + +-keep class org.chromium.ui.resources.dynamics.DynamicResource { *; } + +-keep class org.chromium.ui.resources.dynamics.DynamicResourceLoader { *; } + +-keep class org.chromium.ui.resources.dynamics.ViewResourceAdapter { *; } + +-keep class org.chromium.ui.widget.RectProvider { *; } + +-keep class org.chromium.ui.widget.ViewRectProvider { *; } + +-keep class android.support.v4.content.ContextCompat { + int getColor(android.content.Context, int); +} + +-keep class android.support.v4.content.res.ResourcesCompat { + android.graphics.drawable.Drawable getDrawable(android.content.res.Resources, int, android.content.res.Resources$Theme); +} + +-keep class android.support.v7.content.res.AppCompatResources { + android.graphics.drawable.Drawable getDrawable(android.content.Context, int); +} + +-keep class android.support.v7.widget.RecyclerView$ItemAnimator { + void setAddDuration(long); + long getAddDuration(); +} + +-keep class gen._chrome._android._features._tab_ui._java_resources.srcjar.R { + void onResourcesLoaded(int); + void onResourcesLoadedString(int); + void onResourcesLoadedDrawable(int); + void onResourcesLoadedMipmap(int); + void onResourcesLoadedStyleable(int); + void onResourcesLoadedInteger(int); + void onResourcesLoadedColor(int); + boolean sResourcesDidLoad; + void onResourcesLoadedMenu(int); + void onResourcesLoadedDimen(int); + void onResourcesLoadedXml(int); + void onResourcesLoadedLayout(int); + void onResourcesLoadedTransition(int); + void onResourcesLoadedBool(int); + void onResourcesLoadedFont(int); + void onResourcesLoadedAnim(int); + void onResourcesLoadedAnimator(int); + void onResourcesLoadedArray(int); + void onResourcesLoadedStyle(int); + void onResourcesLoadedFraction(int); + void onResourcesLoadedAttr(int); + void onResourcesLoadedId(int); + void onResourcesLoadedPlurals(int); +} + +-keep class org.apache.http.conn.ssl.SSLSocketFactory { + org.apache.http.conn.ssl.X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER; + org.apache.http.conn.ssl.X509HostnameVerifier STRICT_HOSTNAME_VERIFIER; + org.apache.http.conn.ssl.X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; +} + +-keep class org.chromium.base.ApiCompatibilityUtils { + void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList); + int getColor(android.content.res.Resources, int); +} + +-keep class org.chromium.base.ApplicationStatus { + android.app.Activity getLastTrackedFocusedActivity(); +} + +-keep class org.chromium.base.ContextUtils { + android.content.Context getApplicationContext(); +} + +-keep class org.chromium.base.Log { + void w(java.lang.String, java.lang.String, java.lang.Object[]); +} + +-keep class org.chromium.base.metrics.RecordHistogram { + void recordSparseHistogram(java.lang.String, int); + void recordCountHistogram(java.lang.String, int); +} + +-keep class org.chromium.base.metrics.RecordUserAction { + void record(java.lang.String); +} + +-keep class org.chromium.base.task.PostTask { + void postTask(org.chromium.base.task.TaskTraits, java.lang.Runnable); +} + +-keep class org.chromium.chrome.R$color { + int modern_grey_100; + int modern_grey_800_alpha_38; + int modern_primary_color; + int default_text_color_dark; + int modern_grey_300; +} + +-keep class org.chromium.chrome.R$dimen { + int toolbar_height_no_shadow; + int control_container_height; + int compositor_tab_title_text_size; + int default_favicon_size; +} + +-keep class org.chromium.chrome.R$drawable { + int btn_close; + int ic_globe_24dp; + int chromelogo16; +} + +-keep class org.chromium.chrome.R$plurals { + int bottom_tab_grid_title_placeholder; +} + +-keep class org.chromium.chrome.R$string { + int iph_tab_groups_your_tabs_together_text; + int bottom_tab_grid_opened_full; + int accessibility_tabstrip_tab; + int iph_tab_groups_quickly_compare_pages_text; + int iph_tab_groups_tap_to_see_another_tab_text; + int bottom_tab_grid_opened_half; + int iph_tab_groups_tap_to_see_another_tab_accessibility_text; + int accessibility_tabstrip_btn_close_tab; + int bottom_tab_grid_description; + int bottom_tab_grid_closed; +} + +-keep class org.chromium.chrome.browser.ChromeActivity { + org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher getLifecycleDispatcher(); + org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior getOverviewModeBehavior(); + org.chromium.chrome.browser.toolbar.ToolbarManager getToolbarManager(); + void onBackPressed(); + org.chromium.chrome.browser.compositor.layouts.content.TabContentManager getTabContentManager(); + org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager getFullscreenManager(); + boolean isWarmOnResume(); + org.chromium.chrome.browser.tabmodel.TabModelSelector getTabModelSelector(); + org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController getBottomSheetController(); + org.chromium.chrome.browser.compositor.CompositorViewHolder getCompositorViewHolder(); +} + +-keep class org.chromium.chrome.browser.ChromeFeatureList { + boolean isInitialized(); + boolean isEnabled(java.lang.String); +} + +-keep class org.chromium.chrome.browser.ChromeTabbedActivity { + org.chromium.chrome.browser.tabmodel.TabModelSelector getTabModelSelector(); + org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior getOverviewModeBehavior(); +} + +-keep class org.chromium.chrome.browser.feature_engagement.TrackerFactory { + org.chromium.components.feature_engagement.Tracker getTrackerForProfile(org.chromium.chrome.browser.profiles.Profile); +} + +-keep class org.chromium.chrome.browser.gesturenav.HistoryNavigationLayout { + void setNavigationDelegate(org.chromium.chrome.browser.gesturenav.HistoryNavigationDelegate); +} + +-keep class org.chromium.chrome.browser.metrics.UmaSessionStats { + void registerSyntheticFieldTrial(java.lang.String, java.lang.String); +} + +-keep class org.chromium.chrome.browser.native_page.NativePageFactory { + boolean isNativePageUrl(java.lang.String, boolean); +} + +-keep class org.chromium.chrome.browser.tabmodel.TabCreatorManager$TabCreator { + org.chromium.chrome.browser.tab.Tab createNewTab(org.chromium.content_public.browser.LoadUrlParams, int, org.chromium.chrome.browser.tab.Tab); +} + +-keep class org.chromium.chrome.browser.tabmodel.TabModelFilter { + int index(); + int indexOf(org.chromium.chrome.browser.tab.Tab); + boolean isIncognito(); + java.util.List getRelatedTabList(int); +} + +-keep class org.chromium.chrome.browser.tabmodel.TabModelFilterProvider { + void removeTabModelFilterObserver(org.chromium.chrome.browser.tabmodel.TabModelObserver); + org.chromium.chrome.browser.tabmodel.TabModelFilter getTabModelFilter(boolean); + org.chromium.chrome.browser.tabmodel.TabModelFilter getCurrentTabModelFilter(); + void addTabModelFilterObserver(org.chromium.chrome.browser.tabmodel.TabModelObserver); +} + +-keep class org.chromium.chrome.browser.tabmodel.TabModelUtils { + int getTabIndexById(org.chromium.chrome.browser.tabmodel.TabList, int); + org.chromium.chrome.browser.tab.Tab getTabById(org.chromium.chrome.browser.tabmodel.TabList, int); +} + +-keep class org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil { + boolean shouldShowOmniboxOnTabSwitcher(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils { + boolean isMoveInSameGroup(org.chromium.chrome.browser.tabmodel.TabModel, int, int); + boolean $assertionsDisabled; + void lambda$maybeShowIPH$0(org.chromium.components.feature_engagement.Tracker, java.lang.String); + void startObservingForTabGroupsIPH(org.chromium.chrome.browser.tabmodel.TabModelSelector); + void maybeShowIPH(java.lang.String, android.view.View); + org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver access$000(); + int getLastTabModelIndexForList(org.chromium.chrome.browser.tabmodel.TabModelSelector, java.util.List); + org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver sTabModelSelectorTabObserver; + int getFirstTabModelIndexForList(org.chromium.chrome.browser.tabmodel.TabModelSelector, java.util.List); + org.chromium.chrome.browser.tab.Tab getSelectedTabInGroupForTab(org.chromium.chrome.browser.tabmodel.TabModelSelector, org.chromium.chrome.browser.tab.Tab); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherCoordinator { + org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator mTabGridCoordinator; + java.lang.String lambda$new$0(org.chromium.chrome.browser.tabmodel.TabModelSelector, android.content.Context, org.chromium.chrome.browser.tab.Tab); + org.chromium.ui.modelutil.PropertyModelChangeProcessor mContainerViewChangeProcessor; + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogCoordinator mTabGridDialogCoordinator; + org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher mLifecycleDispatcher; + org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator mMediator; + org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider mMultiThumbnailCardProvider; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator { + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener getGridCardOnClickListener(org.chromium.chrome.browser.tab.Tab); + java.util.List getRelatedTabs(int); + org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator$ResetHandler access$300(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator); + boolean mShouldIgnoreNextSelect; + org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager$FullscreenListener mFullscreenListener; + void lambda$getCreateGroupButtonOnClickListener$1(int); + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator$ResetHandler mTabGridDialogResetHandler; + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + void prepareOverview(); + org.chromium.chrome.browser.tabmodel.TabModelObserver mTabModelObserver; + boolean ableToCreateGroup(org.chromium.chrome.browser.tab.Tab); + void setContentOverlayVisibility(boolean); + org.chromium.ui.modelutil.PropertyModel access$000(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator); + org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager mFullscreenManager; + boolean access$102(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator, boolean); + org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator$ResetHandler mResetHandler; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener getCreateGroupButtonOnClickListener(org.chromium.chrome.browser.tab.Tab); + void destroy(); + org.chromium.base.ObserverList mObservers; + boolean access$100(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator); + void setVisibility(boolean); + boolean ableToOpenDialog(org.chromium.chrome.browser.tab.Tab); + org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver mTabModelSelectorObserver; + void access$400(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator, boolean); + void lambda$getGridCardOnClickListener$0(int); + org.chromium.ui.modelutil.PropertyModel mContainerViewModel; + org.chromium.chrome.browser.compositor.CompositorViewHolder mCompositorViewHolder; + org.chromium.chrome.browser.tabmodel.TabModelSelector access$200(org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider { + android.graphics.Paint access$1000(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider access$1200(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider mTabListFaviconProvider; + java.util.List mThumbnailRects; + float access$900(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + android.graphics.Paint mTextPaint; + java.util.List access$800(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + java.util.List mFaviconRects; + android.graphics.Paint mEmptyThumbnailPaint; + java.util.List access$1100(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + float access$500(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + java.util.List mFaviconBackgroundRects; + int mSize; + android.graphics.Paint access$700(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + org.chromium.chrome.browser.tabmodel.TabModelSelector access$100(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + android.graphics.Paint mThumbnailFramePaint; + org.chromium.chrome.browser.compositor.layouts.content.TabContentManager access$200(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + android.graphics.Paint access$400(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + java.util.List access$300(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + float mRadius; + float mFaviconCirclePadding; + android.graphics.Paint mFaviconBackgroundPaint; + android.graphics.Paint access$600(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); + org.chromium.chrome.browser.compositor.layouts.content.TabContentManager mTabContentManager; + int access$000(org.chromium.chrome.browser.tasks.tab_management.MultiThumbnailCardProvider); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridContainerViewBinder { + void bind(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView, org.chromium.ui.modelutil.PropertyKey); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridDialogCoordinator { + org.chromium.ui.modelutil.PropertyModel mToolbarPropertyModel; + android.content.Context mContext; + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator mMediator; + void updateDialogContent(java.util.List); + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetToolbarCoordinator mToolbarCoordinator; + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator$ResetHandler getResetHandler(); + org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator mTabListCoordinator; + void resetWithListOfTabs(java.util.List); + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogParent mParentLayout; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator { + void setupToolbarClickHandlers(); + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + void onReset(java.lang.Integer); + android.view.View$OnClickListener getCollapseButtonClickListener(); + java.util.List getRelatedTabs(int); + void updateGridTabSwitcher(); + org.chromium.ui.modelutil.PropertyModel mModel; + org.chromium.chrome.browser.tabmodel.TabModelObserver mTabModelObserver; + void lambda$getAddButtonClickListener$1(android.view.View); + void setupScrimViewObserver(); + android.content.Context mContext; + void updateDialog(); + org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator$ResetHandler mDialogResetHandler; + org.chromium.chrome.browser.tabmodel.TabCreatorManager mTabCreatorManager; + boolean $assertionsDisabled; + void access$100(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator); + int access$400(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator); + int access$402(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator, int); + org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcherMediator$ResetHandler mGridTabSwitcherResetHandler; + java.util.List access$300(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator, int); + org.chromium.ui.modelutil.PropertyModel access$200(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator); + void lambda$getCollapseButtonClickListener$0(android.view.View); + android.view.View$OnClickListener getAddButtonClickListener(); + void access$000(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogMediator); + int mCurrentTabId; + void destroy(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridDialogParent { + void showDialog(); + org.chromium.chrome.browser.widget.ScrimView$ScrimParams mScrimParams; + android.widget.PopupWindow mPopupWindow; + void setupDialogAnimation(); + void destroy(); + int mSideMargin; + void updateDialogWithOrientation(android.content.Context, int); + android.content.ComponentCallbacks mComponentCallbacks; + android.widget.LinearLayout mDialogContainerView; + void access$000(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogParent, android.content.Context, int); + org.chromium.chrome.browser.widget.ScrimView mScrimView; + android.animation.Animator access$102(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogParent, android.animation.Animator); + void hideDialog(); + android.animation.ValueAnimator mDialogFadeOut; + android.view.ViewGroup mParent; + android.animation.Animator mCurrentAnimator; + int mTopMargin; + void setupDialogContent(android.content.Context); + void resetDialog(android.view.View, android.view.View); + android.widget.PopupWindow access$200(org.chromium.chrome.browser.tasks.tab_management.TabGridDialogParent); + android.animation.ValueAnimator mDialogFadeIn; + int mStatusBarHeight; + android.widget.FrameLayout$LayoutParams mContainerParams; + void setScrimViewObserver(org.chromium.chrome.browser.widget.ScrimView$ScrimObserver); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetContent { + android.view.View mToolbarView; + void destroy(); + org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView mRecyclerView; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetCoordinator { + void updateBottomSheetContent(java.util.List); + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetToolbarCoordinator mToolbarCoordinator; + org.chromium.ui.modelutil.PropertyModel mToolbarPropertyModel; + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetContent mBottomSheetContent; + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetMediator mMediator; + void destroy(); + org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator mTabGridCoordinator; + void resetWithListOfTabs(java.util.List); + android.content.Context mContext; + void startObservingForCreationIPH(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetMediator { + android.view.View$OnClickListener getAddButtonClickListener(); + org.chromium.chrome.browser.tabmodel.TabCreatorManager mTabCreatorManager; + void lambda$getAddButtonClickListener$3(android.view.View); + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetMediator$ResetHandler mResetHandler; + org.chromium.chrome.browser.tabmodel.TabModelObserver mTabModelObserver; + void lambda$new$1(android.content.res.ColorStateList, boolean); + org.chromium.chrome.browser.ThemeColorProvider$ThemeColorObserver mThemeColorObserver; + void lambda$new$0(int, boolean); + void onReset(org.chromium.chrome.browser.tasks.tab_management.TabGridSheetContent); + void lambda$getCollapseButtonClickListener$2(android.view.View); + org.chromium.chrome.browser.widget.bottomsheet.BottomSheet$BottomSheetContent getCurrentSheetContent(); + boolean $assertionsDisabled; + void setupToolbarClickHandlers(); + android.content.Context mContext; + android.view.View$OnClickListener getCollapseButtonClickListener(); + void destroy(); + void showTabGridSheet(org.chromium.chrome.browser.tasks.tab_management.TabGridSheetContent); + void updateBottomSheet(); + org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController mBottomSheetController; + org.chromium.chrome.browser.ThemeColorProvider mThemeColorProvider; + void access$000(org.chromium.chrome.browser.tasks.tab_management.TabGridSheetMediator); + org.chromium.ui.modelutil.PropertyModel mModel; + org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver mSheetObserver; + org.chromium.chrome.browser.ThemeColorProvider$TintObserver mTintObserver; + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + void hideTabGridSheet(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetProperties { + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey SCRIMVIEW_OBSERVER; + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey PRIMARY_COLOR; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey TINT; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey ADD_CLICK_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey CONTENT_TOP_MARGIN; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey IS_DIALOG_VISIBLE; + org.chromium.ui.modelutil.PropertyKey[] ALL_KEYS; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey COLLAPSE_CLICK_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey HEADER_TITLE; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetToolbarCoordinator { + android.view.View getView(); + org.chromium.chrome.browser.tasks.tab_management.TabGroupUiToolbarView mToolbarView; + org.chromium.ui.modelutil.PropertyModelChangeProcessor mModelChangeProcessor; + void destroy(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridSheetViewBinder { + void bind(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabGridSheetViewBinder$ViewHolder, org.chromium.ui.modelutil.PropertyKey); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridViewBinder { + void lambda$onBindViewHolder$3(org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener, org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, android.view.View); + void lambda$onBindViewHolder$2(org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, android.graphics.Bitmap); + void lambda$onBindViewHolder$0(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, android.view.View); + void lambda$onBindViewHolder$1(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, android.view.View); + void onBindViewHolder(org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, org.chromium.ui.modelutil.PropertyModel); + void onBindViewHolder(org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder, org.chromium.ui.modelutil.PropertyModel, org.chromium.ui.modelutil.PropertyKey); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder { + android.widget.ImageView favicon; + int getTabId(); + org.chromium.ui.widget.ButtonCompat createGroupButton; + android.widget.TextView title; + android.view.View backgroundView; + android.view.View itemView; + org.chromium.chrome.browser.tasks.tab_management.TabGridViewHolder create(android.view.ViewGroup, int); + void setTabId(int); + int mTabId; + java.lang.ref.WeakReference sCloseButtonBitmapWeakRef; + void resetThumbnail(); + android.widget.ImageView thumbnail; + android.widget.ImageView closeButton; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUiCoordinator { + org.chromium.ui.modelutil.PropertyModel mTabStripToolbarModel; + org.chromium.chrome.browser.ThemeColorProvider mThemeColorProvider; + android.content.Context mContext; + org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator mMediator; + org.chromium.chrome.browser.ChromeActivity mActivity; + org.chromium.chrome.browser.tasks.tab_management.TabGridSheetCoordinator mTabGridSheetCoordinator; + void recordSessionCount(); + org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher mActivityLifecycleDispatcher; + org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator mTabStripCoordinator; + boolean $assertionsDisabled; + org.chromium.chrome.browser.tasks.tab_management.TabStripToolbarCoordinator mTabStripToolbarCoordinator; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator { + org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior mOverviewModeBehavior; + boolean mIsTabGroupUiVisible; + org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver mTabModelSelectorTabObserver; + org.chromium.chrome.browser.tabmodel.TabModelSelector access$400(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator); + org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator$ResetHandler access$500(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator); + java.util.List getRelatedTabsForId(int); + org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior$OverviewModeObserver mOverviewModeObserver; + org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver mTabModelSelectorObserver; + boolean access$100(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator); + org.chromium.ui.modelutil.PropertyModel mToolbarPropertyModel; + org.chromium.chrome.browser.ThemeColorProvider$ThemeColorObserver mThemeColorObserver; + void lambda$setupToolbarClickHandlers$3(android.view.View); + org.chromium.chrome.browser.ThemeColorProvider mThemeColorProvider; + void lambda$setupToolbarClickHandlers$2(android.view.View); + void setupToolbarClickHandlers(); + void lambda$new$1(android.content.res.ColorStateList, boolean); + void resetTabStripWithRelatedTabsForId(int); + org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator$BottomControlsVisibilityController mVisibilityController; + void destroy(); + boolean $assertionsDisabled; + void lambda$new$0(int, boolean); + org.chromium.chrome.browser.tabmodel.TabModelObserver mTabModelObserver; + org.chromium.chrome.browser.ThemeColorProvider$TintObserver mTintObserver; + void access$300(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator, int); + boolean mIsClosingAGroup; + org.chromium.chrome.browser.tabmodel.TabCreatorManager mTabCreatorManager; + org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator$ResetHandler mResetHandler; + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + boolean access$102(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator, boolean); + java.util.List access$200(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator, int); + boolean access$000(org.chromium.chrome.browser.tasks.tab_management.TabGroupUiMediator); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUiToolbarView { + android.view.View mMainContent; + void setTint(android.content.res.ColorStateList); + android.view.ViewGroup mContainerView; + org.chromium.ui.widget.ChromeImageView mLeftButton; + void setMainContentVisibility(boolean); + void setTitle(java.lang.String); + org.chromium.ui.widget.ChromeImageView mRightButton; + android.view.View findViewById(int); + android.widget.TextView mTitleTextView; + void setLeftButtonOnClickListener(android.view.View$OnClickListener); + android.view.ViewGroup getViewContainer(); + void setRightButtonOnClickListener(android.view.View$OnClickListener); + void setPrimaryColor(int); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabGroupUiToolbarViewBinder { + void bind(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabGroupUiToolbarView, org.chromium.ui.modelutil.PropertyKey); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties { + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey TOP_PADDING; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey VISIBILITY_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey INITIAL_SCROLL_INDEX; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey ANIMATE_VISIBILITY_CHANGES; + org.chromium.ui.modelutil.PropertyKey[] ALL_KEYS; + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey BOTTOM_CONTROLS_HEIGHT; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey IS_INCOGNITO; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey IS_VISIBLE; + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey TOP_CONTROLS_HEIGHT; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator { + void updateThumbnailLocation(); + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + android.graphics.Rect mThumbnailLocationOfCurrentTab; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator mMediator; + org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView mRecyclerView; + int getResourceId(); + android.graphics.Rect getThumbnailLocationOfCurrentTab(); + int mMode; + void destroy(); + org.chromium.ui.modelutil.SimpleRecyclerViewMcpBase mModelChangeProcessor; + org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView getContainerView(); + void resetWithListOfTabs(java.util.List); + void prepareOverview(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider { + android.graphics.drawable.Drawable getDefaultFaviconDrawable(); + android.graphics.drawable.Drawable getFaviconForUrlSync(java.lang.String, boolean, android.graphics.Bitmap); + android.graphics.drawable.Drawable sRoundedGlobeDrawable; + android.graphics.drawable.Drawable processBitmap(android.graphics.Bitmap); + int mFaviconSize; + void lambda$getFaviconForUrlAsync$0(org.chromium.base.Callback, android.graphics.Bitmap, java.lang.String); + android.graphics.drawable.Drawable sRoundedChromeDrawable; + org.chromium.chrome.browser.profiles.Profile mProfile; + void getFaviconForUrlAsync(java.lang.String, boolean, org.chromium.base.Callback); + org.chromium.chrome.browser.favicon.FaviconHelper mFaviconHelper; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListMediator { + void addTabInfoToModel(org.chromium.chrome.browser.tab.Tab, int, boolean); + boolean isValidMovePosition(int); + android.content.ComponentCallbacks mComponentCallbacks; + org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider mTabListFaviconProvider; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$GridCardOnClickListenerProvider mGridCardOnClickListenerProvider; + boolean mShownIPH; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener access$1300(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + java.util.Map access$800(); + org.chromium.chrome.browser.tabmodel.TabModelSelector access$100(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + boolean access$600(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + java.util.List access$1000(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, int); + void access$900(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, org.chromium.chrome.browser.tab.Tab, int, int); + void registerOrientationListener(android.support.v7.widget.GridLayoutManager); + java.lang.String mComponentName; + boolean mCloseAllRelatedTabs; + java.lang.String access$200(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TitleProvider mTitleProvider; + android.support.v7.widget.helper.ItemTouchHelper$SimpleCallback getItemTouchHelperCallback(float); + void access$700(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, org.chromium.chrome.browser.tab.Tab, boolean); + void onTabClosedFrom(int, java.lang.String); + boolean access$002(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, boolean); + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$IphProvider mIphProvider; + java.util.Map sTabClosedFromMapTabClosedFromMap; + void onTabAdded(org.chromium.chrome.browser.tab.Tab, boolean); + org.chromium.chrome.browser.tab.TabObserver mTabObserver; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$CreateGroupButtonProvider mCreateGroupButtonProvider; + java.util.List getRelatedTabsForId(int); + org.chromium.chrome.browser.tasks.tab_management.TabListFaviconProvider access$400(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener mTabSelectedListener; + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TabActionListener mTabClosedListener; + void resetWithListOfTabs(java.util.List); + org.chromium.chrome.browser.tabmodel.TabModelSelector mTabModelSelector; + boolean access$000(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + void lambda$addTabInfoToModel$0(org.chromium.chrome.browser.tab.Tab, android.graphics.drawable.Drawable); + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$ThumbnailProvider mThumbnailProvider; + void onGroupClosedFrom(int); + org.chromium.chrome.browser.tasks.tab_management.TabListModel mModel; + org.chromium.chrome.browser.tabmodel.TabModelObserver mTabModelObserver; + void onTabMoved(org.chromium.chrome.browser.tab.Tab, int, int); + void access$1200(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, int, java.lang.String); + org.chromium.chrome.browser.tasks.tab_management.TabListModel access$300(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + org.chromium.chrome.browser.tasks.tab_management.TabListMediator$TitleProvider access$500(org.chromium.chrome.browser.tasks.tab_management.TabListMediator); + void access$1100(org.chromium.chrome.browser.tasks.tab_management.TabListMediator, int); + void destroy(); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListModel { + void add(int, org.chromium.ui.modelutil.PropertyObservable); + int size(); + void add(org.chromium.ui.modelutil.PropertyObservable); + java.lang.Object get(int); + org.chromium.ui.modelutil.PropertyObservable removeAt(int); + void set(java.util.Collection); + int indexFromId(int); + void move(int, int); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView { + int getId(); + long access$200(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView); + android.graphics.Rect getRectOfCurrentThumbnail(int); + void setHasFixedSize(boolean); + android.animation.ValueAnimator mFadeInAnimator; + int getPaddingLeft(); + int getPaddingBottom(); + void endAllAnimations(); + long mOriginalAddDuration; + int getResourceId(); + org.chromium.ui.resources.dynamics.ViewResourceAdapter access$300(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView); + org.chromium.ui.resources.dynamics.ViewResourceAdapter mDynamicView; + int computeVerticalScrollOffset(); + org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView$VisibilityListener mListener; + void startShowing(boolean); + android.animation.ValueAnimator access$002(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView, android.animation.ValueAnimator); + void setBackgroundColor(int); + void setAlpha(float); + void setVisibilityListener(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView$VisibilityListener); + android.animation.ValueAnimator mFadeOutAnimator; + void setVisibility(int); + android.view.ViewTreeObserver getViewTreeObserver(); + void setPadding(int, int, int, int); + android.support.v7.widget.RecyclerView$LayoutManager getLayoutManager(); + boolean $assertionsDisabled; + void createDynamicView(org.chromium.ui.resources.dynamics.DynamicResourceLoader); + android.content.res.Resources getResources(); + android.animation.ValueAnimator access$402(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView, android.animation.ValueAnimator); + void prepareOverview(); + void setAdapter(android.support.v7.widget.RecyclerView$Adapter); + android.support.v7.widget.RecyclerView$ItemAnimator getItemAnimator(); + void requestLayout(); + android.view.ViewGroup$LayoutParams getLayoutParams(); + android.support.v7.widget.RecyclerView$ViewHolder findViewHolderForAdapterPosition(int); + void setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager); + void getLocationInWindow(int[]); + void startHiding(boolean); + int getPaddingRight(); + org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView$VisibilityListener access$100(org.chromium.chrome.browser.tasks.tab_management.TabListRecyclerView); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabProperties { + org.chromium.ui.modelutil.PropertyModel$ReadableIntPropertyKey TAB_ID; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey IPH_PROVIDER; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey CREATE_GROUP_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey TAB_SELECTED_LISTENER; + org.chromium.ui.modelutil.PropertyKey[] ALL_KEYS_TAB_GRID; + org.chromium.ui.modelutil.PropertyKey[] ALL_KEYS_TAB_STRIP; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey FAVICON; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey IS_SELECTED; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey TITLE; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey TAB_CLOSED_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey THUMBNAIL_FETCHER; + org.chromium.ui.modelutil.PropertyModel$WritableFloatPropertyKey ALPHA; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabStripToolbarCoordinator { + android.view.ViewGroup getTabListContainerView(); + org.chromium.ui.modelutil.PropertyModel mModel; + org.chromium.ui.modelutil.PropertyModelChangeProcessor mModelChangeProcessor; + org.chromium.chrome.browser.tasks.tab_management.TabGroupUiToolbarView mToolbarView; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabStripToolbarViewProperties { + org.chromium.ui.modelutil.PropertyModel$WritableIntPropertyKey PRIMARY_COLOR; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey ADD_CLICK_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey TINT; + org.chromium.ui.modelutil.PropertyKey[] ALL_KEYS; + org.chromium.ui.modelutil.PropertyModel$WritableObjectPropertyKey EXPAND_CLICK_LISTENER; + org.chromium.ui.modelutil.PropertyModel$WritableBooleanPropertyKey IS_MAIN_CONTENT_VISIBLE; +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabStripViewBinder { + void lambda$onBindViewHolder$1(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder, android.view.View); + void lambda$onBindViewHolder$0(org.chromium.ui.modelutil.PropertyModel, org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder, android.view.View); + void onBindViewHolder(org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder, org.chromium.ui.modelutil.PropertyModel, org.chromium.ui.modelutil.PropertyKey); + void onBindViewHolder(org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder, org.chromium.ui.modelutil.PropertyModel); +} + +-keep class org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder { + android.widget.ImageButton button; + int mTabId; + android.view.View itemView; + org.chromium.chrome.browser.tasks.tab_management.TabStripViewHolder create(android.view.ViewGroup, int); + void setTabId(int); + int getTabId(); +} + +-keep class org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter { + int indexOf(org.chromium.chrome.browser.tab.Tab); + int getTabGroupCount(); + void recordSessionsCount(org.chromium.chrome.browser.tab.Tab); + void moveRelatedTabs(int, int); + org.chromium.chrome.browser.tab.Tab getTabAt(int); +} + +-keep class org.chromium.chrome.browser.util.ColorUtils { + int getPrimaryBackgroundColor(android.content.res.Resources, boolean); +} + +-keep class org.chromium.chrome.browser.util.FeatureUtilities { + boolean isTabGroupsAndroidEnabled(); + boolean isTabGroupsAndroidUiImprovementsEnabled(); +} + +-keep class org.chromium.chrome.browser.util.ViewUtils { + android.support.v4.graphics.drawable.RoundedBitmapDrawable createRoundedBitmapDrawable(android.graphics.Bitmap, int); + int DEFAULT_FAVICON_CORNER_RADIUS; +} + +-keep class org.chromium.chrome.browser.widget.bottomsheet.BottomSheet { + void addObserver(org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver); + void removeObserver(org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver); + org.chromium.chrome.browser.widget.bottomsheet.BottomSheet$BottomSheetContent getCurrentSheetContent(); +} + +-keep class org.chromium.content_public.browser.NavigationHandle { + boolean isSameDocument(); + boolean isValidSearchFormUrl(); + boolean isInMainFrame(); + java.lang.Integer pageTransition(); +} + +-keep class org.chromium.content_public.browser.UiThreadTaskTraits { + org.chromium.base.task.TaskTraits USER_VISIBLE; +} + +-keep class org.chromium.ui.interpolators.BakedBezierInterpolator { + org.chromium.ui.interpolators.BakedBezierInterpolator FADE_IN_CURVE; + org.chromium.ui.interpolators.BakedBezierInterpolator FADE_OUT_CURVE; +} + +-keep class org.chromium.ui.modelutil.PropertyModelChangeProcessor { + void destroy(); + org.chromium.ui.modelutil.PropertyModelChangeProcessor create(org.chromium.ui.modelutil.PropertyObservable, java.lang.Object, org.chromium.ui.modelutil.PropertyModelChangeProcessor$ViewBinder); +} + +-keep class org.chromium.ui.widget.ButtonCompat { + void setVisibility(int); + void setOnClickListener(android.view.View$OnClickListener); +} + +-keep class org.chromium.ui.widget.ChromeImageView { + void setOnClickListener(android.view.View$OnClickListener); +} + +-keep class org.json.JSONObject { + java.lang.Object NULL; +} +
diff --git a/chrome/android/features/tab_ui/proguard_async_manual.flags b/chrome/android/features/tab_ui/proguard_async_manual.flags new file mode 100644 index 0000000..654ee65 --- /dev/null +++ b/chrome/android/features/tab_ui/proguard_async_manual.flags
@@ -0,0 +1,14 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Rules added manually due to types +# 1) used and included in XML files (ie. layout), +# 2) dynamically generated by the compiler (ie. lambda), and +# 3) types not currently being included in our constant pool deps. + +-keep class android.support.v4.graphics.drawable.RoundedBitmapDrawable { *; } +-keep class org.chromium.ui.widget.RoundedCornerImageView { *; } +-keep class org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager$FullscreenListener$$CC { *; } +-keep class org.chromium.chrome.browser.widget.bottomsheet.BottomSheet$BottomSheetContent$$CC { *; } +-keep class org.chromium.chrome.browser.compositor.layouts.OverviewModeController { *; } \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/tab_ui_module_tmpl.gni b/chrome/android/features/tab_ui/tab_ui_module_tmpl.gni index 4e10712..614aed0 100644 --- a/chrome/android/features/tab_ui/tab_ui_module_tmpl.gni +++ b/chrome/android/features/tab_ui/tab_ui_module_tmpl.gni
@@ -5,6 +5,7 @@ import("//build/config/android/rules.gni") import("//build/config/locales.gni") import("//chrome/android/features/dynamic_feature_modules.gni") +import("//chrome/android/features/tab_ui/buildflags.gni") template("tab_ui_module_tmpl") { assert(defined(invoker.version_code)) @@ -39,5 +40,11 @@ deps = [ "//chrome/android/features/tab_ui:java", ] + + # If tab_ui is set as async DFM, generate list of dependencies on base for keep + # rule generation. + if (async_tab_ui) { + enable_class_deps_output = "tabUiConstantPoolDeps.txt" + } } }
diff --git a/chrome/android/touchless/java/res/drawable/ic_apps_blue_24dp.xml b/chrome/android/java/res/drawable/ic_apps_blue_24dp.xml similarity index 100% rename from chrome/android/touchless/java/res/drawable/ic_apps_blue_24dp.xml rename to chrome/android/java/res/drawable/ic_apps_blue_24dp.xml
diff --git a/chrome/android/java/res/layout/top_sites_tile_view.xml b/chrome/android/java/res/layout/top_sites_tile_view.xml new file mode 100644 index 0000000..aca78aa7 --- /dev/null +++ b/chrome/android/java/res/layout/top_sites_tile_view.xml
@@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<!-- An icon tile. --> +<org.chromium.chrome.browser.suggestions.tile.TopSitesTileView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="@dimen/tile_view_width" + android:layout_height="wrap_content" + android:paddingStart="@dimen/tile_view_padding" + android:paddingEnd="@dimen/tile_view_padding" > + + <!-- The icon background. --> + <View + android:id="@+id/tile_view_icon_background" + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_background_margin_top_modern" + android:background="@drawable/tile_view_icon_background_modern" /> + + <!-- The main icon. --> + <ImageView + android:id="@+id/tile_view_icon" + android:layout_width="@dimen/tile_view_icon_size_modern" + android:layout_height="@dimen/tile_view_icon_size_modern" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_margin_top_modern" + android:importantForAccessibility="no" /> + + <!-- The touch highlight. --> + <View + android:id="@+id/tile_view_highlight" + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_background_margin_top_modern" + android:background="@drawable/tile_view_highlight" /> + + <!-- The offline badge. --> + <ImageView + android:id="@+id/offline_badge" + android:layout_width="@dimen/tile_view_offline_badge_size_modern" + android:layout_height="@dimen/tile_view_offline_badge_size_modern" + android:layout_gravity="top|end" + android:layout_marginTop="@dimen/tile_view_offline_badge_margin_top_modern" + android:layout_marginEnd="@dimen/tile_view_offline_badge_margin_end_modern" + android:visibility="gone" + android:contentDescription="@string/accessibility_ntp_offline_badge" + app:srcCompat="@drawable/ic_offline_pin_blue_white" /> + + <!-- The title. --> + <TextView + android:id="@+id/tile_view_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/tile_view_title_margin_top_modern" + android:ellipsize="end" + android:gravity="center_horizontal" + android:lines="2" + android:lineSpacingMultiplier="1.17" + android:textAppearance="@style/TextAppearance.BlackCaption" /> +</org.chromium.chrome.browser.suggestions.tile.TopSitesTileView>
diff --git a/chrome/android/java/res/layout/top_sites_tile_view_condensed.xml b/chrome/android/java/res/layout/top_sites_tile_view_condensed.xml new file mode 100644 index 0000000..1ca4fe9 --- /dev/null +++ b/chrome/android/java/res/layout/top_sites_tile_view_condensed.xml
@@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<!-- An icon tile. --> +<org.chromium.chrome.browser.suggestions.tile.TopSitesTileView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="@dimen/tile_view_width_condensed" + android:layout_height="wrap_content" + android:paddingStart="@dimen/tile_view_padding" + android:paddingEnd="@dimen/tile_view_padding" > + + <!-- The icon background. --> + <View + android:id="@+id/tile_view_icon_background" + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_background_margin_top_modern" + android:background="@drawable/tile_view_icon_background_modern" /> + + <!-- The main icon. --> + <ImageView + android:id="@+id/tile_view_icon" + android:layout_width="@dimen/tile_view_icon_size_modern" + android:layout_height="@dimen/tile_view_icon_size_modern" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_margin_top_modern" + android:importantForAccessibility="no" /> + + <!-- The touch highlight. --> + <View + android:id="@+id/tile_view_highlight" + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:layout_gravity="center_horizontal" + android:layout_marginTop="@dimen/tile_view_icon_background_margin_top_modern" + android:background="@drawable/tile_view_highlight" /> + + <!-- The offline badge. --> + <ImageView + android:id="@+id/offline_badge" + android:layout_width="@dimen/tile_view_offline_badge_size_modern" + android:layout_height="@dimen/tile_view_offline_badge_size_modern" + android:layout_gravity="top|end" + android:layout_marginTop="@dimen/tile_view_offline_badge_margin_top_modern_condensed" + android:layout_marginEnd="@dimen/tile_view_offline_badge_margin_end_modern_condensed" + android:visibility="gone" + android:contentDescription="@string/accessibility_ntp_offline_badge" + app:srcCompat="@drawable/ic_offline_pin_blue_white" /> + + <TextView + android:id="@+id/tile_view_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/tile_view_title_margin_top_modern" + android:ellipsize="end" + android:gravity="center_horizontal" + android:lines="2" + android:lineSpacingMultiplier="1.17" + android:textAppearance="@style/TextAppearance.BlackCaption" /> +</org.chromium.chrome.browser.suggestions.tile.TopSitesTileView>
diff --git a/chrome/android/java/res/xml/legal_information_preferences.xml b/chrome/android/java/res/xml/legal_information_preferences.xml index 216cd19..07fe1b6 100644 --- a/chrome/android/java/res/xml/legal_information_preferences.xml +++ b/chrome/android/java/res/xml/legal_information_preferences.xml
@@ -3,7 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<PreferenceScreen +<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <org.chromium.chrome.browser.preferences.HyperlinkPreference @@ -18,4 +18,4 @@ android:key="privacy_notice" android:title="@string/privacy_notice_title" app:url="@string/chrome_privacy_notice_url" /> -</PreferenceScreen> +</android.support.v7.preference.PreferenceScreen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java index c6968d6..de886c57 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -10,6 +10,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; @@ -295,7 +296,7 @@ * Cache the content of a tab as a thumbnail. * @param tab The tab whose content we will cache. */ - public void cacheTabThumbnail(final Tab tab) { + public void cacheTabThumbnail(@NonNull final Tab tab) { cacheTabThumbnail(tab, null); } @@ -304,7 +305,7 @@ * @param tab The tab whose content we will cache. * @param callback The callback to send the {@link Bitmap} with. */ - public void cacheTabThumbnail(final Tab tab, @Nullable Callback<Bitmap> callback) { + public void cacheTabThumbnail(@NonNull final Tab tab, @Nullable Callback<Bitmap> callback) { if (mNativeTabContentManager != 0 && mSnapshotsEnabled) { if (tab.getNativePage() != null || isNativeViewShowing(tab)) { Bitmap nativeBitmap = readbackNativeBitmap(tab, mThumbnailScale);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java index ef7e18bd..f322b34 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/content_capture/ContentCaptureHistoryDeletionObserver.java
@@ -22,8 +22,10 @@ != historyDeletionInfo.getTimeRangeEnd())) { contentCaptureController.clearAllContentCaptureData(); } else { - contentCaptureController.clearContentCaptureDataForURLs( - historyDeletionInfo.getDeletedURLs()); + String[] deletedURLs = historyDeletionInfo.getDeletedURLs(); + if (deletedURLs.length > 0) { + contentCaptureController.clearContentCaptureDataForURLs(deletedURLs); + } } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 3e3e3d1..1d15b452 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -1993,7 +1993,10 @@ */ private void maybeRecordBackgroundDownload( @UmaBackgroundDownload int event, String downloadGuid) { - if (sBackgroundDownloadIds.remove(downloadGuid)) { + if (sBackgroundDownloadIds.contains(downloadGuid)) { + if (event != UmaBackgroundDownload.INTERRUPTED) { + sBackgroundDownloadIds.remove(downloadGuid); + } DownloadNotificationUmaHelper.recordBackgroundDownloadHistogram(event); } if (downloadGuid.equals(mFirstBackgroundDownloadId)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java index dabcc83a..84688cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java
@@ -106,6 +106,15 @@ return nativeGetVariation(); } + /** + * Gets the current Finch variation for last MostLikely icon that is configured by flag or + * experiment. + */ + @MostLikelyVariation + public static int getIconVariation() { + return nativeGetIconVariation(); + } + public static boolean isEnabled(@ExploreSitesVariation int variation) { return variation == ExploreSitesVariation.ENABLED || variation == ExploreSitesVariation.PERSONALIZED @@ -154,6 +163,7 @@ } static native int nativeGetVariation(); + static native int nativeGetIconVariation(); private static native void nativeGetEspCatalog(Profile profile, List<ExploreSitesCategory> result, Callback<List<ExploreSitesCategory>> callback);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java index b8c2310..488eee2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/HyperlinkPreference.java
@@ -6,7 +6,8 @@ import android.content.Context; import android.content.res.TypedArray; -import android.preference.Preference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; @@ -22,7 +23,6 @@ */ public class HyperlinkPreference extends Preference { - private final int mTitleResId; private final int mUrlResId; private final int mColor; private final boolean mImitateWebLink; @@ -34,7 +34,6 @@ mUrlResId = a.getResourceId(R.styleable.HyperlinkPreference_url, 0); mImitateWebLink = a.getBoolean(R.styleable.HyperlinkPreference_imitateWebLink, false); a.recycle(); - mTitleResId = getTitleRes(); mColor = ApiCompatibilityUtils.getColor( context.getResources(), R.color.default_text_color_link); } @@ -46,9 +45,9 @@ } @Override - protected void onBindView(View view) { - super.onBindView(view); - TextView titleView = (TextView) view.findViewById(android.R.id.title); + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + TextView titleView = (TextView) holder.findViewById(android.R.id.title); titleView.setSingleLine(false); if (mImitateWebLink) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/LegalInformationPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/LegalInformationPreferences.java index 2739980..3def9a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/LegalInformationPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/LegalInformationPreferences.java
@@ -5,18 +5,16 @@ package org.chromium.chrome.browser.preferences; import android.os.Bundle; -import android.preference.PreferenceFragment; +import android.support.v7.preference.PreferenceFragmentCompat; import org.chromium.chrome.R; /** * Fragment to display legal information about Chrome. */ -public class LegalInformationPreferences extends PreferenceFragment { - +public class LegalInformationPreferences extends PreferenceFragmentCompat { @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(Bundle savedInstanceState, String s) { PreferenceUtils.addPreferencesFromResource(this, R.xml.legal_information_preferences); getActivity().setTitle(R.string.legal_information_title); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsTileView.java index ecefd83..b20a7d91 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsTileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsTileView.java
@@ -60,7 +60,7 @@ setOfflineBadgeVisibility(tile.isOfflineAvailable()); } - private void setIconViewLayoutParams(Tile tile) { + protected void setIconViewLayoutParams(Tile tile) { MarginLayoutParams params = (MarginLayoutParams) mIconView.getLayoutParams(); Resources resources = getResources(); if (tile.getType() == TileVisualType.ICON_COLOR
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java index 606acf7..8ae8ea4a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java
@@ -11,6 +11,7 @@ import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.support.annotation.LayoutRes; +import android.support.graphics.drawable.VectorDrawableCompat; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.view.LayoutInflater; import android.view.ViewGroup; @@ -20,11 +21,14 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; +import org.chromium.chrome.browser.explore_sites.ExploreSitesBridge; +import org.chromium.chrome.browser.explore_sites.MostLikelyVariation; import org.chromium.chrome.browser.favicon.IconType; import org.chromium.chrome.browser.favicon.LargeIconBridge; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.suggestions.SuggestionsConfig.TileStyle; +import org.chromium.chrome.browser.suggestions.tile.TopSitesTileView; import org.chromium.chrome.browser.util.ViewUtils; import org.chromium.chrome.browser.widget.RoundedIconGenerator; import org.chromium.components.feature_engagement.EventConstants; @@ -44,6 +48,7 @@ private final Resources mResources; private final ImageFetcher mImageFetcher; private final RoundedIconGenerator mIconGenerator; + private final Resources.Theme mTheme; @TileStyle private final int mStyle; @@ -55,6 +60,9 @@ @LayoutRes private final int mLayout; + @LayoutRes + private final int mTopSitesLayout; + public TileRenderer( Context context, @TileStyle int style, int titleLines, ImageFetcher imageFetcher) { mImageFetcher = imageFetcher; @@ -62,6 +70,7 @@ mTitleLinesCount = titleLines; mResources = context.getResources(); + mTheme = context.getTheme(); mDesiredIconSize = mResources.getDimensionPixelSize(R.dimen.tile_view_icon_size); mIconCornerRadius = mResources.getDimension(R.dimen.tile_view_icon_corner_radius); int minIconSize = mResources.getDimensionPixelSize(R.dimen.tile_view_icon_min_size); @@ -70,6 +79,7 @@ mMinIconSize = Math.min(mDesiredIconSize, minIconSize); mLayout = getLayout(); + mTopSitesLayout = getTopSitesLayout(); int iconColor = ApiCompatibilityUtils.getColor( mResources, R.color.default_favicon_background_color); @@ -127,14 +137,46 @@ @VisibleForTesting SuggestionsTileView buildTileView( Tile tile, ViewGroup parentView, TileGroup.TileSetupDelegate setupDelegate) { - SuggestionsTileView tileView = - (SuggestionsTileView) LayoutInflater.from(parentView.getContext()) - .inflate(mLayout, parentView, false); + SuggestionsTileView tileView; + + if (tile.getSource() == TileSource.EXPLORE) { + tileView = (TopSitesTileView) LayoutInflater.from(parentView.getContext()) + .inflate(mTopSitesLayout, parentView, false); + + int iconVariation = ExploreSitesBridge.getIconVariation(); + if (iconVariation == MostLikelyVariation.ICON_ARROW) { + tile.setIcon(VectorDrawableCompat.create( + mResources, R.drawable.ic_arrow_forward_blue_24dp, mTheme)); + tile.setType(TileVisualType.ICON_REAL); + } else if (iconVariation == MostLikelyVariation.ICON_DOTS) { + tile.setIcon(VectorDrawableCompat.create( + mResources, R.drawable.ic_apps_blue_24dp, mTheme)); + tile.setType(TileVisualType.ICON_REAL); + } else if (iconVariation == MostLikelyVariation.ICON_GROUPED) { + tile.setIcon(VectorDrawableCompat.create( + mResources, R.drawable.ic_apps_blue_24dp, mTheme)); + tile.setType(TileVisualType.ICON_DEFAULT); + + // One task to load actual icon. + LargeIconBridge.LargeIconCallback bridgeCallback = + setupDelegate.createIconLoadCallback(tile); + ExploreSitesBridge.getSummaryImage(Profile.getLastUsedProfile(), mDesiredIconSize, + (Bitmap img) + -> bridgeCallback.onLargeIconAvailable( + img, Color.BLACK, false, IconType.FAVICON)); + } + } else { + tileView = (SuggestionsTileView) LayoutInflater.from(parentView.getContext()) + .inflate(mLayout, parentView, false); + } + tileView.initialize(tile, mTitleLinesCount); // Note: It is important that the callbacks below don't keep a reference to the tile or // modify them as there is no guarantee that the same tile would be used to update the view. - fetchIcon(tile.getData(), setupDelegate.createIconLoadCallback(tile)); + if (tile.getSource() != TileSource.EXPLORE) { + fetchIcon(tile.getData(), setupDelegate.createIconLoadCallback(tile)); + } TileGroup.TileInteractionDelegate delegate = setupDelegate.createInteractionDelegate(tile); if (tile.getSource() == TileSource.HOMEPAGE) { @@ -182,8 +224,11 @@ } public void setTileIconFromBitmap(Tile tile, Bitmap icon) { - RoundedBitmapDrawable roundedIcon = ViewUtils.createRoundedBitmapDrawable( - icon, Math.round(mIconCornerRadius * icon.getWidth() / mDesiredIconSize)); + int radius = Math.round(mIconCornerRadius * icon.getWidth() / mDesiredIconSize); + if (tile.getSource() == TileSource.EXPLORE) { + radius = mDesiredIconSize / 2; + } + RoundedBitmapDrawable roundedIcon = ViewUtils.createRoundedBitmapDrawable(icon, radius); roundedIcon.setAntiAlias(true); roundedIcon.setFilterBitmap(true); @@ -192,6 +237,10 @@ } public void setTileIconFromColor(Tile tile, int fallbackColor, boolean isFallbackColorDefault) { + // Explore should not have generated icons. + if (tile.getSource() == TileSource.EXPLORE) { + return; + } mIconGenerator.setBackgroundColor(fallbackColor); Bitmap icon = mIconGenerator.generateIconForUrl(tile.getUrl()); tile.setIcon(new BitmapDrawable(mResources, icon)); @@ -210,4 +259,16 @@ assert false; return 0; } + + @LayoutRes + private int getTopSitesLayout() { + switch (mStyle) { + case TileStyle.MODERN: + return R.layout.top_sites_tile_view; + case TileStyle.MODERN_CONDENSED: + return R.layout.top_sites_tile_view_condensed; + } + assert false; + return 0; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/OWNERS new file mode 100644 index 0000000..125bc14 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/android/explore_sites/OWNERS \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java new file mode 100644 index 0000000..31b6c51e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java
@@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium 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.suggestions.tile; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; + +import org.chromium.chrome.browser.explore_sites.ExploreSitesBridge; +import org.chromium.chrome.browser.explore_sites.MostLikelyVariation; +import org.chromium.chrome.browser.suggestions.SuggestionsTileView; +import org.chromium.chrome.browser.suggestions.Tile; +import org.chromium.chrome.browser.suggestions.TileVisualType; + +/** + * The view for a top sites tile. Displays the title of the site beneath a large icon. + */ +public class TopSitesTileView extends SuggestionsTileView { + /** + * Constructor for inflating from XML. + */ + public TopSitesTileView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void setIconViewLayoutParams(Tile tile) { + MarginLayoutParams params = (MarginLayoutParams) mIconView.getLayoutParams(); + Resources resources = getResources(); + if (tile.getType() == TileVisualType.ICON_REAL + && ExploreSitesBridge.getIconVariation() == MostLikelyVariation.ICON_GROUPED) { + // Grouped icons have extra large size. + params.width = resources.getDimensionPixelOffset( + org.chromium.chrome.R.dimen.tile_view_icon_size); + params.height = resources.getDimensionPixelSize( + org.chromium.chrome.R.dimen.tile_view_icon_size); + params.topMargin = resources.getDimensionPixelSize( + org.chromium.chrome.R.dimen.tile_view_icon_background_margin_top_modern); + } else { + params.width = resources.getDimensionPixelSize( + org.chromium.chrome.R.dimen.tile_view_icon_size_modern); + params.height = resources.getDimensionPixelSize( + org.chromium.chrome.R.dimen.tile_view_icon_size_modern); + params.topMargin = resources.getDimensionPixelSize( + org.chromium.chrome.R.dimen.tile_view_icon_margin_top_modern); + } + mIconView.setLayoutParams(params); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java index fcc734d0..fa26b8fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsOffsetHelper.java
@@ -103,7 +103,7 @@ mPreviousContentOffsetY = contentOffsetY; mAreOffsetsInitialized = true; - if (FullscreenManager.from(mTab) == null) return; + if (mTab.isHidden()) return; if (SadTab.isShowing(mTab) || mTab.isNativePage()) { showAndroidControls(false); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsState.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsState.java index 6210f6a..ac4062b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsState.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsState.java
@@ -87,7 +87,7 @@ @Override public void onRendererResponsiveStateChanged(Tab tab, boolean isResponsive) { - if (FullscreenManager.from(mTab) == null) return; + if (mTab.isHidden()) return; if (isResponsive) { updateEnabledState(); } else { @@ -198,7 +198,7 @@ @Override public void onNodeAttributeUpdated(boolean editable, boolean password) { - if (FullscreenManager.from(mTab) == null) return; + if (mTab.isHidden()) return; updateEnabledState(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java index 243e5d9..8cf44b6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java
@@ -159,7 +159,7 @@ enableHidingBrowserControls &= !mTab.isShowingErrorPage(); enableHidingBrowserControls &= !webContents.isShowingInterstitialPage(); enableHidingBrowserControls &= !mTab.isRendererUnresponsive(); - enableHidingBrowserControls &= (FullscreenManager.from(mTab) != null); + enableHidingBrowserControls &= !mTab.isHidden(); enableHidingBrowserControls &= DeviceClassManager.enableFullscreen(); enableHidingBrowserControls &= !mIsFullscreenWaitingForLoad; enableHidingBrowserControls &= !TabModalPresenter.isDialogShowing(mTab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelFilter.java index f2066924..3ed6e46 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelFilter.java
@@ -28,6 +28,9 @@ @Override protected void reorder() {} + @Override + protected void resetFilterStateInternal() {} + // TabList implementation. @Override public boolean isIncognito() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java index 16823987..cfacc71 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java
@@ -110,6 +110,25 @@ */ protected abstract void reorder(); + /** + * Concrete class requires to define what to clean up. + */ + protected abstract void resetFilterStateInternal(); + + /** + * Calls {@code resetFilterStateInternal} method to clean up filter internal data, and resets + * the internal data based on the current {@link TabModel}. + */ + protected void resetFilterState() { + resetFilterStateInternal(); + + TabModel tabModel = getTabModel(); + for (int i = 0; i < tabModel.getCount(); i++) { + Tab tab = tabModel.getTabAt(i); + addTab(tab); + } + } + // TODO(crbug.com/948518): This is a band-aid fix for not crashing when undo the last closed // tab, should remove later. /** @@ -161,7 +180,6 @@ @Override public void didMoveTab(Tab tab, int newIndex, int curIndex) { - reorder(); for (TabModelObserver observer : mFilteredObservers) { observer.didMoveTab(tab, newIndex, curIndex); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TaskRecognizer.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TaskRecognizer.java index c6f52d7..9048fca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TaskRecognizer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TaskRecognizer.java
@@ -66,8 +66,8 @@ * @param tab The tab that might be about a product. Must be the current front tab. */ private void tryToShowProduct(Tab tab) { - boolean isCurrentSelectedTab = - tab != null && tab.equals(tab.getActivity().getActivityTab()); + boolean isCurrentSelectedTab = tab != null && tab.getActivity() != null + && tab.equals(tab.getActivity().getActivityTab()); if (mTabInUse != null || !isCurrentSelectedTab) { return; } @@ -131,6 +131,8 @@ */ private void createEphemeralTabFor( Tab activeTab, ResolvedSearchTerm resolvedSearchTerm, Uri searchUrl) { + if (activeTab == null || activeTab.getActivity() == null) return; + EphemeralTabPanel displayPanel = activeTab.getActivity().getEphemeralTabPanel(); if (displayPanel != null) { displayPanel.requestOpenPanel(searchUrl.toString(), resolvedSearchTerm.displayText(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java index bec2314..860b12a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java
@@ -48,6 +48,15 @@ */ public interface Observer { /** + * This method is called after a tab is moved to form a group or moved into an existed + * group. + * @param movedTab The {@link Tab} which has been moved. If a group is merged to a tab or + * another group, this is the last tab of the merged group. + * @param selectedTabIdInGroup The id of the selected {@link Tab} in group. + */ + void didMergeTabToGroup(Tab movedTab, int selectedTabIdInGroup); + + /** * This method is called after a group is moved. * * @param movedTab The tab which has been moved. This is the last tab within the group. @@ -139,6 +148,7 @@ // The number of groups with at least 2 tabs. private int mActualGroupCount; private Tab mAbsentSelectedTab; + private boolean mShouldRecordUma = true; public TabGroupModelFilter(TabModel tabModel) { super(tabModel); @@ -223,6 +233,71 @@ } } + /** + * This method merges the source group that contains the {@code sourceTabId} to the destination + * group that contains the {@code destinationTabId}. This method only operates if two groups are + * in the same {@code TabModel}. + * + * @param sourceTabId The id of the {@link Tab} to get the source group. + * @param destinationTabId The id of a {@link Tab} to get the destination group. + */ + public void mergeTabsToGroup(int sourceTabId, int destinationTabId) { + Tab sourceTab = TabModelUtils.getTabById(getTabModel(), sourceTabId); + Tab destinationTab = TabModelUtils.getTabById(getTabModel(), destinationTabId); + + assert sourceTab != null && destinationTab != null + && sourceTab.isIncognito() + == destinationTab.isIncognito() + : "Attempting to merge groups from different model"; + + int destinationGroupId = destinationTab.getRootId(); + List<Tab> tabsToMerge = getRelatedTabList(sourceTabId); + int sourceTabIndexInTabModel = + TabModelUtils.getTabIndexById(getTabModel(), sourceTab.getId()); + int destinationIndexInTabModel = getTabModelDestinationIndex(destinationTab); + boolean isMovingBackward = sourceTabIndexInTabModel < destinationIndexInTabModel; + + if (!needToUpdateTabModel(tabsToMerge, destinationIndexInTabModel)) { + for (int i = 0; i < tabsToMerge.size(); i++) { + Tab tab = tabsToMerge.get(i); + tab.setRootId(destinationGroupId); + } + resetFilterState(); + + Tab lastMergedTab = tabsToMerge.get(tabsToMerge.size() - 1); + TabGroup group = mGroupIdToGroupMap.get(lastMergedTab.getRootId()); + for (Observer observer : mGroupFilterObserver) { + observer.didMergeTabToGroup( + tabsToMerge.get(tabsToMerge.size() - 1), group.getLastShownTabId()); + } + } else { + for (int i = 0; i < tabsToMerge.size(); i++) { + Tab tab = tabsToMerge.get(i); + tab.setRootId(destinationGroupId); + getTabModel().moveTab(tab.getId(), + isMovingBackward ? destinationIndexInTabModel + : destinationIndexInTabModel++); + } + } + } + + private int getTabModelDestinationIndex(Tab destinationTab) { + List<Integer> destinationGroupedTabIds = + mGroupIdToGroupMap.get(destinationTab.getRootId()).getTabIdList(); + int destinationTabIndex = TabModelUtils.getTabIndexById( + getTabModel(), destinationGroupedTabIds.get(destinationGroupedTabIds.size() - 1)); + + return destinationTabIndex + 1; + } + + private boolean needToUpdateTabModel(List<Tab> tabsToMerge, int destinationIndexInTabModel) { + assert tabsToMerge.size() > 0; + + int firstTabIndexInTabModel = + TabModelUtils.getTabIndexById(getTabModel(), tabsToMerge.get(0).getId()); + return firstTabIndexInTabModel != destinationIndexInTabModel; + } + // TODO(crbug.com/951608): follow up with sessions count histogram for TabGroups. private int updateAndGetSessionsCount(int groupId) { ThreadUtils.assertOnBackgroundThread(); @@ -276,7 +351,8 @@ if (mGroupIdToGroupMap.containsKey(groupId)) { if (mGroupIdToGroupMap.get(groupId).size() == 1) { mActualGroupCount++; - if (tab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND) { + if (mShouldRecordUma + && tab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND) { RecordUserAction.record("TabGroup.Created.OpenInNewTab"); } } @@ -377,24 +453,77 @@ } @Override + protected void resetFilterStateInternal() { + mGroupIdToGroupIndexMap.clear(); + mGroupIdToGroupMap.clear(); + mActualGroupCount = 0; + } + + @Override + protected void resetFilterState() { + mShouldRecordUma = false; + super.resetFilterState(); + + TabModel tabModel = getTabModel(); + selectTab(tabModel.getTabAt(tabModel.index())); + mShouldRecordUma = true; + } + + @Override protected boolean shouldNotifyObserversOnSetIndex() { return mAbsentSelectedTab == null; } @Override public void didMoveTab(Tab tab, int newIndex, int curIndex) { - super.didMoveTab(tab, newIndex, curIndex); + // Need to cache the flag before resetting the internal data map. + boolean isMergeTabToGroup = isMergeTabToGroup(tab); + int groupIdBeforeMove = getGroupIdBeforeMove(tab, isMergeTabToGroup); + assert groupIdBeforeMove != TabGroup.INVALID_GROUP_ID; + TabGroup groupBeforeMove = mGroupIdToGroupMap.get(groupIdBeforeMove); - if (isMoveWithinGroup(tab, curIndex, newIndex)) { + if (isMergeTabToGroup) { + resetFilterState(); + if (groupBeforeMove != null && groupBeforeMove.size() != 1) return; + + TabGroup group = mGroupIdToGroupMap.get(tab.getRootId()); for (Observer observer : mGroupFilterObserver) { - observer.didMoveWithinGroup(tab, curIndex, newIndex); + observer.didMergeTabToGroup(tab, group.getLastShownTabId()); } } else { - if (!hasFinishedMovingGroup(tab, newIndex)) return; - for (Observer observer : mGroupFilterObserver) { - observer.didMoveTabGroup(tab, curIndex, newIndex); + reorder(); + + if (isMoveWithinGroup(tab, curIndex, newIndex)) { + for (Observer observer : mGroupFilterObserver) { + observer.didMoveWithinGroup(tab, curIndex, newIndex); + } + } else { + if (!hasFinishedMovingGroup(tab, newIndex)) return; + for (Observer observer : mGroupFilterObserver) { + observer.didMoveTabGroup(tab, curIndex, newIndex); + } } } + + super.didMoveTab(tab, newIndex, curIndex); + } + + private boolean isMergeTabToGroup(Tab tab) { + TabGroup tabGroup = mGroupIdToGroupMap.get(tab.getRootId()); + return !tabGroup.contains(tab.getId()); + } + + private int getGroupIdBeforeMove(Tab tabToMove, boolean isMoveToDifferentGroup) { + if (!isMoveToDifferentGroup) return tabToMove.getRootId(); + + Set<Integer> groupIdSet = mGroupIdToGroupMap.keySet(); + for (Integer groupIdKey : groupIdSet) { + if (mGroupIdToGroupMap.get(groupIdKey).contains(tabToMove.getId())) { + return groupIdKey; + } + } + + return TabGroup.INVALID_GROUP_ID; } private boolean isMoveWithinGroup( @@ -409,8 +538,13 @@ private boolean hasFinishedMovingGroup(Tab movedTab, int newIndexInTabModel) { TabGroup tabGroup = mGroupIdToGroupMap.get(movedTab.getRootId()); - int offsetIndex = Math.abs(newIndexInTabModel - tabGroup.size() + 1); - return tabGroup.contains(getTabModel().getTabAt(offsetIndex).getId()); + int offsetIndex = newIndexInTabModel - tabGroup.size() + 1; + if (offsetIndex < 0) return false; + + for (int i = newIndexInTabModel; i >= offsetIndex; i--) { + if (getTabModel().getTabAt(i).getRootId() != movedTab.getRootId()) return false; + } + return true; } // TabList implementation.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayout.java index 7d0f412a..b2bf348 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayout.java
@@ -172,7 +172,8 @@ @Override public void onOverviewModeFinishedShowing() { doneShowing(); - mTabContentManager.cacheTabThumbnail(mTabModelSelector.getCurrentTab()); + Tab currentTab = mTabModelSelector.getCurrentTab(); + if (currentTab != null) mTabContentManager.cacheTabThumbnail(currentTab); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 0fab6ff..b6b401d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -2415,7 +2415,7 @@ @SmallTest @Feature({"ContextualSearch"}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/965706") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, message = "crbug.com/965706") public void testTapMultipleSwipeOnlyLoadsContentOnce() throws InterruptedException, TimeoutException { // Simulate a tap and make sure Content is not visible. @@ -2452,7 +2452,7 @@ @SmallTest @Feature({"ContextualSearch"}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) - @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/965706") + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.M, message = "crbug.com/965706") public void testLongPressMultipleSwipeOnlyLoadsContentOnce() throws InterruptedException, TimeoutException { // Simulate a long press and make sure no Content is created.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayoutPerfTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayoutPerfTest.java index f565907..e8a6f49 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayoutPerfTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/GridTabSwitcherLayoutPerfTest.java
@@ -120,6 +120,14 @@ @Test @MediumTest + @CommandLineFlags.Add({"force-fieldtrial-params=Study.Group:downsampling-scale/1"}) + public void testTabToGridFromLiveTabWith10TabsNoDownsample() throws InterruptedException { + prepareTabs(10, NTP_URL); + reportTabToGridPerf(mUrl, "Tab-to-Grid from live tab with 10 tabs (no downsample)"); + } + + @Test + @MediumTest public void testTabToGridFromLiveTabWith10TabsWithoutThumbnail() throws InterruptedException { // Note that most of the tabs won't have thumbnails. prepareTabs(10, null);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java new file mode 100644 index 0000000..631f40e --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilterUnitTest.java
@@ -0,0 +1,344 @@ +// Copyright 2019 The Chromium 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.tasks.tabgroup; + +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.robolectric.annotation.Config; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelUtils; +import org.chromium.testing.local.LocalRobolectricTestRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Tests for {@link TabGroupModelFilter}. + */ +@RunWith(LocalRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class TabGroupModelFilterUnitTest { + private static final int TAB1_ID = 456; + private static final int TAB2_ID = 789; + private static final int TAB3_ID = 123; + private static final int TAB4_ID = 147; + private static final int TAB5_ID = 258; + private static final int TAB6_ID = 369; + private static final int TAB1_ROOT_ID = TAB1_ID; + private static final int TAB2_ROOT_ID = TAB2_ID; + private static final int TAB3_ROOT_ID = TAB2_ID; + private static final int TAB4_ROOT_ID = TAB4_ID; + private static final int TAB5_ROOT_ID = TAB5_ID; + private static final int TAB6_ROOT_ID = TAB5_ID; + private static final int POSITION1 = 0; + private static final int POSITION2 = 1; + private static final int POSITION3 = 2; + private static final int POSITION4 = 3; + private static final int POSITION5 = 4; + private static final int POSITION6 = 5; + + @Mock + TabModel mTabModel; + + @Mock + TabGroupModelFilter.Observer mTabGroupModelFilterObserver; + + @Captor + ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; + + private Tab mTab1; + private Tab mTab2; + private Tab mTab3; + private Tab mTab4; + private Tab mTab5; + private Tab mTab6; + private List<Tab> mTabs = new ArrayList<>(); + + private TabGroupModelFilter mTabGroupModelFilter; + + private Tab prepareTab(int tabId, int rootId) { + Tab tab = mock(Tab.class); + + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + int newRootId = invocation.getArgument(0); + doReturn(newRootId).when(tab).getRootId(); + return null; + } + }).when(tab).setRootId(anyInt()); + + doReturn(tabId).when(tab).getId(); + tab.setRootId(rootId); + + return tab; + } + + private void setRootId(Tab tab, int rootId) { + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + int newRootId = invocation.getArgument(0); + doReturn(newRootId).when(tab).getRootId(); + return null; + } + }).when(tab).setRootId(rootId); + } + + private void setUpTab() { + mTab1 = prepareTab(TAB1_ID, TAB1_ROOT_ID); + mTab2 = prepareTab(TAB2_ID, TAB2_ROOT_ID); + mTab3 = prepareTab(TAB3_ID, TAB3_ROOT_ID); + mTab4 = prepareTab(TAB4_ID, TAB4_ROOT_ID); + mTab5 = prepareTab(TAB5_ID, TAB5_ROOT_ID); + mTab6 = prepareTab(TAB6_ID, TAB6_ROOT_ID); + } + + private void setUpTabModel() { + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + Tab tab = invocation.getArgument(0); + mTabs.add(tab); + return null; + } + }).when(mTabModel).addTab(any(Tab.class), anyInt(), anyInt()); + + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + int movedTabId = invocation.getArgument(0); + int newIndex = invocation.getArgument(1); + + int oldIndex = TabModelUtils.getTabIndexById(mTabModel, movedTabId); + Tab tab = TabModelUtils.getTabById(mTabModel, movedTabId); + + mTabs.remove(tab); + if (oldIndex < newIndex) --newIndex; + mTabs.add(newIndex, tab); + mTabModelObserverCaptor.getValue().didMoveTab(tab, newIndex, oldIndex); + return null; + } + }).when(mTabModel).moveTab(anyInt(), anyInt()); + + doAnswer(new Answer() { + @Override + public Tab answer(InvocationOnMock invocation) throws Throwable { + int index = invocation.getArgument(0); + return mTabs.get(index); + } + }).when(mTabModel).getTabAt(anyInt()); + + doAnswer(new Answer() { + @Override + public Integer answer(InvocationOnMock invocation) throws Throwable { + Tab tab = invocation.getArgument(0); + return mTabs.indexOf(tab); + } + }).when(mTabModel).indexOf(any(Tab.class)); + + doAnswer(new Answer() { + @Override + public Integer answer(InvocationOnMock invocation) throws Throwable { + return mTabs.size(); + } + }).when(mTabModel).getCount(); + + doReturn(0).when(mTabModel).index(); + } + + @Before + public void setUp() { + RecordUserAction.setDisabledForTests(true); + RecordHistogram.setDisabledForTests(true); + + MockitoAnnotations.initMocks(this); + + setUpTab(); + setUpTabModel(); + + doNothing().when(mTabModel).addObserver(mTabModelObserverCaptor.capture()); + + mTabGroupModelFilter = new TabGroupModelFilter(mTabModel); + mTabGroupModelFilter.addTabGroupObserver(mTabGroupModelFilterObserver); + + mTabModel.addTab(mTab1, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab1, TabLaunchType.FROM_CHROME_UI); + + mTabModel.addTab(mTab2, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab2, TabLaunchType.FROM_CHROME_UI); + + mTabModel.addTab(mTab3, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab3, TabLaunchType.FROM_CHROME_UI); + + mTabModel.addTab(mTab4, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab4, TabLaunchType.FROM_CHROME_UI); + + mTabModel.addTab(mTab5, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab5, TabLaunchType.FROM_CHROME_UI); + + mTabModel.addTab(mTab6, -1, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab(mTab6, TabLaunchType.FROM_CHROME_UI); + } + + @After + public void tearDown() { + RecordUserAction.setDisabledForTests(false); + RecordHistogram.setDisabledForTests(false); + } + + @Test + public void mergeTabToGroup_No_Update_TabModel() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab2, mTab3, mTab4)); + + mTabGroupModelFilter.mergeTabsToGroup(mTab4.getId(), mTab2.getId()); + + verify(mTabModel, never()).moveTab(anyInt(), anyInt()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab4.getId()).toArray(), + expectedGroup.toArray()); + } + + @Test + public void mergeTabToGroup_Update_TabModel() { + mTabGroupModelFilter.mergeTabsToGroup(mTab5.getId(), mTab2.getId()); + verify(mTabModel).moveTab(mTab5.getId(), POSITION3 + 1); + } + + @Test + public void mergeOneTabToTab_Forward() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab1, mTab4)); + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab4, mTab2, mTab3, mTab5, mTab6)); + int startIndex = POSITION1; + + mTabGroupModelFilter.mergeTabsToGroup(mTab4.getId(), mTab1.getId()); + + verify(mTabModel).moveTab(mTab4.getId(), ++startIndex); + verify(mTabGroupModelFilterObserver).didMergeTabToGroup(mTab4, mTab1.getId()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab4.getId()).toArray(), + expectedGroup.toArray()); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void mergeGroupToTab_Forward() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab1, mTab5, mTab6)); + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab5, mTab6, mTab2, mTab3, mTab4)); + int startIndex = POSITION1; + + mTabGroupModelFilter.mergeTabsToGroup(mTab5.getId(), mTab1.getId()); + + verify(mTabModel).moveTab(mTab5.getId(), ++startIndex); + verify(mTabModel).moveTab(mTab6.getId(), ++startIndex); + verify(mTabGroupModelFilterObserver).didMergeTabToGroup(mTab6, mTab1.getId()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab5.getId()).toArray(), + expectedGroup.toArray()); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void mergeGroupToGroup_Forward() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab2, mTab3, mTab5, mTab6)); + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3, mTab5, mTab6, mTab4)); + int startIndex = POSITION3; + + mTabGroupModelFilter.mergeTabsToGroup(mTab5.getId(), mTab2.getId()); + + verify(mTabModel).moveTab(mTab5.getId(), ++startIndex); + verify(mTabModel).moveTab(mTab6.getId(), ++startIndex); + verify(mTabGroupModelFilterObserver).didMergeTabToGroup(mTab6, mTab2.getId()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab5.getId()).toArray(), + expectedGroup.toArray()); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void mergeOneTabToTab_Backward() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab4, mTab1)); + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab2, mTab3, mTab4, mTab1, mTab5, mTab6)); + int startIndex = POSITION4; + + mTabGroupModelFilter.mergeTabsToGroup(mTab1.getId(), mTab4.getId()); + + verify(mTabModel).moveTab(mTab1.getId(), startIndex + 1); + verify(mTabGroupModelFilterObserver).didMergeTabToGroup(mTab1, mTab4.getId()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab1.getId()).toArray(), + expectedGroup.toArray()); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void mergeGroupToTab_Backward() { + List<Tab> expectedGroup = new ArrayList<>(Arrays.asList(mTab4, mTab2, mTab3)); + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab4, mTab2, mTab3, mTab5, mTab6)); + int startIndex = POSITION4; + + mTabGroupModelFilter.mergeTabsToGroup(mTab2.getId(), mTab4.getId()); + + verify(mTabModel).moveTab(mTab2.getId(), startIndex + 1); + verify(mTabModel).moveTab(mTab3.getId(), startIndex + 1); + verify(mTabGroupModelFilterObserver).didMergeTabToGroup(mTab3, mTab4.getId()); + assertArrayEquals(mTabGroupModelFilter.getRelatedTabList(mTab2.getId()).toArray(), + expectedGroup.toArray()); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void moveGroup_Backward() { + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab4, mTab2, mTab3, mTab5, mTab6)); + int startIndex = POSITION4; + + mTabGroupModelFilter.moveRelatedTabs(mTab2.getId(), startIndex + 1); + + verify(mTabModel).moveTab(mTab2.getId(), startIndex + 1); + verify(mTabModel).moveTab(mTab3.getId(), startIndex + 1); + verify(mTabGroupModelFilterObserver).didMoveTabGroup(mTab3, POSITION3 - 1, startIndex); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } + + @Test + public void moveGroup_Forward() { + List<Tab> expectedTabModel = + new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3, mTab5, mTab6, mTab4)); + int startIndex = POSITION3; + + mTabGroupModelFilter.moveRelatedTabs(mTab5.getId(), startIndex + 1); + + verify(mTabModel).moveTab(mTab5.getId(), startIndex + 1); + verify(mTabModel).moveTab(mTab6.getId(), startIndex + 2); + verify(mTabGroupModelFilterObserver).didMoveTabGroup(mTab6, POSITION6, startIndex + 2); + assertArrayEquals(mTabs.toArray(), expectedTabModel.toArray()); + } +}
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index a871bf2a..b8f6bc1 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-76.0.3809.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-77.0.3812.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabMediator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabMediator.java index 1cb7c16..c079824 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabMediator.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabMediator.java
@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.history.BrowsingHistoryBridge; import org.chromium.chrome.browser.history.HistoryItem; import org.chromium.chrome.browser.history.HistoryProvider; +import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.native_page.NativePageHost; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.EmptyTabObserver; @@ -137,12 +138,12 @@ boolean willReturnIcon = mIconBridge.getLargeIconForUrl(item.getUrl(), mContext.getResources().getDimensionPixelSize(R.dimen.open_last_tab_icon_size), (icon, fallbackColor, isFallbackColorDefault, iconType) -> { - setAndShowButton(item.getUrl(), icon, fallbackColor); + setAndShowButton(item.getUrl(), icon, fallbackColor, title); }); // False if icon bridge won't call us back. if (!willReturnIcon) { - setAndShowButton(item.getUrl(), null, R.color.default_icon_color); + setAndShowButton(item.getUrl(), null, R.color.default_icon_color, title); } mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_LOAD_SUCCESS, true); } @@ -153,7 +154,7 @@ @Override public void hasOtherFormsOfBrowsingData(boolean hasOtherForms) {} - private void setAndShowButton(String url, Bitmap icon, int fallbackColor) { + private void setAndShowButton(String url, Bitmap icon, int fallbackColor, String title) { mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_ON_CLICK_LISTENER, view -> { mNativePageHost.loadUrl(new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK), /* Explore page is never off the record. */ false); @@ -164,5 +165,36 @@ icon = mIconGenerator.generateIconForUrl(url); } mModel.set(OpenLastTabProperties.OPEN_LAST_TAB_FAVICON, icon); + + final Bitmap shortcutIcon = icon; + TouchlessContextMenuManager.Delegate delegate = + new TouchlessContextMenuManager.EmptyDelegate() { + @Override + public boolean isItemSupported( + @ContextMenuManager.ContextMenuItemId int menuItemId) { + return menuItemId == ContextMenuManager.ContextMenuItemId.ADD_TO_MY_APPS; + } + + @Override + public String getUrl() { + return url; + } + + @Override + public String getContextMenuTitle() { + return title; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public Bitmap getIconBitmap() { + return shortcutIcon; + } + }; + mModel.set(OpenLastTabProperties.CONTEXT_MENU_DELEGATE, delegate); } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabProperties.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabProperties.java index 6c2ee7e..3cde4fe 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabProperties.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabProperties.java
@@ -8,6 +8,7 @@ import android.view.View; import org.chromium.base.Callback; +import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -41,9 +42,13 @@ .ReadableObjectPropertyKey<Callback<View>> ASYNC_FOCUS_DELEGATE = new PropertyModel.ReadableObjectPropertyKey<>(); + public static final PropertyModel + .WritableObjectPropertyKey<ContextMenuManager.Delegate> CONTEXT_MENU_DELEGATE = + new PropertyModel.WritableObjectPropertyKey<>(); + // Property keys for the open last tab button. public static final PropertyKey[] ALL_KEYS = {OPEN_LAST_TAB_ON_CLICK_LISTENER, OPEN_LAST_TAB_FAVICON, OPEN_LAST_TAB_TITLE, OPEN_LAST_TAB_TIMESTAMP, OPEN_LAST_TAB_LOAD_SUCCESS, OPEN_LAST_TAB_FIRST_LAUNCH, ON_FOCUS_CALLBACK, - SHOULD_FOCUS_VIEW, ASYNC_FOCUS_DELEGATE}; + SHOULD_FOCUS_VIEW, ASYNC_FOCUS_DELEGATE, CONTEXT_MENU_DELEGATE}; }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabView.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabView.java index e50e07d7..0a404821 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabView.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabView.java
@@ -16,6 +16,7 @@ import android.widget.TextView; import org.chromium.base.Callback; +import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.touchless.R; /** @@ -102,4 +103,8 @@ void setAsyncFocusDelegate(Callback<View> asyncFocusDelegate) { mAsyncFocusDelegate = asyncFocusDelegate; } + + void setContextMenuDelegate(ContextMenuManager.Delegate delegate) { + ContextMenuManager.registerViewForTouchlessContextMenu(mLastTabView, delegate); + } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabViewBinder.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabViewBinder.java index 76de5934..a448710 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabViewBinder.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/OpenLastTabViewBinder.java
@@ -32,6 +32,8 @@ model.set(OpenLastTabProperties.SHOULD_FOCUS_VIEW, false); } else if (propertyKey == OpenLastTabProperties.ASYNC_FOCUS_DELEGATE) { view.setAsyncFocusDelegate(model.get(OpenLastTabProperties.ASYNC_FOCUS_DELEGATE)); + } else if (propertyKey == OpenLastTabProperties.CONTEXT_MENU_DELEGATE) { + view.setContextMenuDelegate(model.get(OpenLastTabProperties.CONTEXT_MENU_DELEGATE)); } else { assert false : "Unhandled property detected."; }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java index 3230c33..cbbe04a 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java
@@ -43,6 +43,22 @@ Bitmap getIconBitmap(); } + /** + * Empty implementation of Delegate to allow derived classes to only implement methods they + * need. + */ + public static class EmptyDelegate extends ContextMenuManager.EmptyDelegate implements Delegate { + @Override + public String getTitle() { + return null; + } + + @Override + public Bitmap getIconBitmap() { + return null; + } + } + private final Activity mActivity; private final ModalDialogManager mDialogManager; private PropertyModel mTouchlessMenuModel;
diff --git a/chrome/app_shim/app_shim_controller.mm b/chrome/app_shim/app_shim_controller.mm index 14b4d209..5d11a28 100644 --- a/chrome/app_shim/app_shim_controller.mm +++ b/chrome/app_shim/app_shim_controller.mm
@@ -307,8 +307,8 @@ remote_cocoa::mojom::ApplicationAssociatedRequest request) { remote_cocoa::ApplicationBridge::Get()->BindRequest(std::move(request)); remote_cocoa::ApplicationBridge::Get()->SetContentNSViewCreateCallbacks( - base::BindRepeating(content::CreateRenderWidgetHostNSView), - base::BindRepeating(content::CreateWebContentsNSView)); + base::BindRepeating(remote_cocoa::CreateRenderWidgetHostNSView), + base::BindRepeating(remote_cocoa::CreateWebContentsNSView)); } void AppShimController::CreateCommandDispatcherForWidget(uint64_t widget_id) {
diff --git a/chrome/browser/android/explore_sites/explore_sites_bridge.cc b/chrome/browser/android/explore_sites/explore_sites_bridge.cc index 4ddaf1a..6131b04f 100644 --- a/chrome/browser/android/explore_sites/explore_sites_bridge.cc +++ b/chrome/browser/android/explore_sites/explore_sites_bridge.cc
@@ -115,6 +115,12 @@ } // static +jint JNI_ExploreSitesBridge_GetIconVariation(JNIEnv* env) { + return static_cast<jint>( + chrome::android::explore_sites::GetMostLikelyVariation()); +} + +// static void JNI_ExploreSitesBridge_GetIcon( JNIEnv* env, const JavaParamRef<jobject>& j_profile,
diff --git a/chrome/browser/android/explore_sites/explore_sites_feature.h b/chrome/browser/android/explore_sites/explore_sites_feature.h index 03e459f..48126d3 100644 --- a/chrome/browser/android/explore_sites/explore_sites_feature.h +++ b/chrome/browser/android/explore_sites/explore_sites_feature.h
@@ -32,6 +32,7 @@ }; // A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.explore_sites enum class MostLikelyVariation { NONE, ICON_ARROW, ICON_DOTS, ICON_GROUPED }; ExploreSitesVariation GetExploreSitesVariation();
diff --git a/chrome/browser/bad_message.h b/chrome/browser/bad_message.h index ae0b395..96bed3f8 100644 --- a/chrome/browser/bad_message.h +++ b/chrome/browser/bad_message.h
@@ -22,7 +22,8 @@ // values in histograms. enum BadMessageReason { WRLHH_LOGGING_STOPPED_BAD_STATE = 0, - PPH_EXTRA_PREVIEW_MESSAGE, + PPH_EXTRA_PREVIEW_MESSAGE = 1, + PMF_INVALID_INITIATOR_ORIGIN = 2, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc index c20e0df..570d735 100644 --- a/chrome/browser/chrome_content_browser_client_browsertest.cc +++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -676,4 +676,37 @@ INSTANTIATE_TEST_SUITE_P(All, PrefersColorSchemeTest, testing::Bool()); +#if defined(OS_CHROMEOS) +class ProtocolHandlerTest : public InProcessBrowserTest { + public: + ProtocolHandlerTest() = default; + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->Start()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerTest); +}; + +// Tests that if a protocol handler is registered for a scheme, an external +// program (another Chrome tab in this case) is not launched to handle the +// navigation. +IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, ExternalProgramNotLaunched) { + ui_test_utils::NavigateToURL(browser(), GURL("mailto:bob@example.com")); + + // If an external program (Chrome) was launched, it will result in a second + // tab being opened. + EXPECT_EQ(1, browser()->tab_strip_model()->count()); + + // Make sure the protocol handler redirected the navigation. + base::string16 expected_title = base::ASCIIToUTF16("mail.google.com"); + content::TitleWatcher title_watcher( + browser()->tab_strip_model()->GetActiveWebContents(), expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); +} +#endif + } // namespace content
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc index 65e0ae2..0268f68 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.cc
@@ -28,7 +28,7 @@ #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
diff --git a/chrome/browser/notifications/scheduler/impression_history_tracker.cc b/chrome/browser/notifications/scheduler/impression_history_tracker.cc index 6defe73c..def4dc4 100644 --- a/chrome/browser/notifications/scheduler/impression_history_tracker.cc +++ b/chrome/browser/notifications/scheduler/impression_history_tracker.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/numerics/ranges.h" namespace notifications { @@ -17,17 +18,35 @@ return lhs.create_time < rhs.create_time; } +std::string ToDatabaseKey(SchedulerClientType type) { + switch (type) { + case SchedulerClientType::kTest1: + return "Test1"; + case SchedulerClientType::kTest2: + return "Test2"; + case SchedulerClientType::kTest3: + return "Test3"; + case SchedulerClientType::kUnknown: + NOTREACHED(); + return std::string(); + } +} + ImpressionHistoryTrackerImpl::ImpressionHistoryTrackerImpl( const SchedulerConfig& config, std::unique_ptr<CollectionStore<ClientState>> store) : store_(std::move(store)), config_(config), initialized_(false), + delegate_(nullptr), weak_ptr_factory_(this) {} ImpressionHistoryTrackerImpl::~ImpressionHistoryTrackerImpl() = default; -void ImpressionHistoryTrackerImpl::Init(InitCallback callback) { +void ImpressionHistoryTrackerImpl::Init(Delegate* delegate, + InitCallback callback) { + DCHECK(!delegate_ && delegate); + delegate_ = delegate; store_->InitAndLoad( base::BindOnce(&ImpressionHistoryTrackerImpl::OnStoreInitialized, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); @@ -36,11 +55,32 @@ void ImpressionHistoryTrackerImpl::AnalyzeImpressionHistory() { for (auto& client_state : client_states_) AnalyzeImpressionHistory(client_state.second.get()); + if (MaybeUpdateAllDb()) + NotifyImpressionUpdate(); } -const ImpressionHistoryTracker::ClientStates& -ImpressionHistoryTrackerImpl::GetClientStates() const { - return client_states_; +void ImpressionHistoryTrackerImpl::GetClientStates( + std::map<SchedulerClientType, const ClientState*>* client_states) const { + DCHECK(client_states); + client_states->clear(); + for (const auto& pair : client_states_) { + client_states->emplace(pair.first, pair.second.get()); + } +} + +void ImpressionHistoryTrackerImpl::OnClick(const std::string& notification_id) { + OnClickInternal(notification_id, true /*update_db*/); +} + +void ImpressionHistoryTrackerImpl::OnActionClick( + const std::string& notification_id, + ActionButtonType button_type) { + OnButtonClickInternal(notification_id, button_type, true /*update_db*/); +} + +void ImpressionHistoryTrackerImpl::OnDismiss( + const std::string& notification_id) { + OnDismissInternal(notification_id, true /*update_db*/); } void ImpressionHistoryTrackerImpl::OnStoreInitialized( @@ -55,11 +95,16 @@ initialized_ = true; // Load the data to memory, and sort the impression list. + // TODO(xingliu): Persist ClientState for new registered client and remove + // deprecated client. https://crbug.com/968606. for (auto it = entries.begin(); it != entries.end(); ++it) { auto& entry = (*it); auto type = entry->type; std::sort(entry->impressions.begin(), entry->impressions.end(), &CreateTimeCompare); + for (auto& impression : entry->impressions) { + impression_map_.emplace(impression.guid, &impression); + } client_states_.emplace(type, std::move(*it)); } @@ -78,33 +123,36 @@ // Prune out expired impression. if (now - impression->create_time > config_.impression_expiration) { + impression_map_.erase(impression->guid); client_state->impressions.erase(it++); + SetNeedsUpdate(client_state->type, true); continue; } else { ++it; } - // TODO(xingliu): Use a delegate to get ImpressionResult from notification - // scheduler API consumer. + // TODO(xingliu): Use scheduling params to determine ImpressionResult. + // https://crbug.com/968880 switch (impression->feedback) { - case UserFeedback::kNotHelpful: - // One unhelpful clicks results in suppression. - ApplyNegativeImpression(client_state, impression); - break; case UserFeedback::kDismiss: dismisses.emplace_back(impression); - PruneImpression(&dismisses, - impression->create_time - config_.dismiss_duration); + PruneImpressionByCreateTime( + &dismisses, impression->create_time - config_.dismiss_duration); // Three consecutive dismisses will result in suppression. ApplyNegativeImpressions(client_state, &dismisses, config_.dismiss_count); break; case UserFeedback::kClick: + OnClickInternal(impression->guid, false /*update_db*/); + break; case UserFeedback::kHelpful: - // Any body click or helpful button click will increase maximum - // notification deliver. - ApplyPositiveImpression(client_state, impression); + OnButtonClickInternal(impression->guid, ActionButtonType::kHelpful, + false /*update_db*/); + break; + case UserFeedback::kNotHelpful: + OnButtonClickInternal(impression->guid, ActionButtonType::kUnhelpful, + false /*update_db*/); break; case UserFeedback::kIgnore: break; @@ -117,12 +165,12 @@ } } - // Perform suppression recovery. - SuppressionRecovery(client_state); + // Check suppression expiration. + CheckSuppressionExpiration(client_state); } // static -void ImpressionHistoryTrackerImpl::PruneImpression( +void ImpressionHistoryTrackerImpl::PruneImpressionByCreateTime( std::deque<Impression*>* impressions, const base::Time& start_time) { DCHECK(impressions); @@ -143,9 +191,18 @@ if (impression->integrated) return; + SetNeedsUpdate(client_state->type, true); impression->integrated = true; impression->impression = ImpressionResult::kPositive; + // A positive impression directly releases the suppression. + if (client_state->suppression_info.has_value()) { + client_state->current_max_daily_show = + client_state->suppression_info->recover_goal; + client_state->suppression_info.reset(); + return; + } + // Increase |current_max_daily_show| by 1. client_state->current_max_daily_show = base::ClampToRange(++client_state->current_max_daily_show, 0, @@ -180,6 +237,7 @@ if (impression->integrated) return; + SetNeedsUpdate(client_state->type, true); impression->integrated = true; impression->impression = ImpressionResult::kNegative; @@ -191,8 +249,7 @@ client_state->current_max_daily_show = 0; } -// Recovers from suppression caused by negative impressions. -void ImpressionHistoryTrackerImpl::SuppressionRecovery( +void ImpressionHistoryTrackerImpl::CheckSuppressionExpiration( ClientState* client_state) { // No suppression to recover from. if (!client_state->suppression_info.has_value()) @@ -211,6 +268,125 @@ // Clear suppression if fully recovered. client_state->suppression_info.reset(); + SetNeedsUpdate(client_state->type, true); +} + +bool ImpressionHistoryTrackerImpl::MaybeUpdateDb(SchedulerClientType type) { + auto it = client_states_.find(type); + if (it == client_states_.end()) + return false; + + bool db_updated = false; + if (NeedsUpdate(type)) { + store_->Update(ToDatabaseKey(type), *(it->second.get()), base::DoNothing()); + db_updated = true; + } + SetNeedsUpdate(type, false); + return db_updated; +} + +bool ImpressionHistoryTrackerImpl::MaybeUpdateAllDb() { + bool db_updated = false; + for (const auto& client_state : client_states_) { + auto type = client_state.second->type; + db_updated |= MaybeUpdateDb(type); + } + + return db_updated; +} + +void ImpressionHistoryTrackerImpl::SetNeedsUpdate(SchedulerClientType type, + bool needs_update) { + need_update_db_[type] = needs_update; +} + +bool ImpressionHistoryTrackerImpl::NeedsUpdate(SchedulerClientType type) const { + auto it = need_update_db_.find(type); + return it == need_update_db_.end() ? false : it->second; +} + +void ImpressionHistoryTrackerImpl::NotifyImpressionUpdate() { + if (delegate_) + delegate_->OnImpressionUpdated(); +} + +Impression* ImpressionHistoryTrackerImpl::FindImpressionNeedsUpdate( + const std::string& notification_guid) { + auto it = impression_map_.find(notification_guid); + if (it == impression_map_.end()) + return nullptr; + auto* impression = it->second; + + if (impression->integrated) + return nullptr; + + return it->second; +} + +void ImpressionHistoryTrackerImpl::OnClickInternal( + const std::string& notification_guid, + bool update_db) { + auto* impression = FindImpressionNeedsUpdate(notification_guid); + if (!impression) + return; + + auto it = client_states_.find(impression->type); + if (it == client_states_.end()) + return; + ClientState* client_state = it->second.get(); + ApplyPositiveImpression(client_state, impression); + impression->feedback = UserFeedback::kClick; + + if (update_db && MaybeUpdateDb(client_state->type)) + NotifyImpressionUpdate(); +} + +void ImpressionHistoryTrackerImpl::OnButtonClickInternal( + const std::string& notification_guid, + ActionButtonType button_type, + bool update_db) { + auto* impression = FindImpressionNeedsUpdate(notification_guid); + if (!impression) + return; + auto it = client_states_.find(impression->type); + if (it == client_states_.end()) + return; + + ClientState* client_state = it->second.get(); + switch (button_type) { + case ActionButtonType::kHelpful: + ApplyPositiveImpression(client_state, impression); + impression->feedback = UserFeedback::kHelpful; + break; + case ActionButtonType::kUnhelpful: + ApplyNegativeImpression(client_state, impression); + impression->feedback = UserFeedback::kNotHelpful; + break; + case ActionButtonType::kUnknownAction: + NOTIMPLEMENTED(); + break; + } + + if (update_db && MaybeUpdateDb(client_state->type)) + NotifyImpressionUpdate(); +} + +void ImpressionHistoryTrackerImpl::OnDismissInternal( + const std::string& notification_guid, + bool update_db) { + auto* impression = FindImpressionNeedsUpdate(notification_guid); + if (!impression) + return; + + auto it = client_states_.find(impression->type); + if (it == client_states_.end()) + return; + ClientState* client_state = it->second.get(); + + AnalyzeImpressionHistory(client_state); + + if (update_db && MaybeUpdateDb(client_state->type)) + NotifyImpressionUpdate(); } } // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/impression_history_tracker.h b/chrome/browser/notifications/scheduler/impression_history_tracker.h index 60a1401..e409fce 100644 --- a/chrome/browser/notifications/scheduler/impression_history_tracker.h +++ b/chrome/browser/notifications/scheduler/impression_history_tracker.h
@@ -8,6 +8,7 @@ #include <deque> #include <map> #include <memory> +#include <string> #include "base/callback.h" #include "base/macros.h" @@ -16,26 +17,41 @@ #include "chrome/browser/notifications/scheduler/collection_store.h" #include "chrome/browser/notifications/scheduler/impression_types.h" #include "chrome/browser/notifications/scheduler/scheduler_config.h" +#include "chrome/browser/notifications/scheduler/user_action_handler.h" namespace notifications { // Provides functionalities to update notification impression history and adjust // maximum daily notification shown to the user. -class ImpressionHistoryTracker { +class ImpressionHistoryTracker : public UserActionHandler { public: using ClientStates = std::map<SchedulerClientType, std::unique_ptr<ClientState>>; using InitCallback = base::OnceCallback<void(bool)>; + class Delegate { + public: + Delegate() = default; + virtual ~Delegate() = default; + + // Called when the impression data is updated. + virtual void OnImpressionUpdated() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(Delegate); + }; + // Initializes the impression tracker. - virtual void Init(InitCallback callback) = 0; + virtual void Init(Delegate* delegate, InitCallback callback) = 0; // Analyzes the impression history for all notification clients, and adjusts // the |current_max_daily_show|. virtual void AnalyzeImpressionHistory() = 0; // Queries the client states. - virtual const ClientStates& GetClientStates() const = 0; + virtual void GetClientStates( + std::map<SchedulerClientType, const ClientState*>* client_states) + const = 0; virtual ~ImpressionHistoryTracker() = default; @@ -56,9 +72,14 @@ private: // ImpressionHistoryTracker implementation. - void Init(InitCallback callback) override; + void Init(Delegate* delegate, InitCallback callback) override; void AnalyzeImpressionHistory() override; - const ClientStates& GetClientStates() const override; + void GetClientStates(std::map<SchedulerClientType, const ClientState*>* + client_states) const override; + void OnClick(const std::string& notification_id) override; + void OnActionClick(const std::string& notification_id, + ActionButtonType button_type) override; + void OnDismiss(const std::string& notification_id) override; // Called after |store_| is initialized. void OnStoreInitialized(InitCallback callback, @@ -67,8 +88,8 @@ // Helper method to prune impressions created before |start_time|. Assumes // |impressions| are sorted by creation time. - static void PruneImpression(std::deque<Impression*>* impressions, - const base::Time& start_time); + static void PruneImpressionByCreateTime(std::deque<Impression*>* impressions, + const base::Time& start_time); // Analyzes the impression history for a particular client. void AnalyzeImpressionHistory(ClientState* client_state); @@ -87,13 +108,38 @@ void ApplyNegativeImpression(ClientState* client_state, Impression* impression); - // Recovers from suppression caused by negative impressions. - void SuppressionRecovery(ClientState* client_state); + // Checks if suppression is expired and recover to a certain daily quota. + void CheckSuppressionExpiration(ClientState* client_state); + + // Tries to update the database records for |type|. Returns whether the db is + // actually updated. + bool MaybeUpdateDb(SchedulerClientType type); + bool MaybeUpdateAllDb(); + + // Sets/Gets the flag if impression data for |type| needs update in the + // database. + void SetNeedsUpdate(SchedulerClientType type, bool needs_update); + bool NeedsUpdate(SchedulerClientType type) const; + + // Notifies the delegate about impression data update. + void NotifyImpressionUpdate(); + + // Finds an impression that needs to update based on notification id. + Impression* FindImpressionNeedsUpdate(const std::string& notification_guid); + + void OnClickInternal(const std::string& notification_guid, bool update_db); + void OnButtonClickInternal(const std::string& notification_guid, + ActionButtonType button_type, + bool update_db); + void OnDismissInternal(const std::string& notification_guid, bool update_db); // Impression history and global states for all notification scheduler // clients. ClientStates client_states_; + // Notification guid to Impression map. + std::map<std::string, Impression*> impression_map_; + // The storage that persists data. std::unique_ptr<CollectionStore<ClientState>> store_; @@ -103,6 +149,11 @@ // Whether the impression tracker is successfully initialized. bool initialized_; + // If the database needs an update when any of the impression data is updated. + std::map<SchedulerClientType, bool> need_update_db_; + + Delegate* delegate_; + base::WeakPtrFactory<ImpressionHistoryTrackerImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ImpressionHistoryTrackerImpl); };
diff --git a/chrome/browser/notifications/scheduler/impression_history_tracker_unittest.cc b/chrome/browser/notifications/scheduler/impression_history_tracker_unittest.cc index fa9c124..0f06d1a 100644 --- a/chrome/browser/notifications/scheduler/impression_history_tracker_unittest.cc +++ b/chrome/browser/notifications/scheduler/impression_history_tracker_unittest.cc
@@ -21,6 +21,8 @@ namespace notifications { namespace { +const char kGuid1[] = "guid1"; + struct TestCase { // Input data that will be pushed to the target class. std::vector<test::ImpressionTestData> input; @@ -29,24 +31,25 @@ std::vector<test::ImpressionTestData> expected; }; -// Verifies the |output|. -void VerifyClientStates( - const std::vector<test::ImpressionTestData>& expected_test_data, - const ImpressionHistoryTracker::ClientStates& output) { - ImpressionHistoryTracker::ClientStates expected_client_states; - test::AddImpressionTestData(expected_test_data, &expected_client_states); +Impression CreateImpression(const base::Time& create_time, + const std::string& guid) { + return {create_time, + UserFeedback::kNoFeedback, + ImpressionResult::kInvalid, + false /* integrated */, + SchedulerTaskTime::kMorning, + guid, + SchedulerClientType::kTest1}; +} - DCHECK_EQ(expected_client_states.size(), output.size()); - for (const auto& expected : expected_client_states) { - auto output_it = output.find(expected.first); - DCHECK(output_it != output.end()); - EXPECT_EQ(*expected.second, *output_it->second) - << "Unmatch client states: \n" - << "Expected: \n" - << expected.second->DebugPrint() << " \n" - << "Acutual: \n" - << output_it->second->DebugPrint(); - } +TestCase CreateDefaultTestCase() { + TestCase test_case; + test_case.input = {{SchedulerClientType::kTest1, + 2 /* current_max_daily_show */, + {}, + base::nullopt /* suppression_info */}}; + test_case.expected = test_case.input; + return test_case; } class MockImpressionStore : public CollectionStore<ClientState> { @@ -69,10 +72,20 @@ DISALLOW_COPY_AND_ASSIGN(MockImpressionStore); }; -// TODO(xingliu): Add more test cases following the test doc. -class ImpressionHistoryTrackerTest : public testing::Test { +class MockDelegate : public ImpressionHistoryTracker::Delegate { public: - ImpressionHistoryTrackerTest() : store_(nullptr) {} + MockDelegate() = default; + ~MockDelegate() = default; + MOCK_METHOD0(OnImpressionUpdated, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockDelegate); +}; + +// TODO(xingliu): Add more test cases following the test doc. +class ImpressionHistoryTrackerTest : public ::testing::Test { + public: + ImpressionHistoryTrackerTest() : store_(nullptr), delegate_(nullptr) {} ~ImpressionHistoryTrackerTest() override = default; void SetUp() override { @@ -81,24 +94,14 @@ } protected: - void RunTestCase(TestCase test_case) { - // Prepare test input data. - StoreEntries input_states; - test::AddImpressionTestData(test_case.input, &input_states); - - // Do stuff. - InitTrackerWithData(std::move(input_states)); - impression_trakcer_->AnalyzeImpressionHistory(); - - // Verify output data. - VerifyClientStates(test_case.expected, - impression_trakcer_->GetClientStates()); - } - // Creates the tracker and push in data. - void InitTrackerWithData(StoreEntries entries) { + void InitTrackerWithData(const TestCase& test_case) { + StoreEntries entries; + test::AddImpressionTestData(test_case.input, &entries); + auto store = std::make_unique<MockImpressionStore>(); store_ = store.get(); + delegate_ = std::make_unique<MockDelegate>(); impression_trakcer_ = std::make_unique<ImpressionHistoryTrackerImpl>( config_, std::move(store)); @@ -109,22 +112,48 @@ std::move(cb).Run(true, std::move(entries)); })); base::RunLoop loop; - impression_trakcer_->Init(base::BindOnce( - [](base::RepeatingClosure closure, bool success) { - EXPECT_TRUE(success); - std::move(closure).Run(); - }, - loop.QuitClosure())); + impression_trakcer_->Init( + delegate_.get(), base::BindOnce( + [](base::RepeatingClosure closure, bool success) { + EXPECT_TRUE(success); + std::move(closure).Run(); + }, + loop.QuitClosure())); loop.Run(); } + // Verifies the |expected_test_data| matches the internal states. + void VerifyClientStates(const TestCase& test_case) { + std::map<SchedulerClientType, const ClientState*> client_states; + impression_trakcer_->GetClientStates(&client_states); + + ImpressionHistoryTracker::ClientStates expected_client_states; + test::AddImpressionTestData(test_case.expected, &expected_client_states); + + DCHECK_EQ(expected_client_states.size(), client_states.size()); + for (const auto& expected : expected_client_states) { + auto output_it = client_states.find(expected.first); + DCHECK(output_it != client_states.end()); + EXPECT_EQ(*expected.second, *output_it->second) + << "Unmatch client states: \n" + << "Expected: \n" + << expected.second->DebugPrint() << " \n" + << "Acutual: \n" + << output_it->second->DebugPrint(); + } + } + const SchedulerConfig& config() const { return config_; } + MockImpressionStore* store() { return store_; } + MockDelegate* delegate() { return delegate_.get(); } + ImpressionHistoryTracker* tracker() { return impression_trakcer_.get(); } private: base::test::ScopedTaskEnvironment scoped_task_environment_; SchedulerConfig config_; std::unique_ptr<ImpressionHistoryTracker> impression_trakcer_; MockImpressionStore* store_; + std::unique_ptr<MockDelegate> delegate_; DISALLOW_COPY_AND_ASSIGN(ImpressionHistoryTrackerTest); }; @@ -136,10 +165,17 @@ config().impression_expiration; auto not_expired_time = base::Time::Now() + base::TimeDelta::FromDays(1) - config().impression_expiration; - Impression expired{expired_create_time, UserFeedback::kNoFeedback, - ImpressionResult::kInvalid, false /* integrated */}; - Impression not_expired{not_expired_time, UserFeedback::kNoFeedback, - ImpressionResult::kInvalid, false /* integrated */}; + Impression expired{expired_create_time, UserFeedback::kNoFeedback, + ImpressionResult::kInvalid, false /* integrated */, + SchedulerTaskTime::kMorning, "guid1", + SchedulerClientType::kTest1}; + Impression not_expired{not_expired_time, + UserFeedback::kNoFeedback, + ImpressionResult::kInvalid, + false /* integrated */, + SchedulerTaskTime::kMorning, + "guid2", + SchedulerClientType::kTest1}; // The impressions in the input should be sorted by creation time when gets // loaded to memory. @@ -156,30 +192,83 @@ {not_expired}, base::nullopt /* suppression_info */}}; - RunTestCase(std::move(test_case)); + InitTrackerWithData(test_case); + EXPECT_CALL(*store(), Update(_, _, _)); + EXPECT_CALL(*delegate(), OnImpressionUpdated()); + tracker()->AnalyzeImpressionHistory(); + VerifyClientStates(test_case); } -// Verifies positive impression will increase the daily max. -TEST_F(ImpressionHistoryTrackerTest, PositiveImpression) { - TestCase test_case; - base::Time create_time = base::Time::Now() - base::TimeDelta::FromSeconds(1); - - test_case.input = {{SchedulerClientType::kTest1, - 2 /* current_max_daily_show */, - {{create_time, UserFeedback::kHelpful, - ImpressionResult::kInvalid, false /* integrated */}}, - base::nullopt /* suppression_info */}}; - - // Positive impression should bump |the current_max_daily_show| and update - // other data. - test_case.expected = {{SchedulerClientType::kTest1, - 3 /* current_max_daily_show */, - {{create_time, UserFeedback::kHelpful, - ImpressionResult::kPositive, true /* integrated */}}, - base::nullopt /* suppression_info */}}; - - RunTestCase(std::move(test_case)); +// If impression has been deleted, click should have no result. +TEST_F(ImpressionHistoryTrackerTest, ClickNoImpression) { + TestCase test_case = CreateDefaultTestCase(); + InitTrackerWithData(test_case); + EXPECT_CALL(*store(), Update(_, _, _)).Times(0); + EXPECT_CALL(*delegate(), OnImpressionUpdated()).Times(0); + tracker()->OnClick(kGuid1); + VerifyClientStates(test_case); } +struct UserActionTestParam { + ImpressionResult impression_result = ImpressionResult::kInvalid; + UserFeedback user_feedback = UserFeedback::kNoFeedback; + int current_max_daily_show = 0; + base::Optional<ActionButtonType> button_type; + base::Optional<SuppressionInfo> suppression_info; +}; + +class ImpressionHistoryTrackerUserActionTest + : public ImpressionHistoryTrackerTest, + public ::testing::WithParamInterface<UserActionTestParam> { + public: + ImpressionHistoryTrackerUserActionTest() = default; + ~ImpressionHistoryTrackerUserActionTest() override = default; + + private: + DISALLOW_COPY_AND_ASSIGN(ImpressionHistoryTrackerUserActionTest); +}; + +// TODO(xingliu): Add test for unhelpful/dismiss, need to use base::Clock to +// mock base::Time::Now(). +const UserActionTestParam kUserActionTestParams[] = { + {ImpressionResult::kPositive, UserFeedback::kClick, 3, base::nullopt, + base::nullopt}, + {ImpressionResult::kPositive, UserFeedback::kHelpful, 3, + ActionButtonType::kHelpful, base::nullopt}}; + +// User actions like clicks should update the ClientState data accordingly. +TEST_P(ImpressionHistoryTrackerUserActionTest, UserAction) { + TestCase test_case = CreateDefaultTestCase(); + Impression impression = CreateImpression(base::Time::Now(), kGuid1); + DCHECK(!test_case.input.empty()); + test_case.input.front().impressions.emplace_back(impression); + + impression.impression = GetParam().impression_result; + impression.integrated = true; + impression.feedback = GetParam().user_feedback; + + test_case.expected.front().current_max_daily_show = + GetParam().current_max_daily_show; + test_case.expected.front().impressions.emplace_back(impression); + test_case.expected.front().suppression_info = GetParam().suppression_info; + + InitTrackerWithData(test_case); + EXPECT_CALL(*store(), Update(_, _, _)); + EXPECT_CALL(*delegate(), OnImpressionUpdated()); + + // Trigger user action. + if (GetParam().user_feedback == UserFeedback::kClick) + tracker()->OnClick(kGuid1); + else if (GetParam().button_type.has_value()) + tracker()->OnActionClick(kGuid1, GetParam().button_type.value()); + + VerifyClientStates(test_case); +} + +INSTANTIATE_TEST_SUITE_P(, + ImpressionHistoryTrackerUserActionTest, + testing::ValuesIn(kUserActionTestParams)); + } // namespace + } // namespace notifications
diff --git a/chrome/browser/notifications/scheduler/impression_types.cc b/chrome/browser/notifications/scheduler/impression_types.cc index 10e2616f..12eeaf5 100644 --- a/chrome/browser/notifications/scheduler/impression_types.cc +++ b/chrome/browser/notifications/scheduler/impression_types.cc
@@ -14,7 +14,8 @@ bool Impression::operator==(const Impression& other) const { return create_time == other.create_time && feedback == other.feedback && impression == other.impression && integrated == other.integrated && - task_start_time == other.task_start_time && guid == other.guid; + task_start_time == other.task_start_time && guid == other.guid && + type == other.type; } SuppressionInfo::SuppressionInfo(const base::Time& last_trigger, @@ -55,14 +56,27 @@ for (const auto& impression : impressions) { std::ostringstream stream; - stream << "Impression, create_time:" << impression.create_time << " \n" - << "feedback: " << static_cast<int>(impression.feedback) << " \n" + stream << "Impression, create_time:" << impression.create_time << "\n" + << " create_time in microseconds:" + << impression.create_time.ToDeltaSinceWindowsEpoch().InMicroseconds() + << "\n" + << "feedback: " << static_cast<int>(impression.feedback) << "\n" << "impression result: " << static_cast<int>(impression.impression) << " \n" - << "integrated: " << impression.integrated << " \n" + << "integrated: " << impression.integrated << "\n" << "task start time: " << static_cast<int>(impression.task_start_time) << "\n" - << "guid: " << impression.guid << "\n"; + << "guid: " << impression.guid << "\n" + << "type: " << static_cast<int>(impression.type); + log += stream.str(); + } + + if (suppression_info.has_value()) { + std::ostringstream stream; + stream << "Suppression info, last_trigger_time:" + << suppression_info->last_trigger_time << "\n" + << "duration:" << suppression_info->duration << "\n" + << "recover_goal:" << suppression_info->recover_goal; log += stream.str(); }
diff --git a/chrome/browser/notifications/scheduler/impression_types.h b/chrome/browser/notifications/scheduler/impression_types.h index 607f0dd..2399547 100644 --- a/chrome/browser/notifications/scheduler/impression_types.h +++ b/chrome/browser/notifications/scheduler/impression_types.h
@@ -48,6 +48,11 @@ // The unique identifier of the notification. std::string guid; + + // The type of the notification. Not persisted to disk, set after database + // initialized. + // TODO(xingliu): Consider to persist this as well. + SchedulerClientType type = SchedulerClientType::kUnknown; }; // Contains details about supression and recovery after suppression expired.
diff --git a/chrome/browser/notifications/scheduler/notification_scheduler.cc b/chrome/browser/notifications/scheduler/notification_scheduler.cc index 11f3a07..4c84d8bd 100644 --- a/chrome/browser/notifications/scheduler/notification_scheduler.cc +++ b/chrome/browser/notifications/scheduler/notification_scheduler.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/notifications/scheduler/notification_scheduler.h" +#include <string> #include <utility> #include <vector> @@ -22,6 +23,7 @@ #include "chrome/browser/notifications/scheduler/notification_scheduler_client_registrar.h" #include "chrome/browser/notifications/scheduler/notification_scheduler_context.h" #include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h" +#include "chrome/browser/notifications/scheduler/user_action_handler.h" namespace notifications { namespace { @@ -40,19 +42,22 @@ // Initializes subsystems in notification scheduler, |callback| will be // invoked if all initializations finished or anyone of them failed. The // object should be destroyed along with the |callback|. - void Init(NotificationSchedulerContext* context, - ScheduledNotificationManager::Delegate* delegate, - InitCallback callback) { + void Init( + NotificationSchedulerContext* context, + ScheduledNotificationManager::Delegate* notification_manager_delegate, + ImpressionHistoryTracker::Delegate* impression_tracker_delegate, + InitCallback callback) { callback_ = std::move(callback); context->icon_store()->Init(base::BindOnce( &InitHelper::OnIconStoreInitialized, weak_ptr_factory_.GetWeakPtr())); context->impression_tracker()->Init( + impression_tracker_delegate, base::BindOnce(&InitHelper::OnImpressionTrackerInitialized, weak_ptr_factory_.GetWeakPtr())); - context->notification_manager()->Init( - delegate, base::BindOnce(&InitHelper::OnNotificationManagerInitialized, - weak_ptr_factory_.GetWeakPtr())); + notification_manager_delegate, + base::BindOnce(&InitHelper::OnNotificationManagerInitialized, + weak_ptr_factory_.GetWeakPtr())); } private: @@ -98,7 +103,9 @@ class NotificationSchedulerImpl : public NotificationScheduler, public NotificationBackgroundTaskScheduler::Handler, - public ScheduledNotificationManager::Delegate { + public ScheduledNotificationManager::Delegate, + public ImpressionHistoryTracker::Delegate, + public UserActionHandler { public: NotificationSchedulerImpl( std::unique_ptr<NotificationSchedulerContext> context) @@ -112,7 +119,7 @@ auto helper = std::make_unique<InitHelper>(); auto* helper_ptr = helper.get(); helper_ptr->Init( - context_.get(), this, + context_.get(), this, this, base::BindOnce(&NotificationSchedulerImpl::OnInitialized, weak_ptr_factory_.GetWeakPtr(), std::move(helper), std::move(init_callback))); @@ -153,22 +160,23 @@ NOTIMPLEMENTED(); } + // ImpressionHistoryTracker::Delegate implementation. + void OnImpressionUpdated() override { ScheduleBackgroundTask(); } + void FindNotificationToShow(SchedulerTaskTime task_start_time) { DisplayDecider::Results results; ScheduledNotificationManager::Notifications notifications; context_->notification_manager()->GetAllNotifications(¬ifications); - const auto& client_states = - context_->impression_tracker()->GetClientStates(); - DisplayDecider::ClientStates client_state_ptrs; - for (const auto& client_state : client_states) { - client_state_ptrs.emplace(client_state.first, client_state.second.get()); - } + + DisplayDecider::ClientStates client_states; + context_->impression_tracker()->GetClientStates(&client_states); + std::vector<SchedulerClientType> clients; context_->client_registrar()->GetRegisteredClients(&clients); context_->display_decider()->FindNotificationsToShow( context_->config(), std::move(clients), DistributionPolicy::Create(), - task_start_time, std::move(notifications), std::move(client_state_ptrs), + task_start_time, std::move(notifications), std::move(client_states), &results); // TODO(xingliu): Update impression data after notification shown. @@ -184,6 +192,19 @@ NOTIMPLEMENTED(); } + void OnClick(const std::string& notification_id) override { + context_->impression_tracker()->OnClick(notification_id); + } + + void OnActionClick(const std::string& notification_id, + ActionButtonType button_type) override { + context_->impression_tracker()->OnActionClick(notification_id, button_type); + } + + void OnDismiss(const std::string& notification_id) override { + context_->impression_tracker()->OnDismiss(notification_id); + } + std::unique_ptr<NotificationSchedulerContext> context_; base::WeakPtrFactory<NotificationSchedulerImpl> weak_ptr_factory_;
diff --git a/chrome/browser/notifications/scheduler/proto_conversion.cc b/chrome/browser/notifications/scheduler/proto_conversion.cc index bd6b026..8322989 100644 --- a/chrome/browser/notifications/scheduler/proto_conversion.cc +++ b/chrome/browser/notifications/scheduler/proto_conversion.cc
@@ -284,6 +284,7 @@ impression.task_start_time = FromSchedulerTaskTime(proto_impression.task_start_time()); impression.guid = proto_impression.guid(); + impression.type = client_state->type; client_state->impressions.emplace_back(std::move(impression)); }
diff --git a/chrome/browser/notifications/scheduler/proto_conversion_unittest.cc b/chrome/browser/notifications/scheduler/proto_conversion_unittest.cc index d60c2299..d3b641c 100644 --- a/chrome/browser/notifications/scheduler/proto_conversion_unittest.cc +++ b/chrome/browser/notifications/scheduler/proto_conversion_unittest.cc
@@ -96,12 +96,17 @@ // Verifies impression proto conversion. TEST(ProtoConversionTest, ImpressionProtoConversion) { ClientState client_state; + client_state.type = SchedulerClientType::kTest1; base::Time create_time; bool success = base::Time::FromString("03/25/19 00:00:00 AM", &create_time); DCHECK(success); - Impression impression{ - create_time, UserFeedback::kHelpful, ImpressionResult::kPositive, - true, SchedulerTaskTime::kMorning, kGuid}; + Impression impression{create_time, + UserFeedback::kHelpful, + ImpressionResult::kPositive, + true /*integrated*/, + SchedulerTaskTime::kMorning, + kGuid, + SchedulerClientType::kTest1}; client_state.impressions.emplace_back(impression); TestClientStateConversion(&client_state);
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index 99f676af7..b0ba960 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc
@@ -63,9 +63,10 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) override { return new PrerenderContents(prerender_manager, profile, url, referrer, - origin); + initiator_origin, origin); } }; @@ -169,17 +170,20 @@ PrerenderContents::Observer::~Observer() {} -PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager, - Profile* profile, - const GURL& url, - const content::Referrer& referrer, - Origin origin) +PrerenderContents::PrerenderContents( + PrerenderManager* prerender_manager, + Profile* profile, + const GURL& url, + const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, + Origin origin) : prerender_mode_(DEPRECATED_FULL_PRERENDER), prerendering_has_started_(false), prerender_canceler_binding_(this), prerender_manager_(prerender_manager), prerender_url_(url), referrer_(referrer), + initiator_origin_(initiator_origin), profile_(profile), has_finished_loading_(false), final_status_(FINAL_STATUS_UNKNOWN), @@ -190,6 +194,24 @@ origin_(origin), network_bytes_(0), weak_factory_(this) { + switch (origin) { + case ORIGIN_OMNIBOX: + case ORIGIN_EXTERNAL_REQUEST: + case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER: + DCHECK(!initiator_origin_.has_value()); + break; + + case ORIGIN_GWS_PRERENDER: + case ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN: + case ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN: + case ORIGIN_LINK_REL_NEXT: + DCHECK(initiator_origin_.has_value()); + break; + case ORIGIN_NONE: + case ORIGIN_MAX: + NOTREACHED(); + } + DCHECK(prerender_manager); registry_.AddInterface(base::Bind( &PrerenderContents::OnPrerenderCancelerRequest, base::Unretained(this))); @@ -281,6 +303,7 @@ content::NavigationController::LoadURLParams load_url_params( prerender_url_); load_url_params.referrer = referrer_; + load_url_params.initiator_origin = initiator_origin_; load_url_params.transition_type = ui::PAGE_TRANSITION_LINK; if (origin_ == ORIGIN_OMNIBOX) { load_url_params.transition_type = ui::PageTransitionFromInt(
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h index 9c19d7c..dca0c20 100644 --- a/chrome/browser/prerender/prerender_contents.h +++ b/chrome/browser/prerender/prerender_contents.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/optional.h" #include "base/time/time.h" #include "base/values.h" #include "chrome/browser/prerender/prerender_final_status.h" @@ -28,6 +29,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/gfx/geometry/rect.h" +#include "url/origin.h" class Profile; @@ -71,6 +73,7 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) = 0; private: @@ -240,6 +243,7 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin); // Set the final status for how the PrerenderContents was used. This @@ -311,6 +315,10 @@ // The referrer. content::Referrer referrer_; + // The origin of the page requesting the prerender. Empty when the prerender + // is browser initiated. + base::Optional<url::Origin> initiator_origin_; + // The profile being used Profile* profile_;
diff --git a/chrome/browser/prerender/prerender_link_manager.cc b/chrome/browser/prerender/prerender_link_manager.cc index 74fcee9..b800643 100644 --- a/chrome/browser/prerender/prerender_link_manager.cc +++ b/chrome/browser/prerender/prerender_link_manager.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/public/common/prerender/prerender_rel_type.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" +#include "url/origin.h" #if BUILDFLAG(ENABLE_EXTENSIONS) #include "components/guest_view/browser/guest_view_base.h" @@ -136,6 +137,7 @@ const GURL& url, uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id) { DCHECK_EQ(nullptr, FindByLauncherChildIdAndPrerenderId(launcher_child_id, @@ -164,10 +166,10 @@ return; } - LinkPrerender - prerender(launcher_child_id, prerender_id, url, rel_types, referrer, size, - render_view_route_id, manager_->GetCurrentTimeTicks(), - prerender_contents); + LinkPrerender prerender(launcher_child_id, prerender_id, url, rel_types, + referrer, initiator_origin, size, + render_view_route_id, manager_->GetCurrentTimeTicks(), + prerender_contents); prerenders_.push_back(prerender); RecordLinkManagerAdded(rel_types); if (prerender_contents) @@ -229,6 +231,7 @@ const GURL& url, uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id, TimeTicks creation_time, @@ -238,6 +241,7 @@ url(url), rel_types(rel_types), referrer(referrer), + initiator_origin(initiator_origin), size(size), render_view_route_id(render_view_route_id), creation_time(creation_time), @@ -355,7 +359,7 @@ std::unique_ptr<PrerenderHandle> handle = manager_->AddPrerenderFromLinkRelPrerender( it->launcher_child_id, it->render_view_route_id, it->url, - it->rel_types, it->referrer, it->size); + it->rel_types, it->referrer, it->initiator_origin, it->size); if (!handle) { // This prerender couldn't be launched, it's gone. prerenders_.erase(it);
diff --git a/chrome/browser/prerender/prerender_link_manager.h b/chrome/browser/prerender/prerender_link_manager.h index 02ea701..a63ac44 100644 --- a/chrome/browser/prerender/prerender_link_manager.h +++ b/chrome/browser/prerender/prerender_link_manager.h
@@ -17,6 +17,7 @@ #include "chrome/browser/prerender/prerender_handle.h" #include "components/keyed_service/core/keyed_service.h" #include "url/gurl.h" +#include "url/origin.h" namespace content { struct Referrer; @@ -51,6 +52,7 @@ const GURL& url, uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id); @@ -80,6 +82,7 @@ const GURL& url, uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id, base::TimeTicks creation_time, @@ -93,6 +96,7 @@ GURL url; uint32_t rel_types; content::Referrer referrer; + url::Origin initiator_origin; gfx::Size size; int render_view_route_id;
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index 4fd535c..00ab1b0 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc
@@ -220,6 +220,7 @@ const GURL& url, const uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size) { Origin origin = rel_types & blink::kPrerenderRelTypePrerender ? ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN @@ -244,8 +245,9 @@ source_web_contents->GetController() .GetDefaultSessionStorageNamespace(); } - return AddPrerenderWithPreconnectFallback( - origin, url, referrer, gfx::Rect(size), session_storage_namespace); + return AddPrerenderWithPreconnectFallback(origin, url, referrer, + initiator_origin, gfx::Rect(size), + session_storage_namespace); } std::unique_ptr<PrerenderHandle> PrerenderManager::AddPrerenderFromOmnibox( @@ -259,7 +261,7 @@ return nullptr; } return AddPrerenderWithPreconnectFallback( - ORIGIN_OMNIBOX, url, content::Referrer(), gfx::Rect(size), + ORIGIN_OMNIBOX, url, content::Referrer(), base::nullopt, gfx::Rect(size), session_storage_namespace); } @@ -270,7 +272,7 @@ SessionStorageNamespace* session_storage_namespace, const gfx::Rect& bounds) { return AddPrerenderWithPreconnectFallback(ORIGIN_EXTERNAL_REQUEST, url, - referrer, bounds, + referrer, base::nullopt, bounds, session_storage_namespace); } @@ -281,8 +283,8 @@ SessionStorageNamespace* session_storage_namespace, const gfx::Rect& bounds) { return AddPrerenderWithPreconnectFallback( - ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, url, referrer, bounds, - session_storage_namespace); + ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, url, referrer, base::nullopt, + bounds, session_storage_namespace); } void PrerenderManager::CancelAllPrerenders() { @@ -769,6 +771,7 @@ Origin origin, const GURL& url_arg, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, const gfx::Rect& bounds, SessionStorageNamespace* session_storage_namespace) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -877,7 +880,7 @@ } std::unique_ptr<PrerenderContents> prerender_contents = - CreatePrerenderContents(url, referrer, origin); + CreatePrerenderContents(url, referrer, initiator_origin, origin); DCHECK(prerender_contents); PrerenderContents* prerender_contents_ptr = prerender_contents.get(); if (IsNoStatePrefetchEnabled()) @@ -1026,10 +1029,11 @@ std::unique_ptr<PrerenderContents> PrerenderManager::CreatePrerenderContents( const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) { DCHECK_CURRENTLY_ON(BrowserThread::UI); return base::WrapUnique(prerender_contents_factory_->CreatePrerenderContents( - this, profile_, url, referrer, origin)); + this, profile_, url, referrer, initiator_origin, origin)); } void PrerenderManager::SortActivePrerenders() {
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index 7985195..0c87472f 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/time/clock.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -28,6 +29,7 @@ #include "content/public/browser/notification_registrar.h" #include "content/public/browser/render_process_host_observer.h" #include "url/gurl.h" +#include "url/origin.h" class Profile; @@ -119,6 +121,7 @@ const GURL& url, uint32_t rel_types, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size); // Adds a prerender for |url| if valid. As the prerender request is coming @@ -444,6 +447,7 @@ Origin origin, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, const gfx::Rect& bounds, content::SessionStorageNamespace* session_storage_namespace); @@ -474,6 +478,7 @@ virtual std::unique_ptr<PrerenderContents> CreatePrerenderContents( const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin); // Insures the |active_prerenders_| are sorted by increasing expiry time. Call
diff --git a/chrome/browser/prerender/prerender_message_filter.cc b/chrome/browser/prerender/prerender_message_filter.cc index 658d3f6..f8986ee 100644 --- a/chrome/browser/prerender/prerender_message_filter.cc +++ b/chrome/browser/prerender/prerender_message_filter.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/singleton.h" #include "base/task/post_task.h" +#include "chrome/browser/bad_message.h" #include "chrome/browser/prerender/prerender_final_status.h" #include "chrome/browser/prerender/prerender_link_manager.h" #include "chrome/browser/prerender/prerender_link_manager_factory.h" @@ -16,6 +17,7 @@ #include "chrome/common/prerender_messages.h" #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/child_process_security_policy.h" using content::BrowserThread; @@ -112,15 +114,23 @@ int prerender_id, const PrerenderAttributes& attributes, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!prerender_link_manager_) return; + if (!initiator_origin.opaque() && + !content::ChildProcessSecurityPolicy::GetInstance() + ->CanAccessDataForOrigin(render_process_id_, + initiator_origin.GetURL())) { + bad_message::ReceivedBadMessage(this, + bad_message::PMF_INVALID_INITIATOR_ORIGIN); + return; + } prerender_link_manager_->OnAddPrerender( - render_process_id_, prerender_id, - attributes.url, attributes.rel_types, referrer, - size, render_view_route_id); + render_process_id_, prerender_id, attributes.url, attributes.rel_types, + referrer, initiator_origin, size, render_view_route_id); } void PrerenderMessageFilter::OnCancelPrerender(
diff --git a/chrome/browser/prerender/prerender_message_filter.h b/chrome/browser/prerender/prerender_message_filter.h index c2d5fca3..8f9d8bad 100644 --- a/chrome/browser/prerender/prerender_message_filter.h +++ b/chrome/browser/prerender/prerender_message_filter.h
@@ -13,6 +13,7 @@ #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_thread.h" #include "url/gurl.h" +#include "url/origin.h" class Profile; struct PrerenderAttributes; @@ -57,6 +58,7 @@ void OnAddPrerender(int prerender_id, const PrerenderAttributes& attributes, const content::Referrer& referrer, + const url::Origin& initiator_origin, const gfx::Size& size, int render_view_route_id); void OnCancelPrerender(int prerender_id);
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index e1edb86..63487af 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -359,6 +359,66 @@ loop.Run(); } +// Check cookie loading for a cross-domain prefetched pages. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, + PrefetchCookieCrossDomainSameSiteStrict) { + constexpr char kSecondaryDomain[] = "www.foo.com"; + GURL cross_domain_url = + embedded_test_server()->GetURL(kSecondaryDomain, "/echoall"); + + EXPECT_TRUE(SetCookie(current_browser()->profile(), cross_domain_url, + "cookie_A=A; SameSite=Strict;")); + EXPECT_TRUE(SetCookie(current_browser()->profile(), cross_domain_url, + "cookie_B=B; SameSite=Lax;")); + + std::unique_ptr<TestPrerender> test_prerender = + PrefetchFromURL(cross_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + + ui_test_utils::NavigateToURL(current_browser(), cross_domain_url); + + EXPECT_TRUE(WaitForLoadStop( + current_browser()->tab_strip_model()->GetActiveWebContents())); + + std::string html_content; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + current_browser()->tab_strip_model()->GetActiveWebContents(), + "domAutomationController.send(document.body.innerHTML)", &html_content)); + + // For any cross origin navigation (including prerender), SameSite Strict + // cookies should not be sent, but Lax should. + EXPECT_EQ(std::string::npos, html_content.find("cookie_A=A")); + EXPECT_NE(std::string::npos, html_content.find("cookie_B=B")); +} + +// Check cookie loading for a same-domain prefetched pages. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, + PrefetchCookieSameDomainSameSiteStrict) { + GURL same_domain_url = embedded_test_server()->GetURL("/echoall"); + + EXPECT_TRUE(SetCookie(current_browser()->profile(), same_domain_url, + "cookie_A=A; SameSite=Strict;")); + EXPECT_TRUE(SetCookie(current_browser()->profile(), same_domain_url, + "cookie_B=B; SameSite=Lax;")); + + std::unique_ptr<TestPrerender> test_prerender = + PrefetchFromURL(same_domain_url, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + + ui_test_utils::NavigateToURL(current_browser(), same_domain_url); + + EXPECT_TRUE(WaitForLoadStop( + current_browser()->tab_strip_model()->GetActiveWebContents())); + + std::string html_content; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + current_browser()->tab_strip_model()->GetActiveWebContents(), + "domAutomationController.send(document.body.innerHTML)", &html_content)); + + // For any same origin navigation (including prerender), SameSite Strict + // cookies should not be sent, but Lax should. + EXPECT_NE(std::string::npos, html_content.find("cookie_A=A")); + EXPECT_NE(std::string::npos, html_content.find("cookie_B=B")); +} + // Check that the LOAD_PREFETCH flag is set. IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchLoadFlag) { GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
diff --git a/chrome/browser/prerender/prerender_test_utils.cc b/chrome/browser/prerender/prerender_test_utils.cc index 224d614..dcdf296 100644 --- a/chrome/browser/prerender/prerender_test_utils.cc +++ b/chrome/browser/prerender/prerender_test_utils.cc
@@ -276,10 +276,16 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin, FinalStatus expected_final_status, bool ignore_final_status) - : PrerenderContents(prerender_manager, profile, url, referrer, origin), + : PrerenderContents(prerender_manager, + profile, + url, + referrer, + initiator_origin, + origin), expected_final_status_(expected_final_status), observer_(this), new_render_view_host_(nullptr), @@ -529,15 +535,16 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) { ExpectedContents expected; if (!expected_contents_queue_.empty()) { expected = expected_contents_queue_.front(); expected_contents_queue_.pop_front(); } - TestPrerenderContents* contents = - new TestPrerenderContents(prerender_manager, profile, url, referrer, - origin, expected.final_status, expected.ignore); + TestPrerenderContents* contents = new TestPrerenderContents( + prerender_manager, profile, url, referrer, initiator_origin, origin, + expected.final_status, expected.ignore); if (expected.handle) expected.handle->OnPrerenderCreated(contents); return contents;
diff --git a/chrome/browser/prerender/prerender_test_utils.h b/chrome/browser/prerender/prerender_test_utils.h index 69b49a0..70bd70b 100644 --- a/chrome/browser/prerender/prerender_test_utils.h +++ b/chrome/browser/prerender/prerender_test_utils.h
@@ -108,6 +108,7 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin, FinalStatus expected_final_status, bool ignore_final_status); @@ -288,6 +289,7 @@ Profile* profile, const GURL& url, const content::Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) override; private:
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc index 71baedb6..dde12e0 100644 --- a/chrome/browser/prerender/prerender_unittest.cc +++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -70,6 +70,7 @@ DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager, const GURL& url, Origin origin, + const base::Optional<url::Origin>& initiator_origin, FinalStatus expected_final_status); ~DummyPrerenderContents() override; @@ -190,15 +191,17 @@ FinalStatus expected_final_status) { return SetNextPrerenderContents(std::make_unique<DummyPrerenderContents>( this, url, ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, + url::Origin::Create(GURL("https://uniquedifferentorigin.com")), expected_final_status)); } DummyPrerenderContents* CreateNextPrerenderContents( const GURL& url, + const base::Optional<url::Origin>& initiator_origin, Origin origin, FinalStatus expected_final_status) { return SetNextPrerenderContents(std::make_unique<DummyPrerenderContents>( - this, url, origin, expected_final_status)); + this, url, origin, initiator_origin, expected_final_status)); } DummyPrerenderContents* CreateNextPrerenderContents( @@ -207,6 +210,7 @@ FinalStatus expected_final_status) { auto prerender_contents = std::make_unique<DummyPrerenderContents>( this, url, ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, + url::Origin::Create(GURL("https://uniquedifferentorigin.com")), expected_final_status); for (const GURL& alias : alias_urls) EXPECT_TRUE(prerender_contents->AddAliasURL(alias)); @@ -258,6 +262,7 @@ std::unique_ptr<PrerenderContents> CreatePrerenderContents( const GURL& url, const Referrer& referrer, + const base::Optional<url::Origin>& initiator_origin, Origin origin) override { CHECK(next_prerender_contents_); EXPECT_EQ(url, next_prerender_contents_->prerender_url()); @@ -286,11 +291,13 @@ UnitTestPrerenderManager* test_prerender_manager, const GURL& url, Origin origin, + const base::Optional<url::Origin>& initiator_origin, FinalStatus expected_final_status) : PrerenderContents(test_prerender_manager, nullptr, url, Referrer(), + initiator_origin, origin), route_id_(g_next_route_id_++), test_prerender_manager_(test_prerender_manager), @@ -388,7 +395,7 @@ bool AddSimplePrerender(const GURL& url) { prerender_link_manager()->OnAddPrerender( kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes, - content::Referrer(), kSize, kDefaultRenderViewRouteId); + content::Referrer(), url::Origin(), kSize, kDefaultRenderViewRouteId); return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id()); } @@ -401,7 +408,7 @@ referrer.url = GURL("https://www.google.com"); prerender_link_manager()->OnAddPrerender( kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes, referrer, - kSize, kDefaultRenderViewRouteId); + url::Origin::Create(referrer.url), kSize, kDefaultRenderViewRouteId); return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id()); } @@ -496,7 +503,8 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(kGWSPrefetchHoldback); prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_GWS_PRERENDER, FINAL_STATUS_MANAGER_SHUTDOWN); + url, url::Origin::Create(GURL("www.google.com")), ORIGIN_GWS_PRERENDER, + FINAL_STATUS_MANAGER_SHUTDOWN); EXPECT_FALSE(AddSimpleGWSPrerender(url)); } @@ -526,7 +534,8 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature(kGWSPrefetchHoldback); prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_GWS_PRERENDER, FINAL_STATUS_MANAGER_SHUTDOWN); + url, url::Origin::Create(GURL("www.google.com")), ORIGIN_GWS_PRERENDER, + FINAL_STATUS_MANAGER_SHUTDOWN); EXPECT_TRUE(AddSimpleGWSPrerender(url)); } @@ -760,15 +769,15 @@ prerender_manager()->SetTickClockForTesting(tick_clock()); // Prefetch the url once. - prerender_manager()->CreateNextPrerenderContents(kUrl, ORIGIN_OMNIBOX, - FINAL_STATUS_CANCELLED); + prerender_manager()->CreateNextPrerenderContents( + kUrl, base::nullopt, ORIGIN_OMNIBOX, FINAL_STATUS_CANCELLED); EXPECT_TRUE( prerender_manager()->AddPrerenderFromOmnibox(kUrl, nullptr, gfx::Size())); // Cancel the prerender so that it is not reused. prerender_manager()->CancelAllPrerenders(); prerender_manager()->CreateNextPrerenderContents( - kUrl, ORIGIN_OMNIBOX, FINAL_STATUS_MANAGER_SHUTDOWN); + kUrl, base::nullopt, ORIGIN_OMNIBOX, FINAL_STATUS_MANAGER_SHUTDOWN); // Prefetching again before time_to_live aborts, because it is a duplicate. tick_clock()->Advance(base::TimeDelta::FromSeconds(1)); @@ -937,12 +946,12 @@ // Schedule a pending prerender launched from the prerender. DummyPrerenderContents* pending_prerender_contents = prerender_manager()->CreateNextPrerenderContents( - pending_url, - ORIGIN_GWS_PRERENDER, - FINAL_STATUS_USED); + pending_url, url::Origin::Create(GURL("https://www.google.com")), + ORIGIN_GWS_PRERENDER, FINAL_STATUS_USED); prerender_link_manager()->OnAddPrerender( child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, - Referrer(url, network::mojom::ReferrerPolicy::kDefault), kSize, route_id); + Referrer(url, network::mojom::ReferrerPolicy::kDefault), + url::Origin::Create(pending_url), kSize, route_id); EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); EXPECT_FALSE(pending_prerender_contents->prerendering_has_started()); @@ -979,12 +988,12 @@ // Schedule a pending prerender launched from the prerender. DummyPrerenderContents* pending_prerender_contents = prerender_manager()->CreateNextPrerenderContents( - pending_url, - ORIGIN_GWS_PRERENDER, - FINAL_STATUS_UNSUPPORTED_SCHEME); + pending_url, url::Origin::Create(GURL("https://www.google.com")), + ORIGIN_GWS_PRERENDER, FINAL_STATUS_UNSUPPORTED_SCHEME); prerender_link_manager()->OnAddPrerender( child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, - Referrer(url, network::mojom::ReferrerPolicy::kDefault), kSize, route_id); + Referrer(url, network::mojom::ReferrerPolicy::kDefault), + url::Origin::Create(pending_url), kSize, route_id); EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); EXPECT_FALSE(pending_prerender_contents->prerendering_has_started()); @@ -1017,7 +1026,8 @@ // Schedule a pending prerender launched from the prerender. prerender_link_manager()->OnAddPrerender( child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, - Referrer(url, network::mojom::ReferrerPolicy::kDefault), kSize, route_id); + Referrer(url, network::mojom::ReferrerPolicy::kDefault), + url::Origin::Create(pending_url), kSize, route_id); EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); // Cancel the pending prerender. @@ -1042,7 +1052,8 @@ url, FINAL_STATUS_MANAGER_SHUTDOWN); prerender_link_manager()->OnAddPrerender( - 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200); + 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), + url::Origin::Create(url), kSize, 200); EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id())); } @@ -1141,7 +1152,7 @@ TEST_F(PrerenderTest, OmniboxAllowedWhenNotDisabled) { DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - GURL("http://www.example.com"), ORIGIN_OMNIBOX, + GURL("http://www.example.com"), base::nullopt, ORIGIN_OMNIBOX, FINAL_STATUS_MANAGER_SHUTDOWN); EXPECT_TRUE(prerender_manager()->AddPrerenderFromOmnibox( @@ -1205,7 +1216,8 @@ GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, FINAL_STATUS_USED); + url, url::Origin::Create(GURL("https://www.notgoogle.com")), + ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, FINAL_STATUS_USED); EXPECT_TRUE(AddSimplePrerender(url)); EXPECT_TRUE(prerender_contents->prerendering_has_started()); std::unique_ptr<PrerenderContents> entry = @@ -1222,7 +1234,8 @@ net::NetworkChangeNotifier::GetConnectionType())); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, FINAL_STATUS_USED); + url, url::Origin::Create(GURL("https://www.notexample.com")), + ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, FINAL_STATUS_USED); EXPECT_TRUE(AddSimplePrerender(url)); EXPECT_TRUE(prerender_contents->prerendering_has_started()); std::unique_ptr<PrerenderContents> entry = @@ -1242,8 +1255,7 @@ GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, - ORIGIN_EXTERNAL_REQUEST, + url, base::nullopt, ORIGIN_EXTERNAL_REQUEST, FINAL_STATUS_MANAGER_SHUTDOWN); std::unique_ptr<PrerenderHandle> prerender_handle( prerender_manager()->AddPrerenderFromExternalRequest( @@ -1271,7 +1283,7 @@ GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_EXTERNAL_REQUEST, FINAL_STATUS_USED); + url, base::nullopt, ORIGIN_EXTERNAL_REQUEST, FINAL_STATUS_USED); std::unique_ptr<PrerenderHandle> prerender_handle( prerender_manager()->AddPrerenderFromExternalRequest( url, content::Referrer(), nullptr, gfx::Rect(kSize))); @@ -1293,7 +1305,8 @@ DummyPrerenderContents* prerender_contents = nullptr; std::unique_ptr<PrerenderHandle> prerender_handle; prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, FINAL_STATUS_USED); + url, base::nullopt, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, + FINAL_STATUS_USED); prerender_handle = prerender_manager()->AddForcedPrerenderFromExternalRequest( url, content::Referrer(), nullptr, gfx::Rect(kSize)); EXPECT_TRUE(prerender_handle); @@ -1700,7 +1713,7 @@ GURL pending_url("http://www.neverlaunched.com"); prerender_link_manager()->OnAddPrerender( child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, - content::Referrer(), kSize, route_id); + content::Referrer(), url::Origin::Create(pending_url), kSize, route_id); const int second_prerender_id = last_prerender_id(); EXPECT_FALSE(IsEmptyPrerenderLinkManager()); @@ -1841,7 +1854,7 @@ GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( - url, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, + url, base::nullopt, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, FINAL_STATUS_MANAGER_SHUTDOWN); std::unique_ptr<PrerenderHandle> prerender_handle = prerender_manager()->AddForcedPrerenderFromExternalRequest(
diff --git a/chrome/browser/resources/extensions/activity_log/activity_log_history.html b/chrome/browser/resources/extensions/activity_log/activity_log_history.html index e7eab6e4..87ae011 100644 --- a/chrome/browser/resources/extensions/activity_log/activity_log_history.html +++ b/chrome/browser/resources/extensions/activity_log/activity_log_history.html
@@ -3,16 +3,15 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/promise_resolver.html"> <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="activity_log_history_item.html"> <link rel="import" href="../shared_style.html"> <dom-module id="activity-log-history"> <template> - <style include="paper-button-style shared-style"> + <style include="shared-style"> :host { --activity-log-call-and-count-width: 514px; --activity-type-width: 85px; @@ -56,10 +55,10 @@ <cr-search-field label="$i18n{activityLogSearchLabel}" on-search-changed="onSearchChanged_"> </cr-search-field > - <paper-button class="clear-activities-button" + <cr-button class="clear-activities-button" on-click="onClearActivitiesClick_"> $i18n{clearActivities} - </paper-button> + </cr-button> <cr-icon-button id="more-actions" iron-icon="cr:more-vert" title="$i18n{activityLogMoreActionsLabel}" on-click="onMoreActionsClick_"></cr-icon-button>
diff --git a/chrome/browser/resources/extensions/activity_log/activity_log_stream.html b/chrome/browser/resources/extensions/activity_log/activity_log_stream.html index 4ae7a45d..9f1c675 100644 --- a/chrome/browser/resources/extensions/activity_log/activity_log_stream.html +++ b/chrome/browser/resources/extensions/activity_log/activity_log_stream.html
@@ -1,16 +1,15 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_search_field/cr_search_field.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="activity_log_stream_item.html"> <link rel="import" href="../shared_style.html"> <dom-module id="activity-log-stream"> <template> - <style include="shared-style paper-button-style"> + <style include="shared-style"> :host { --activity-log-call-and-time-width: 575px; --activity-type-width: 85px; @@ -50,18 +49,17 @@ <cr-search-field label="$i18n{activityLogSearchLabel}" on-search-changed="onSearchChanged_"> </cr-search-field > - <paper-button id="toggle-stream-button" on-click="onToggleButtonClick_"> + <cr-button id="toggle-stream-button" on-click="onToggleButtonClick_"> <span hidden$="[[isStreamOn_]]"> $i18n{startActivityStream} </span> <span hidden$="[[!isStreamOn_]]"> $i18n{stopActivityStream} </span> - </paper-button> - <paper-button class="clear-activities-button" - on-click="clearStream"> + </cr-button> + <cr-button class="clear-activities-button" on-click="clearStream"> $i18n{clearActivities} - </paper-button> + </cr-button> </div> <div id="empty-stream-message" class="activity-message" hidden$="[[!isStreamEmpty_(activityStream_.length)]]">
diff --git a/chrome/browser/resources/extensions/detail_view.html b/chrome/browser/resources/extensions/detail_view.html index b021c518..c279068a 100644 --- a/chrome/browser/resources/extensions/detail_view.html +++ b/chrome/browser/resources/extensions/detail_view.html
@@ -1,12 +1,12 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_container_shadow_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -16,7 +16,6 @@ <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="item_behavior.html"> @@ -31,7 +30,8 @@ <dom-module id="extensions-detail-view"> <template> - <style include="iron-flex cr-shared-style cr-icons action-link paper-button-style shared-style"> + <style include="iron-flex cr-shared-style cr-icons action-link + shared-style"> :host { --iron-icon-fill-color: var(--cr-secondary-text-color); display: block; @@ -189,10 +189,10 @@ icon-aria-label="[[data.controlledInfo.type]]"> </cr-tooltip-icon> <template is="dom-if" if="[[isTerminated_(data.state)]]"> - <paper-button id="terminated-reload-button" class="action-button" + <cr-button id="terminated-reload-button" class="action-button" on-click="onReloadTap_"> $i18n{itemReload} - </paper-button> + </cr-button> </template> <cr-toggle id="enable-toggle" aria-label$="[[appOrExtension( @@ -217,10 +217,10 @@ </template> </span> <template is="dom-if" if="[[!isTerminated_(data.state)]]"> - <paper-button id="warnings-reload-button" class="action-button" + <cr-button id="warnings-reload-button" class="action-button" on-click="onReloadTap_"> $i18n{itemReload} - </paper-button> + </cr-button> </template> </div> <div class="section continuation warning" id="suspicious-warning" @@ -238,10 +238,10 @@ hidden$="[[!data.disableReasons.corruptInstall]]"> <iron-icon class="warning-icon" icon="cr:warning"></iron-icon> <span>$i18n{itemCorruptInstall}</span> - <paper-button id="repair-button" class="action-button" + <cr-button id="repair-button" class="action-button" on-click="onRepairTap_"> $i18n{itemRepair} - </paper-button> + </cr-button> </div> <div class="section continuation warning" id="blacklisted-warning" hidden$="[[!data.blacklistText]]">
diff --git a/chrome/browser/resources/extensions/error_page.html b/chrome/browser/resources/extensions/error_page.html index d5254f4..4e39a8b7 100644 --- a/chrome/browser/resources/extensions/error_page.html +++ b/chrome/browser/resources/extensions/error_page.html
@@ -1,10 +1,10 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_container_shadow_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> @@ -12,7 +12,6 @@ <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="code_section.html"> <link rel="import" href="item_util.html"> @@ -21,7 +20,7 @@ <dom-module id="extensions-error-page"> <template> - <style include="paper-button-style cr-icons cr-shared-style shared-style"> + <style include="cr-icons cr-shared-style shared-style"> :host { display: block; height: 100%; @@ -144,9 +143,9 @@ aria-label="$i18n{back}" on-click="onCloseButtonTap_"> </cr-icon-button> <span>$i18n{errorsPageHeading}</span> - <paper-button on-click="onClearAllTap_" hidden="[[!entries_.length]]"> + <cr-button on-click="onClearAllTap_" hidden="[[!entries_.length]]"> $i18n{clearAll} - </paper-button> + </cr-button> </div> <div class="section"> <div id="errorsList">
diff --git a/chrome/browser/resources/extensions/install_warnings_dialog.html b/chrome/browser/resources/extensions/install_warnings_dialog.html index 19b213005..3763bf59 100644 --- a/chrome/browser/resources/extensions/install_warnings_dialog.html +++ b/chrome/browser/resources/extensions/install_warnings_dialog.html
@@ -1,17 +1,16 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="code_section.html"> <dom-module id="extensions-install-warnings-dialog"> <template> - <style include="cr-shared-style paper-button-style"> + <style include="cr-shared-style"> div[slot='body'] ul { background-color: var(--paper-red-50); margin: 0; @@ -36,9 +35,9 @@ </ul> </div> <div slot="button-container"> - <paper-button class="action-button" on-click="onOkTap_"> + <cr-button class="action-button" on-click="onOkTap_"> $i18n{ok} - </paper-button> + </cr-button> </div> </cr-dialog> </template>
diff --git a/chrome/browser/resources/extensions/item.html b/chrome/browser/resources/extensions/item.html index 5fa187a..6829b68 100644 --- a/chrome/browser/resources/extensions/item.html +++ b/chrome/browser/resources/extensions/item.html
@@ -1,11 +1,11 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> @@ -25,7 +25,8 @@ <dom-module id="extensions-item"> <template> - <style include="iron-flex cr-hidden-style cr-icons action-link paper-button-style shared-style"> + <style include="iron-flex cr-hidden-style cr-icons action-link + shared-style"> .bounded-text, .multiline-clippable-text, .clippable-flex-text { @@ -145,7 +146,7 @@ padding-top: 8px; } - #button-strip paper-button { + #button-strip cr-button { margin-inline-start: 8px; } @@ -304,20 +305,20 @@ </div> <div id="button-strip" class="layout horizontal center"> <div class="layout flex horizontal center"> - <paper-button id="detailsButton" on-click="onDetailsTap_" + <cr-button id="detailsButton" on-click="onDetailsTap_" aria-describedby="a11yAssociation"> $i18n{itemDetails} - </paper-button> - <paper-button id="remove-button" on-click="onRemoveTap_" + </cr-button> + <cr-button id="remove-button" on-click="onRemoveTap_" aria-describedby="a11yAssociation" hidden="[[isControlled_(data.controlledInfo)]]"> $i18n{remove} - </paper-button> + </cr-button> <template is="dom-if" if="[[shouldShowErrorsButton_(data.*)]]"> - <paper-button id="errors-button" on-click="onErrorsTap_" + <cr-button id="errors-button" on-click="onErrorsTap_" aria-describedby="a11yAssociation"> $i18n{itemErrors} - </paper-button> + </cr-button> </template> </div> <template is="dom-if" if="[[!computeDevReloadButtonHidden_(data.*)]]"> @@ -326,16 +327,16 @@ on-click="onReloadTap_"></cr-icon-button> </template> <template is="dom-if" if="[[data.disableReasons.corruptInstall]]"> - <paper-button id="repair-button" class="action-button" + <cr-button id="repair-button" class="action-button" aria-describedby="a11yAssociation" on-click="onRepairTap_"> $i18n{itemRepair} - </paper-button> + </cr-button> </template> <template is="dom-if" if="[[isTerminated_(data.state)]]"> - <paper-button id="terminated-reload-button" on-click="onReloadTap_" + <cr-button id="terminated-reload-button" on-click="onReloadTap_" aria-describedby="a11yAssociation" class="action-button"> $i18n{itemReload} - </paper-button> + </cr-button> </template> <cr-toggle id="enable-toggle" aria-label$="[[appOrExtension(
diff --git a/chrome/browser/resources/extensions/kiosk_dialog.html b/chrome/browser/resources/extensions/kiosk_dialog.html index 78eb1bae..7210150 100644 --- a/chrome/browser/resources/extensions/kiosk_dialog.html +++ b/chrome/browser/resources/extensions/kiosk_dialog.html
@@ -1,23 +1,22 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="item_behavior.html"> <link rel="import" href="kiosk_browser_proxy.html"> <dom-module id="extensions-kiosk-dialog"> <template> - <style include="cr-shared-style paper-button-style cr-icons"> + <style include="cr-shared-style cr-icons"> #add-kiosk-app { margin-bottom: 10px; margin-top: 20px; @@ -27,7 +26,7 @@ width: 350px; } - #add-kiosk-app paper-button { + #add-kiosk-app cr-button { margin-inline-start: 10px; } @@ -88,12 +87,12 @@ </span> </div> <div class="item-controls"> - <paper-button hidden="[[!canEditAutoLaunch_]]" + <cr-button hidden="[[!canEditAutoLaunch_]]" on-click="onAutoLaunchButtonTap_"> [[getAutoLaunchButtonLabel_(item.autoLaunch, '$i18nPolymer{kioskDisableAutoLaunch}', '$i18nPolymer{kioskEnableAutoLaunch}')]] - </paper-button> + </cr-button> <cr-icon-button class="icon-delete-gray" on-click="onDeleteAppTap_"></cr-icon-button> </div> @@ -106,10 +105,10 @@ invalid="[[errorAppId_]]" on-keydown="clearInputInvalid_" error-message="[[getErrorMessage_( '$i18nPolymer{kioskInvalidApp}', errorAppId_)]]"> - <paper-button id="add-button" on-click="onAddAppTap_" + <cr-button id="add-button" on-click="onAddAppTap_" disabled="[[!addAppInput_]]" slot="suffix"> $i18n{add} - </paper-button> + </cr-button> </cr-input> </div> <cr-checkbox disabled="[[!canEditBailout_]]" id="bailout" @@ -119,9 +118,9 @@ </cr-checkbox> </div> <div slot="button-container"> - <paper-button class="action-button" on-click="onDoneTap_"> + <cr-button class="action-button" on-click="onDoneTap_"> $i18n{done} - </paper-button> + </cr-button> </div> </cr-dialog> <cr-dialog id="confirm-dialog" close-text="$i18n{close}" @@ -129,14 +128,12 @@ <div slot="title">$i18n{kioskDisableBailoutWarningTitle}</div> <div slot="body">$i18n{kioskDisableBailoutWarningBody}</div> <div slot="button-container"> - <paper-button class="cancel-button" - on-click="onBailoutDialogCancelTap_"> + <cr-button class="cancel-button" on-click="onBailoutDialogCancelTap_"> $i18n{cancel} - </paper-button> - <paper-button class="action-button" - on-click="onBailoutDialogConfirmTap_"> + </cr-button> + <cr-button class="action-button" on-click="onBailoutDialogConfirmTap_"> $i18n{confirm} - </paper-button> + </cr-button> </div> </cr-dialog> </template>
diff --git a/chrome/browser/resources/extensions/load_error.html b/chrome/browser/resources/extensions/load_error.html index 77a0f3d1..682b4fb 100644 --- a/chrome/browser/resources/extensions/load_error.html +++ b/chrome/browser/resources/extensions/load_error.html
@@ -1,17 +1,16 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> <link rel="import" href="code_section.html"> <dom-module id="extensions-load-error"> <template> - <style include="cr-shared-style paper-button-style"> + <style include="cr-shared-style"> .description-row { display: flex; } @@ -44,13 +43,13 @@ </div> <div slot="button-container"> <paper-spinner-lite active="[[retrying_]]"></paper-spinner-lite> - <paper-button class="cancel-button" on-click="close"> + <cr-button class="cancel-button" on-click="close"> $i18n{cancel} - </paper-button> - <paper-button class="action-button" disabled="[[retrying_]]" + </cr-button> + <cr-button class="action-button" disabled="[[retrying_]]" on-click="onRetryTap_"> $i18n{loadErrorRetry} - </paper-button> + </cr-button> </div> </cr-dialog> </template>
diff --git a/chrome/browser/resources/extensions/pack_dialog.html b/chrome/browser/resources/extensions/pack_dialog.html index 1a3c789..6718e23 100644 --- a/chrome/browser/resources/extensions/pack_dialog.html +++ b/chrome/browser/resources/extensions/pack_dialog.html
@@ -1,25 +1,24 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/util.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="pack_dialog_alert.html"> <dom-module id="extensions-pack-dialog"> <template> - <style include="cr-shared-style paper-button-style"> + <style include="cr-shared-style"> cr-input { margin-top: var(--cr-form-field-bottom-spacing); --cr-input-error-display: none; } - paper-button[slot='suffix'] { + cr-button[slot='suffix'] { margin-inline-start: 10px; } @@ -34,27 +33,27 @@ <div>$i18n{packDialogContent}</div> <cr-input id="root-dir" label="$i18n{packDialogExtensionRoot}" value="{{packDirectory_}}"> - <paper-button id="root-dir-browse" on-click="onRootBrowse_" + <cr-button id="root-dir-browse" on-click="onRootBrowse_" slot="suffix"> $i18n{packDialogBrowse} - </paper-button> + </cr-button> </cr-input> <cr-input id="key-file" label="$i18n{packDialogKeyFile}" value="{{keyFile_}}"> - <paper-button id="key-file-browse" on-click="onKeyBrowse_" + <cr-button id="key-file-browse" on-click="onKeyBrowse_" slot="suffix"> $i18n{packDialogBrowse} - </paper-button> + </cr-button> </cr-input> </div> <div slot="button-container"> - <paper-button class="cancel-button" on-click="onCancelTap_"> + <cr-button class="cancel-button" on-click="onCancelTap_"> $i18n{cancel} - </paper-button> - <paper-button class="action-button" on-click="onConfirmTap_" + </cr-button> + <cr-button class="action-button" on-click="onConfirmTap_" disabled="[[!packDirectory_]]"> $i18n{packDialogConfirm} - </paper-button> + </cr-button> </div> </cr-dialog> <template is="dom-if" if="[[lastResponse_]]" restamp>
diff --git a/chrome/browser/resources/extensions/pack_dialog_alert.html b/chrome/browser/resources/extensions/pack_dialog_alert.html index 79fa1a74..a08e9fe 100644 --- a/chrome/browser/resources/extensions/pack_dialog_alert.html +++ b/chrome/browser/resources/extensions/pack_dialog_alert.html
@@ -1,15 +1,14 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <dom-module id="extensions-pack-dialog-alert"> <template> - <style include="cr-shared-style paper-button-style"> + <style include="cr-shared-style"> .body { white-space: pre-wrap; word-break: break-word; @@ -21,14 +20,14 @@ <!-- No whitespace or new-lines allowed within the div.body tag. --> <div class="body" slot="body">[[model.message]]</div> <div class="button-container" slot="button-container"> - <paper-button class$="[[getCancelButtonClass_(confirmLabel_)]]" + <cr-button class$="[[getCancelButtonClass_(confirmLabel_)]]" on-click="onCancelTap_" hidden="[[!cancelLabel_]]"> [[cancelLabel_]] - </paper-button> - <paper-button class="action-button" on-click="onConfirmTap_" + </cr-button> + <cr-button class="action-button" on-click="onConfirmTap_" hidden="[[!confirmLabel_]]"> [[confirmLabel_]] - </paper-button> + </cr-button> </div> </cr-dialog> </template>
diff --git a/chrome/browser/resources/extensions/runtime_host_permissions.html b/chrome/browser/resources/extensions/runtime_host_permissions.html index 3b6c39f..5215c32 100644 --- a/chrome/browser/resources/extensions/runtime_host_permissions.html +++ b/chrome/browser/resources/extensions/runtime_host_permissions.html
@@ -4,7 +4,6 @@ <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -14,15 +13,13 @@ <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/md_select_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="runtime_hosts_dialog.html"> <link rel="import" href="shared_style.html"> <link rel="import" href="strings.html"> <dom-module id="extensions-runtime-host-permissions"> <template> - <style include="cr-shared-style action-link md-select paper-button-style - shared-style"> + <style include="cr-shared-style action-link md-select shared-style"> iron-icon { --iron-icon-height: var(--cr-icon-size); --iron-icon-width: var(--cr-icon-size);
diff --git a/chrome/browser/resources/extensions/runtime_hosts_dialog.html b/chrome/browser/resources/extensions/runtime_hosts_dialog.html index b639ed57..db6b162 100644 --- a/chrome/browser/resources/extensions/runtime_hosts_dialog.html +++ b/chrome/browser/resources/extensions/runtime_hosts_dialog.html
@@ -1,15 +1,14 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="strings.html"> <dom-module id="extensions-runtime-hosts-dialog"> <template> - <style include="cr-shared-style paper-button-style"></style> + <style include="cr-shared-style"></style> <cr-dialog id="dialog" close-text="$i18n{close}"> <div slot="title">[[computeDialogTitle_(currentSite)]]</div> <div slot="body"> @@ -23,13 +22,13 @@ </cr-input> </div> <div slot="button-container"> - <paper-button class="cancel-button" on-click="onCancelTap_"> + <cr-button class="cancel-button" on-click="onCancelTap_"> $i18n{cancel} - </paper-button> - <paper-button class="action-button" id="submit" on-click="onSubmitTap_" + </cr-button> + <cr-button class="action-button" id="submit" on-click="onSubmitTap_" disabled="[[computeSubmitButtonDisabled_(inputInvalid_, site_)]]"> [[computeSubmitButtonLabel_(currentSite)]] - </paper-button> + </cr-button> </div> </cr-dialog> </template>
diff --git a/chrome/browser/resources/extensions/toolbar.html b/chrome/browser/resources/extensions/toolbar.html index 77ee1f8..3379fc6 100644 --- a/chrome/browser/resources/extensions/toolbar.html +++ b/chrome/browser/resources/extensions/toolbar.html
@@ -1,10 +1,10 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> -<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_tooltip_icon.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/assert.html"> @@ -17,7 +17,7 @@ <dom-module id="extensions-toolbar"> <template> - <style include="cr-hidden-style paper-button-style"> + <style include="cr-hidden-style"> :host { --border-bottom-height: 1px; --button-row-height: calc(2 * var(--padding-top-bottom) + @@ -74,7 +74,7 @@ width: 100%; } - #buttonStrip paper-button { + #buttonStrip cr-button { margin-inline-end: 16px; } @@ -120,22 +120,22 @@ </template> <div id="devDrawer" expanded$="[[expanded_]]"> <div id="buttonStrip"> - <paper-button hidden$="[[!canLoadUnpacked]]" id="loadUnpacked" + <cr-button hidden$="[[!canLoadUnpacked]]" id="loadUnpacked" on-click="onLoadUnpackedTap_"> $i18n{toolbarLoadUnpacked} - </paper-button> - <paper-button id="packExtensions" on-click="onPackTap_"> + </cr-button> + <cr-button id="packExtensions" on-click="onPackTap_"> $i18n{toolbarPack} - </paper-button> - <paper-button id="updateNow" on-click="onUpdateNowTap_" + </cr-button> + <cr-button id="updateNow" on-click="onUpdateNowTap_" title="$i18n{toolbarUpdateNowTooltip}"> $i18n{toolbarUpdateNow} - </paper-button> + </cr-button> <if expr="chromeos"> - <paper-button id="kioskExtensions" on-click="onKioskTap_" + <cr-button id="kioskExtensions" on-click="onKioskTap_" hidden$="[[!kioskEnabled]]"> $i18n{manageKioskApp} - </paper-button> + </cr-button> </if> </div> </div>
diff --git a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html index 209d833..be487dc8 100644 --- a/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html +++ b/chrome/browser/resources/pdf/elements/viewer-zoom-toolbar/viewer-zoom-button.html
@@ -31,10 +31,10 @@ } cr-icon-button { - --cr-icon-button-border-radius: 50%; --cr-icon-button-size: 36px; --cr-icon-button-icon-size: 20px; background-color: rgb(242, 242, 242); + border-radius: 50%; color: var(--paper-grey-700); overflow: visible; @apply --shadow-elevation-2dp;
diff --git a/chrome/browser/resources/usb_internals/descriptor_panel.js b/chrome/browser/resources/usb_internals/descriptor_panel.js index f894ea5..baef3be 100644 --- a/chrome/browser/resources/usb_internals/descriptor_panel.js +++ b/chrome/browser/resources/usb_internals/descriptor_panel.js
@@ -8,9 +8,15 @@ */ cr.define('descriptor_panel', function() { + const INPUT_TYPE_DECIMAL_WITH_DROPDOWN = 0; + const INPUT_TYPE_HEX_BYTE = 1; + // Standard USB requests and descriptor types: const GET_DESCRIPTOR_REQUEST = 0x06; + const CONTROL_TRANSFER_DIRECTION_HOST_TO_DEVICE = 0; + const CONTROL_TRANSFER_DIRECTION_DEVICE_TO_HOST = 1; + const DEVICE_DESCRIPTOR_TYPE = 0x01; const CONFIGURATION_DESCRIPTOR_TYPE = 0x02; const STRING_DESCRIPTOR_TYPE = 0x03; @@ -408,12 +414,12 @@ } /** - * Checks if the status of a descriptor read indicates success. + * Checks if the status of a control transfer indicates success. * @param {number} status * @param {string} defaultMessage * @private */ - checkDescriptorGetSuccess_(status, defaultMessage) { + checkTransferSuccess_(status, defaultMessage) { let failReason = ''; switch (status) { case device.mojom.UsbTransferStatus.COMPLETED: @@ -465,6 +471,22 @@ } /** + * Shows an warning message. + * @param {string} message + * @private + */ + showWarn_(message) { + const warnTemplate = document.querySelector('#warn'); + + const clone = document.importNode(warnTemplate.content, true); + + const warnText = clone.querySelector('warn'); + warnText.textContent = message; + + this.rootElement_.prepend(clone); + } + + /** * Gets device descriptor of current device. * @return {!Uint8Array} * @private @@ -484,7 +506,7 @@ usbControlTransferParams, DEVICE_DESCRIPTOR_LENGTH, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the device descriptor.'); return new Uint8Array(response.data); @@ -621,7 +643,7 @@ usbControlTransferParams, CONFIGURATION_DESCRIPTOR_LENGTH, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the device configuration descriptor to determine ' + 'the total descriptor length.'); @@ -633,7 +655,7 @@ response = await this.usbDeviceProxy_.controlTransferIn( usbControlTransferParams, length, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the complete configuration descriptor.'); @@ -1008,7 +1030,7 @@ usbControlTransferParams, MAX_STRING_DESCRIPTOR_LENGTH, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the device string descriptor to determine ' + 'all supported languages.'); @@ -1071,7 +1093,7 @@ CONTROL_TRANSFER_TIMEOUT_MS); const languageCodeStr = parseLanguageCode(languageCode); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, `Failed to read the device string descriptor of index: ${ index}, language: ${languageCodeStr}.`); @@ -1208,12 +1230,13 @@ button.addEventListener('click', () => { this.clearView(); const index = Number.parseInt(this.indexInput_.value); - if (this.checkIndexValueValid_(index)) { + if (this.checkParamValid_(index, 'Index', 1, 255)) { if (languageCodeInput.value === 'All') { this.renderStringDescriptorForAllLanguages(index); } else { const languageCode = Number.parseInt(languageCodeInput.value); - if (this.checkLanguageCodeValueValid_(languageCode)) { + if (this.checkParamValid_( + languageCode, 'Language Code', 0, 65535)) { this.renderStringDescriptorForLanguageCode(index, languageCode); } } @@ -1231,36 +1254,6 @@ } /** - * Checks if the user input index is a valid uint8 number. - * @param {number} index - * @return {boolean} - * @private - */ - checkIndexValueValid_(index) { - // index is 8 bit. 0 is reserved to query all supported language codes. - if (Number.isNaN(index) || index < 1 || index > 255) { - this.showError_('Invalid Index.'); - return false; - } - return true; - } - - /** - * Checks if the user input language code is a valid uint16 number. - * @param {number} languageCode - * @return {boolean} - * @private - */ - checkLanguageCodeValueValid_(languageCode) { - if (Number.isNaN(languageCode) || languageCode < 0 || - languageCode > 65535) { - this.showError_('Invalid Language Code.'); - return false; - } - return true; - } - - /** * Gets the Binary device Object Store (BOS) descriptor of the current * device, which contains the WebUSB descriptor and Microsoft OS 2.0 * descriptor. @@ -1282,7 +1275,7 @@ usbControlTransferParams, BOS_DESCRIPTOR_HEADER_LENGTH, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the device BOS descriptor to determine ' + 'the total descriptor length.'); @@ -1294,7 +1287,7 @@ response = await this.usbDeviceProxy_.controlTransferIn( usbControlTransferParams, length, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the complete BOS descriptor.'); return new Uint8Array(response.data); @@ -1733,7 +1726,7 @@ usbControlTransferParams, MAX_URL_DESCRIPTOR_LENGTH, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( urlResponse.status, 'Failed to read the device URL descriptor.'); } catch (e) { this.showError_(e.message); @@ -1792,7 +1785,7 @@ usbControlTransferParams, msOs20DescriptorSetLength, CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the Microsoft OS 2.0 descriptor set.'); } catch (e) { @@ -1834,7 +1827,7 @@ const response = await this.usbDeviceProxy_.controlTransferOut( usbControlTransferParams, [], CONTROL_TRANSFER_TIMEOUT_MS); - this.checkDescriptorGetSuccess_( + this.checkTransferSuccess_( response.status, 'Failed to read the Microsoft OS 2.0 ' + 'descriptor alternate enumeration set.'); @@ -2552,6 +2545,340 @@ return offset; } + + /** + * Gets response of the given request. + * @param {!device.mojom.UsbControlTransferParams} usbControlTransferParams + * @param {number} length + * @param {number} direction + * @private + */ + async sendTestingRequest_(usbControlTransferParams, length, direction) { + try { + await this.usbDeviceProxy_.open(); + + if (direction === 'Device-to-Host') { + const response = await this.usbDeviceProxy_.controlTransferIn( + usbControlTransferParams, length, CONTROL_TRANSFER_TIMEOUT_MS); + this.checkTransferSuccess_( + response.status, 'Failed to send request.'); + this.renderTestingData_(new Uint8Array(response.data)); + } else if (direction === 'Host-to-Device') { + const dataString = this.rootElement_.querySelector('textarea').value; + + const data = []; + for (let i = 0; i < dataString.length; i += 2) { + data.push(Number.parseInt(dataString.substring(i, i + 2), 16)); + } + + const response = await this.usbDeviceProxy_.controlTransferOut( + usbControlTransferParams, new Uint8Array(data), + CONTROL_TRANSFER_TIMEOUT_MS); + this.checkTransferSuccess_( + response.status, 'Failed to send request.'); + } + } catch (e) { + this.showError_(e.message); + return; + } finally { + await this.usbDeviceProxy_.close(); + } + } + + /** + * Renders a view to display response data in hex format. + * @param {!Uint8Array} rawData + * @private + */ + async renderTestingData_(rawData) { + const displayElement = this.addNewDescriptorDisplayElement_(); + /** @type {!cr.ui.Tree} */ + const rawDataTreeRoot = displayElement.rawDataTreeRoot; + rawDataTreeRoot.style.display = 'none'; + /** @type {!HTMLElement} */ + const rawDataByteElement = displayElement.rawDataByteElement; + renderRawDataBytes(rawDataByteElement, rawData); + } + + /** + * Initializes the testing tool panel for input and query functionality. + */ + initialTestingToolPanel() { + this.showWarn_( + 'Warning: This tool can send arbitrary commands to the device. ' + + 'Invalid commands may cause unexpected results.'); + const inputTableRows = + this.rootElement_.querySelector('tbody').querySelectorAll('tr'); + const buttons = + this.rootElement_.querySelector('tbody').querySelectorAll('button'); + const dataInputArea = this.rootElement_.querySelector('textarea'); + dataInputArea.addEventListener('keypress', () => { + const index = dataInputArea.selectionStart; + dataInputArea.value = dataInputArea.value.substring(0, index) + + dataInputArea.value.substring(index + 1); + dataInputArea.selectionEnd = index; + }); + + const testingToolPanelInputTypeSelector = + this.rootElement_.querySelector('#input-type'); + testingToolPanelInputTypeSelector.addEventListener('change', () => { + this.clearView(); + const index = testingToolPanelInputTypeSelector.selectedIndex; + inputTableRows.forEach(row => row.hidden = true); + inputTableRows[index].hidden = false; + + const direction = getRequestTypeDirection(inputTableRows[index], index); + const length = getRequestLength(inputTableRows[index], index); + this.rootElement_.querySelector('#data-input-area').hidden = + (direction !== 'Host-to-Device'); + dataInputArea.value = '00'.repeat(length); + dataInputArea.maxLength = length * 2; + }); + + for (const [i, inputTableRow] of inputTableRows.entries()) { + let directionInputElement; + switch (i) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + directionInputElement = + inputTableRow.querySelector('#transfer-direction'); + break; + case INPUT_TYPE_HEX_BYTE: + directionInputElement = + inputTableRow.querySelector('#query-request-type'); + break; + } + directionInputElement.addEventListener('change', () => { + this.rootElement_.querySelector('#data-input-area').hidden = + (getRequestTypeDirection(inputTableRow, i) !== 'Host-to-Device'); + }); + + inputTableRow.querySelector('#query-length') + .addEventListener('blur', () => { + const length = getRequestLength(inputTableRow, i); + dataInputArea.value = '00'.repeat(length); + dataInputArea.maxLength = length * 2; + }); + } + + for (const [i, button] of buttons.entries()) { + button.addEventListener('click', () => { + this.clearView(); + + const direction = getRequestTypeDirection(inputTableRows[i], i); + const type = getRequestType(inputTableRows[i], i); + const recipient = getRequestTypeRecipient(inputTableRows[i], i); + const request = getRequestCode(inputTableRows[i], i); + const value = getRequestValue(inputTableRows[i], i); + const index = getRequestIndex(inputTableRows[i], i); + const dataLength = getRequestLength(inputTableRows[i], i); + + if (this.checkEnumParamValid_( + type, 'Transfer Type', device.mojom.UsbControlTransferType) && + this.checkEnumParamValid_( + recipient, 'Transfer Recipient', + device.mojom.UsbControlTransferRecipient) && + this.checkParamValid_(request, 'Transfer Request', 0, 255) && + this.checkParamValid_(value, 'wValue', 0, 65535) && + this.checkParamValid_(index, 'wIndex', 0, 65535) && + this.checkParamValid_(dataLength, 'Length', 0, 65535)) { + /** @type {!device.mojom.UsbControlTransferParams} */ + const usbControlTransferParams = { + type: device.mojom.UsbControlTransferType[type], + recipient: device.mojom.UsbControlTransferRecipient[recipient], + request, + value, + index, + }; + this.sendTestingRequest_( + usbControlTransferParams, dataLength, direction); + } + }); + } + } + + /** + * Checks if the user input is a valid number. + * @param {number} paramValue + * @param {string} paramName + * @param {number} min + * @param {number} max + * @return {boolean} + * @private + */ + checkParamValid_(paramValue, paramName, min, max) { + if (Number.isNaN(paramValue) || paramValue < min || paramValue > max) { + this.showError_(`Invalid ${paramName}.`); + return false; + } + return true; + } + + /** + * Checks if the user input for a enum field is valid. + * @param {string} enumString + * @param {string} paramName + * @param {!Object} enumObject + * @return {boolean} + * @private + */ + checkEnumParamValid_(enumString, paramName, enumObject) { + if (enumObject[enumString] !== undefined) { + return true; + } + this.showError_(`Invalid ${paramName}`); + return false; + } + } + + /** + * Get the USB control transfer type. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {string} + */ + function getRequestType(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return inputRow.querySelector('#transfer-type').value; + case INPUT_TYPE_HEX_BYTE: + const value = Number.parseInt( + inputRow.querySelector('#query-request-type').value, 16); + switch (value >> 5 & 0x03) { + case 0: + return 'STANDARD'; + case 1: + return 'CLASS'; + case 2: + return 'VENDOR'; + } + default: + return ''; + } + } + + /** + * Get the USB control transfer recipient. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {string} + */ + function getRequestTypeRecipient(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return inputRow.querySelector('#transfer-recipient').value; + case INPUT_TYPE_HEX_BYTE: + const value = Number.parseInt( + inputRow.querySelector('#query-request-type').value, 16); + switch (value & 0x1F) { + case 0: + return 'DEVICE'; + case 1: + return 'INTERFACE'; + case 2: + return 'ENDPOINT'; + case 3: + return 'OTHER'; + } + default: + return ''; + } + } + + /** + * Get the USB control transfer direction. 0 for device-to-host, 1 for + * host-to-device. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {number} + */ + function getRequestTypeDirection(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return inputRow.querySelector('#transfer-direction').value; + case INPUT_TYPE_HEX_BYTE: + const value = Number.parseInt( + inputRow.querySelector('#query-request-type').value, 16); + switch (value >> 7) { + case CONTROL_TRANSFER_DIRECTION_HOST_TO_DEVICE: + return 'Host-to-Device'; + case CONTROL_TRANSFER_DIRECTION_DEVICE_TO_HOST: + return 'Device-to-Host'; + } + default: + return 'Device-to-Host'; + } + } + + /** + * Get the USB control transfer request code. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {number} + */ + function getRequestCode(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return Number.parseInt(inputRow.querySelector('#query-request').value); + case INPUT_TYPE_HEX_BYTE: + return Number.parseInt( + inputRow.querySelector('#query-request').value, 16); + default: + return Number.NaN; + } + } + + /** + * Get the value of USB control transfer request wValue field. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {number} + */ + function getRequestValue(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return Number.parseInt(inputRow.querySelector('#query-value').value); + case INPUT_TYPE_HEX_BYTE: + return Number.parseInt( + inputRow.querySelector('#query-value').value, 16); + default: + return Number.NaN; + } + } + + /** + * Get the value of USB control transfer request wIndex field. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {number} + */ + function getRequestIndex(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return Number.parseInt(inputRow.querySelector('#query-index').value); + case INPUT_TYPE_HEX_BYTE: + return Number.parseInt( + inputRow.querySelector('#query-index').value, 16); + default: + return Number.NaN; + } + } + + /** + * Get the length of the data transferred during USB control transfer. + * @param {!HTMLElement} inputRow + * @param {number} inputType + * @return {number} + */ + function getRequestLength(inputRow, inputType) { + switch (inputType) { + case INPUT_TYPE_DECIMAL_WITH_DROPDOWN: + return Number.parseInt(inputRow.querySelector('#query-length').value); + case INPUT_TYPE_HEX_BYTE: + return Number.parseInt( + inputRow.querySelector('#query-length').value, 16); + default: + return Number.NaN; + } } /**
diff --git a/chrome/browser/resources/usb_internals/devices_page.js b/chrome/browser/resources/usb_internals/devices_page.js index f6196e0..84cf946 100644 --- a/chrome/browser/resources/usb_internals/devices_page.js +++ b/chrome/browser/resources/usb_internals/devices_page.js
@@ -225,6 +225,19 @@ bosDescriptorPanel.renderBosDescriptor(); } }); + + const testingToolPanelButton = + tabPanel.querySelector('#testing-tool-button'); + const testingToolElement = tabPanel.querySelector('.testing-tool-panel'); + const testingToolPanel = new descriptor_panel.DescriptorPanel( + usbDeviceProxy, testingToolElement); + testingToolPanel.initialTestingToolPanel(); + testingToolPanelButton.addEventListener('click', () => { + testingToolElement.hidden = !testingToolElement.hidden; + // Clear the panel before rendering new data. + testingToolPanel.clearView(); + }); + // window.deviceTabInitializedFn() provides a hook for the test suite to // perform test actions after the device tab query descriptors actions are // initialized.
diff --git a/chrome/browser/resources/usb_internals/usb_internals.css b/chrome/browser/resources/usb_internals/usb_internals.css index 393e91fe..670b0eb 100644 --- a/chrome/browser/resources/usb_internals/usb_internals.css +++ b/chrome/browser/resources/usb_internals/usb_internals.css
@@ -134,9 +134,29 @@ margin-inline-start: 16px; } +#input-type { + display: block; +} + +#testing-tool tr td select { + display: block; + width: 100%; +} + +textarea { + display: block; + font-family: monospace; +} + error { color: red; display: block; font-size: 16px; padding-inline-start: 20px; +} + +warn { + color: red; + display: block; + font-size: 24px; } \ No newline at end of file
diff --git a/chrome/browser/resources/usb_internals/usb_internals.html b/chrome/browser/resources/usb_internals/usb_internals.html index 1450f51..80cbf6a9 100644 --- a/chrome/browser/resources/usb_internals/usb_internals.html +++ b/chrome/browser/resources/usb_internals/usb_internals.html
@@ -166,6 +166,76 @@ </button> </div> <div class="bos-descriptor-panel" hidden></div> + <div class="descriptor-button"> + <button id="testing-tool-button">Testing Tool Panel</button> + </div> + <div class="testing-tool-panel" hidden> + <select id="input-type"> + <option label="Decimal with Dropdown Menu"></option> + <option label="Hex Bytes"></option> + </select> + <table class="styled-table"> + <thead> + <tr> + <th>bmRequestType</th> + <th>bRequest</th> + <th>wValue</th> + <th>wIndex</th> + <th>wLength</th> + </tr> + </thead> + <tbody id="testing-tool"> + <tr> + <td> + <select id="transfer-direction"> + <option label="Host-to-Device" value="Host-to-Device"> + </option> + <option label="Device-to-Host" value="Device-to-Host"> + </option> + </select> + <select id="transfer-type"> + <option label="Standard" value="STANDARD"></option> + <option label="Class" value="CLASS"></option> + <option label="Vendor" value="VENDOR"></option> + </select> + <select id="transfer-recipient"> + <option label="Device" value="DEVICE"></option> + <option label="Interface" value="INTERFACE"></option> + <option label="Endpoint" value="ENDPOINT"></option> + <option label="Other" value="OTHER"></option> + </select> + </td> + <td><input id="query-request" type="number" value="0"></td> + <td><input id="query-value" type="number" value="0"></td> + <td><input id="query-index" type="number" value="0"></td> + <td><input id="query-length" type="number" value="0"></td> + <td><button>Send</button></td> + </tr> + <tr hidden> + <td> + 0x<input id="query-request-type" type="number" placeholder="00"> + </td> + <td> + 0x<input id="query-request" type="number" placeholder="00"> + </td> + <td> + 0x<input id="query-value" type="number" placeholder="0000"> + </td> + <td> + 0x<input id="query-index" type="number" placeholder="0000"> + </td> + <td> + 0x<input id="query-length" type="number" placeholder="0000"> + </td> + <td><button>Send</button></td> + </tr> + </tbody> + </table> + <div id='data-input-area'> + Data (in Hex): + <textarea cols="31"></textarea> + </div> + </div> </tabpanel> </template> @@ -192,6 +262,10 @@ <error></error> </template> + <template id="warn"> + <warn></warn> + </template> + <template id="descriptor-panel-title"> <descriptorpaneltitle></descriptorpaneltitle> </template>
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 0f0ba6a..bbbab343 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -429,8 +429,7 @@ struct BookmarkBarView::DropLocation { DropLocation() - : index(-1), - operation(ui::DragDropTypes::DRAG_NONE), + : operation(ui::DragDropTypes::DRAG_NONE), on(false), button_type(DROP_BOOKMARK) {} @@ -440,7 +439,7 @@ } // Index into the model the drop is over. This is relative to the root node. - int index; + base::Optional<size_t> index; // Drop constants. int operation; @@ -634,8 +633,8 @@ } // Then check the bookmark buttons. - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - views::View* child = GetBookmarkButton(i); + for (size_t i = 0; i < bookmark_buttons_.size(); ++i) { + views::View* child = bookmark_buttons_[i]; if (!child->GetVisible()) break; if (child->bounds().Contains(adjusted_loc)) @@ -669,7 +668,7 @@ int index = model_->bookmark_bar_node()->GetIndexOf(node); if (index == -1 || !node->is_folder()) return nullptr; - return static_cast<views::MenuButton*>(GetBookmarkButton(index)); + return static_cast<views::MenuButton*>(bookmark_buttons_[size_t{index}]); } void BookmarkBarView::GetAnchorPositionForButton( @@ -844,19 +843,21 @@ if (model_->loaded() && model_->bookmark_bar_node()->child_count() > 0) { bool last_visible = x < max_x; - int button_count = GetBookmarkButtonCount(); - for (int i = 0; i <= button_count; ++i) { + size_t button_count = bookmark_buttons_.size(); + for (size_t i = 0; i <= button_count; ++i) { if (i == button_count) { // Add another button if there is room for it (and there is another // button to load). if (!last_visible || !model_->loaded() || - model_->bookmark_bar_node()->child_count() <= button_count) + model_->bookmark_bar_node()->children().size() <= button_count) break; InsertBookmarkButtonAtIndex( - CreateBookmarkButton(model_->bookmark_bar_node()->GetChild(i)), i); - button_count = GetBookmarkButtonCount(); + CreateBookmarkButton( + model_->bookmark_bar_node()->children()[i].get()), + i); + button_count = bookmark_buttons_.size(); } - views::View* child = GetBookmarkButton(i); + views::View* child = bookmark_buttons_[i]; gfx::Size pref = child->GetPreferredSize(); int next_x = x + pref.width() + bookmark_bar_button_padding; last_visible = next_x < max_x; @@ -875,9 +876,9 @@ overflow_button_->SetBounds(x, y, overflow_pref.width(), height); const bool show_overflow = model_->loaded() && - (model_->bookmark_bar_node()->child_count() > GetBookmarkButtonCount() || - (GetBookmarkButtonCount() > 0 && - !GetBookmarkButton(GetBookmarkButtonCount() - 1)->GetVisible())); + (model_->bookmark_bar_node()->children().size() > + bookmark_buttons_.size() || + (!bookmark_buttons_.empty() && !bookmark_buttons_.back()->GetVisible())); overflow_button_->SetVisible(show_overflow); x += overflow_pref.width(); @@ -918,17 +919,18 @@ View::PaintChildren(paint_info); if (drop_info_.get() && drop_info_->valid && - drop_info_->location.operation != 0 && drop_info_->location.index != -1 && + drop_info_->location.operation != 0 && + drop_info_->location.index.has_value() && drop_info_->location.button_type != DROP_OVERFLOW && !drop_info_->location.on) { - int index = drop_info_->location.index; - DCHECK(index <= GetBookmarkButtonCount()); + size_t index = drop_info_->location.index.value(); + DCHECK_LE(index, bookmark_buttons_.size()); int x = 0; int y = 0; int h = height(); - if (index == GetBookmarkButtonCount()) { + if (index == bookmark_buttons_.size()) { if (index != 0) - x = GetBookmarkButton(index - 1)->bounds().right(); + x = bookmark_buttons_[index - 1]->bounds().right(); else if (managed_bookmarks_button_->GetVisible()) x = managed_bookmarks_button_->bounds().right(); else if (apps_page_shortcut_->GetVisible()) @@ -936,11 +938,11 @@ else x = kBookmarkBarHorizontalMargin; } else { - x = GetBookmarkButton(index)->x(); + x = bookmark_buttons_[index]->x(); } - if (GetBookmarkButtonCount() > 0 && GetBookmarkButton(0)->GetVisible()) { - y = GetBookmarkButton(0)->y(); - h = GetBookmarkButton(0)->height(); + if (!bookmark_buttons_.empty() && bookmark_buttons_.front()->GetVisible()) { + y = bookmark_buttons_.front()->y(); + h = bookmark_buttons_.front()->height(); } // Since the drop indicator is painted directly onto the canvas, we must @@ -1025,12 +1027,14 @@ if (location.on || location.button_type == DROP_OVERFLOW || location.button_type == DROP_OTHER_FOLDER) { const BookmarkNode* node; - if (location.button_type == DROP_OTHER_FOLDER) + if (location.button_type == DROP_OTHER_FOLDER) { node = model_->other_node(); - else if (location.button_type == DROP_OVERFLOW) + } else if (location.button_type == DROP_OVERFLOW) { node = model_->bookmark_bar_node(); - else - node = model_->bookmark_bar_node()->GetChild(location.index); + } else { + node = + model_->bookmark_bar_node()->children()[location.index.value()].get(); + } StartShowFolderDropMenuTimer(node); } @@ -1045,7 +1049,7 @@ drop_info_->valid = false; - if (drop_info_->location.index != -1) { + if (drop_info_->location.index.has_value()) { // TODO(sky): optimize the paint region. SchedulePaint(); } @@ -1065,21 +1069,23 @@ (drop_info_->location.button_type == DROP_OTHER_FOLDER) ? model_->other_node() : model_->bookmark_bar_node(); - int index = drop_info_->location.index; - if (index != -1) { + if (drop_info_->location.index.has_value()) { // TODO(sky): optimize the SchedulePaint region. SchedulePaint(); } + const BookmarkNode* parent_node; + int index; if (drop_info_->location.button_type == DROP_OTHER_FOLDER) { parent_node = root; index = parent_node->child_count(); } else if (drop_info_->location.on) { - parent_node = root->GetChild(index); + parent_node = root->children()[drop_info_->location.index.value()].get(); index = parent_node->child_count(); } else { parent_node = root; + index = int{drop_info_->location.index.value()}; } const BookmarkNodeData data = drop_info_->data; DCHECK(data.is_valid()); @@ -1151,7 +1157,7 @@ // There should be no buttons. If non-zero it means Load was invoked more than // once, or we didn't properly clear things. Either of which shouldn't happen. // The actual bookmark buttons are added from Layout(). - DCHECK_EQ(0, GetBookmarkButtonCount()); + DCHECK(bookmark_buttons_.empty()); DCHECK(model->other_node()); other_bookmarks_button_->SetAccessibleName(model->other_node()->GetTitle()); other_bookmarks_button_->SetText(model->other_node()->GetTitle()); @@ -1186,7 +1192,7 @@ BookmarkNodeRemovedImpl(model, old_parent, old_index); if (BookmarkNodeAddedImpl(model, new_parent, new_index)) needs_layout_and_paint = true; - if (was_throbbing && new_index < GetBookmarkButtonCount()) + if (was_throbbing && new_index < int{bookmark_buttons_.size()}) StartThrobbing(new_parent->GetChild(new_index), false); if (needs_layout_and_paint) LayoutAndPaint(); @@ -1244,7 +1250,7 @@ bookmark_buttons_.clear(); // Create the new buttons. - for (int i = 0, child_count = node->child_count(); i < child_count; ++i) + for (int i = 0; i < node->child_count(); ++i) InsertBookmarkButtonAtIndex(CreateBookmarkButton(node->GetChild(i)), i); LayoutAndPaint(); @@ -1260,28 +1266,22 @@ ui::OSExchangeData* data) { base::RecordAction(UserMetricsAction("BookmarkBar_DragButton")); - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); - gfx::ImageSkia icon; - views::Widget* widget = sender->GetWidget(); - if (node->is_url()) { - const gfx::Image& image = model_->GetFavicon(node); - icon = image.IsEmpty() ? favicon::GetDefaultFavicon().AsImageSkia() - : image.AsImageSkia(); - } else { - icon = chrome::GetBookmarkFolderIcon( - widget->GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_LabelEnabledColor)); - } - - button_drag_utils::SetDragImage(node->url(), node->GetTitle(), icon, - &press_pt, *widget, data); - WriteBookmarkDragData(node, data); - return; - } + const auto* node = GetNodeForSender(sender); + gfx::ImageSkia icon; + views::Widget* widget = sender->GetWidget(); + if (node->is_url()) { + const gfx::Image& image = model_->GetFavicon(node); + icon = image.IsEmpty() ? favicon::GetDefaultFavicon().AsImageSkia() + : image.AsImageSkia(); + } else { + icon = + chrome::GetBookmarkFolderIcon(widget->GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_LabelEnabledColor)); } - NOTREACHED(); + + button_drag_utils::SetDragImage(node->url(), node->GetTitle(), icon, + &press_pt, *widget, data); + WriteBookmarkDragData(node, data); } int BookmarkBarView::GetDragOperationsForView(View* sender, @@ -1295,14 +1295,8 @@ return ui::DragDropTypes::DRAG_NONE; } - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - return chrome::GetBookmarkDragOperation( - browser_->profile(), model_->bookmark_bar_node()->GetChild(i)); - } - } - NOTREACHED(); - return ui::DragDropTypes::DRAG_NONE; + return chrome::GetBookmarkDragOperation(browser_->profile(), + GetNodeForSender(sender)); } bool BookmarkBarView::CanStartDragForView(views::View* sender, @@ -1313,18 +1307,11 @@ gfx::Vector2d move_offset = p - press_pt; gfx::Vector2d horizontal_offset(move_offset.x(), 0); if (!View::ExceededDragThreshold(horizontal_offset) && move_offset.y() > 0) { - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - if (sender == GetBookmarkButton(i)) { - const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(i); - // If the folder button was dragged, show the menu instead. - if (node && node->is_folder()) { - views::MenuButton* menu_button = - static_cast<views::MenuButton*>(sender); - menu_button->Activate(nullptr); - return false; - } - break; - } + // If the folder button was dragged, show the menu instead. + const auto* node = GetNodeForSender(sender); + if (node->is_folder()) { + static_cast<views::MenuButton*>(sender)->Activate(nullptr); + return false; } } return true; @@ -1420,8 +1407,8 @@ // clicked on, except for the apps page shortcut, which must behave as if // the user clicked on the bookmark bar background. int bookmark_button_index = GetIndexForButton(source); - DCHECK(bookmark_button_index != -1 && - bookmark_button_index < GetBookmarkButtonCount()); + DCHECK_NE(-1, bookmark_button_index); + DCHECK_LT(size_t{bookmark_button_index}, bookmark_buttons_.size()); const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(bookmark_button_index); nodes.push_back(node); @@ -1494,27 +1481,15 @@ } } -int BookmarkBarView::GetBookmarkButtonCount() const { - return bookmark_buttons_.size(); -} - -views::LabelButton* BookmarkBarView::GetBookmarkButton(int index) { - // CHECK as otherwise we may do the wrong cast. - CHECK(index >= 0 && index < GetBookmarkButtonCount()); - return bookmark_buttons_[index]; -} - BookmarkLaunchLocation BookmarkBarView::GetBookmarkLaunchLocation() const { return BOOKMARK_LAUNCH_LOCATION_ATTACHED_BAR; } int BookmarkBarView::GetFirstHiddenNodeIndex() { - const int bb_count = GetBookmarkButtonCount(); - for (int i = 0; i < bb_count; ++i) { - if (!GetBookmarkButton(i)->GetVisible()) - return i; - } - return bb_count; + const auto i = + std::find_if(bookmark_buttons_.cbegin(), bookmark_buttons_.cend(), + [](const auto* button) { return !button->GetVisible(); }); + return i - bookmark_buttons_.cbegin(); } MenuButton* BookmarkBarView::CreateOtherBookmarksButton() { @@ -1637,7 +1612,7 @@ const bool needs_layout_and_paint = UpdateOtherAndManagedButtonsVisibility(); if (parent != model->bookmark_bar_node()) return needs_layout_and_paint; - if (index < GetBookmarkButtonCount()) { + if (index < int{bookmark_buttons_.size()}) { const BookmarkNode* node = parent->GetChild(index); InsertBookmarkButtonAtIndex(CreateBookmarkButton(node), index); return true; @@ -1645,7 +1620,7 @@ // If the new node was added after the last button we've created we may be // able to fit it. Assume we can by returning true, which forces a Layout() // and creation of the button (if it fits). - return index == GetBookmarkButtonCount(); + return index == int{bookmark_buttons_.size()}; } bool BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model, @@ -1661,10 +1636,10 @@ // Only children of the bookmark_bar_node get buttons. return needs_layout; } - if (index >= GetBookmarkButtonCount()) + if (size_t{index} >= bookmark_buttons_.size()) return needs_layout; - views::LabelButton* button = GetBookmarkButton(index); + views::LabelButton* button = bookmark_buttons_[size_t{index}]; bookmark_buttons_.erase(bookmark_buttons_.cbegin() + index); delete button; return true; @@ -1686,9 +1661,9 @@ } int index = model->bookmark_bar_node()->GetIndexOf(node); DCHECK_NE(-1, index); - if (index >= GetBookmarkButtonCount()) + if (size_t{index} >= bookmark_buttons_.size()) return; // Buttons are created as needed. - views::LabelButton* button = GetBookmarkButton(index); + views::LabelButton* button = bookmark_buttons_[size_t{index}]; const int old_pref_width = button->GetPreferredSize().width(); ConfigureButton(node, button); if (old_pref_width != button->GetPreferredSize().width()) @@ -1766,7 +1741,7 @@ location->button_type = DROP_OTHER_FOLDER; location->on = true; found = true; - } else if (!GetBookmarkButtonCount()) { + } else if (bookmark_buttons_.empty()) { // No bookmarks, accept the drop. location->index = 0; const BookmarkNode* node = data.GetFirstNode(model_, profile->GetPath()); @@ -1778,10 +1753,10 @@ return; } - for (int i = 0; i < GetBookmarkButtonCount() && - GetBookmarkButton(i)->GetVisible() && !found; + for (size_t i = 0; i < bookmark_buttons_.size() && + bookmark_buttons_[i]->GetVisible() && !found; i++) { - views::LabelButton* button = GetBookmarkButton(i); + views::LabelButton* button = bookmark_buttons_[i]; int button_x = mirrored_x - button->x(); int button_w = button->width(); if (button_x < button_w) { @@ -1832,10 +1807,11 @@ } if (location->on) { - const BookmarkNode* parent = - (location->button_type == DROP_OTHER_FOLDER) - ? model_->other_node() - : model_->bookmark_bar_node()->GetChild(location->index); + const BookmarkNode* parent = (location->button_type == DROP_OTHER_FOLDER) + ? model_->other_node() + : model_->bookmark_bar_node() + ->children()[location->index.value()] + .get(); location->operation = chrome::GetBookmarkDropOperation( profile, event, data, parent, parent->child_count()); if (!location->operation && !data.has_single_url() && @@ -1845,10 +1821,19 @@ } } else { location->operation = chrome::GetBookmarkDropOperation( - profile, event, data, model_->bookmark_bar_node(), location->index); + profile, event, data, model_->bookmark_bar_node(), + location->index.value()); } } +const BookmarkNode* BookmarkBarView::GetNodeForSender(View* sender) const { + const auto i = + std::find(bookmark_buttons_.cbegin(), bookmark_buttons_.cend(), sender); + DCHECK(i != bookmark_buttons_.cend()); + size_t child = i - bookmark_buttons_.cbegin(); + return model_->bookmark_bar_node()->children()[child].get(); +} + void BookmarkBarView::WriteBookmarkDragData(const BookmarkNode* node, ui::OSExchangeData* data) { DCHECK(node && data); @@ -1876,7 +1861,7 @@ // Node is hidden, animate the overflow button. throbbing_view_ = overflow_button_; } else if (!overflow_only) { - throbbing_view_ = static_cast<Button*>(GetBookmarkButton(index)); + throbbing_view_ = static_cast<Button*>(bookmark_buttons_[size_t{index}]); } } else if (bookmarks::IsDescendantOf(node, managed_->managed_node())) { throbbing_view_ = managed_bookmarks_button_; @@ -1908,7 +1893,7 @@ // Node is hidden, animate the overflow button. return overflow_button_; } - return static_cast<Button*>(GetBookmarkButton(old_index_on_bb)); + return static_cast<Button*>(bookmark_buttons_[size_t{old_index_on_bb}]); } if (bookmarks::IsDescendantOf(parent, managed_->managed_node())) return managed_bookmarks_button_; @@ -1921,9 +1906,9 @@ const ui::ThemeProvider* theme_provider = GetThemeProvider(); if (!theme_provider) return; - for (int i = 0; i < GetBookmarkButtonCount(); ++i) { - ConfigureButton(model_->bookmark_bar_node()->GetChild(i), - GetBookmarkButton(i)); + for (size_t i = 0; i < bookmark_buttons_.size(); ++i) { + ConfigureButton(model_->bookmark_bar_node()->children()[i].get(), + bookmark_buttons_[i]); } const SkColor color = GetBookmarkBarTextColor();
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h index b25c170f..c596fbe 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -253,23 +253,13 @@ // calculating the preferred height. void Init(); - // NOTE: unless otherwise stated all methods that take an int for an index are - // in terms of the bookmark bar view. Typically the view index and model index - // are the same, but they may differ during animations or drag and drop. + // NOTE: unless otherwise stated all methods that take an index are in terms + // of the bookmark bar view. Typically the view index and model index are the + // same, but they may differ during animations or drag and drop. // // It's easy to get the mapping wrong. For this reason all these methods are // private. - // Returns the number of bookmark bar url/folder buttons that have been - // created. This does not necessarily represent the number of bookmark bar - // nodes, nor the number of visible bookmark bar buttons. Buttons are created - // lazily to fill available space, and may be hidden for ordering or sizing - // changes. - int GetBookmarkButtonCount() const; - - // Returns the button at the specified index. - views::LabelButton* GetBookmarkButton(int index); - // Returns BOOKMARK_LAUNCH_LOCATION_DETACHED_BAR or // BOOKMARK_LAUNCH_LOCATION_ATTACHED_BAR based on detached node_data. BookmarkLaunchLocation GetBookmarkLaunchLocation() const; @@ -329,6 +319,10 @@ const bookmarks::BookmarkNodeData& data, DropLocation* location); + // Returns the node corresponding to |sender|, which is one of the + // |bookmark_buttons_|. + const bookmarks::BookmarkNode* GetNodeForSender(View* sender) const; + // Writes a BookmarkNodeData for node to data. void WriteBookmarkDragData(const bookmarks::BookmarkNode* node, ui::OSExchangeData* data);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc index 52d1af1..ae02766 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -368,12 +368,12 @@ size.set_width(size.width() - 25); bb_view_->SetBounds(0, 0, size.width(), size.height()); bb_view_->Layout(); - } while (bb_view_->GetBookmarkButton(6)->GetVisible()); + } while (bb_view_->bookmark_buttons_[6]->GetVisible()); return size; } - views::LabelButton* GetBookmarkButton(int view_index) { - return bb_view_->GetBookmarkButton(view_index); + views::LabelButton* GetBookmarkButton(size_t view_index) { + return bb_view_->bookmark_buttons_[view_index]; } // See comment above class description for what this does.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h index 8420c51c..060645d 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h
@@ -14,10 +14,10 @@ explicit BookmarkBarViewTestHelper(BookmarkBarView* bbv) : bbv_(bbv) {} ~BookmarkBarViewTestHelper() {} - int GetBookmarkButtonCount() { return bbv_->GetBookmarkButtonCount(); } + size_t GetBookmarkButtonCount() { return bbv_->bookmark_buttons_.size(); } - views::LabelButton* GetBookmarkButton(int index) { - return bbv_->GetBookmarkButton(index); + views::LabelButton* GetBookmarkButton(size_t index) { + return bbv_->bookmark_buttons_[index]; } views::LabelButton* apps_page_shortcut() { return bbv_->apps_page_shortcut_; }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc index 26161f6b..e6d5547 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -54,8 +54,8 @@ // the bookmark bar. Each label is separated by a space. std::string GetStringForVisibleButtons() { std::string result; - for (int i = 0; i < test_helper_->GetBookmarkButtonCount() && - test_helper_->GetBookmarkButton(i)->GetVisible(); + for (size_t i = 0; i < test_helper_->GetBookmarkButtonCount() && + test_helper_->GetBookmarkButton(i)->GetVisible(); ++i) { if (i != 0) result += " "; @@ -69,7 +69,7 @@ // visible. // NOTE: if the model has more than |count| buttons this results in // |count| + 1 buttons. - void SizeUntilButtonsVisible(int count) { + void SizeUntilButtonsVisible(size_t count) { const int start_width = bookmark_bar_view_->width(); const int height = bookmark_bar_view_->GetPreferredSize().height(); for (int i = 0; @@ -173,7 +173,7 @@ EXPECT_TRUE(test_helper_->overflow_button()->GetVisible()); SizeUntilButtonsVisible(1); - EXPECT_EQ(2, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(2u, test_helper_->GetBookmarkButtonCount()); const int width_for_one = bookmark_bar_view_->bounds().width(); EXPECT_TRUE(test_helper_->overflow_button()->GetVisible()); @@ -181,7 +181,7 @@ bookmark_bar_view_->SetBounds( 0, 0, 5000, bookmark_bar_view_->bounds().height()); bookmark_bar_view_->Layout(); - EXPECT_EQ(6, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(6u, test_helper_->GetBookmarkButtonCount()); EXPECT_FALSE(test_helper_->overflow_button()->GetVisible()); bookmark_bar_view_->SetBounds( @@ -198,21 +198,21 @@ EXPECT_TRUE(BookmarkModelFactory::GetForBrowserContext(profile())->loaded()); AddNodesToBookmarkBarFromModelString("a b c d e f "); CreateBookmarkBarView(); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); SizeUntilButtonsVisible(1); - EXPECT_EQ(2, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(2u, test_helper_->GetBookmarkButtonCount()); // Go really big, which should force all buttons to be added. bookmark_bar_view_->SetBounds( 0, 0, 5000, bookmark_bar_view_->bounds().height()); bookmark_bar_view_->Layout(); - EXPECT_EQ(6, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(6u, test_helper_->GetBookmarkButtonCount()); // Ensure buttons were added in the correct place. auto button_iter = bookmark_bar_view_->FindChild(test_helper_->managed_bookmarks_button()); - for (int i = 0; i < test_helper_->GetBookmarkButtonCount(); ++i) { + for (size_t i = 0; i < test_helper_->GetBookmarkButtonCount(); ++i) { ++button_iter; ASSERT_NE(bookmark_bar_view_->children().cend(), button_iter); EXPECT_EQ(test_helper_->GetBookmarkButton(i), *button_iter); @@ -224,19 +224,19 @@ CreateBookmarkModelAndBookmarkBarView(); EXPECT_TRUE(BookmarkModelFactory::GetForBrowserContext(profile())->loaded()); AddNodesToBookmarkBarFromModelString("a b c d e f "); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); SizeUntilButtonsVisible(1); - EXPECT_EQ(2, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(2u, test_helper_->GetBookmarkButtonCount()); // Go really big, which should force all buttons to be added. bookmark_bar_view_->SetBounds( 0, 0, 5000, bookmark_bar_view_->bounds().height()); bookmark_bar_view_->Layout(); - EXPECT_EQ(6, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(6u, test_helper_->GetBookmarkButtonCount()); // Ensure buttons were added in the correct place. auto button_iter = bookmark_bar_view_->FindChild(test_helper_->managed_bookmarks_button()); - for (int i = 0; i < test_helper_->GetBookmarkButtonCount(); ++i) { + for (size_t i = 0; i < test_helper_->GetBookmarkButtonCount(); ++i) { ++button_iter; ASSERT_NE(bookmark_bar_view_->children().cend(), button_iter); EXPECT_EQ(test_helper_->GetBookmarkButton(i), *button_iter); @@ -258,9 +258,9 @@ BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile()); const BookmarkNode* bookmark_bar_node = model->bookmark_bar_node(); AddNodesToBookmarkBarFromModelString("a b c d e f "); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); SizeUntilButtonsVisible(1); - EXPECT_EQ(2, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(2u, test_helper_->GetBookmarkButtonCount()); // Remove the 2nd node, should still only have 1 visible. model->Remove(bookmark_bar_node->GetChild(1)); @@ -277,11 +277,11 @@ BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile()); const BookmarkNode* bookmark_bar_node = model->bookmark_bar_node(); AddNodesToBookmarkBarFromModelString("a b c d e f "); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); // Move 'c' first resulting in 'c a b d e f'. model->Move(bookmark_bar_node->GetChild(2), bookmark_bar_node, 0); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); // Make enough room for 1 node. SizeUntilButtonsVisible(1); @@ -309,10 +309,10 @@ BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile()); const BookmarkNode* bookmark_bar_node = model->bookmark_bar_node(); AddNodesToBookmarkBarFromModelString("a b c d e f "); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); model->SetTitle(bookmark_bar_node->GetChild(0), base::ASCIIToUTF16("a1")); - EXPECT_EQ(0, test_helper_->GetBookmarkButtonCount()); + EXPECT_EQ(0u, test_helper_->GetBookmarkButtonCount()); // Make enough room for 1 node. SizeUntilButtonsVisible(1); @@ -332,13 +332,13 @@ EXPECT_EQ("a1 b1", GetStringForVisibleButtons()); model->SetTitle(bookmark_bar_node->GetChild(0), base::ASCIIToUTF16("a_really_long_title")); - EXPECT_LE(1, test_helper_->GetBookmarkButtonCount()); + EXPECT_LE(1u, test_helper_->GetBookmarkButtonCount()); // Change the title back and make sure the 2nd button is visible again. Don't // use GetStringForVisibleButtons() here as more buttons may have been // created. model->SetTitle(bookmark_bar_node->GetChild(0), base::ASCIIToUTF16("a1")); - ASSERT_LE(2, test_helper_->GetBookmarkButtonCount()); + ASSERT_LE(2u, test_helper_->GetBookmarkButtonCount()); EXPECT_TRUE(test_helper_->GetBookmarkButton(0)->GetVisible()); EXPECT_TRUE(test_helper_->GetBookmarkButton(1)->GetVisible()); @@ -394,7 +394,7 @@ bookmarks::test::AddNodesFromModelString(model, model->bookmark_bar_node(), "a b"); SizeUntilButtonsVisible(1); - ASSERT_EQ(1, test_helper_->GetBookmarkButtonCount()); + ASSERT_EQ(1u, test_helper_->GetBookmarkButtonCount()); views::LabelButton* button = test_helper_->GetBookmarkButton(0); ASSERT_TRUE(button);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index 388df3a..a3695b93 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -558,9 +558,15 @@ void PageInfoBubbleView::OnWidgetDestroying(views::Widget* widget) { PageInfoBubbleViewBase::OnWidgetDestroying(widget); + bool reload_prompt; presenter_->OnUIClosing(&reload_prompt); - std::move(closing_callback_).Run(widget->closed_reason(), reload_prompt); + + // This method mostly shouldn't be re-entrant but there are a few cases where + // it can be (see crbug/966308). In that case, we have already run the closing + // callback so should not attempt to do it again. + if (closing_callback_) + std::move(closing_callback_).Run(widget->closed_reason(), reload_prompt); } void PageInfoBubbleView::ButtonPressed(views::Button* button,
diff --git a/chrome/common/prerender_messages.h b/chrome/common/prerender_messages.h index 0c00cc89..ca7d57d 100644 --- a/chrome/common/prerender_messages.h +++ b/chrome/common/prerender_messages.h
@@ -15,6 +15,7 @@ #include "ui/gfx/geometry/size.h" #include "url/gurl.h" #include "url/ipc/url_param_traits.h" +#include "url/origin.h" #define IPC_MESSAGE_START PrerenderMsgStart @@ -32,12 +33,13 @@ // Notifies of the insertion of a <link rel=prerender> element in the // document. -IPC_MESSAGE_CONTROL5(PrerenderHostMsg_AddLinkRelPrerender, - int /* prerender_id, assigned by WebPrerendererClient */, - PrerenderAttributes, - content::Referrer, - gfx::Size, - int /* render_view_route_id of launcher */) +IPC_MESSAGE_CONTROL(PrerenderHostMsg_AddLinkRelPrerender, + int /* prerender_id, assigned by WebPrerendererClient */, + PrerenderAttributes, + content::Referrer, + url::Origin /* initiator_origin */, + gfx::Size, + int /* render_view_route_id of launcher */) // Notifies on removal of a <link rel=prerender> element from the document. IPC_MESSAGE_CONTROL1(PrerenderHostMsg_CancelLinkRelPrerender,
diff --git a/chrome/renderer/prerender/prerender_dispatcher.cc b/chrome/renderer/prerender/prerender_dispatcher.cc index f1ca010..a259c667 100644 --- a/chrome/renderer/prerender/prerender_dispatcher.cc +++ b/chrome/renderer/prerender/prerender_dispatcher.cc
@@ -22,6 +22,7 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "url/gurl.h" +#include "url/origin.h" namespace prerender { @@ -164,7 +165,8 @@ GURL(prerender.Url()), content::Referrer(blink::WebStringToGURL(prerender.GetReferrer()), prerender.GetReferrerPolicy())), - extra_data.size(), extra_data.render_view_route_id())); + prerender.SecurityOrigin(), extra_data.size(), + extra_data.render_view_route_id())); } void PrerenderDispatcher::Cancel(const WebPrerender& prerender) {
diff --git a/chrome/test/data/webui/cr_elements/cr_radio_button_test.js b/chrome/test/data/webui/cr_elements/cr_radio_button_test.js index fddfcecd..d6ea3a8 100644 --- a/chrome/test/data/webui/cr_elements/cr_radio_button_test.js +++ b/chrome/test/data/webui/cr_elements/cr_radio_button_test.js
@@ -67,7 +67,7 @@ radioButton.fire('focus'); assertTrue(!!radioButton.$$('paper-ripple')); assertTrue(radioButton.$$('paper-ripple').holdDown); - radioButton.fire('pointerup'); + radioButton.fire('up'); assertFalse(radioButton.$$('paper-ripple').holdDown); }); });
diff --git a/chrome/test/data/webui/extensions/kiosk_mode_test.js b/chrome/test/data/webui/extensions/kiosk_mode_test.js index b7a634cc5..ff47705 100644 --- a/chrome/test/data/webui/extensions/kiosk_mode_test.js +++ b/chrome/test/data/webui/extensions/kiosk_mode_test.js
@@ -100,8 +100,8 @@ expectTrue(items[0].querySelector('span').hidden); expectFalse(items[1].querySelector('span').hidden); // No permission to edit auto-launch so buttons should be hidden. - expectTrue(items[0].querySelector('paper-button').hidden); - expectTrue(items[1].querySelector('paper-button').hidden); + expectTrue(items[0].querySelector('cr-button').hidden); + expectTrue(items[1].querySelector('cr-button').hidden); // Bailout checkbox should be hidden when auto-launch editing // disabled. expectTrue(dialog.$$('cr-checkbox').hidden); @@ -125,7 +125,7 @@ return initPage() .then(() => { buttons = - dialog.shadowRoot.querySelectorAll('.list-item paper-button'); + dialog.shadowRoot.querySelectorAll('.list-item cr-button'); // Has permission to edit auto-launch so buttons should be seen. expectFalse(buttons[0].hidden); expectFalse(buttons[1].hidden);
diff --git a/chrome/test/media_router/BUILD.gn b/chrome/test/media_router/BUILD.gn index 5950a99..cddd27a0 100644 --- a/chrome/test/media_router/BUILD.gn +++ b/chrome/test/media_router/BUILD.gn
@@ -156,17 +156,7 @@ "//tools/perf:perf", ] data_deps = [ - ":telemetry_extension_resources", + "//tools/perf/contrib/media_router_benchmarks:telemetry_extension_resources", ] } } - -copy("telemetry_extension_resources") { - sources = [ - "telemetry/extension/manifest.json", - "telemetry/extension/script.js", - ] - outputs = [ - "$root_out_dir/media_router/telemetry_extension/{{source_file_part}}", - ] -}
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 6ecc39c5..123fde0 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -12234.0.0 \ No newline at end of file +12242.0.0 \ No newline at end of file
diff --git a/components/omnibox/browser/contextual_suggestions_service.cc b/components/omnibox/browser/contextual_suggestions_service.cc index 9cec318..ec9f858f 100644 --- a/components/omnibox/browser/contextual_suggestions_service.cc +++ b/components/omnibox/browser/contextual_suggestions_service.cc
@@ -89,7 +89,7 @@ // stream_type = 1 corresponds to zero suggest suggestions. request->SetInteger("stream_type", 1); const int experiment_id = - OmniboxFieldTrial::GetZeroSuggestRedirectToChromeExperimentId(); + OmniboxFieldTrial::GetOnFocusSuggestionsCustomEndpointExperimentId(); if (experiment_id >= 0) request->SetInteger("experiment_id", experiment_id); std::string result; @@ -176,7 +176,8 @@ return GURL(); } - if (!base::FeatureList::IsEnabled(omnibox::kZeroSuggestRedirectToChrome)) { + if (!base::FeatureList::IsEnabled( + omnibox::kOnFocusSuggestionsCustomEndpoint)) { return GURL(); } @@ -191,16 +192,16 @@ } const std::string server_address_param = - OmniboxFieldTrial::GetZeroSuggestRedirectToChromeServerAddress(); + OmniboxFieldTrial::GetOnFocusSuggestionsCustomEndpointURL(); GURL suggest_url(server_address_param.empty() ? kDefaultExperimentalServerAddress : server_address_param); - // Check that the suggest URL for redirect to chrome field trial is valid. + // Check that the custom endpoint URL is valid. if (!suggest_url.is_valid()) { return GURL(); } - // Check that the suggest URL for redirect to chrome is HTTPS. + // Check that the custom endpoint URL is HTTPS. if (!suggest_url.SchemeIsCryptographic()) { return GURL(); }
diff --git a/components/omnibox/browser/contextual_suggestions_service.h b/components/omnibox/browser/contextual_suggestions_service.h index d75b0e7..eaab5ee 100644 --- a/components/omnibox/browser/contextual_suggestions_service.h +++ b/components/omnibox/browser/contextual_suggestions_service.h
@@ -31,7 +31,16 @@ class SimpleURLLoader; } // namespace network -// A service to fetch suggestions from a remote endpoint given a URL. +// A service to fetch suggestions from a remote endpoint. Usually, the remote +// endpoint is the default search provider's suggest service. However, the +// endpoint URL can be customized by field trial. +// +// This service is always sent the user's authentication state, so the +// suggestions always can be personalized. This service is also sometimes sent +// the user's current URL, so the suggestions are sometimes also contextual. +// +// TODO(tommycli): Probably we should just rename this RemoteSuggestionsService, +// as the suggestions are not always contextual. class ContextualSuggestionsService : public KeyedService { public: // |identity_manager| may be null but only unauthenticated requests will
diff --git a/components/omnibox/browser/contextual_suggestions_service_unittest.cc b/components/omnibox/browser/contextual_suggestions_service_unittest.cc index 24c15aa..5caac0aa 100644 --- a/components/omnibox/browser/contextual_suggestions_service_unittest.cc +++ b/components/omnibox/browser/contextual_suggestions_service_unittest.cc
@@ -49,7 +49,7 @@ TEST_F(ContextualSuggestionsServiceTest, EnsureAttachCookies) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature( - omnibox::kZeroSuggestRedirectToChrome); + omnibox::kOnFocusSuggestionsCustomEndpoint); network::ResourceRequest resource_request; test_url_loader_factory_.SetInterceptor(
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index 3baed92..1d09030 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -258,18 +258,18 @@ } // static -int OmniboxFieldTrial::GetZeroSuggestRedirectToChromeExperimentId() { +int OmniboxFieldTrial::GetOnFocusSuggestionsCustomEndpointExperimentId() { return base::GetFieldTrialParamByFeatureAsInt( - omnibox::kZeroSuggestRedirectToChrome, - kZeroSuggestRedirectToChromeExperimentIdParam, + omnibox::kOnFocusSuggestionsCustomEndpoint, + kOnFocusSuggestionsEndpointExperimentIdParam, /*default_value=*/-1); } // static -std::string OmniboxFieldTrial::GetZeroSuggestRedirectToChromeServerAddress() { +std::string OmniboxFieldTrial::GetOnFocusSuggestionsCustomEndpointURL() { return base::GetFieldTrialParamValueByFeature( - omnibox::kZeroSuggestRedirectToChrome, - kZeroSuggestRedirectToChromeServerAddressParam); + omnibox::kOnFocusSuggestionsCustomEndpoint, + kOnFocusSuggestionsEndpointURLParam); } bool OmniboxFieldTrial::ShortcutsScoringMaxRelevance( @@ -806,10 +806,10 @@ const char OmniboxFieldTrial::kSimplifyHttpsIndicatorParameterKeepSecureChip[] = "keep-secure-chip"; -const char OmniboxFieldTrial::kZeroSuggestRedirectToChromeExperimentIdParam[] = - "ZeroSuggestRedirectToChromeExperimentID"; -const char OmniboxFieldTrial::kZeroSuggestRedirectToChromeServerAddressParam[] = - "ZeroSuggestRedirectToChromeServerAddress"; +const char OmniboxFieldTrial::kOnFocusSuggestionsEndpointExperimentIdParam[] = + "CustomEndpointExperimentID"; +const char OmniboxFieldTrial::kOnFocusSuggestionsEndpointURLParam[] = + "CustomEndpointURL"; // static int OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs = 100;
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index dfc9389..da99015 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -177,14 +177,14 @@ metrics::OmniboxEventProto::PageClassification page_classification); // --------------------------------------------------------- -// For the Zero Suggest Redirect to Chrome field trial. +// For the On Focus Suggestions Custom Endpoint field trial. // Returns the server-side experiment ID to use for contextual suggestions. // Returns -1 if there is no associated experiment ID. -int GetZeroSuggestRedirectToChromeExperimentId(); +int GetOnFocusSuggestionsCustomEndpointExperimentId(); // Returns the server address associated with the current field trial. -std::string GetZeroSuggestRedirectToChromeServerAddress(); +std::string GetOnFocusSuggestionsCustomEndpointURL(); // --------------------------------------------------------- // For the ShortcutsScoringMaxRelevance experiment that's part of the @@ -512,9 +512,9 @@ extern const char kSimplifyHttpsIndicatorParameterBothToLock[]; extern const char kSimplifyHttpsIndicatorParameterKeepSecureChip[]; -// Parameter names used by Zero Suggest Redirect to Chrome. -extern const char kZeroSuggestRedirectToChromeExperimentIdParam[]; -extern const char kZeroSuggestRedirectToChromeServerAddressParam[]; +// Parameter names used by On Focus Suggestions Custom Endpoint. +extern const char kOnFocusSuggestionsEndpointExperimentIdParam[]; +extern const char kOnFocusSuggestionsEndpointURLParam[]; // The amount of time to wait before sending a new suggest request after the // previous one unless overridden by a field trial parameter.
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc index 60d12d4..3f98b03 100644 --- a/components/omnibox/browser/zero_suggest_provider.cc +++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -180,9 +180,8 @@ return; } - const std::string current_url = result_type_running_ == DEFAULT_SERP_FOR_URL - ? current_query_ - : std::string(); + const std::string current_url = + result_type_running_ == REMOTE_SEND_URL ? current_query_ : std::string(); // Create a request for suggestions, routing completion to // OnContextualSuggestionsLoaderAvailable. client() @@ -350,7 +349,7 @@ // When running the personalized service, we want to store suggestion // responses if non-empty. - if (result_type_running_ == DEFAULT_SERP && !json_data.empty()) { + if (result_type_running_ == REMOTE_NO_URL && !json_data.empty()) { client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults, json_data); @@ -564,7 +563,7 @@ } void ZeroSuggestProvider::MaybeUseCachedSuggestions() { - if (result_type_running_ != DEFAULT_SERP) + if (result_type_running_ != REMOTE_NO_URL) return; std::string json_data = @@ -590,7 +589,6 @@ const bool can_send_current_url = CanSendURL( current_url, suggest_url, default_provider, current_page_classification_, template_url_service->search_terms_data(), client()); - // Collect metrics on eligibility. GURL arbitrary_insecure_url(kArbitraryInsecureUrlString); ZeroSuggestEligibility eligibility = ZeroSuggestEligibility::ELIGIBLE; @@ -614,7 +612,7 @@ if (current_page_classification_ == metrics::OmniboxEventProto::CHROMEOS_APP_LIST) { - return DEFAULT_SERP; + return REMOTE_NO_URL; } if (OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial( @@ -623,7 +621,7 @@ client()->GetPrefs(), client()->IsAuthenticated(), template_url_service) ? MOST_VISITED - : DEFAULT_SERP; + : REMOTE_NO_URL; } if (OmniboxFieldTrial::InZeroSuggestMostVisitedWithoutSerpFieldTrial( @@ -639,5 +637,5 @@ return MOST_VISITED; } - return can_send_current_url ? DEFAULT_SERP_FOR_URL : NONE; + return can_send_current_url ? REMOTE_SEND_URL : NONE; }
diff --git a/components/omnibox/browser/zero_suggest_provider.h b/components/omnibox/browser/zero_suggest_provider.h index 38e8e77..dbb0dfa 100644 --- a/components/omnibox/browser/zero_suggest_provider.h +++ b/components/omnibox/browser/zero_suggest_provider.h
@@ -64,6 +64,7 @@ void ResetSession() override; private: + FRIEND_TEST_ALL_PREFIXES(ZeroSuggestProviderTest, TypeOfResultToRun); FRIEND_TEST_ALL_PREFIXES(ZeroSuggestProviderTest, TestStartWillStopForSomeInput); ZeroSuggestProvider(AutocompleteProviderClient* client, @@ -76,12 +77,19 @@ // at any time. enum ResultType { NONE, - DEFAULT_SERP, // The default search provider is queried for - // zero-suggest suggestions. - DEFAULT_SERP_FOR_URL, // The default search provider is queried for - // zero-suggest suggestions that are specific - // to the visited URL. - MOST_VISITED + + // A remote endpoint (usually the default search provider) is queried for + // suggestions. The endpoint is sent the user's authentication state, but + // not sent the current URL. + REMOTE_NO_URL, + + // A remote endpoint (usually the default search provider) is queried for + // suggestions. The endpoint is sent the user's authentication state and + // the current URL. + REMOTE_SEND_URL, + + // Gets the most visited sites from local history. + MOST_VISITED, }; // BaseSearchProvider:
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc index 3ef6720..0b4287a 100644 --- a/components/omnibox/browser/zero_suggest_provider_unittest.cc +++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" +#include "build/build_config.h" #include "components/history/core/browser/top_sites.h" #include "components/omnibox/browser/autocomplete_provider_listener.h" #include "components/omnibox/browser/mock_autocomplete_provider_client.h" @@ -155,7 +156,7 @@ void SetZeroSuggestVariantForAllContexts(const std::string& variant); base::test::ScopedTaskEnvironment scoped_task_environment_; - base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_; std::unique_ptr<FakeAutocompleteProviderClient> client_; scoped_refptr<ZeroSuggestProvider> provider_; @@ -202,12 +203,55 @@ void ZeroSuggestProviderTest::SetZeroSuggestVariantForAllContexts( const std::string& variant) { - scoped_feature_list_.InitAndEnableFeatureWithParameters( + scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>(); + scoped_feature_list_->InitAndEnableFeatureWithParameters( omnibox::kOnFocusSuggestions, {{std::string(OmniboxFieldTrial::kZeroSuggestVariantRule) + ":*:*", variant}}); } +TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun) { + GURL current_url = GURL("https://example.com/"); + GURL suggest_url = GURL("https://www.google.com/complete/?q={searchTerms}"); + + // Expect NONE by default if URL data collection is inactive. + EXPECT_CALL(*client_, IsPersonalizedUrlDataCollectionActive()) + .WillRepeatedly(testing::Return(false)); + +#if defined(OS_IOS) || defined(OS_ANDROID) + // iOS and Android both default to MOST_VISITED. + EXPECT_EQ(ZeroSuggestProvider::ResultType::MOST_VISITED, + provider_->TypeOfResultToRun(current_url, suggest_url)); +#else + // Expect REMOTE_SEND_URL type if client is authenticated and provides URLs. + EXPECT_EQ(ZeroSuggestProvider::ResultType::NONE, + provider_->TypeOfResultToRun(current_url, suggest_url)); +#endif + + EXPECT_CALL(*client_, IsAuthenticated()) + .WillRepeatedly(testing::Return(true)); + EXPECT_CALL(*client_, IsPersonalizedUrlDataCollectionActive()) + .WillRepeatedly(testing::Return(true)); + +#if defined(OS_IOS) || defined(OS_ANDROID) + // iOS and Android both default to MOST_VISITED, even if authenticated. + EXPECT_EQ(ZeroSuggestProvider::ResultType::MOST_VISITED, + provider_->TypeOfResultToRun(current_url, suggest_url)); +#else + // Expect REMOTE_SEND_URL type if client is authenticated and provides URLs. + EXPECT_EQ(ZeroSuggestProvider::ResultType::REMOTE_SEND_URL, + provider_->TypeOfResultToRun(current_url, suggest_url)); +#endif + + CreatePersonalizedFieldTrial(); + EXPECT_EQ(ZeroSuggestProvider::ResultType::REMOTE_NO_URL, + provider_->TypeOfResultToRun(current_url, suggest_url)); + + CreateMostVisitedFieldTrial(); + EXPECT_EQ(ZeroSuggestProvider::ResultType::MOST_VISITED, + provider_->TypeOfResultToRun(current_url, suggest_url)); +} + TEST_F(ZeroSuggestProviderTest, TestDoesNotReturnMatchesForPrefix) { CreatePersonalizedFieldTrial(); @@ -468,7 +512,7 @@ prefs->GetString(omnibox::kZeroSuggestCachedResults)); } -TEST_F(ZeroSuggestProviderTest, RedirectToChrome) { +TEST_F(ZeroSuggestProviderTest, CustomEndpoint) { CreateContextualSuggestFieldTrial(); // Coverage for the URL-specific page. (Regression test for a DCHECK). // This is exercising ContextualSuggestionsService::CreateExperimentalRequest, @@ -478,11 +522,10 @@ // redirect to chrome mode on. base::test::ScopedFeatureList features; std::map<std::string, std::string> params; - params[std::string( - OmniboxFieldTrial::kZeroSuggestRedirectToChromeServerAddressParam)] = + params[std::string(OmniboxFieldTrial::kOnFocusSuggestionsEndpointURLParam)] = "https://cuscochromeextension-pa.googleapis.com/v1/omniboxsuggestions"; features.InitAndEnableFeatureWithParameters( - omnibox::kZeroSuggestRedirectToChrome, params); + omnibox::kOnFocusSuggestionsCustomEndpoint, params); EXPECT_CALL(*client_, IsAuthenticated()) .WillRepeatedly(testing::Return(true));
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index 443a2c0b..a3777fb 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -285,7 +285,8 @@ const base::Feature kOnFocusSuggestions{"OmniboxOnFocusSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; -// Feature used for the Zero Suggest Redirect to Chrome Field Trial. +// Feature used to specify a custom endpoint URL for on-focus suggestions that +// are sourced via RPC. // // This feature is *enabled* in order to *disable* all forms of suggestions // based on the URL on-focus (whether from "redirect to Chrome" or the @@ -296,8 +297,9 @@ // If this feature were not enabled, Chrome would use the default suggest // server for suggestions based on the current URL on focus. There is no // code in Chrome to disable that, so that why we took this route. -const base::Feature kZeroSuggestRedirectToChrome{ - "ZeroSuggestRedirectToChrome", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kOnFocusSuggestionsCustomEndpoint{ + "OmniboxOnFocusSuggestionsCustomEndpoint", + base::FEATURE_ENABLED_BY_DEFAULT}; // Allow suggestions to be shown to the user on the New Tab Page upon focusing // URL bar (the omnibox).
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index b96a4f6..4ea8861 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -51,7 +51,7 @@ // On-Focus Suggestions a.k.a. ZeroSuggest. extern const base::Feature kOnFocusSuggestions; -extern const base::Feature kZeroSuggestRedirectToChrome; +extern const base::Feature kOnFocusSuggestionsCustomEndpoint; extern const base::Feature kZeroSuggestionsOnNTP; } // namespace omnibox
diff --git a/components/optimization_guide/proto/BUILD.gn b/components/optimization_guide/proto/BUILD.gn index 07abdc94..a703e47 100644 --- a/components/optimization_guide/proto/BUILD.gn +++ b/components/optimization_guide/proto/BUILD.gn
@@ -6,6 +6,8 @@ proto_library("optimization_guide_proto") { sources = [ + "common_types.proto", "hints.proto", + "previews_metadata.proto", ] }
diff --git a/components/optimization_guide/proto/common_types.proto b/components/optimization_guide/proto/common_types.proto new file mode 100644 index 0000000..0f83460 --- /dev/null +++ b/components/optimization_guide/proto/common_types.proto
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; + +package optimization_guide.proto; + +// The possible effective connection type values. +// +// The values should match those of //net/nqe/effective_connection_type.h in the +// Chromium repository. +enum EffectiveConnectionType { + // Effective connection type reported when the network quality is unknown. + EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0; + + // Effective connection type reported when the Internet is unreachable, + // either because the device does not have a connection or because the + // connection is too slow to be usable. + EFFECTIVE_CONNECTION_TYPE_OFFLINE = 1; + + // Effective connection type reported when the network has the quality of a + // poor 2G connection. + EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 2; + + // Effective connection type reported when the network has the quality of a + // faster 2G connection. + EFFECTIVE_CONNECTION_TYPE_2G = 3; + + // Effective connection type reported when the network has the quality of a + // 3G connection. + EFFECTIVE_CONNECTION_TYPE_3G = 4; + + // Effective connection type reported when the network has the quality of a + // 4G connection. + EFFECTIVE_CONNECTION_TYPE_4G = 5; +}
diff --git a/components/optimization_guide/proto/hints.proto b/components/optimization_guide/proto/hints.proto index a45de45..fd24217 100644 --- a/components/optimization_guide/proto/hints.proto +++ b/components/optimization_guide/proto/hints.proto
@@ -7,6 +7,9 @@ package optimization_guide.proto; +import "common_types.proto"; +import "previews_metadata.proto"; + // Information about the hint that the client already has for a host. message MatchedHintInfo { // Describes the granularity of the key field. @@ -127,23 +130,6 @@ HOST_SUFFIX = 1; } -enum LoadingOptimizationType { - LOADING_UNSPECIFIED = 0; - // The resource should not be loaded. - LOADING_BLOCK_RESOURCE = 1; -} - -message ResourceLoadingHint { - // The pattern to match against the resource URL. - // - // The pattern may be a single substring to match against the URL or it may be - // an ordered set of substrings to match where the substrings are separated by - // the ‘*’ wildcard character (with an implicit ‘*’ at the beginning and end). - optional string resource_pattern = 1; - // The type of loading optimization to apply to the resource. - optional LoadingOptimizationType loading_optimization_type = 2; -} - message Optimization { // The type of optimization the hint applies to. optional OptimizationType optimization_type = 1; @@ -155,13 +141,13 @@ // Ex: If the received bytes is 100 and the inflation_percent is 30, the // inflated bytes calculated by the client will be 30 in order to have a total // consumed bytes value of 130. - optional int64 inflation_percent = 2; + optional int64 inflation_percent = 2 [deprecated = true]; // An ordered set of resource loading hints for OptimizationType // RESOURCE_LOADING. // // Only the first ResourceLoadingHint record that matches a target resource // URL will be applied to that resource. - repeated ResourceLoadingHint resource_loading_hints = 3; + repeated ResourceLoadingHint resource_loading_hints = 3 [deprecated = true]; // The experiment name that activates the optimization. // // If a non-empty name is provided, the optimization will be disabled unless @@ -182,36 +168,11 @@ // same name, the optimization will be disabled and skipped for that client. // An empty name is not experimental. optional string excluded_experiment_name = 5; -} - -// The possible effective connection type values. -// -// The values should match those of //net/nqe/effective_connection_type.h in the -// Chromium repository. -enum EffectiveConnectionType { - // Effective connection type reported when the network quality is unknown. - EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0; - - // Effective connection type reported when the Internet is unreachable, - // either because the device does not have a connection or because the - // connection is too slow to be usable. - EFFECTIVE_CONNECTION_TYPE_OFFLINE = 1; - - // Effective connection type reported when the network has the quality of a - // poor 2G connection. - EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 2; - - // Effective connection type reported when the network has the quality of a - // faster 2G connection. - EFFECTIVE_CONNECTION_TYPE_2G = 3; - - // Effective connection type reported when the network has the quality of a - // 3G connection. - EFFECTIVE_CONNECTION_TYPE_3G = 4; - - // Effective connection type reported when the network has the quality of a - // 4G connection. - EFFECTIVE_CONNECTION_TYPE_4G = 5; + // The metadata associated with the optimization type. + // + // It is expected that the client and server have agreed upon the appropriate + // metadata type for the optimization type. + oneof metadata { PreviewsMetadata previews_metadata = 10; } } message PageHint { @@ -224,7 +185,7 @@ optional string page_pattern = 1; // The maximum effective connection type threshold for triggering the // optimization associated with this hint. - optional EffectiveConnectionType max_ect_trigger = 2; + optional EffectiveConnectionType max_ect_trigger = 2 [deprecated = true]; // An ordered set of optimizations that should be whitelisted for this page // pattern. //
diff --git a/components/optimization_guide/proto/previews_metadata.proto b/components/optimization_guide/proto/previews_metadata.proto new file mode 100644 index 0000000..c152bf6 --- /dev/null +++ b/components/optimization_guide/proto/previews_metadata.proto
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package optimization_guide.proto; + +import "common_types.proto"; + +enum LoadingOptimizationType { + LOADING_UNSPECIFIED = 0; + // The resource should not be loaded. + LOADING_BLOCK_RESOURCE = 1; +} + +message ResourceLoadingHint { + // The pattern to match against the resource URL. + // + // The pattern may be a single substring to match against the URL or it may be + // an ordered set of substrings to match where the substrings are separated by + // the ‘*’ wildcard character (with an implicit ‘*’ at the beginning and end). + optional string resource_pattern = 1; + // The type of loading optimization to apply to the resource. + optional LoadingOptimizationType loading_optimization_type = 2; +} + +// Optimization metadata associated with Previews. +// +// Currently, this is just populated for optimization types NOSCRIPT and +// RESOURCE_LOADING. +message PreviewsMetadata { + // A percent value to inflate the number of received bytes by for the purposes + // of data savings calculations in the client. + // + // If this value is set to 0, the client should use its configured default. + // + // Ex: If the received bytes is 100 and the inflation_percent is 30, the + // inflated bytes calculated by the client will be 30 in order to have a total + // consumed bytes value of 130. + optional int64 inflation_percent = 1; + // The maximum effective connection type threshold for triggering the + // optimization associated with this optimization. + optional EffectiveConnectionType max_ect_trigger = 2; + // An ordered set of resource loading hints. + // + // Only the first ResourceLoadingHint record that matches a target resource + // URL will be applied to that resource. + repeated ResourceLoadingHint resource_loading_hints = 3; +}
diff --git a/components/previews/content/previews_hints.cc b/components/previews/content/previews_hints.cc index d52a110..12aa84c 100644 --- a/components/previews/content/previews_hints.cc +++ b/components/previews/content/previews_hints.cc
@@ -422,10 +422,18 @@ return false; } // |type| is the first whitelisted optimization this client supports. - *out_inflation_percent = optimization.inflation_percent(); - if (matched_page_hint->has_max_ect_trigger()) { + // Extract any applicable metadata for it. + if (optimization.has_previews_metadata()) { + *out_inflation_percent = + optimization.previews_metadata().inflation_percent(); *out_ect_threshold = ConvertProtoEffectiveConnectionType( - matched_page_hint->max_ect_trigger()); + optimization.previews_metadata().max_ect_trigger()); + } else { + *out_inflation_percent = optimization.inflation_percent(); + if (matched_page_hint->has_max_ect_trigger()) { + *out_ect_threshold = ConvertProtoEffectiveConnectionType( + matched_page_hint->max_ect_trigger()); + } } *out_serialized_hint_version_string = hint->version(); @@ -498,8 +506,17 @@ continue; } - for (const auto& resource_loading_hint : - optimization.resource_loading_hints()) { + google::protobuf::RepeatedPtrField< + optimization_guide::proto::ResourceLoadingHint> + resource_loading_hints; + if (optimization.has_previews_metadata()) { + resource_loading_hints = + optimization.previews_metadata().resource_loading_hints(); + } else { + resource_loading_hints = optimization.resource_loading_hints(); + } + + for (const auto& resource_loading_hint : resource_loading_hints) { if (!resource_loading_hint.resource_pattern().empty() && resource_loading_hint.loading_optimization_type() == optimization_guide::proto::LOADING_BLOCK_RESOURCE) {
diff --git a/components/previews/content/previews_hints_unittest.cc b/components/previews/content/previews_hints_unittest.cc index 9ffcb4f8..cd91a15c 100644 --- a/components/previews/content/previews_hints_unittest.cc +++ b/components/previews/content/previews_hints_unittest.cc
@@ -423,6 +423,35 @@ resource_hint2b->set_loading_optimization_type( optimization_guide::proto::LOADING_BLOCK_RESOURCE); resource_hint2b->set_resource_pattern("resource2b.js"); + // Page hint for "/has_metadata/" with all details provided in metadata and + // should take precedence over the details at the top-level. + optimization_guide::proto::PageHint* page_hint3 = hint1->add_page_hints(); + page_hint3->set_page_pattern("/has_metadata/"); + page_hint3->set_max_ect_trigger( + optimization_guide::proto::EffectiveConnectionType:: + EFFECTIVE_CONNECTION_TYPE_4G); + optimization_guide::proto::Optimization* optimization_with_metadata = + page_hint3->add_whitelisted_optimizations(); + optimization_with_metadata->set_optimization_type( + optimization_guide::proto::RESOURCE_LOADING); + optimization_with_metadata->set_inflation_percent(12345); + optimization_guide::proto::ResourceLoadingHint* unused_resource_hint = + optimization_with_metadata->add_resource_loading_hints(); + unused_resource_hint->set_loading_optimization_type( + optimization_guide::proto::LOADING_BLOCK_RESOURCE); + unused_resource_hint->set_resource_pattern("unused_resource_hint.js"); + optimization_guide::proto::PreviewsMetadata* previews_metadata = + optimization_with_metadata->mutable_previews_metadata(); + previews_metadata->set_inflation_percent(123); + optimization_guide::proto::ResourceLoadingHint* resource_hint3 = + previews_metadata->add_resource_loading_hints(); + resource_hint3->set_loading_optimization_type( + optimization_guide::proto::LOADING_BLOCK_RESOURCE); + resource_hint3->set_resource_pattern("resource3.js"); + previews_metadata->set_max_ect_trigger( + optimization_guide::proto::EffectiveConnectionType:: + EFFECTIVE_CONNECTION_TYPE_3G); + ParseConfig(config); // Verify optimization providing inflation_percent and hints version. @@ -467,6 +496,24 @@ EXPECT_EQ(2ul, patterns_to_block2.size()); EXPECT_EQ("resource2a.js", patterns_to_block2[0]); EXPECT_EQ("resource2b.js", patterns_to_block2[1]); + + // Verify page hint having data stored in metadata. + inflation_percent = 0; + ect_threshold = + net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + serialized_hint_version_string = ""; + EXPECT_TRUE(MaybeLoadHintAndCheckIsWhitelisted( + GURL("https://www.somedomain.org/has_metadata/"), + PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent, &ect_threshold, + &serialized_hint_version_string)); + EXPECT_EQ(123, inflation_percent); + std::vector<std::string> patterns_to_block3; + previews_hints()->GetResourceLoadingHints( + GURL("https://www.somedomain.org/has_metadata/"), &patterns_to_block3); + EXPECT_EQ(1ul, patterns_to_block3.size()); + EXPECT_EQ("resource3.js", patterns_to_block3[0]); + EXPECT_EQ(net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G, + ect_threshold); } TEST_F(PreviewsHintsTest,
diff --git a/components/previews/core/previews_constants.cc b/components/previews/core/previews_constants.cc index 7597b091..cc90d62 100644 --- a/components/previews/core/previews_constants.cc +++ b/components/previews/core/previews_constants.cc
@@ -12,4 +12,7 @@ const char kPreviewsOptimizationGuideOnLoadedHintResultHistogramString[] = "PreviewsOptimizationGuide.OnLoadedHint.Result"; +extern const char kOptimizationGuideServiceDefaultURL[] = + "https://optimizationguide-pa.googleapis.com/v1:GetHints"; + } // namespace previews
diff --git a/components/previews/core/previews_constants.h b/components/previews/core/previews_constants.h index 87216f4..0a7ac8a1 100644 --- a/components/previews/core/previews_constants.h +++ b/components/previews/core/previews_constants.h
@@ -15,6 +15,10 @@ // finished loading. extern const char kPreviewsOptimizationGuideOnLoadedHintResultHistogramString[]; +// The remote Optimization Guide Service production server to fetcher hints +// from. +extern const char kOptimizationGuideServiceDefaultURL[]; + } // namespace previews #endif // COMPONENTS_PREVIEWS_CORE_PREVIEWS_CONSTANTS_H_
diff --git a/components/previews/core/previews_experiments.cc b/components/previews/core/previews_experiments.cc index 9496cbd..87f6589 100644 --- a/components/previews/core/previews_experiments.cc +++ b/components/previews/core/previews_experiments.cc
@@ -13,9 +13,11 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "components/previews/core/previews_constants.h" #include "components/previews/core/previews_features.h" #include "components/previews/core/previews_switches.h" #include "google_apis/google_api_keys.h" +#include "net/base/url_util.h" namespace previews { @@ -47,7 +49,6 @@ const char kNoScriptInflationPercent[] = "NoScriptInflationPercent"; const char kNoScriptInflationBytes[] = "NoScriptInflationBytes"; -const char kOptimizationGuideServiceURL[] = ""; // Inflation parameters for estimating ResourceLoadingHints data savings. const char kResourceLoadingHintsInflationPercent[] = @@ -251,8 +252,13 @@ std::string url = base::GetFieldTrialParamValueByFeature( features::kOptimizationHintsFetching, "optimization_guide_service_url"); - if (url.empty()) - return GURL(kOptimizationGuideServiceURL); + if (url.empty() || !GURL(url).SchemeIs(url::kHttpsScheme)) { + if (!url.empty()) + LOG(WARNING) + << "Empty or invalid optimization_guide_service_url provided: " + << url; + return GURL(previews::kOptimizationGuideServiceDefaultURL); + } return GURL(url); }
diff --git a/components/previews/core/previews_experiments_unittest.cc b/components/previews/core/previews_experiments_unittest.cc index 4c28d43..c10af9a 100644 --- a/components/previews/core/previews_experiments_unittest.cc +++ b/components/previews/core/previews_experiments_unittest.cc
@@ -15,6 +15,7 @@ #include "base/strings/string_util.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "components/previews/core/previews_constants.h" #include "components/previews/core/previews_features.h" #include "components/variations/variations_associated_data.h" @@ -227,6 +228,31 @@ } } +TEST(PreviewsExperimentsTest, TestGetOptimizationGuideServiceURLHTTPSOnly) { + base::test::ScopedFeatureList scoped_feature_list; + + scoped_feature_list.InitAndEnableFeatureWithParameters( + features::kOptimizationHintsFetching, + {{"optimization_guide_service_url", "http://NotAnHTTPSServer.com"}}); + + EXPECT_EQ(params::GetOptimizationGuideServiceURL().spec(), + kOptimizationGuideServiceDefaultURL); + EXPECT_TRUE( + params::GetOptimizationGuideServiceURL().SchemeIs(url::kHttpsScheme)); +} + +TEST(PreviewsExperimentsTest, TestGetOptimizationGuideServiceURLViaFinch) { + base::test::ScopedFeatureList scoped_feature_list; + + std::string optimization_guide_service_url = "https://finchserver.com/"; + scoped_feature_list.InitAndEnableFeatureWithParameters( + features::kOptimizationHintsFetching, + {{"optimization_guide_service_url", optimization_guide_service_url}}); + + EXPECT_EQ(params::GetOptimizationGuideServiceURL().spec(), + optimization_guide_service_url); +} + } // namespace } // namespace previews
diff --git a/components/send_tab_to_self/OWNERS b/components/send_tab_to_self/OWNERS index cbbc50e6..a49acc9 100644 --- a/components/send_tab_to_self/OWNERS +++ b/components/send_tab_to_self/OWNERS
@@ -1,5 +1,6 @@ hansberry@chromium.org jeffreycohen@chromium.org sebsg@chromium.org +tgupta@chromium.org # COMPONENT: UI>Browser>Sharing
diff --git a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm index 98b4efb..f94cd81 100644 --- a/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm +++ b/content/app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm
@@ -10,8 +10,8 @@ #include "base/bind.h" #include "base/macros.h" #include "base/no_destructor.h" -#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h" -#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h" +#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h" +#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h" #include "content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h" #include "content/browser/renderer_host/input/web_input_event_builders_mac.h" #include "content/common/render_widget_host_ns_view.mojom.h" @@ -21,21 +21,21 @@ #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #include "ui/base/cocoa/remote_accessibility_api.h" -namespace content { +namespace remote_cocoa { namespace { class RenderWidgetHostNSViewBridgeOwner - : public RenderWidgetHostNSViewClientHelper { + : public RenderWidgetHostNSViewHostHelper { public: explicit RenderWidgetHostNSViewBridgeOwner( - mojom::RenderWidgetHostNSViewClientAssociatedPtr client, - mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request) - : client_(std::move(client)) { - bridge_ = std::make_unique<RenderWidgetHostNSViewBridgeLocal>(client_.get(), - this); + mojom::RenderWidgetHostNSViewHostAssociatedPtr client, + mojom::RenderWidgetHostNSViewAssociatedRequest bridge_request) + : host_(std::move(client)) { + bridge_ = std::make_unique<remote_cocoa::RenderWidgetHostNSViewBridge>( + host_.get(), this); bridge_->BindRequest(std::move(bridge_request)); - client_.set_connection_error_handler( + host_.set_connection_error_handler( base::BindOnce(&RenderWidgetHostNSViewBridgeOwner::OnConnectionError, base::Unretained(this))); } @@ -43,12 +43,12 @@ private: void OnConnectionError() { delete this; } - std::unique_ptr<InputEvent> TranslateEvent( + std::unique_ptr<content::InputEvent> TranslateEvent( const blink::WebInputEvent& web_event) { - return std::make_unique<InputEvent>(web_event, ui::LatencyInfo()); + return std::make_unique<content::InputEvent>(web_event, ui::LatencyInfo()); } - // RenderWidgetHostNSViewClientHelper implementation. + // RenderWidgetHostNSViewHostHelper implementation. id GetRootBrowserAccessibilityElement() override { // The RenderWidgetHostViewCocoa in the app shim process does not // participate in the accessibility tree. Only the instance in the browser @@ -60,112 +60,109 @@ return nil; } void SetAccessibilityWindow(NSWindow* window) override { - client_->SetRemoteAccessibilityWindowToken( + host_->SetRemoteAccessibilityWindowToken( ui::RemoteAccessibility::GetTokenForLocalElement(window)); } - void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event, + void ForwardKeyboardEvent(const content::NativeWebKeyboardEvent& key_event, const ui::LatencyInfo& latency_info) override { const blink::WebKeyboardEvent* web_event = static_cast<const blink::WebKeyboardEvent*>(&key_event); - std::unique_ptr<InputEvent> input_event = - std::make_unique<InputEvent>(*web_event, latency_info); - client_->ForwardKeyboardEvent(std::move(input_event), - key_event.skip_in_browser); + std::unique_ptr<content::InputEvent> input_event = + std::make_unique<content::InputEvent>(*web_event, latency_info); + host_->ForwardKeyboardEvent(std::move(input_event), + key_event.skip_in_browser); } void ForwardKeyboardEventWithCommands( - const NativeWebKeyboardEvent& key_event, + const content::NativeWebKeyboardEvent& key_event, const ui::LatencyInfo& latency_info, - const std::vector<EditCommand>& commands) override { + const std::vector<content::EditCommand>& commands) override { const blink::WebKeyboardEvent* web_event = static_cast<const blink::WebKeyboardEvent*>(&key_event); - std::unique_ptr<InputEvent> input_event = - std::make_unique<InputEvent>(*web_event, latency_info); - client_->ForwardKeyboardEventWithCommands( + std::unique_ptr<content::InputEvent> input_event = + std::make_unique<content::InputEvent>(*web_event, latency_info); + host_->ForwardKeyboardEventWithCommands( std::move(input_event), key_event.skip_in_browser, commands); } void RouteOrProcessMouseEvent( const blink::WebMouseEvent& web_event) override { - client_->RouteOrProcessMouseEvent(TranslateEvent(web_event)); + host_->RouteOrProcessMouseEvent(TranslateEvent(web_event)); } void RouteOrProcessTouchEvent( const blink::WebTouchEvent& web_event) override { - client_->RouteOrProcessTouchEvent(TranslateEvent(web_event)); + host_->RouteOrProcessTouchEvent(TranslateEvent(web_event)); } void RouteOrProcessWheelEvent( const blink::WebMouseWheelEvent& web_event) override { - client_->RouteOrProcessWheelEvent(TranslateEvent(web_event)); + host_->RouteOrProcessWheelEvent(TranslateEvent(web_event)); } void ForwardMouseEvent(const blink::WebMouseEvent& web_event) override { - client_->ForwardMouseEvent(TranslateEvent(web_event)); + host_->ForwardMouseEvent(TranslateEvent(web_event)); } void ForwardWheelEvent(const blink::WebMouseWheelEvent& web_event) override { - client_->ForwardWheelEvent(TranslateEvent(web_event)); + host_->ForwardWheelEvent(TranslateEvent(web_event)); } void GestureBegin(blink::WebGestureEvent begin_event, bool is_synthetically_injected) override { // The gesture type is not yet known, but assign a type to avoid // serialization asserts (the type will be stripped on the other side). begin_event.SetType(blink::WebInputEvent::kGestureScrollBegin); - client_->GestureBegin(TranslateEvent(begin_event), - is_synthetically_injected); + host_->GestureBegin(TranslateEvent(begin_event), is_synthetically_injected); } void GestureUpdate(blink::WebGestureEvent update_event) override { - client_->GestureUpdate(TranslateEvent(update_event)); + host_->GestureUpdate(TranslateEvent(update_event)); } void GestureEnd(blink::WebGestureEvent end_event) override { - client_->GestureEnd(TranslateEvent(end_event)); + host_->GestureEnd(TranslateEvent(end_event)); } void SmartMagnify(const blink::WebGestureEvent& web_event) override { - client_->SmartMagnify(TranslateEvent(web_event)); + host_->SmartMagnify(TranslateEvent(web_event)); } - mojom::RenderWidgetHostNSViewClientAssociatedPtr client_; - std::unique_ptr<RenderWidgetHostNSViewBridgeLocal> bridge_; + mojom::RenderWidgetHostNSViewHostAssociatedPtr host_; + std::unique_ptr<RenderWidgetHostNSViewBridge> bridge_; base::scoped_nsobject<NSAccessibilityRemoteUIElement> remote_accessibility_element_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewBridgeOwner); }; - } void CreateRenderWidgetHostNSView( mojo::ScopedInterfaceEndpointHandle host_handle, mojo::ScopedInterfaceEndpointHandle view_request_handle) { - // Cast from the stub interface to the mojom::RenderWidgetHostNSViewClient - // and mojom::RenderWidgetHostNSViewBridge private interfaces. + // Cast from the stub interface to the mojom::RenderWidgetHostNSViewHost + // and mojom::RenderWidgetHostNSView private interfaces. // TODO(ccameron): Remove the need for this cast. // https://crbug.com/888290 - mojom::RenderWidgetHostNSViewClientAssociatedPtr client( - mojo::AssociatedInterfacePtrInfo<mojom::RenderWidgetHostNSViewClient>( + mojom::RenderWidgetHostNSViewHostAssociatedPtr host( + mojo::AssociatedInterfacePtrInfo<mojom::RenderWidgetHostNSViewHost>( std::move(host_handle), 0)); - mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request( + mojom::RenderWidgetHostNSViewAssociatedRequest ns_view_request( std::move(view_request_handle)); // Create a RenderWidgetHostNSViewBridgeOwner. The resulting object will be // destroyed when its underlying pipe is closed. ignore_result(new RenderWidgetHostNSViewBridgeOwner( - std::move(client), std::move(bridge_request))); + std::move(host), std::move(ns_view_request))); } void CreateWebContentsNSView( uint64_t view_id, mojo::ScopedInterfaceEndpointHandle host_handle, mojo::ScopedInterfaceEndpointHandle view_request_handle) { - mojom::WebContentsNSViewClientAssociatedPtr client( - mojo::AssociatedInterfacePtrInfo<mojom::WebContentsNSViewClient>( + mojom::WebContentsNSViewHostAssociatedPtr host( + mojo::AssociatedInterfacePtrInfo<mojom::WebContentsNSViewHost>( std::move(host_handle), 0)); - mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request( + mojom::WebContentsNSViewAssociatedRequest ns_view_request( std::move(view_request_handle)); // Note that the resulting object will be destroyed when its underlying pipe // is closed. mojo::MakeStrongAssociatedBinding( std::make_unique<WebContentsNSViewBridge>( - view_id, - mojom::WebContentsNSViewClientAssociatedPtr(std::move(client))), - std::move(bridge_request), + view_id, mojom::WebContentsNSViewHostAssociatedPtr(std::move(host))), + std::move(ns_view_request), ui::WindowResizeHelperMac::Get()->task_runner()); } -} // namespace content +} // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/popup_window_mac.h b/content/app_shim_remote_cocoa/popup_window_mac.h index 518ffb8..92ffb12 100644 --- a/content/app_shim_remote_cocoa/popup_window_mac.h +++ b/content/app_shim_remote_cocoa/popup_window_mac.h
@@ -13,7 +13,7 @@ @class NSWindow; @class RenderWidgetHostViewCocoa; -namespace content { +namespace remote_cocoa { // Helper class for RHWVMacs that are initialized using InitAsPopup. Note that // this refers to UI that creates its own NSWindow, and does not refer to JS @@ -35,6 +35,6 @@ DISALLOW_COPY_AND_ASSIGN(PopupWindowMac); }; -} // namespace content +} // namespace remote_cocoa #endif // CONTENT_APP_SHIM_REMOTE_COCOA_POPUP_WINDOW_MAC_H_
diff --git a/content/app_shim_remote_cocoa/popup_window_mac.mm b/content/app_shim_remote_cocoa/popup_window_mac.mm index 3125dfc..0a35063 100644 --- a/content/app_shim_remote_cocoa/popup_window_mac.mm +++ b/content/app_shim_remote_cocoa/popup_window_mac.mm
@@ -80,7 +80,7 @@ @end -namespace content { +namespace remote_cocoa { PopupWindowMac::PopupWindowMac(const gfx::Rect& content_rect, RenderWidgetHostViewCocoa* cocoa_view) @@ -115,4 +115,4 @@ popup_window_.autorelease(); } -} // namespace content +} // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h similarity index 80% rename from content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h rename to content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h index 6f19cda..0ac0181 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h +++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_ -#define CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_ +#ifndef CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_ +#define CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_ #import <Cocoa/Cocoa.h> @@ -16,31 +16,29 @@ #include "ui/accelerated_widget_mac/display_ca_layer_tree.h" #include "ui/display/display_observer.h" -namespace content { +namespace remote_cocoa { // Mojo bridge for a RenderWidgetHostViewMac's NSView. This class may be // instantiated in the same process as its RenderWidgetHostViewMac, or it may // be in a different process. -class RenderWidgetHostNSViewBridgeLocal - : public mojom::RenderWidgetHostNSViewBridge, - public display::DisplayObserver { +class RenderWidgetHostNSViewBridge : public mojom::RenderWidgetHostNSView, + public display::DisplayObserver { public: - RenderWidgetHostNSViewBridgeLocal( - mojom::RenderWidgetHostNSViewClient* client, - RenderWidgetHostNSViewClientHelper* client_helper); - ~RenderWidgetHostNSViewBridgeLocal() override; + RenderWidgetHostNSViewBridge(mojom::RenderWidgetHostNSViewHost* client, + RenderWidgetHostNSViewHostHelper* client_helper); + ~RenderWidgetHostNSViewBridge() override; - // Bind to a remote request for a bridge interface. + // Bind to a remote request for a mojo interface. void BindRequest( - mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request); + mojom::RenderWidgetHostNSViewAssociatedRequest bridge_request); // TODO(ccameron): RenderWidgetHostViewMac and other functions currently use // this method to communicate directly with RenderWidgetHostViewCocoa. The // goal of this class is to eliminate this direct communication (so this // method is expected to go away). - RenderWidgetHostViewCocoa* GetRenderWidgetHostViewCocoa(); + RenderWidgetHostViewCocoa* GetNSView(); - // mojom::RenderWidgetHostNSViewBridge implementation. + // mojom::RenderWidgetHostNSView implementation. void InitAsPopup(const gfx::Rect& content_rect) override; void SetParentWebContentsNSView(uint64_t parent_ns_view_id) override; void DisableDisplay() override; @@ -57,7 +55,7 @@ void SetCompositionRangeInfo(const gfx::Range& range) override; void CancelComposition() override; void SetShowingContextMenu(bool showing) override; - void DisplayCursor(const WebCursor& cursor) override; + void DisplayCursor(const content::WebCursor& cursor) override; void SetCursorLocked(bool locked) override; void ShowDictionaryOverlayForSelection() override; void ShowDictionaryOverlay( @@ -93,11 +91,11 @@ base::string16 tooltip_text_; // The binding for this object (only used when remotely instantiated). - mojo::AssociatedBinding<mojom::RenderWidgetHostNSViewBridge> binding_; + mojo::AssociatedBinding<mojom::RenderWidgetHostNSView> binding_; - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewBridgeLocal); + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewBridge); }; -} // namespace content +} // namespace remote_cocoa -#endif // CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_ +#endif // CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm similarity index 77% rename from content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm rename to content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm index 2aa04c3..758ed69e 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm +++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h" +#import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h" #include "base/mac/scoped_cftyperef.h" #include "base/strings/sys_string_conversions.h" #include "components/remote_cocoa/app_shim/ns_view_ids.h" -#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h" +#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h" #include "content/common/cursors/webcursor.h" #import "skia/ext/skia_utils_mac.h" #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" @@ -16,17 +16,17 @@ #include "ui/events/keycodes/dom/dom_code.h" #include "ui/gfx/mac/coordinate_conversion.h" -namespace content { +namespace remote_cocoa { -RenderWidgetHostNSViewBridgeLocal::RenderWidgetHostNSViewBridgeLocal( - mojom::RenderWidgetHostNSViewClient* client, - RenderWidgetHostNSViewClientHelper* client_helper) +RenderWidgetHostNSViewBridge::RenderWidgetHostNSViewBridge( + mojom::RenderWidgetHostNSViewHost* host, + RenderWidgetHostNSViewHostHelper* host_helper) : binding_(this) { display::Screen::GetScreen()->AddObserver(this); cocoa_view_.reset([[RenderWidgetHostViewCocoa alloc] - initWithClient:client - withClientHelper:client_helper]); + initWithHost:host + withHostHelper:host_helper]); background_layer_.reset([[CALayer alloc] init]); display_ca_layer_tree_ = @@ -35,8 +35,8 @@ [cocoa_view_ setWantsLayer:YES]; } -RenderWidgetHostNSViewBridgeLocal::~RenderWidgetHostNSViewBridgeLocal() { - [cocoa_view_ setClientDisconnected]; +RenderWidgetHostNSViewBridge::~RenderWidgetHostNSViewBridge() { + [cocoa_view_ setHostDisconnected]; // Do not immediately remove |cocoa_view_| from the NSView heirarchy, because // the call to -[NSView removeFromSuperview] may cause use to call into the // RWHVMac during tear-down, via WebContentsImpl::UpdateWebContentsVisibility. @@ -49,23 +49,21 @@ popup_window_.reset(); } -void RenderWidgetHostNSViewBridgeLocal::BindRequest( - mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request) { +void RenderWidgetHostNSViewBridge::BindRequest( + mojom::RenderWidgetHostNSViewAssociatedRequest bridge_request) { binding_.Bind(std::move(bridge_request), ui::WindowResizeHelperMac::Get()->task_runner()); } -RenderWidgetHostViewCocoa* -RenderWidgetHostNSViewBridgeLocal::GetRenderWidgetHostViewCocoa() { +RenderWidgetHostViewCocoa* RenderWidgetHostNSViewBridge::GetNSView() { return cocoa_view_; } -void RenderWidgetHostNSViewBridgeLocal::InitAsPopup( - const gfx::Rect& content_rect) { +void RenderWidgetHostNSViewBridge::InitAsPopup(const gfx::Rect& content_rect) { popup_window_ = std::make_unique<PopupWindowMac>(content_rect, cocoa_view_); } -void RenderWidgetHostNSViewBridgeLocal::SetParentWebContentsNSView( +void RenderWidgetHostNSViewBridge::SetParentWebContentsNSView( uint64_t parent_ns_view_id) { NSView* parent_ns_view = remote_cocoa::GetNSViewFromId(parent_ns_view_id); // If the browser passed an invalid handle, then there is no recovery. @@ -77,11 +75,11 @@ [parent_ns_view addSubview:cocoa_view_]; } -void RenderWidgetHostNSViewBridgeLocal::MakeFirstResponder() { +void RenderWidgetHostNSViewBridge::MakeFirstResponder() { [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; } -void RenderWidgetHostNSViewBridgeLocal::DisableDisplay() { +void RenderWidgetHostNSViewBridge::DisableDisplay() { if (display_disabled_) return; SetBackgroundColor(SK_ColorTRANSPARENT); @@ -89,7 +87,7 @@ display_disabled_ = true; } -void RenderWidgetHostNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) { +void RenderWidgetHostNSViewBridge::SetBounds(const gfx::Rect& rect) { // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, // TODO(thakis): fix, http://crbug.com/73362 @@ -130,14 +128,14 @@ } } -void RenderWidgetHostNSViewBridgeLocal::SetCALayerParams( +void RenderWidgetHostNSViewBridge::SetCALayerParams( const gfx::CALayerParams& ca_layer_params) { if (display_disabled_) return; display_ca_layer_tree_->UpdateCALayerTree(ca_layer_params); } -void RenderWidgetHostNSViewBridgeLocal::SetBackgroundColor(SkColor color) { +void RenderWidgetHostNSViewBridge::SetBackgroundColor(SkColor color) { if (display_disabled_) return; ScopedCAActionDisabler disabler; @@ -146,12 +144,12 @@ [background_layer_ setBackgroundColor:cg_color]; } -void RenderWidgetHostNSViewBridgeLocal::SetVisible(bool visible) { +void RenderWidgetHostNSViewBridge::SetVisible(bool visible) { ScopedCAActionDisabler disabler; [cocoa_view_ setHidden:!visible]; } -void RenderWidgetHostNSViewBridgeLocal::SetTooltipText( +void RenderWidgetHostNSViewBridge::SetTooltipText( const base::string16& tooltip_text) { // Called from the renderer to tell us what the tooltip text should be. It // calls us frequently so we need to cache the value to prevent doing a lot @@ -175,25 +173,24 @@ [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; } -void RenderWidgetHostNSViewBridgeLocal::SetCompositionRangeInfo( +void RenderWidgetHostNSViewBridge::SetCompositionRangeInfo( const gfx::Range& range) { [cocoa_view_ setCompositionRange:range]; [cocoa_view_ setMarkedRange:range.ToNSRange()]; } -void RenderWidgetHostNSViewBridgeLocal::CancelComposition() { +void RenderWidgetHostNSViewBridge::CancelComposition() { [cocoa_view_ cancelComposition]; } -void RenderWidgetHostNSViewBridgeLocal::SetTextInputType( +void RenderWidgetHostNSViewBridge::SetTextInputType( ui::TextInputType text_input_type) { [cocoa_view_ setTextInputType:text_input_type]; } -void RenderWidgetHostNSViewBridgeLocal::SetTextSelection( - const base::string16& text, - uint64_t offset, - const gfx::Range& range) { +void RenderWidgetHostNSViewBridge::SetTextSelection(const base::string16& text, + uint64_t offset, + const gfx::Range& range) { [cocoa_view_ setTextSelectionText:text offset:offset range:range]; // Updates markedRange when there is no marked text so that retrieving // markedRange immediately after calling setMarkdText: returns the current @@ -203,11 +200,11 @@ } } -void RenderWidgetHostNSViewBridgeLocal::SetShowingContextMenu(bool showing) { +void RenderWidgetHostNSViewBridge::SetShowingContextMenu(bool showing) { [cocoa_view_ setShowingContextMenu:showing]; } -void RenderWidgetHostNSViewBridgeLocal::OnDisplayMetricsChanged( +void RenderWidgetHostNSViewBridge::OnDisplayMetricsChanged( const display::Display& display, uint32_t changed_metrics) { // Note that -updateScreenProperties is also be called by the notification @@ -216,21 +213,22 @@ [cocoa_view_ updateScreenProperties]; } -void RenderWidgetHostNSViewBridgeLocal::DisplayCursor(const WebCursor& cursor) { - WebCursor non_const_cursor(cursor); +void RenderWidgetHostNSViewBridge::DisplayCursor( + const content::WebCursor& cursor) { + content::WebCursor non_const_cursor(cursor); [cocoa_view_ updateCursor:non_const_cursor.GetNativeCursor()]; } -void RenderWidgetHostNSViewBridgeLocal::SetCursorLocked(bool locked) { +void RenderWidgetHostNSViewBridge::SetCursorLocked(bool locked) { [cocoa_view_ setCursorLocked:locked]; } -void RenderWidgetHostNSViewBridgeLocal::ShowDictionaryOverlayForSelection() { +void RenderWidgetHostNSViewBridge::ShowDictionaryOverlayForSelection() { NSRange selection_range = [cocoa_view_ selectedRange]; [cocoa_view_ showLookUpDictionaryOverlayFromRange:selection_range]; } -void RenderWidgetHostNSViewBridgeLocal::ShowDictionaryOverlay( +void RenderWidgetHostNSViewBridge::ShowDictionaryOverlay( const mac::AttributedStringCoder::EncodedString& encoded_string, const gfx::Point& baseline_point) { NSAttributedString* string = @@ -238,13 +236,14 @@ if ([string length] == 0) return; NSPoint flipped_baseline_point = { - baseline_point.x(), [cocoa_view_ frame].size.height - baseline_point.y(), + baseline_point.x(), + [cocoa_view_ frame].size.height - baseline_point.y(), }; [cocoa_view_ showDefinitionForAttributedString:string atPoint:flipped_baseline_point]; } -void RenderWidgetHostNSViewBridgeLocal::LockKeyboard( +void RenderWidgetHostNSViewBridge::LockKeyboard( const base::Optional<std::vector<uint32_t>>& uint_dom_codes) { base::Optional<base::flat_set<ui::DomCode>> dom_codes; if (uint_dom_codes) { @@ -255,8 +254,8 @@ [cocoa_view_ lockKeyboard:std::move(dom_codes)]; } -void RenderWidgetHostNSViewBridgeLocal::UnlockKeyboard() { +void RenderWidgetHostNSViewBridge::UnlockKeyboard() { [cocoa_view_ unlockKeyboard]; } -} // namespace content +} // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h b/content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h similarity index 79% rename from content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h rename to content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h index 757f0c4..9bbc9736 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h +++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.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_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_ -#define CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_ +#ifndef CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_HOST_HELPER_H_ +#define CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_HOST_HELPER_H_ #include "base/macros.h" @@ -21,24 +21,26 @@ } // namespace ui namespace content { - -namespace mojom { -class RenderWidgetHostNSViewClient; -} // namespace mojom - struct EditCommand; struct NativeWebKeyboardEvent; +} // namespace content + +namespace remote_cocoa { + +namespace mojom { +class RenderWidgetHostNSViewHost; +} // namespace mojom // An interface through which the NSView for a RenderWidgetHostViewMac is to // communicate with the RenderWidgetHostViewMac (potentially in another -// process). Unlike mojom::RenderWidgetHostNSViewClient, this object is always +// process). Unlike mojom::RenderWidgetHostNSViewHost, this object is always // instantiated in the local process. This is to implement functions that // cannot be sent across mojo or to avoid unnecessary translation of event // types. -class RenderWidgetHostNSViewClientHelper { +class RenderWidgetHostNSViewHostHelper { public: - RenderWidgetHostNSViewClientHelper() {} - virtual ~RenderWidgetHostNSViewClientHelper() {} + RenderWidgetHostNSViewHostHelper() {} + virtual ~RenderWidgetHostNSViewHostHelper() {} // Return the RenderWidget's BrowserAccessibilityManager's root accessibility // node. @@ -52,12 +54,13 @@ // Forward a keyboard event to the RenderWidgetHost that is currently handling // the key-down event. - virtual void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event, - const ui::LatencyInfo& latency_info) = 0; + virtual void ForwardKeyboardEvent( + const content::NativeWebKeyboardEvent& key_event, + const ui::LatencyInfo& latency_info) = 0; virtual void ForwardKeyboardEventWithCommands( - const NativeWebKeyboardEvent& key_event, + const content::NativeWebKeyboardEvent& key_event, const ui::LatencyInfo& latency_info, - const std::vector<EditCommand>& commands) = 0; + const std::vector<content::EditCommand>& commands) = 0; // Forward events to the renderer or the input router, as appropriate. virtual void RouteOrProcessMouseEvent( @@ -81,9 +84,9 @@ const blink::WebGestureEvent& smart_magnify_event) = 0; private: - DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewClientHelper); + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewHostHelper); }; -} // namespace content +} // namespace remote_cocoa -#endif // CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_ +#endif // CONTENT_APP_SHIM_REMOTE_COCOA_RENDER_WIDGET_HOST_NS_VIEW_HOST_HELPER_H_
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h index b8eb522..0013b7c 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h +++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h
@@ -24,27 +24,29 @@ namespace blink { class WebGestureEvent; -} +} // namespace blink namespace content { -namespace mojom { -class RenderWidgetHostNSViewClient; -} - -class RenderWidgetHostNSViewClientHelper; class RenderWidgetHostViewMac; class RenderWidgetHostViewMacEditCommandHelper; -} +} // namespace content + +namespace remote_cocoa { +namespace mojom { +class RenderWidgetHostNSViewHost; +} // namespace mojom +class RenderWidgetHostNSViewHostHelper; +} // namespace remote_cocoa namespace ui { enum class DomCode; struct DidOverscrollParams; -} +} // namespace ui @protocol RenderWidgetHostViewMacDelegate; -@protocol RenderWidgetHostNSViewClientOwner -- (content::mojom::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient; +@protocol RenderWidgetHostNSViewHostOwner +- (remote_cocoa::mojom::RenderWidgetHostNSViewHost*)renderWidgetHostNSViewHost; @end // This is the view that lives in the Cocoa view hierarchy. In Windows-land, @@ -54,29 +56,29 @@ // TODO(ccameron): Hide this interface behind RenderWidgetHostNSViewBridge. @interface RenderWidgetHostViewCocoa : ToolTipBaseView <CommandDispatcherTarget, - RenderWidgetHostNSViewClientOwner, + RenderWidgetHostNSViewHostOwner, NSCandidateListTouchBarItemDelegate, NSTextInputClient, NSAccessibility> { @private // The communications channel to the RenderWidgetHostViewMac. This pointer is - // always valid. When the original client disconnects, |client_| is changed to - // point to |dummyClient_|, to avoid having to preface every dereference with + // always valid. When the original host disconnects, |host_| is changed to + // point to |dummyHost_|, to avoid having to preface every dereference with // a nullptr check. - content::mojom::RenderWidgetHostNSViewClient* client_; + remote_cocoa::mojom::RenderWidgetHostNSViewHost* host_; - // A separate client interface for the parts of the interface to + // A separate host interface for the parts of the interface to // RenderWidgetHostViewMac that cannot or should not be forwarded over mojo. // This includes events (where the extra translation is unnecessary or loses // information) and access to accessibility structures (only present in the // browser process). - content::RenderWidgetHostNSViewClientHelper* clientHelper_; + remote_cocoa::RenderWidgetHostNSViewHostHelper* hostHelper_; - // Dummy client and client helper that are always valid (see above comments - // about client_). - content::mojom::RenderWidgetHostNSViewClientPtr dummyClient_; - std::unique_ptr<content::RenderWidgetHostNSViewClientHelper> - dummyClientHelper_; + // Dummy host and host helper that are always valid (see above comments + // about host_). + remote_cocoa::mojom::RenderWidgetHostNSViewHostPtr dummyHost_; + std::unique_ptr<remote_cocoa::RenderWidgetHostNSViewHostHelper> + dummyHostHelper_; // This ivar is the cocoa delegate of the NSResponder. base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate>> @@ -98,7 +100,7 @@ // Controlled by setShowingContextMenu. BOOL showingContextMenu_; - // Set during -setFrame to avoid spamming client_ with origin and size + // Set during -setFrame to avoid spamming host_ with origin and size // changes. BOOL inSetFrame_; @@ -228,8 +230,8 @@ - (void)setCanBeKeyView:(BOOL)can; - (void)setCloseOnDeactivate:(BOOL)b; -// Inidicate that the client was destroyed and can't be called back into. -- (void)setClientDisconnected; +// Inidicate that the host was destroyed and can't be called back into. +- (void)setHostDisconnected; // True for always-on-top special windows (e.g. Balloons and Panels). - (BOOL)acceptsMouseEventsWhenInactive; // Cancel ongoing composition (abandon the marked text). @@ -242,7 +244,7 @@ - (void)showLookUpDictionaryOverlayFromRange:(NSRange)range; - (BOOL)suppressNextKeyUpForTesting:(int)keyCode; // Query the display::Display from the view's NSWindow's NSScreen and forward -// it to the RenderWidgetHostNSViewClient (only if the screen is non-nil). +// it to the RenderWidgetHostNSViewHost (only if the screen is non-nil). - (void)updateScreenProperties; // Indicate if the embedding WebContents is showing a web content context menu. - (void)setShowingContextMenu:(BOOL)showing; @@ -268,8 +270,8 @@ - (void)setAccessibilityParentElement:(id)accessibilityParent; // Methods previously marked as private. -- (id)initWithClient:(content::mojom::RenderWidgetHostNSViewClient*)client - withClientHelper:(content::RenderWidgetHostNSViewClientHelper*)clientHelper; +- (id)initWithHost:(remote_cocoa::mojom::RenderWidgetHostNSViewHost*)host + withHostHelper:(remote_cocoa::RenderWidgetHostNSViewHostHelper*)hostHelper; - (void)setResponderDelegate: (NSObject<RenderWidgetHostViewMacDelegate>*)delegate; - (void)processedGestureScrollEvent:(const blink::WebGestureEvent&)event
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm index 8284524..188fe917 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm +++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -38,8 +38,6 @@ using content::EditCommand; using content::InputEvent; using content::NativeWebKeyboardEvent; -using content::mojom::RenderWidgetHostNSViewClient; -using content::RenderWidgetHostNSViewClientHelper; using content::RenderWidgetHostViewMacEditCommandHelper; using content::WebGestureEventBuilder; using content::WebMouseEventBuilder; @@ -50,17 +48,19 @@ using blink::WebMouseWheelEvent; using blink::WebGestureEvent; using blink::WebTouchEvent; +using remote_cocoa::mojom::RenderWidgetHostNSViewHost; +using remote_cocoa::RenderWidgetHostNSViewHostHelper; namespace { -// A dummy RenderWidgetHostNSViewClientHelper implementation which no-ops all +// A dummy RenderWidgetHostNSViewHostHelper implementation which no-ops all // functions. -class DummyClientHelper : public RenderWidgetHostNSViewClientHelper { +class DummyHostHelper : public RenderWidgetHostNSViewHostHelper { public: - explicit DummyClientHelper() {} + explicit DummyHostHelper() {} private: - // RenderWidgetHostNSViewClientHelper implementation. + // RenderWidgetHostNSViewHostHelper implementation. id GetRootBrowserAccessibilityElement() override { return nil; } id GetFocusedBrowserAccessibilityElement() override { return nil; } void SetAccessibilityWindow(NSWindow* window) override {} @@ -84,7 +84,7 @@ void GestureEnd(blink::WebGestureEvent end_event) override {} void SmartMagnify(const blink::WebGestureEvent& web_event) override {} - DISALLOW_COPY_AND_ASSIGN(DummyClientHelper); + DISALLOW_COPY_AND_ASSIGN(DummyHostHelper); }; // Touch bar identifier. @@ -167,10 +167,10 @@ - (void)windowChangedGlobalFrame:(NSNotification*)notification; - (void)windowDidBecomeKey:(NSNotification*)notification; - (void)windowDidResignKey:(NSNotification*)notification; -- (void)sendViewBoundsInWindowToClient; +- (void)sendViewBoundsInWindowToHost; - (void)requestTextSuggestions API_AVAILABLE(macos(10.12.2)); -- (void)sendWindowFrameInScreenToClient; -- (bool)clientIsDisconnected; +- (void)sendWindowFrameInScreenToHost; +- (bool)hostIsDisconnected; - (void)invalidateTouchBar API_AVAILABLE(macos(10.12.2)); // NSCandidateListTouchBarItemDelegate implementation @@ -187,16 +187,16 @@ @synthesize textInputType = textInputType_; @synthesize spellCheckerForTesting = spellCheckerForTesting_; -- (id)initWithClient:(RenderWidgetHostNSViewClient*)client - withClientHelper:(RenderWidgetHostNSViewClientHelper*)clientHelper { +- (id)initWithHost:(RenderWidgetHostNSViewHost*)host + withHostHelper:(RenderWidgetHostNSViewHostHelper*)hostHelper { self = [super initWithFrame:NSZeroRect]; if (self) { self.acceptsTouchEvents = YES; editCommandHelper_.reset(new RenderWidgetHostViewMacEditCommandHelper); editCommandHelper_->AddEditingSelectorsToClass([self class]); - client_ = client; - clientHelper_ = clientHelper; + host_ = host; + hostHelper_ = hostHelper; canBeKeyView_ = YES; isStylusEnteringProximity_ = false; keyboardLockActive_ = false; @@ -209,7 +209,7 @@ } - (void)dealloc { - DCHECK([self clientIsDisconnected]); + DCHECK([self hostIsDisconnected]); [[NSNotificationCenter defaultCenter] removeObserver:self]; // Update and cache the new input context. Otherwise, @@ -222,16 +222,16 @@ [super dealloc]; } -- (void)sendViewBoundsInWindowToClient { +- (void)sendViewBoundsInWindowToHost { TRACE_EVENT0("browser", - "RenderWidgetHostViewCocoa::sendViewBoundsInWindowToClient"); + "RenderWidgetHostViewCocoa::sendViewBoundsInWindowToHost"); if (inSetFrame_) return; NSRect viewBoundsInView = [self bounds]; NSWindow* enclosingWindow = [self window]; if (!enclosingWindow) { - client_->OnBoundsInWindowChanged(gfx::Rect(viewBoundsInView), false); + host_->OnBoundsInWindowChanged(gfx::Rect(viewBoundsInView), false); return; } @@ -239,7 +239,7 @@ gfx::Rect gfxViewBoundsInWindow(viewBoundsInWindow); gfxViewBoundsInWindow.set_y(NSHeight([enclosingWindow frame]) - NSMaxY(viewBoundsInWindow)); - client_->OnBoundsInWindowChanged(gfxViewBoundsInWindow, true); + host_->OnBoundsInWindowChanged(gfxViewBoundsInWindow, true); } - (void)requestTextSuggestions { @@ -333,13 +333,13 @@ compositionRange_ = range; } -- (void)sendWindowFrameInScreenToClient { +- (void)sendWindowFrameInScreenToHost { TRACE_EVENT0("browser", - "RenderWidgetHostViewCocoa::sendWindowFrameInScreenToClient"); + "RenderWidgetHostViewCocoa::sendWindowFrameInScreenToHost"); NSWindow* enclosingWindow = [self window]; if (!enclosingWindow) return; - client_->OnWindowFrameInScreenChanged( + host_->OnWindowFrameInScreenChanged( gfx::ScreenRectFromNSRect([enclosingWindow frame])); } @@ -410,27 +410,27 @@ closeOnDeactivate_ = b; } -- (void)setClientDisconnected { - // Set the client to be an abandoned message pipe, and set the clientHelper - // to forward messages to that client. - content::mojom::RenderWidgetHostNSViewClientRequest dummyClientRequest = - mojo::MakeRequest(&dummyClient_); - dummyClientHelper_ = std::make_unique<DummyClientHelper>(); - client_ = dummyClient_.get(); - clientHelper_ = dummyClientHelper_.get(); +- (void)setHostDisconnected { + // Set the host to be an abandoned message pipe, and set the hostHelper + // to forward messages to that host. + remote_cocoa::mojom::RenderWidgetHostNSViewHostRequest dummyHostRequest = + mojo::MakeRequest(&dummyHost_); + dummyHostHelper_ = std::make_unique<DummyHostHelper>(); + host_ = dummyHost_.get(); + hostHelper_ = dummyHostHelper_.get(); // |responderDelegate_| may attempt to access the RenderWidgetHostViewMac // through its internal pointers, so detach it here. - // TODO(ccameron): Force |responderDelegate_| to use the |client_| as well, - // and the viewGone method to clientGone. + // TODO(ccameron): Force |responderDelegate_| to use the |host_| as well, + // and the viewGone method to hostGone. if (responderDelegate_ && [responderDelegate_ respondsToSelector:@selector(viewGone:)]) [responderDelegate_ viewGone:self]; responderDelegate_.reset(); } -- (bool)clientIsDisconnected { - return client_ == dummyClient_.get(); +- (bool)hostIsDisconnected { + return host_ == dummyHost_.get(); } - (void)setShowingContextMenu:(BOOL)showing { @@ -460,7 +460,7 @@ WebMouseEvent web_event = WebMouseEventBuilder::Build(event, self); web_event.SetModifiers(web_event.GetModifiers() | WebInputEvent::kRelativeMotionEvent); - clientHelper_->ForwardMouseEvent(web_event); + hostHelper_->ForwardMouseEvent(web_event); } - (BOOL)shouldIgnoreMouseEvent:(NSEvent*)theEvent { @@ -556,7 +556,7 @@ WebMouseEventBuilder::Build(theEvent, self, pointerType_); exitEvent.SetType(WebInputEvent::kMouseLeave); exitEvent.button = WebMouseEvent::Button::kNoButton; - clientHelper_->ForwardMouseEvent(exitEvent); + hostHelper_->ForwardMouseEvent(exitEvent); } mouseEventWasIgnored_ = YES; [self updateCursor:nil]; @@ -570,14 +570,14 @@ WebMouseEventBuilder::Build(theEvent, self, pointerType_); enterEvent.SetType(WebInputEvent::kMouseMove); enterEvent.button = WebMouseEvent::Button::kNoButton; - clientHelper_->RouteOrProcessMouseEvent(enterEvent); + hostHelper_->RouteOrProcessMouseEvent(enterEvent); } mouseEventWasIgnored_ = NO; // Don't cancel child popups; killing them on a mouse click would prevent the // user from positioning the insertion point in the text field spawning the // popup. A click outside the text field would cause the text field to drop - // the focus, and then EditorClientImpl::textFieldDidEndEditing() would cancel + // the focus, and then EditorHostImpl::textFieldDidEndEditing() would cancel // the popup anyway, so we're OK. if (type == NSLeftMouseDown) hasOpenMouseDown_ = YES; @@ -625,10 +625,10 @@ WebMouseEvent event = WebMouseEventBuilder::Build(theEvent, self, pointerType_); last_mouse_screen_position_ = event.PositionInScreen(); - clientHelper_->RouteOrProcessMouseEvent(event); + hostHelper_->RouteOrProcessMouseEvent(event); } else { WebTouchEvent event = WebTouchEventBuilder::Build(theEvent, self); - clientHelper_->RouteOrProcessTouchEvent(event); + hostHelper_->RouteOrProcessTouchEvent(event); } } @@ -783,10 +783,10 @@ return; } - // Tell the client that we are beginning a keyboard event. This ensures that + // Tell the host that we are beginning a keyboard event. This ensures that // all event and Ime messages target the same RenderWidgetHost throughout this // function call. - client_->BeginKeyboardEvent(); + host_->BeginKeyboardEvent(); bool shouldAutohideCursor = textInputType_ != ui::TEXT_INPUT_TYPE_NONE && eventType == NSKeyDown && @@ -794,7 +794,7 @@ // We only handle key down events and just simply forward other events. if (eventType != NSKeyDown) { - clientHelper_->ForwardKeyboardEvent(event, latency_info); + hostHelper_->ForwardKeyboardEvent(event, latency_info); // Possibly autohide the cursor. if (shouldAutohideCursor) { @@ -802,7 +802,7 @@ cursorHidden_ = YES; } - client_->EndKeyboardEvent(); + host_->EndKeyboardEvent(); return; } @@ -852,7 +852,7 @@ NativeWebKeyboardEvent fakeEvent = event; fakeEvent.windows_key_code = 0xE5; // VKEY_PROCESSKEY fakeEvent.skip_in_browser = true; - clientHelper_->ForwardKeyboardEvent(fakeEvent, latency_info); + hostHelper_->ForwardKeyboardEvent(fakeEvent, latency_info); // If this key event was handled by the input method, but // -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above) // enqueued edit commands, then in order to let webkit handle them @@ -863,8 +863,8 @@ if (hasEditCommands_ && !hasMarkedText_) delayEventUntilAfterImeCompostion = YES; } else { - clientHelper_->ForwardKeyboardEventWithCommands(event, latency_info, - editCommands_); + hostHelper_->ForwardKeyboardEventWithCommands(event, latency_info, + editCommands_); } // Then send keypress and/or composition related events. @@ -881,7 +881,7 @@ BOOL textInserted = NO; if (textToBeInserted_.length() > ((hasMarkedText_ || oldHasMarkedText) ? 0u : 1u)) { - client_->ImeCommitText(textToBeInserted_, gfx::Range::InvalidRange()); + host_->ImeCommitText(textToBeInserted_, gfx::Range::InvalidRange()); textInserted = YES; } @@ -892,15 +892,15 @@ // composition node in WebKit. // When marked text is available, |markedTextSelectedRange_| will be the // range being selected inside the marked text. - client_->ImeSetComposition(markedText_, ime_text_spans_, - setMarkedTextReplacementRange_, - markedTextSelectedRange_.location, - NSMaxRange(markedTextSelectedRange_)); + host_->ImeSetComposition(markedText_, ime_text_spans_, + setMarkedTextReplacementRange_, + markedTextSelectedRange_.location, + NSMaxRange(markedTextSelectedRange_)); } else if (oldHasMarkedText && !hasMarkedText_ && !textInserted) { if (unmarkTextCalled_) { - client_->ImeFinishComposingText(); + host_->ImeFinishComposingText(); } else { - client_->ImeCancelCompositionFromCocoa(); + host_->ImeCancelCompositionFromCocoa(); } } @@ -922,8 +922,8 @@ fakeEvent.skip_in_browser = true; ui::LatencyInfo fake_event_latency_info = latency_info; fake_event_latency_info.set_source_event_type(ui::SourceEventType::OTHER); - clientHelper_->ForwardKeyboardEvent(fakeEvent, fake_event_latency_info); - clientHelper_->ForwardKeyboardEventWithCommands( + hostHelper_->ForwardKeyboardEvent(fakeEvent, fake_event_latency_info); + hostHelper_->ForwardKeyboardEventWithCommands( event, fake_event_latency_info, editCommands_); } @@ -937,7 +937,7 @@ event.text[0] = textToBeInserted_[0]; event.text[1] = 0; event.skip_in_browser = true; - clientHelper_->ForwardKeyboardEvent(event, latency_info); + hostHelper_->ForwardKeyboardEvent(event, latency_info); } else if ((!textInserted || delayEventUntilAfterImeCompostion) && event.text[0] != '\0' && ((modifierFlags & kCtrlCmdKeyMask) || @@ -947,7 +947,7 @@ // cases, unless the key event generated any other command. event.SetType(blink::WebInputEvent::kChar); event.skip_in_browser = true; - clientHelper_->ForwardKeyboardEvent(event, latency_info); + hostHelper_->ForwardKeyboardEvent(event, latency_info); } } @@ -957,7 +957,7 @@ cursorHidden_ = YES; } - client_->EndKeyboardEvent(); + host_->EndKeyboardEvent(); } - (BOOL)suppressNextKeyUpForTesting:(int)keyCode { @@ -978,7 +978,7 @@ // History-swiping is not possible if the logic reaches this point. WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self); webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent); - clientHelper_->ForwardWheelEvent(webEvent); + hostHelper_->ForwardWheelEvent(webEvent); if (endWheelMonitor_) { [NSEvent removeMonitor:endWheelMonitor_]; @@ -992,7 +992,7 @@ WebGestureEvent gestureBeginEvent(WebGestureEventBuilder::Build(event, self)); - clientHelper_->GestureBegin(gestureBeginEvent, isSyntheticallyInjected); + hostHelper_->GestureBegin(gestureBeginEvent, isSyntheticallyInjected); } - (void)handleEndGestureWithEvent:(NSEvent*)event { @@ -1007,7 +1007,7 @@ endEvent.SetType(WebInputEvent::kGesturePinchEnd); endEvent.SetSourceDevice(blink::WebGestureDevice::kTouchpad); endEvent.SetNeedsWheelEvent(true); - clientHelper_->GestureEnd(endEvent); + hostHelper_->GestureEnd(endEvent); } } @@ -1062,11 +1062,11 @@ - (void)smartMagnifyWithEvent:(NSEvent*)event { const WebGestureEvent& smartMagnifyEvent = WebGestureEventBuilder::Build(event, self); - clientHelper_->SmartMagnify(smartMagnifyEvent); + hostHelper_->SmartMagnify(smartMagnifyEvent); } - (void)showLookUpDictionaryOverlayFromRange:(NSRange)range { - client_->LookUpDictionaryOverlayFromRange(gfx::Range(range)); + host_->LookUpDictionaryOverlayFromRange(gfx::Range(range)); } // This is invoked only on 10.8 or newer when the user taps a word using @@ -1074,7 +1074,7 @@ - (void)quickLookWithEvent:(NSEvent*)event { NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; gfx::PointF rootPoint(point.x, NSHeight([self frame]) - point.y); - client_->LookUpDictionaryOverlayAtPoint(rootPoint); + host_->LookUpDictionaryOverlayAtPoint(rootPoint); } // This method handles 2 different types of hardware events. @@ -1144,7 +1144,7 @@ // This is responsible for content scrolling! WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self); webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent); - clientHelper_->RouteOrProcessWheelEvent(webEvent); + hostHelper_->RouteOrProcessWheelEvent(webEvent); } // Called repeatedly during a pinch gesture, with incremental change values. @@ -1177,7 +1177,7 @@ } WebGestureEvent updateEvent = WebGestureEventBuilder::Build(event, self); - clientHelper_->GestureUpdate(updateEvent); + hostHelper_->GestureUpdate(updateEvent); } - (void)viewWillMoveToWindow:(NSWindow*)newWindow { @@ -1228,8 +1228,8 @@ object:newWindow]; } - clientHelper_->SetAccessibilityWindow(newWindow); - [self sendWindowFrameInScreenToClient]; + hostHelper_->SetAccessibilityWindow(newWindow); + [self sendWindowFrameInScreenToHost]; } - (void)updateScreenProperties { @@ -1238,10 +1238,10 @@ return; // TODO(ccameron): This will call [enclosingWindow screen], which may return - // nil. Do that call here to avoid sending bogus display info to the client. + // nil. Do that call here to avoid sending bogus display info to the host. display::Display display = display::Screen::GetScreen()->GetDisplayNearestView(self); - client_->OnDisplayChanged(display); + host_->OnDisplayChanged(display); } // This will be called when the NSView's NSWindow moves from one NSScreen to @@ -1257,42 +1257,42 @@ } - (void)windowChangedGlobalFrame:(NSNotification*)notification { - [self sendWindowFrameInScreenToClient]; + [self sendWindowFrameInScreenToHost]; // Update the view bounds relative to the window, as they may have changed // during layout, and we don't explicitly listen for re-layout of parent // views. - [self sendViewBoundsInWindowToClient]; + [self sendViewBoundsInWindowToHost]; } - (void)setFrame:(NSRect)r { // Note that -setFrame: calls through -setFrameSize: and -setFrameOrigin. To - // avoid spamming the client with transiently invalid states, only send one + // avoid spamming the host with transiently invalid states, only send one // message at the end. inSetFrame_ = YES; [super setFrame:r]; inSetFrame_ = NO; - [self sendViewBoundsInWindowToClient]; + [self sendViewBoundsInWindowToHost]; } - (void)setFrameOrigin:(NSPoint)newOrigin { [super setFrameOrigin:newOrigin]; - [self sendViewBoundsInWindowToClient]; + [self sendViewBoundsInWindowToHost]; } - (void)setFrameSize:(NSSize)newSize { [super setFrameSize:newSize]; - [self sendViewBoundsInWindowToClient]; + [self sendViewBoundsInWindowToHost]; } - (BOOL)canBecomeKeyView { - if ([self clientIsDisconnected]) + if ([self hostIsDisconnected]) return NO; return canBeKeyView_; } - (BOOL)acceptsFirstResponder { - if ([self clientIsDisconnected]) + if ([self hostIsDisconnected]) return NO; return canBeKeyView_; @@ -1304,7 +1304,7 @@ if ([responderDelegate_ respondsToSelector:@selector(windowDidBecomeKey)]) [responderDelegate_ windowDidBecomeKey]; if ([self window].isKeyWindow) - client_->OnWindowIsKeyChanged(true); + host_->OnWindowIsKeyChanged(true); } - (void)windowDidResignKey:(NSNotification*)notification { @@ -1318,16 +1318,16 @@ if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) return; - client_->OnWindowIsKeyChanged(false); + host_->OnWindowIsKeyChanged(false); } - (BOOL)becomeFirstResponder { - if ([self clientIsDisconnected]) + if ([self hostIsDisconnected]) return NO; if ([responderDelegate_ respondsToSelector:@selector(becomeFirstResponder)]) [responderDelegate_ becomeFirstResponder]; - client_->OnFirstResponderChanged(true); + host_->OnFirstResponderChanged(true); // Cancel any onging composition text which was left before we lost focus. // TODO(suzhe): We should do it in -resignFirstResponder: method, but @@ -1351,10 +1351,10 @@ if ([responderDelegate_ respondsToSelector:@selector(resignFirstResponder)]) [responderDelegate_ resignFirstResponder]; - client_->OnFirstResponderChanged(false); + host_->OnFirstResponderChanged(false); if (closeOnDeactivate_) { [self setHidden:YES]; - client_->RequestShutdown(); + host_->RequestShutdown(); } // We should cancel any onging composition whenever RWH's Blur() method gets @@ -1377,10 +1377,10 @@ } bool is_for_main_frame = false; - client_->SyncIsWidgetForMainFrame(&is_for_main_frame); + host_->SyncIsWidgetForMainFrame(&is_for_main_frame); bool is_speaking = false; - client_->SyncIsSpeaking(&is_speaking); + host_->SyncIsSpeaking(&is_speaking); SEL action = [item action]; @@ -1403,8 +1403,8 @@ return editCommandHelper_->IsMenuItemEnabled(action, self); } -- (RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient { - return client_; +- (RenderWidgetHostNSViewHost*)renderWidgetHostNSViewHost { + return host_; } - (void)setAccessibilityParentElement:(id)accessibilityParent { @@ -1412,7 +1412,7 @@ } - (id)accessibilityHitTest:(NSPoint)point { - id root_element = clientHelper_->GetRootBrowserAccessibilityElement(); + id root_element = hostHelper_->GetRootBrowserAccessibilityElement(); if (!root_element) return self; NSPoint pointInWindow = @@ -1424,13 +1424,13 @@ } - (id)accessibilityFocusedUIElement { - return clientHelper_->GetFocusedBrowserAccessibilityElement(); + return hostHelper_->GetFocusedBrowserAccessibilityElement(); } // NSAccessibility formal protocol: - (NSArray*)accessibilityChildren { - id root = clientHelper_->GetRootBrowserAccessibilityElement(); + id root = hostHelper_->GetRootBrowserAccessibilityElement(); if (root) return @[ root ]; return nil; @@ -1458,7 +1458,7 @@ // [WebHTMLView keyDown] -> // EventHandler::keyEvent() -> // ... -// [WebEditorClient handleKeyboardEvent] -> +// [WebEditorHost handleKeyboardEvent] -> // [WebHTMLView _interceptEditingKeyEvent] -> // [NSResponder interpretKeyEvents] -> // [WebHTMLView insertText] -> @@ -1475,7 +1475,7 @@ // |Sync IPC (KeyDown)| (*1) -> // EventHandler::keyEvent() (renderer) -> // ... -// EditorClientImpl::handleKeyboardEvent() (renderer) -> +// EditorHostImpl::handleKeyboardEvent() (renderer) -> // |Sync IPC| (*2) -> // [RenderWidgetHostViewMac _interceptEditingKeyEvent] (browser) -> // [self interpretKeyEvents] -> @@ -1485,7 +1485,7 @@ // // (*1) we need to wait until this call finishes since WebHTMLView uses the // result of EventHandler::keyEvent(). -// (*2) we need to wait until this call finishes since WebEditorClient uses +// (*2) we need to wait until this call finishes since WebEditorHost uses // the result of [WebHTMLView _interceptEditingKeyEvent]. // // This needs many sync IPC messages sent between a browser and a renderer for @@ -1532,7 +1532,7 @@ gfx::PointF rootPoint(thePoint.x, thePoint.y); uint32_t index = UINT32_MAX; - client_->SyncGetCharacterIndexAtPoint(rootPoint, &index); + host_->SyncGetCharacterIndexAtPoint(rootPoint, &index); // |index| could be WTF::notFound (-1) and its value is different from // NSNotFound so we need to convert it. if (index == UINT32_MAX) @@ -1548,9 +1548,8 @@ bool success = false; if (actualRange) gfxActualRange = gfx::Range(*actualRange); - client_->SyncGetFirstRectForRange(gfx::Range(theRange), gfxRect, - gfxActualRange, &gfxRect, &gfxActualRange, - &success); + host_->SyncGetFirstRectForRange(gfx::Range(theRange), gfxRect, gfxActualRange, + &gfxRect, &gfxActualRange, &success); if (!success) { // The call to cancelComposition comes from https://crrev.com/350261. [self cancelComposition]; @@ -1674,7 +1673,7 @@ // If we are handling a key down event, then FinishComposingText() will be // called in keyEvent: method. if (!handlingKeyDown_) { - client_->ImeFinishComposingText(); + host_->ImeFinishComposingText(); } else { unmarkTextCalled_ = YES; } @@ -1717,9 +1716,9 @@ if (handlingKeyDown_) { setMarkedTextReplacementRange_ = gfx::Range(replacementRange); } else { - client_->ImeSetComposition(markedText_, ime_text_spans_, - gfx::Range(replacementRange), - newSelRange.location, NSMaxRange(newSelRange)); + host_->ImeSetComposition(markedText_, ime_text_spans_, + gfx::Range(replacementRange), newSelRange.location, + NSMaxRange(newSelRange)); } } @@ -1745,7 +1744,7 @@ base::CompareCase::INSENSITIVE_ASCII)) editCommands_.push_back(EditCommand(command, "")); } else { - client_->ExecuteEditCommand(command); + host_->ExecuteEditCommand(command); } } @@ -1771,8 +1770,7 @@ textToBeInserted_.append(base::SysNSStringToUTF16(im_text)); } else { gfx::Range replacement_range(replacementRange); - client_->ImeCommitText(base::SysNSStringToUTF16(im_text), - replacement_range); + host_->ImeCommitText(base::SysNSStringToUTF16(im_text), replacement_range); } // Inserting text will delete all marked text automatically. @@ -1786,11 +1784,11 @@ - (void)viewDidMoveToWindow { // Update the window's frame, the view's bounds, focus, and the display info, // as they have not been updated while unattached to a window. - [self sendWindowFrameInScreenToClient]; - [self sendViewBoundsInWindowToClient]; + [self sendWindowFrameInScreenToHost]; + [self sendViewBoundsInWindowToHost]; [self updateScreenProperties]; - client_->OnWindowIsKeyChanged([[self window] isKeyWindow]); - client_->OnFirstResponderChanged([[self window] firstResponder] == self); + host_->OnWindowIsKeyChanged([[self window] isKeyWindow]); + host_->OnFirstResponderChanged([[self window] firstResponder] == self); // If we switch windows (or are removed from the view hierarchy), cancel any // open mouse-downs. @@ -1798,37 +1796,37 @@ WebMouseEvent event(WebInputEvent::kMouseUp, WebInputEvent::kNoModifiers, ui::EventTimeForNow()); event.button = WebMouseEvent::Button::kLeft; - clientHelper_->ForwardMouseEvent(event); + hostHelper_->ForwardMouseEvent(event); hasOpenMouseDown_ = NO; } } - (void)undo:(id)sender { - client_->Undo(); + host_->Undo(); } - (void)redo:(id)sender { - client_->Redo(); + host_->Redo(); } - (void)cut:(id)sender { - client_->Cut(); + host_->Cut(); } - (void)copy:(id)sender { - client_->Copy(); + host_->Copy(); } - (void)copyToFindPboard:(id)sender { - client_->CopyToFindPboard(); + host_->CopyToFindPboard(); } - (void)paste:(id)sender { - client_->Paste(); + host_->Paste(); } - (void)pasteAndMatchStyle:(id)sender { - client_->PasteAndMatchStyle(); + host_->PasteAndMatchStyle(); } - (void)selectAll:(id)sender { @@ -1839,15 +1837,15 @@ // menu handler, neither is true. // Explicitly call SelectAll() here to make sure the renderer returns // selection results. - client_->SelectAll(); + host_->SelectAll(); } - (void)startSpeaking:(id)sender { - client_->StartSpeaking(); + host_->StartSpeaking(); } - (void)stopSpeaking:(id)sender { - client_->StopSpeaking(); + host_->StopSpeaking(); } - (void)cancelComposition { @@ -1866,7 +1864,7 @@ if (!hasMarkedText_) return; - client_->ImeFinishComposingText(); + host_->ImeFinishComposingText(); [self cancelComposition]; } @@ -1926,7 +1924,7 @@ - (void)popupWindowWillClose:(NSNotification*)notification { [self setHidden:YES]; - client_->RequestShutdown(); + host_->RequestShutdown(); } - (void)invalidateTouchBar {
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h index c7f2875..7f1d237 100644 --- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h +++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
@@ -18,26 +18,27 @@ @class WebContentsViewCocoa; namespace content { - class WebContentsViewMac; +} // namespace content + +namespace remote_cocoa { // A wrapper around a WebContentsViewCocoa, to be accessed via the mojo // interface WebContentsNSViewBridge. -class CONTENT_EXPORT WebContentsNSViewBridge - : public mojom::WebContentsNSViewBridge { +class CONTENT_EXPORT WebContentsNSViewBridge : public mojom::WebContentsNSView { public: // Create a bridge that will access its client in another process via a mojo // interface. WebContentsNSViewBridge(uint64_t view_id, - mojom::WebContentsNSViewClientAssociatedPtr client); + mojom::WebContentsNSViewHostAssociatedPtr client); // Create a bridge that will access its client directly in-process. // TODO(ccameron): Change this to expose only the mojom::WebContentsNSView // when all communication is through mojo. WebContentsNSViewBridge(uint64_t view_id, - WebContentsViewMac* web_contents_view); + content::WebContentsViewMac* web_contents_view); ~WebContentsNSViewBridge() override; - WebContentsViewCocoa* cocoa_view() const { return cocoa_view_.get(); } + WebContentsViewCocoa* GetNSView() const { return ns_view_.get(); } // mojom::WebContentsNSViewBridge: void SetParentNSView(uint64_t parent_ns_view_id) override; @@ -46,16 +47,16 @@ void SetVisible(bool visible) override; void MakeFirstResponder() override; void TakeFocus(bool reverse) override; - void StartDrag(const DropData& drop_data, + void StartDrag(const content::DropData& drop_data, uint32_t operation_mask, const gfx::ImageSkia& image, const gfx::Vector2d& image_offset) override; private: - base::scoped_nsobject<WebContentsViewCocoa> cocoa_view_; - mojom::WebContentsNSViewClientAssociatedPtr client_; + base::scoped_nsobject<WebContentsViewCocoa> ns_view_; + mojom::WebContentsNSViewHostAssociatedPtr host_; - std::unique_ptr<remote_cocoa::ScopedNSViewIdMapping> view_id_; + std::unique_ptr<ScopedNSViewIdMapping> view_id_; DISALLOW_COPY_AND_ASSIGN(WebContentsNSViewBridge); };
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm index c5815d1..be4f275 100644 --- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm +++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
@@ -9,27 +9,27 @@ #include "content/browser/web_contents/web_contents_view_mac.h" #include "ui/gfx/image/image_skia_util_mac.h" -namespace content { +namespace remote_cocoa { WebContentsNSViewBridge::WebContentsNSViewBridge( uint64_t view_id, - mojom::WebContentsNSViewClientAssociatedPtr client) - : client_(std::move(client)) { - cocoa_view_.reset( + mojom::WebContentsNSViewHostAssociatedPtr client) + : host_(std::move(client)) { + ns_view_.reset( [[WebContentsViewCocoa alloc] initWithViewsHostableView:nullptr]); - [cocoa_view_ setClient:client_.get()]; + [ns_view_ setHost:host_.get()]; view_id_ = std::make_unique<remote_cocoa::ScopedNSViewIdMapping>( - view_id, cocoa_view_.get()); + view_id, ns_view_.get()); } WebContentsNSViewBridge::WebContentsNSViewBridge( uint64_t view_id, - WebContentsViewMac* web_contents_view) { - cocoa_view_.reset([[WebContentsViewCocoa alloc] + content::WebContentsViewMac* web_contents_view) { + ns_view_.reset([[WebContentsViewCocoa alloc] initWithViewsHostableView:web_contents_view]); - [cocoa_view_ setClient:web_contents_view]; + [ns_view_ setHost:web_contents_view]; view_id_ = std::make_unique<remote_cocoa::ScopedNSViewIdMapping>( - view_id, cocoa_view_.get()); + view_id, ns_view_.get()); } WebContentsNSViewBridge::~WebContentsNSViewBridge() { @@ -37,24 +37,24 @@ // while the user was operating a UI control which resulted in a // close. In that case, the Cocoa view outlives the // WebContentsViewMac instance due to Cocoa retain count. - [cocoa_view_ setClient:nullptr]; - [cocoa_view_ clearViewsHostableView]; - [cocoa_view_ removeFromSuperview]; + [ns_view_ setHost:nullptr]; + [ns_view_ clearViewsHostableView]; + [ns_view_ removeFromSuperview]; } void WebContentsNSViewBridge::SetParentNSView(uint64_t parent_ns_view_id) { NSView* parent_ns_view = remote_cocoa::GetNSViewFromId(parent_ns_view_id); // If the browser passed an invalid handle, then there is no recovery. CHECK(parent_ns_view); - [parent_ns_view addSubview:cocoa_view_]; + [parent_ns_view addSubview:ns_view_]; } void WebContentsNSViewBridge::ResetParentNSView() { - [cocoa_view_ removeFromSuperview]; + [ns_view_ removeFromSuperview]; } void WebContentsNSViewBridge::SetBounds(const gfx::Rect& bounds_in_window) { - NSWindow* window = [cocoa_view_ window]; + NSWindow* window = [ns_view_ window]; NSRect window_content_rect = [window contentRectForFrameRect:[window frame]]; NSRect ns_bounds_in_window = NSMakeRect(bounds_in_window.x(), @@ -62,36 +62,36 @@ bounds_in_window.height(), bounds_in_window.width(), bounds_in_window.height()); NSRect ns_bounds_in_superview = - [[cocoa_view_ superview] convertRect:ns_bounds_in_window fromView:nil]; - [cocoa_view_ setFrame:ns_bounds_in_superview]; + [[ns_view_ superview] convertRect:ns_bounds_in_window fromView:nil]; + [ns_view_ setFrame:ns_bounds_in_superview]; } void WebContentsNSViewBridge::SetVisible(bool visible) { - [cocoa_view_ setHidden:!visible]; + [ns_view_ setHidden:!visible]; } void WebContentsNSViewBridge::MakeFirstResponder() { - if ([cocoa_view_ acceptsFirstResponder]) - [[cocoa_view_ window] makeFirstResponder:cocoa_view_]; + if ([ns_view_ acceptsFirstResponder]) + [[ns_view_ window] makeFirstResponder:ns_view_]; } void WebContentsNSViewBridge::TakeFocus(bool reverse) { if (reverse) - [[cocoa_view_ window] selectPreviousKeyView:cocoa_view_]; + [[ns_view_ window] selectPreviousKeyView:ns_view_]; else - [[cocoa_view_ window] selectNextKeyView:cocoa_view_]; + [[ns_view_ window] selectNextKeyView:ns_view_]; } -void WebContentsNSViewBridge::StartDrag(const DropData& drop_data, +void WebContentsNSViewBridge::StartDrag(const content::DropData& drop_data, uint32_t operation_mask, const gfx::ImageSkia& image, const gfx::Vector2d& image_offset) { NSPoint offset = NSPointFromCGPoint( gfx::PointAtOffsetFromOrigin(image_offset).ToCGPoint()); - [cocoa_view_ startDragWithDropData:drop_data - dragOperationMask:operation_mask - image:gfx::NSImageFromImageSkia(image) - offset:offset]; + [ns_view_ startDragWithDropData:drop_data + dragOperationMask:operation_mask + image:gfx::NSImageFromImageSkia(image) + offset:offset]; } -} // namespace content +} // namespace remote_cocoa
diff --git a/content/app_shim_remote_cocoa/web_contents_view_cocoa.h b/content/app_shim_remote_cocoa/web_contents_view_cocoa.h index 48529f4..230e259 100644 --- a/content/app_shim_remote_cocoa/web_contents_view_cocoa.h +++ b/content/app_shim_remote_cocoa/web_contents_view_cocoa.h
@@ -12,20 +12,23 @@ namespace content { struct DropData; -namespace mojom { -class WebContentsNSViewClient; -} // namespace mojom } // namespace content +namespace remote_cocoa { +namespace mojom { +class WebContentsNSViewHost; +} // namespace mojom +} // namespace remote_cocoa + @class WebDragSource; CONTENT_EXPORT @interface WebContentsViewCocoa : BaseView <ViewsHostable> { @private - // Instances of this class are owned by both client_ and AppKit. It is - // possible for an instance to outlive its webContentsView_. The client_ must - // call -clearClientAndView in its destructor. - content::mojom::WebContentsNSViewClient* client_; + // Instances of this class are owned by both host_ and AppKit. It is + // possible for an instance to outlive its webContentsView_. The host_ must + // call -clearHostAndView in its destructor. + remote_cocoa::mojom::WebContentsNSViewHost* host_; // The interface exported to views::Views that embed this as a sub-view. ui::ViewsHostableView* viewsHostableView_; @@ -36,7 +39,7 @@ // Set or un-set the mojo interface through which to communicate with the // browser process. -- (void)setClient:(content::mojom::WebContentsNSViewClient*)client; +- (void)setHost:(remote_cocoa::mojom::WebContentsNSViewHost*)host; - (void)setMouseDownCanMoveWindow:(BOOL)canMove;
diff --git a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm index 1bd2729..615fe67 100644 --- a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm +++ b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm
@@ -15,7 +15,9 @@ #include "ui/base/cocoa/cocoa_base_utils.h" #include "ui/base/dragdrop/cocoa_dnd_util.h" -using content::mojom::DraggingInfo; +using remote_cocoa::mojom::DraggingInfo; +using remote_cocoa::mojom::SelectionDirection; +using remote_cocoa::mojom::Visibility; using content::DropData; //////////////////////////////////////////////////////////////////////////////// @@ -92,10 +94,10 @@ } - (void)mouseEvent:(NSEvent*)theEvent { - if (!client_) + if (!host_) return; - client_->OnMouseEvent([theEvent type] == NSMouseMoved, - [theEvent type] == NSMouseExited); + host_->OnMouseEvent([theEvent type] == NSMouseMoved, + [theEvent type] == NSMouseExited); } - (void)setMouseDownCanMoveWindow:(BOOL)canMove { @@ -104,9 +106,9 @@ - (BOOL)mouseDownCanMoveWindow { // This is needed to prevent mouseDowns from moving the window - // around. The default implementation returns YES only for opaque - // views. WebContentsViewCocoa does not draw itself in any way, but - // its subviews do paint their entire frames. Returning NO here + // around. The default implementation returns YES only for opaque + // views. WebContentsViewCocoa does not draw itself in any way, but + // its subviews do paint their entire frames. Returning NO here // saves us the effort of overriding this method in every possible // subview. return mouseDownCanMoveWindow_; @@ -120,10 +122,10 @@ dragOperationMask:(NSDragOperation)operationMask image:(NSImage*)image offset:(NSPoint)offset { - if (!client_) + if (!host_) return; dragSource_.reset([[WebDragSource alloc] - initWithClient:client_ + initWithHost:host_ view:self dropData:&dropData image:image @@ -174,45 +176,45 @@ // NSDraggingDestination methods - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { - if (!client_) + if (!host_) return NSDragOperationNone; // Fill out a DropData from pasteboard. DropData dropData; content::PopulateDropDataFromPasteboard(&dropData, [sender draggingPasteboard]); - client_->SetDropData(dropData); + host_->SetDropData(dropData); auto draggingInfo = DraggingInfo::New(); [self populateDraggingInfo:draggingInfo.get() fromNSDraggingInfo:sender]; uint32_t result = 0; - client_->DraggingEntered(std::move(draggingInfo), &result); + host_->DraggingEntered(std::move(draggingInfo), &result); return result; } - (void)draggingExited:(id<NSDraggingInfo>)sender { - if (!client_) + if (!host_) return; - client_->DraggingExited(); + host_->DraggingExited(); } - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender { - if (!client_) + if (!host_) return NSDragOperationNone; auto draggingInfo = DraggingInfo::New(); [self populateDraggingInfo:draggingInfo.get() fromNSDraggingInfo:sender]; uint32_t result = 0; - client_->DraggingUpdated(std::move(draggingInfo), &result); + host_->DraggingUpdated(std::move(draggingInfo), &result); return result; } - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { - if (!client_) + if (!host_) return NO; auto draggingInfo = DraggingInfo::New(); [self populateDraggingInfo:draggingInfo.get() fromNSDraggingInfo:sender]; bool result = false; - client_->PerformDragOperation(std::move(draggingInfo), &result); + host_->PerformDragOperation(std::move(draggingInfo), &result); return result; } @@ -220,14 +222,14 @@ viewsHostableView_ = nullptr; } -- (void)setClient:(content::mojom::WebContentsNSViewClient*)client { - if (!client) - [dragSource_ clearClientAndWebContentsView]; - client_ = client; +- (void)setHost:(remote_cocoa::mojom::WebContentsNSViewHost*)host { + if (!host) + [dragSource_ clearHostAndWebContentsView]; + host_ = host; } - (void)viewDidBecomeFirstResponder:(NSNotification*)notification { - if (!client_) + if (!host_) return; NSView* view = [notification object]; @@ -238,34 +240,34 @@ static_cast<NSSelectionDirection>([[[notification userInfo] objectForKey:kSelectionDirection] unsignedIntegerValue]); - content::mojom::SelectionDirection direction; + SelectionDirection direction; switch (ns_direction) { case NSDirectSelection: - direction = content::mojom::SelectionDirection::kDirect; + direction = SelectionDirection::kDirect; break; case NSSelectingNext: - direction = content::mojom::SelectionDirection::kForward; + direction = SelectionDirection::kForward; break; case NSSelectingPrevious: - direction = content::mojom::SelectionDirection::kReverse; + direction = SelectionDirection::kReverse; break; default: return; } - client_->OnBecameFirstResponder(direction); + host_->OnBecameFirstResponder(direction); } - (void)updateWebContentsVisibility { - if (!client_) + if (!host_) return; - content::mojom::Visibility visibility = content::mojom::Visibility::kVisible; + Visibility visibility = Visibility::kVisible; if ([self isHiddenOrHasHiddenAncestor] || ![self window]) - visibility = content::mojom::Visibility::kHidden; + visibility = Visibility::kHidden; else if ([[self window] occlusionState] & NSWindowOcclusionStateVisible) - visibility = content::mojom::Visibility::kVisible; + visibility = Visibility::kVisible; else - visibility = content::mojom::Visibility::kOccluded; - client_->OnWindowVisibilityChanged(visibility); + visibility = Visibility::kOccluded; + host_->OnWindowVisibilityChanged(visibility); } - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
diff --git a/content/app_shim_remote_cocoa/web_drag_source_mac.h b/content/app_shim_remote_cocoa/web_drag_source_mac.h index 0a166e3f..3dc1b22 100644 --- a/content/app_shim_remote_cocoa/web_drag_source_mac.h +++ b/content/app_shim_remote_cocoa/web_drag_source_mac.h
@@ -18,19 +18,22 @@ namespace content { struct DropData; -namespace mojom { -class WebContentsNSViewClient; -} // namespace mojom } // namespace content +namespace remote_cocoa { +namespace mojom { +class WebContentsNSViewHost; +} // namespace mojom +} // namespace remote_cocoa + // A class that handles tracking and event processing for a drag and drop // originating from the content area. CONTENT_EXPORT @interface WebDragSource : NSObject { @private - // The client through which to communicate with the WebContentsImpl. Owns - // |self| and resets |client_| via clearClientAndWebContentsView. - content::mojom::WebContentsNSViewClient* client_; + // The host through which to communicate with the WebContentsImpl. Owns + // |self| and resets |host_| via clearHostAndWebContentsView. + remote_cocoa::mojom::WebContentsNSViewHost* host_; // The view from which the drag was initiated. Weak reference. // An instance of this class may outlive |contentsView_|. The destructor of @@ -65,16 +68,16 @@ // Initialize a WebDragSource object for a drag (originating on the given // contentsView and with the given dropData and pboard). Fill the pasteboard // with data types appropriate for dropData. -- (id)initWithClient:(content::mojom::WebContentsNSViewClient*)client - view:(NSView*)contentsView - dropData:(const content::DropData*)dropData - image:(NSImage*)image - offset:(NSPoint)offset - pasteboard:(NSPasteboard*)pboard - dragOperationMask:(NSDragOperation)dragOperationMask; +- (id)initWithHost:(remote_cocoa::mojom::WebContentsNSViewHost*)host + view:(NSView*)contentsView + dropData:(const content::DropData*)dropData + image:(NSImage*)image + offset:(NSPoint)offset + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask; // Call when the web contents is gone. -- (void)clearClientAndWebContentsView; +- (void)clearHostAndWebContentsView; // Returns a mask of the allowed drag operations. - (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
diff --git a/content/app_shim_remote_cocoa/web_drag_source_mac.mm b/content/app_shim_remote_cocoa/web_drag_source_mac.mm index d6f709c..1234fee 100644 --- a/content/app_shim_remote_cocoa/web_drag_source_mac.mm +++ b/content/app_shim_remote_cocoa/web_drag_source_mac.mm
@@ -49,15 +49,15 @@ @implementation WebDragSource -- (id)initWithClient:(content::mojom::WebContentsNSViewClient*)client - view:(NSView*)contentsView - dropData:(const DropData*)dropData - image:(NSImage*)image - offset:(NSPoint)offset - pasteboard:(NSPasteboard*)pboard - dragOperationMask:(NSDragOperation)dragOperationMask { +- (id)initWithHost:(remote_cocoa::mojom::WebContentsNSViewHost*)host + view:(NSView*)contentsView + dropData:(const DropData*)dropData + image:(NSImage*)image + offset:(NSPoint)offset + pasteboard:(NSPasteboard*)pboard + dragOperationMask:(NSDragOperation)dragOperationMask { if ((self = [super init])) { - client_ = client; + host_ = host; contentsView_ = contentsView; DCHECK(contentsView_); @@ -79,8 +79,8 @@ return self; } -- (void)clearClientAndWebContentsView { - client_ = nullptr; +- (void)clearHostAndWebContentsView { + host_ = nullptr; contentsView_ = nil; } @@ -206,7 +206,7 @@ - (void)endDragAt:(NSPoint)screenPoint operation:(NSDragOperation)operation { - if (!client_ || !contentsView_) + if (!host_ || !contentsView_) return; if (dragImage_) { @@ -229,7 +229,7 @@ if (operation == (NSDragOperationMove | NSDragOperationCopy)) operation &= ~NSDragOperationMove; - client_->EndDrag( + host_->EndDrag( operation, gfx::PointF(localPoint.x, viewFrame.size.height - localPoint.y), gfx::PointF(screenPoint.x, screenFrame.size.height - screenPoint.y)); @@ -239,7 +239,7 @@ } - (NSString*)dragPromisedFileTo:(NSString*)path { - if (!client_) + if (!host_) return nil; // Be extra paranoid; avoid crashing. if (!dropData_) { @@ -248,7 +248,7 @@ } base::FilePath filePath(SysNSStringToUTF8(path)); filePath = filePath.Append(downloadFileName_); - client_->DragPromisedFileTo(filePath, *dropData_, downloadURL_, &filePath); + host_->DragPromisedFileTo(filePath, *dropData_, downloadURL_, &filePath); return SysUTF8ToNSString(filePath.BaseName().value()); }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 5665846..f525fc6 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2580,9 +2580,9 @@ "../app_shim_remote_cocoa/ns_view_bridge_factory_impl.mm", "../app_shim_remote_cocoa/popup_window_mac.h", "../app_shim_remote_cocoa/popup_window_mac.mm", - "../app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h", - "../app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm", - "../app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h", + "../app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h", + "../app_shim_remote_cocoa/render_widget_host_ns_view_bridge.mm", + "../app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h", "../app_shim_remote_cocoa/render_widget_host_view_cocoa.h", "../app_shim_remote_cocoa/render_widget_host_view_cocoa.mm", "../app_shim_remote_cocoa/web_contents_view_cocoa.h",
diff --git a/content/browser/cookie_store/cookie_store_manager_unittest.cc b/content/browser/cookie_store/cookie_store_manager_unittest.cc index 37f5d43..c624b3a8 100644 --- a/content/browser/cookie_store/cookie_store_manager_unittest.cc +++ b/content/browser/cookie_store/cookie_store_manager_unittest.cc
@@ -8,6 +8,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/test/bind_test_util.h" #include "content/browser/cookie_store/cookie_store_context.h" #include "content/browser/cookie_store/cookie_store_manager.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" @@ -45,12 +46,10 @@ base::RunLoop run_loop; cookie_store_service_->AppendSubscriptions( service_worker_registration_id, std::move(subscriptions), - base::BindOnce( - [](base::RunLoop* run_loop, bool* success, bool service_success) { - *success = service_success; - run_loop->Quit(); - }, - &run_loop, &success)); + base::BindLambdaForTesting([&](bool service_success) { + success = service_success; + run_loop.Quit(); + })); run_loop.Run(); return success; } @@ -61,14 +60,12 @@ base::RunLoop run_loop; cookie_store_service_->GetSubscriptions( service_worker_registration_id, - base::BindOnce( - [](base::RunLoop* run_loop, base::Optional<Subscriptions>* result, - Subscriptions service_result, bool service_success) { + base::BindLambdaForTesting( + [&](Subscriptions service_result, bool service_success) { if (service_success) - *result = std::move(service_result); - run_loop->Quit(); - }, - &run_loop, &result)); + result = std::move(service_result); + run_loop.Quit(); + })); run_loop.Run(); return result; } @@ -297,18 +294,15 @@ base::RunLoop run_loop; worker_test_helper_->context()->RegisterServiceWorker( GURL(script_url), options, - base::BindOnce( - [](base::RunLoop* run_loop, bool* success, int64_t* registration_id, - blink::ServiceWorkerStatusCode status, - const std::string& status_message, - int64_t service_worker_registration_id) { - *success = (status == blink::ServiceWorkerStatusCode::kOk); - *registration_id = service_worker_registration_id; - EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status) - << blink::ServiceWorkerStatusToString(status); - run_loop->Quit(); - }, - &run_loop, &success, ®istration_id)); + base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status, + const std::string& status_message, + int64_t service_worker_registration_id) { + success = (status == blink::ServiceWorkerStatusCode::kOk); + registration_id = service_worker_registration_id; + EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status) + << blink::ServiceWorkerStatusToString(status); + run_loop.Quit(); + })); run_loop.Run(); if (!success) return kInvalidRegistrationId; @@ -325,14 +319,12 @@ options.set_include_httponly(); cookie_manager_->SetCanonicalCookie( cookie, "https", options, - base::BindOnce( - [](base::RunLoop* run_loop, bool* success, - net::CanonicalCookie::CookieInclusionStatus service_success) { - *success = (service_success == - net::CanonicalCookie::CookieInclusionStatus::INCLUDE); - run_loop->Quit(); - }, - &run_loop, &success)); + base::BindLambdaForTesting( + [&](net::CanonicalCookie::CookieInclusionStatus service_success) { + success = (service_success == + net::CanonicalCookie::CookieInclusionStatus::INCLUDE); + run_loop.Quit(); + })); run_loop.Run(); return success; }
diff --git a/content/browser/frame_host/popup_menu_helper_mac.mm b/content/browser/frame_host/popup_menu_helper_mac.mm index 097604d..76b42c7 100644 --- a/content/browser/frame_host/popup_menu_helper_mac.mm +++ b/content/browser/frame_host/popup_menu_helper_mac.mm
@@ -63,7 +63,7 @@ RenderWidgetHostViewMac* rwhvm = static_cast<RenderWidgetHostViewMac*>(GetRenderWidgetHostView()); base::scoped_nsobject<RenderWidgetHostViewCocoa> cocoa_view( - [rwhvm->cocoa_view() retain]); + [rwhvm->GetInProcessNSView() retain]); // Display the menu. base::scoped_nsobject<WebMenuRunner> runner([[WebMenuRunner alloc]
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 8113209..23a4833 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -15,7 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "components/viz/common/surfaces/surface_id.h" -#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h" +#include "content/app_shim_remote_cocoa/render_widget_host_ns_view_host_helper.h" #include "content/browser/renderer_host/browser_compositor_view_mac.h" #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -34,6 +34,7 @@ namespace mojom { class Application; } // namespace mojom +class RenderWidgetHostNSViewBridge; } // namespace remote_cocoa namespace ui { @@ -51,7 +52,6 @@ class CursorManager; class RenderWidgetHost; -class RenderWidgetHostNSViewBridgeLocal; class RenderWidgetHostViewMac; class WebContents; class WebCursor; @@ -74,8 +74,8 @@ // RenderWidgetHostView class hierarchy described in render_widget_host_view.h. class CONTENT_EXPORT RenderWidgetHostViewMac : public RenderWidgetHostViewBase, - public RenderWidgetHostNSViewClientHelper, - public mojom::RenderWidgetHostNSViewClient, + public remote_cocoa::RenderWidgetHostNSViewHostHelper, + public remote_cocoa::mojom::RenderWidgetHostNSViewHost, public BrowserCompositorMacClient, public TextInputManager::Observer, public ui::GestureProviderClient, @@ -93,7 +93,7 @@ // to use RWHVChildFrame (http://crbug.com/330264). RenderWidgetHostViewMac(RenderWidgetHost* widget, bool is_guest_view_hack); - RenderWidgetHostViewCocoa* cocoa_view() const; + RenderWidgetHostViewCocoa* GetInProcessNSView() const; // |delegate| is used to separate out the logic from the NSResponder delegate. // |delegate| is retained by this class. @@ -304,7 +304,7 @@ // RenderWidgetHostImpl as well. void UpdateNSViewAndDisplayProperties(); - // RenderWidgetHostNSViewClientHelper implementation. + // RenderWidgetHostNSViewHostHelper implementation. id GetRootBrowserAccessibilityElement() override; id GetFocusedBrowserAccessibilityElement() override; void SetAccessibilityWindow(NSWindow* window) override; @@ -326,7 +326,7 @@ void GestureEnd(blink::WebGestureEvent end_event) override; void SmartMagnify(const blink::WebGestureEvent& smart_magnify_event) override; - // mojom::RenderWidgetHostNSViewClient implementation. + // mojom::RenderWidgetHostNSViewHost implementation. void SyncIsWidgetForMainFrame( SyncIsWidgetForMainFrameCallback callback) override; bool SyncIsWidgetForMainFrame(bool* is_for_main_frame) override; @@ -522,21 +522,22 @@ void GetPageTextForSpeech(SpeechCallback callback); // Interface through which the NSView is to be manipulated. This points either - // to |ns_view_bridge_local_| or to (to-be-added) |ns_view_bridge_remote_|. - mojom::RenderWidgetHostNSViewBridge* ns_view_bridge_ = nullptr; + // to |in_process_ns_view_bridge_| or to |remote_ns_view_ptr_|. + remote_cocoa::mojom::RenderWidgetHostNSView* ns_view_ = nullptr; - // If |ns_view_bridge_| is hosted in this process, then this will be non-null, + // If |ns_view_| is hosted in this process, then this will be non-null, // and may be used to query the actual RenderWidgetHostViewCocoa that is being // used for |this|. Any functionality that uses |new_view_bridge_local_| will // not work when the RenderWidgetHostViewCocoa is hosted in an app process. - std::unique_ptr<RenderWidgetHostNSViewBridgeLocal> ns_view_bridge_local_; + std::unique_ptr<remote_cocoa::RenderWidgetHostNSViewBridge> + in_process_ns_view_bridge_; // If the NSView is hosted in a remote process and accessed via mojo then - // - |ns_view_bridge_| will point to |ns_view_bridge_remote_| - // - |ns_view_client_binding_| is the binding provided to the bridge. - mojom::RenderWidgetHostNSViewBridgeAssociatedPtr ns_view_bridge_remote_; - mojo::AssociatedBinding<mojom::RenderWidgetHostNSViewClient> - ns_view_client_binding_; + // - |ns_view_| will point to |remote_ns_view_ptr_| + // - |remote_ns_view_client_binding_| is the binding provided to the bridge. + remote_cocoa::mojom::RenderWidgetHostNSViewAssociatedPtr remote_ns_view_ptr_; + mojo::AssociatedBinding<remote_cocoa::mojom::RenderWidgetHostNSViewHost> + remote_ns_view_client_binding_; // State tracked by Show/Hide/IsShowing. bool is_visible_ = false;
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 16d28b6..d450d95 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -23,7 +23,7 @@ #include "components/remote_cocoa/common/application.mojom.h" #include "components/viz/common/features.h" #include "components/viz/common/switches.h" -#import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.h" +#import "content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge.h" #import "content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h" #import "content/browser/accessibility/browser_accessibility_cocoa.h" #import "content/browser/accessibility/browser_accessibility_mac.h" @@ -125,7 +125,7 @@ const gfx::CALayerParams* ca_layer_params = browser_compositor_->GetLastCALayerParams(); if (ca_layer_params) - ns_view_bridge_->SetCALayerParams(*ca_layer_params); + ns_view_->SetCALayerParams(*ca_layer_params); // Take this opportunity to update the VSync parameters, if needed. if (display_link_) { @@ -173,7 +173,7 @@ : RenderWidgetHostViewBase(widget), page_at_minimum_scale_(true), mouse_wheel_phase_handler_(this), - ns_view_client_binding_(this), + remote_ns_view_client_binding_(this), is_loading_(false), is_guest_view_hack_(is_guest_view_hack), popup_parent_host_view_(nullptr), @@ -183,10 +183,10 @@ this), accessibility_focus_overrider_(this), weak_factory_(this) { - // The NSView is on the other side of |ns_view_bridge_|. - ns_view_bridge_local_ = - std::make_unique<RenderWidgetHostNSViewBridgeLocal>(this, this); - ns_view_bridge_ = ns_view_bridge_local_.get(); + // The NSView is on the other side of |ns_view_|. + in_process_ns_view_bridge_ = + std::make_unique<remote_cocoa::RenderWidgetHostNSViewBridge>(this, this); + ns_view_ = in_process_ns_view_bridge_.get(); // Guess that the initial screen we will be on is the screen of the current // window (since that's the best guess that we have, and is usually right). @@ -200,7 +200,7 @@ browser_compositor_.reset(new BrowserCompositorMac( this, this, host()->is_hidden(), display_, frame_sink_id)); - DCHECK(![cocoa_view() window]); + DCHECK(![GetInProcessNSView() window]); if (!is_guest_view_hack_) host()->SetView(this); @@ -248,9 +248,9 @@ // Disconnect from the previous bridge (this will have the effect of // destroying the associated bridge), and close the binding (to allow it - // to be re-bound). Note that |ns_view_bridge_local_| remains valid. - ns_view_client_binding_.Close(); - ns_view_bridge_remote_.reset(); + // to be re-bound). Note that |in_process_ns_view_bridge_| remains valid. + remote_ns_view_client_binding_.Close(); + remote_ns_view_ptr_.reset(); // Enable accessibility focus overriding for remote NSViews. accessibility_focus_overrider_.SetAppIsRemote(remote_cocoa_application != @@ -258,16 +258,16 @@ // If no host is specified, then use the locally hosted NSView. if (!remote_cocoa_application) { - ns_view_bridge_ = ns_view_bridge_local_.get(); + ns_view_ = in_process_ns_view_bridge_.get(); return; } - mojom::RenderWidgetHostNSViewClientAssociatedPtr client; - ns_view_client_binding_.Bind(mojo::MakeRequest(&client)); - mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request = - mojo::MakeRequest(&ns_view_bridge_remote_); + remote_cocoa::mojom::RenderWidgetHostNSViewHostAssociatedPtr client; + remote_ns_view_client_binding_.Bind(mojo::MakeRequest(&client)); + remote_cocoa::mojom::RenderWidgetHostNSViewAssociatedRequest bridge_request = + mojo::MakeRequest(&remote_ns_view_ptr_); - // Cast from mojom::RenderWidgetHostNSViewClientPtr and + // Cast from mojom::RenderWidgetHostNSViewHostPtr and // mojom::RenderWidgetHostNSViewBridgeRequest to the public interfaces // accepted by the application. // TODO(ccameron): Remove the need for this cast. @@ -280,8 +280,8 @@ remote_cocoa_application->CreateRenderWidgetHostNSView( std::move(stub_client), std::move(stub_bridge_request)); - ns_view_bridge_ = ns_view_bridge_remote_.get(); - ns_view_bridge_remote_->SetParentWebContentsNSView(parent_ns_view_id); + ns_view_ = remote_ns_view_ptr_.get(); + remote_ns_view_ptr_->SetParentWebContentsNSView(parent_ns_view_id); } void RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) { @@ -293,7 +293,7 @@ // must be done lazily because not all code has been updated to use // ui::Views (e.g, content_shell). display_only_using_parent_ui_layer_ = true; - ns_view_bridge_->DisableDisplay(); + ns_view_->DisableDisplay(); } if (browser_compositor_) browser_compositor_->SetParentUiLayer(parent_ui_layer); @@ -301,18 +301,19 @@ void RenderWidgetHostViewMac::SetParentAccessibilityElement( id parent_accessibility_element) { - [cocoa_view() setAccessibilityParentElement:parent_accessibility_element]; + [GetInProcessNSView() + setAccessibilityParentElement:parent_accessibility_element]; } -RenderWidgetHostViewCocoa* RenderWidgetHostViewMac::cocoa_view() const { - if (ns_view_bridge_local_) - return ns_view_bridge_local_->GetRenderWidgetHostViewCocoa(); +RenderWidgetHostViewCocoa* RenderWidgetHostViewMac::GetInProcessNSView() const { + if (in_process_ns_view_bridge_) + return in_process_ns_view_bridge_->GetNSView(); return nullptr; } void RenderWidgetHostViewMac::SetDelegate( NSObject<RenderWidgetHostViewMacDelegate>* delegate) { - [cocoa_view() setResponderDelegate:delegate]; + [GetInProcessNSView() setResponderDelegate:delegate]; } ui::TextInputType RenderWidgetHostViewMac::GetTextInputType() { @@ -363,7 +364,7 @@ popup_parent_host_view_->popup_child_host_view_ = this; // This path is used by the time/date picker. - ns_view_bridge_->InitAsPopup(pos); + ns_view_->InitAsPopup(pos); } void RenderWidgetHostViewMac::InitAsFullscreen( @@ -437,7 +438,7 @@ void RenderWidgetHostViewMac::Show() { is_visible_ = true; - ns_view_bridge_->SetVisible(is_visible_); + ns_view_->SetVisible(is_visible_); browser_compositor_->SetViewVisible(is_visible_); browser_compositor_->SetRenderWidgetHostIsHidden(false); @@ -446,7 +447,7 @@ void RenderWidgetHostViewMac::Hide() { is_visible_ = false; - ns_view_bridge_->SetVisible(is_visible_); + ns_view_->SetVisible(is_visible_); browser_compositor_->SetViewVisible(is_visible_); host()->WasHidden(); browser_compositor_->SetRenderWidgetHostIsHidden(true); @@ -492,19 +493,19 @@ } void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { - ns_view_bridge_->SetBounds(rect); + ns_view_->SetBounds(rect); } gfx::NativeView RenderWidgetHostViewMac::GetNativeView() { - return cocoa_view(); + return GetInProcessNSView(); } gfx::NativeViewAccessible RenderWidgetHostViewMac::GetNativeViewAccessible() { - return cocoa_view(); + return GetInProcessNSView(); } void RenderWidgetHostViewMac::Focus() { - ns_view_bridge_->MakeFirstResponder(); + ns_view_->MakeFirstResponder(); } bool RenderWidgetHostViewMac::HasFocus() { @@ -534,7 +535,7 @@ } void RenderWidgetHostViewMac::DisplayCursor(const WebCursor& cursor) { - ns_view_bridge_->DisplayCursor(cursor); + ns_view_->DisplayCursor(cursor); } CursorManager* RenderWidgetHostViewMac::GetCursorManager() { @@ -558,7 +559,7 @@ if (!did_update_state) return; - ns_view_bridge_->SetTextInputType(GetTextInputType()); + ns_view_->SetTextInputType(GetTextInputType()); // |updated_view| is the last view to change its TextInputState which can be // used to start/stop monitoring composition info when it has a focused @@ -593,7 +594,7 @@ void RenderWidgetHostViewMac::OnImeCancelComposition( TextInputManager* text_input_manager, RenderWidgetHostViewBase* updated_view) { - ns_view_bridge_->CancelComposition(); + ns_view_->CancelComposition(); } void RenderWidgetHostViewMac::OnImeCompositionRangeChanged( @@ -605,7 +606,7 @@ return; // The RangeChanged message is only sent with valid values. The current // caret position (start == end) will be sent if there is no IME range. - ns_view_bridge_->SetCompositionRangeInfo(info->range); + ns_view_->SetCompositionRangeInfo(info->range); } void RenderWidgetHostViewMac::OnSelectionBoundsChanged( @@ -650,8 +651,8 @@ if (!selection) return; - ns_view_bridge_->SetTextSelection(selection->text(), selection->offset(), - selection->range()); + ns_view_->SetTextSelection(selection->text(), selection->offset(), + selection->range()); } void RenderWidgetHostViewMac::OnGestureEvent( @@ -687,15 +688,15 @@ // it. if (mouse_locked_) { mouse_locked_ = false; - ns_view_bridge_->SetCursorLocked(false); + ns_view_->SetCursorLocked(false); } // Destroy the local and remote briges to the NSView. Note that the NSView on - // the other side of |ns_view_bridge_| may outlive us due to other retains. - ns_view_bridge_ = nullptr; - ns_view_bridge_local_.reset(); - ns_view_client_binding_.Close(); - ns_view_bridge_remote_.reset(); + // the other side of |ns_view_| may outlive us due to other retains. + ns_view_ = nullptr; + in_process_ns_view_bridge_.reset(); + remote_ns_view_client_binding_.Close(); + remote_ns_view_ptr_.reset(); // Delete the delegated frame state, which will reach back into // host(). @@ -723,7 +724,7 @@ void RenderWidgetHostViewMac::DisplayTooltipText( const base::string16& tooltip_text) { - ns_view_bridge_->SetTooltipText(tooltip_text); + ns_view_->SetTooltipText(tooltip_text); } viz::ScopedSurfaceIdAllocator @@ -820,7 +821,7 @@ // void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) { - ns_view_bridge_->SetShowingContextMenu(showing); + ns_view_->SetShowingContextMenu(showing); } uint32_t RenderWidgetHostViewMac::GetCaptureSequenceNumber() const { @@ -885,7 +886,7 @@ const gfx::CALayerParams* ca_layer_params = view_mac->browser_compositor_->GetLastCALayerParams(); if (ca_layer_params) - ns_view_bridge_->SetCALayerParams(*ca_layer_params); + ns_view_->SetCALayerParams(*ca_layer_params); browser_compositor_->TakeFallbackContentFrom( view_mac->browser_compositor_.get()); } @@ -1056,7 +1057,7 @@ void RenderWidgetHostViewMac::FocusedNodeChanged( bool is_editable_node, const gfx::Rect& node_bounds_in_screen) { - ns_view_bridge_->CancelComposition(); + ns_view_->CancelComposition(); // If the Mac Zoom feature is enabled, update it with the bounds of the // current focused node so that it can ensure that it's scrolled into view. @@ -1122,10 +1123,10 @@ mouse_locked_ = true; // Lock position of mouse cursor and hide it. - ns_view_bridge_->SetCursorLocked(true); + ns_view_->SetCursorLocked(true); // Clear the tooltip window. - ns_view_bridge_->SetTooltipText(base::string16()); + ns_view_->SetTooltipText(base::string16()); return true; } @@ -1134,7 +1135,7 @@ if (!mouse_locked_) return; mouse_locked_ = false; - ns_view_bridge_->SetCursorLocked(false); + ns_view_->SetCursorLocked(false); if (host()) host()->LostMouseLock(); @@ -1149,7 +1150,7 @@ uint_dom_codes->push_back(static_cast<uint32_t>(dom_code)); } is_keyboard_locked_ = true; - ns_view_bridge_->LockKeyboard(uint_dom_codes); + ns_view_->LockKeyboard(uint_dom_codes); return true; } @@ -1158,7 +1159,7 @@ return; is_keyboard_locked_ = false; - ns_view_bridge_->UnlockKeyboard(); + ns_view_->UnlockKeyboard(); } bool RenderWidgetHostViewMac::IsKeyboardLocked() { @@ -1183,7 +1184,8 @@ case WebInputEvent::kGestureScrollBegin: case WebInputEvent::kGestureScrollUpdate: case WebInputEvent::kGestureScrollEnd: - [cocoa_view() processedGestureScrollEvent:event consumed:consumed]; + [GetInProcessNSView() processedGestureScrollEvent:event + consumed:consumed]; return; default: break; @@ -1210,7 +1212,7 @@ void RenderWidgetHostViewMac::DidOverscroll( const ui::DidOverscrollParams& params) { - [cocoa_view() processedOverscroll:params]; + [GetInProcessNSView() processedOverscroll:params]; } std::unique_ptr<SyntheticGestureTarget> @@ -1218,7 +1220,7 @@ RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(GetRenderWidgetHost()); return std::unique_ptr<SyntheticGestureTarget>( - new SyntheticGestureTargetMac(host, cocoa_view())); + new SyntheticGestureTargetMac(host, GetInProcessNSView())); } const viz::LocalSurfaceIdAllocation& @@ -1344,7 +1346,7 @@ void RenderWidgetHostViewMac::ShowDefinitionForSelection() { // This will round-trip to the NSView to determine the selection range. - ns_view_bridge_->ShowDictionaryOverlayForSelection(); + ns_view_->ShowDictionaryOverlayForSelection(); } void RenderWidgetHostViewMac::UpdateBackgroundColor() { @@ -1372,7 +1374,7 @@ if (color == background_layer_color_) return; background_layer_color_ = color; - ns_view_bridge_->SetBackgroundColor(color); + ns_view_->SetBackgroundColor(color); } BrowserAccessibilityManager* @@ -1384,14 +1386,14 @@ gfx::NativeViewAccessible RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessible() { - return cocoa_view(); + return GetInProcessNSView(); } gfx::NativeViewAccessible RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessibleForWindow() { if (remote_window_accessible_) return remote_window_accessible_.get(); - return [cocoa_view() window]; + return [GetInProcessNSView() window]; } void RenderWidgetHostViewMac::SetTextInputActive(bool active) { @@ -1416,7 +1418,7 @@ } /////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostNSViewClientHelper and mojom::RenderWidgetHostNSViewClient +// RenderWidgetHostNSViewHostHelper and mojom::RenderWidgetHostNSViewHost // implementation: id RenderWidgetHostViewMac::GetRootBrowserAccessibilityElement() { @@ -1612,7 +1614,7 @@ host()->ForwardMouseEvent(web_event); if (web_event.GetType() == WebInputEvent::kMouseLeave) - ns_view_bridge_->SetTooltipText(base::string16()); + ns_view_->SetTooltipText(base::string16()); } void RenderWidgetHostViewMac::ForwardWheelEvent( @@ -1922,8 +1924,8 @@ } /////////////////////////////////////////////////////////////////////////////// -// mojom::RenderWidgetHostNSViewClient functions that translate events and -// forward them to the RenderWidgetHostNSViewClientHelper implementation: +// mojom::RenderWidgetHostNSViewHost functions that translate events and +// forward them to the RenderWidgetHostNSViewHostHelper implementation: void RenderWidgetHostViewMac::ForwardKeyboardEvent( std::unique_ptr<InputEvent> input_event, @@ -2112,7 +2114,7 @@ if (auto* rwhv = widget_host->GetView()) baseline_point = rwhv->TransformPointToRootCoordSpace(baseline_point); } - ns_view_bridge_->ShowDictionaryOverlay(encoded_string, baseline_point); + ns_view_->ShowDictionaryOverlay(encoded_string, baseline_point); } }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm index 4c51146..72ec2ae0 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_browsertest.mm
@@ -75,9 +75,9 @@ RenderWidgetHostViewMac* rwhv_mac = static_cast<RenderWidgetHostViewMac*>(rwhv); - NSRect rect = - [rwhv_mac->cocoa_view() firstRectForCharacterRange:NSMakeRange(2, 1) - actualRange:nullptr]; + NSRect rect = [rwhv_mac->GetInProcessNSView() + firstRectForCharacterRange:NSMakeRange(2, 1) + actualRange:nullptr]; EXPECT_GT(NSMinX(rect), 0); EXPECT_GT(NSWidth(rect), 0); EXPECT_GT(NSHeight(rect), 0);
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h index e48fbadb..d5eb9e9 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h
@@ -43,7 +43,7 @@ // Each selector is connected to a single c method which forwards the message // to WebCore's ExecuteEditCommand() function. // This method is idempotent. - // The class passed in must conform to the RenderWidgetHostNSViewClientOwner + // The class passed in must conform to the RenderWidgetHostNSViewHostOwner // protocol. void AddEditingSelectorsToClass(Class klass); @@ -52,7 +52,7 @@ // owner - An object we can retrieve a RenderWidgetHostViewMac from to // determine the command states. bool IsMenuItemEnabled(SEL item_action, - id<RenderWidgetHostNSViewClientOwner> owner); + id<RenderWidgetHostNSViewHostOwner> owner); // Converts an editing selector into a command name that can be sent to // webkit.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm index d0e908ba..680b0a8b 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
@@ -116,7 +116,7 @@ // RenderWidgetHostViewMacEditCommandHelper::AddEditingSelectorsToClass(). // // self - the object we're attached to; it must implement the -// RenderWidgetHostNSViewClientOwner protocol. +// RenderWidgetHostNSViewHostOwner protocol. // _cmd - the selector that fired. // sender - the id of the object that sent the message. // @@ -129,8 +129,7 @@ // The WebFrame is in the Chrome glue layer and forwards the message to WebCore. void EditCommandImp(id self, SEL _cmd, id sender) { // Make sure |self| is the right type. - DCHECK( - [self conformsToProtocol:@protocol(RenderWidgetHostNSViewClientOwner)]); + DCHECK([self conformsToProtocol:@protocol(RenderWidgetHostNSViewHostOwner)]); // SEL -> command name string. NSString* command_name_ns = @@ -138,10 +137,10 @@ std::string command([command_name_ns UTF8String]); // Forward the edit command string down the pipeline. - mojom::RenderWidgetHostNSViewClient* client = [( - id<RenderWidgetHostNSViewClientOwner>)self renderWidgetHostNSViewClient]; - DCHECK(client); - client->ExecuteEditCommand(command); + remote_cocoa::mojom::RenderWidgetHostNSViewHost* host = + [(id<RenderWidgetHostNSViewHostOwner>)self renderWidgetHostNSViewHost]; + DCHECK(host); + host->ExecuteEditCommand(command); } } // namespace @@ -208,7 +207,7 @@ bool RenderWidgetHostViewMacEditCommandHelper::IsMenuItemEnabled( SEL item_action, - id<RenderWidgetHostNSViewClientOwner> owner) { + id<RenderWidgetHostNSViewHostOwner> owner) { const char* selector_name = sel_getName(item_action); // TODO(jeremy): The final form of this function will check state // associated with the Browser.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm index f27cb7c6..3fc406e 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -36,15 +36,15 @@ @end // Class that owns a RenderWidgetHostViewMac. -@interface RenderWidgetHostNSViewClientOwner - : NSObject<RenderWidgetHostNSViewClientOwner> { +@interface RenderWidgetHostNSViewHostOwner + : NSObject <RenderWidgetHostNSViewHostOwner> { RenderWidgetHostViewMac* rwhvm_; } - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm; @end -@implementation RenderWidgetHostNSViewClientOwner +@implementation RenderWidgetHostNSViewHostOwner - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm { if ((self = [super init])) { @@ -53,7 +53,7 @@ return self; } -- (content::mojom::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient { +- (remote_cocoa::mojom::RenderWidgetHostNSViewHost*)renderWidgetHostNSViewHost { return rwhvm_; } @@ -152,16 +152,16 @@ ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get()); - // Owned by its |cocoa_view()|, i.e. |rwhv_cocoa|. + // Owned by its |GetInProcessNSView()|, i.e. |rwhv_cocoa|. RenderWidgetHostViewMac* rwhv_mac = new RenderWidgetHostViewMac( render_widget, false); base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa( - [rwhv_mac->cocoa_view() retain]); + [rwhv_mac->GetInProcessNSView() retain]); RenderWidgetHostViewMacEditCommandHelper helper; NSArray* edit_command_strings = helper.GetEditSelectorNames(); - RenderWidgetHostNSViewClientOwner* rwhwvm_owner = - [[[RenderWidgetHostNSViewClientOwner alloc] + RenderWidgetHostNSViewHostOwner* rwhwvm_owner = + [[[RenderWidgetHostNSViewHostOwner alloc] initWithRenderWidgetHostViewMac:rwhv_mac] autorelease]; helper.AddEditingSelectorsToClass([rwhwvm_owner class]); @@ -215,8 +215,8 @@ // Test RenderWidgetHostViewMacEditCommandHelper::IsMenuItemEnabled. TEST_F(RenderWidgetHostViewMacEditCommandHelperTest, TestMenuItemEnabling) { RenderWidgetHostViewMacEditCommandHelper helper; - RenderWidgetHostNSViewClientOwner* rwhvm_owner = - [[[RenderWidgetHostNSViewClientOwner alloc] init] autorelease]; + RenderWidgetHostNSViewHostOwner* rwhvm_owner = + [[[RenderWidgetHostNSViewHostOwner alloc] init] autorelease]; // The select all menu should always be enabled. SEL select_all = NSSelectorFromString(@"selectAll:");
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index ecbabcc..859cb7c6 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -492,7 +492,7 @@ &delegate_, process_host_.get(), process_host_->GetNextRoutingID())); host_->set_owner_delegate(&mock_owner_delegate_); rwhv_mac_ = new RenderWidgetHostViewMac(host_.get(), false); - rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]); + rwhv_cocoa_.reset([rwhv_mac_->GetInProcessNSView() retain]); window_.reset([[CocoaTestHelperWindow alloc] init]); window_.get().pretendIsKeyWindow = YES; @@ -599,7 +599,7 @@ host_->GetAndResetDispatchedMessages(); EXPECT_EQ(0U, events.size()); - [rwhv_mac_->cocoa_view() + [rwhv_mac_->GetInProcessNSView() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode( 0x7B, 0xF70F, NSKeyDown, NSControlKeyMask)]; base::RunLoop().RunUntilIdle(); @@ -611,7 +611,7 @@ // fire keypress event process_host_->sink().ClearMessages(); EXPECT_EQ(0U, process_host_->sink().message_count()); - [rwhv_mac_->cocoa_view() + [rwhv_mac_->GetInProcessNSView() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode( 0x2E, 0xF728, NSKeyDown, NSControlKeyMask)]; base::RunLoop().RunUntilIdle(); @@ -619,7 +619,7 @@ EXPECT_EQ("RawKeyDown", GetMessageNames(events)); // Simulate a printable char, should generate keypress event - [rwhv_mac_->cocoa_view() + [rwhv_mac_->GetInProcessNSView() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(0x58, 'x', NSKeyDown, NSControlKeyMask)]; base::RunLoop().RunUntilIdle(); @@ -632,8 +632,9 @@ TEST_F(RenderWidgetHostViewMacTest, InvalidKeyCode) { // Simulate "Convert" key on JIS PC keyboard, will generate a |NSFlagsChanged| // NSEvent with |keyCode| == 0xFF. - [rwhv_mac_->cocoa_view() keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode( - 0xFF, 0, NSFlagsChanged, 0)]; + [rwhv_mac_->GetInProcessNSView() + keyEvent:cocoa_test_event_utils::KeyEventWithKeyCode(0xFF, 0, + NSFlagsChanged, 0)]; base::RunLoop().RunUntilIdle(); EXPECT_EQ(0U, host_->GetAndResetDispatchedMessages().size()); } @@ -906,7 +907,7 @@ // |RenderWidgetHostImp::Focus()|. TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) { EXPECT_CALL(*host_, Focus()); - [window_ makeFirstResponder:rwhv_mac_->cocoa_view()]; + [window_ makeFirstResponder:rwhv_mac_->GetInProcessNSView()]; testing::Mock::VerifyAndClearExpectations(host_.get()); EXPECT_CALL(*host_, Blur()); @@ -935,7 +936,7 @@ // Verifies that ui::INPUT_EVENT_LATENCY_UI_COMPONENT is added // properly in scrollWheel function. NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan),3); - [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent1]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent1]; ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency( ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr)); @@ -944,7 +945,7 @@ // properly in shortCircuitScrollWheelEvent function which is called // in scrollWheel. NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded),0); - [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent2]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent2]; ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency( ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr)); } @@ -955,7 +956,7 @@ // Send a wheel event for scrolling by 3 lines. // Verifies that SourceEventType exists in forwarded LatencyInfo object. NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); - [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent]; ASSERT_TRUE(host_->lastWheelEventLatencyInfo.source_event_type() == ui::SourceEventType::WHEEL); } @@ -963,7 +964,7 @@ TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) { // Send an initial wheel event with NSEventPhaseBegan to the view. NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0); - [rwhv_mac_->cocoa_view() scrollWheel:event1]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:event1]; // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends. base::RunLoop().RunUntilIdle(); @@ -990,14 +991,14 @@ // Send a NSEvent of NSTabletProximity type which has a device type of eraser. NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true, NSEraserPointingDevice); - [rwhv_mac_->cocoa_view() tabletEvent:event]; + [rwhv_mac_->GetInProcessNSView() tabletEvent:event]; // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends. base::RunLoop().RunUntilIdle(); event = MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletPoint); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1010,14 +1011,14 @@ // Send a NSEvent of NSTabletProximity type which has a device type of pen. NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true, NSPenPointingDevice); - [rwhv_mac_->cocoa_view() tabletEvent:event]; + [rwhv_mac_->GetInProcessNSView() tabletEvent:event]; // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends. base::RunLoop().RunUntilIdle(); event = MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletPoint); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1032,7 +1033,7 @@ NSEvent* event = MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletProximity, true); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1042,7 +1043,7 @@ events.clear(); event = cocoa_test_event_utils::EnterEvent({1, 1}, window_); - [rwhv_mac_->cocoa_view() mouseEntered:event]; + [rwhv_mac_->GetInProcessNSView() mouseEntered:event]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseMove", GetMessageNames(events)); @@ -1057,7 +1058,7 @@ NSEvent* event = MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeDefault); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1070,7 +1071,7 @@ // Send a NSEvent of NSTabletProximity type which has a device type of pen. NSEvent* event = MockTabletEventWithParams(kCGEventTabletProximity, true, NSPenPointingDevice); - [rwhv_mac_->cocoa_view() tabletEvent:event]; + [rwhv_mac_->GetInProcessNSView() tabletEvent:event]; // Flush and clear other messages (e.g. begin frames) the RWHVMac also sends. base::RunLoop().RunUntilIdle(); static_cast<RenderWidgetHostImpl*>(rwhv_mac_->GetRenderWidgetHost()) @@ -1080,7 +1081,7 @@ event = MockMouseEventWithParams( kCGEventLeftMouseDown, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletPoint, false, true); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1094,7 +1095,7 @@ event = MockMouseEventWithParams( kCGEventLeftMouseDragged, {16, 29}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletPoint, false, true); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("TouchMove", GetMessageNames(events)); @@ -1108,7 +1109,7 @@ event = MockMouseEventWithParams(kCGEventLeftMouseUp, {16, 29}, kCGMouseButtonLeft, kCGEventMouseSubtypeTabletPoint, false); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("TouchEnd GestureScrollEnd", GetMessageNames(events)); @@ -1125,7 +1126,7 @@ event = MockMouseEventWithParams(kCGEventLeftMouseDown, {6, 9}, kCGMouseButtonLeft, kCGEventMouseSubtypeDefault); - [rwhv_mac_->cocoa_view() mouseEvent:event]; + [rwhv_mac_->GetInProcessNSView() mouseEvent:event]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseDown", GetMessageNames(events)); @@ -1161,7 +1162,7 @@ // Send an initial wheel event for scrolling by 3 lines. NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); - [rwhv_mac_->cocoa_view() scrollWheel:event1]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:event1]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = @@ -1187,7 +1188,7 @@ // Send another wheel event, this time for scrolling by 0 lines (empty event). NSEvent* event2 = MockScrollWheelEventWithPhase(@selector(phaseChanged), 0); - [rwhv_mac_->cocoa_view() scrollWheel:event2]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:event2]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseWheel", GetMessageNames(events)); @@ -1206,7 +1207,7 @@ TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) { int32_t routing_id = process_host_->GetNextRoutingID(); - // Owned by its |cocoa_view()|. + // Owned by its |GetInProcessNSView()|. MockRenderWidgetHostImpl* rwh = MockRenderWidgetHostImpl::Create( &delegate_, process_host_.get(), routing_id); RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, true); @@ -1220,10 +1221,10 @@ (RenderWidgetHostViewGuest::Create(rwh, nullptr, view->GetWeakPtr())) ->GetWeakPtr(); - // Remove the cocoa_view() so |view| also goes away before |rwh|. + // Remove the GetInProcessNSView() so |view| also goes away before |rwh|. { base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa; - rwhv_cocoa.reset([view->cocoa_view() retain]); + rwhv_cocoa.reset([view->GetInProcessNSView() retain]); } RecycleAndWait(); @@ -1284,7 +1285,7 @@ // Send a wheel event without phase information for scrolling by 3 lines. NSEvent* wheelEvent = MockScrollWheelEventWithoutPhase(3); - [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host_->GetAndResetDispatchedMessages(); @@ -1336,7 +1337,7 @@ // Send an initial wheel event for scrolling by 3 lines. NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); - [view->cocoa_view() scrollWheel:wheelEvent1]; + [view->GetInProcessNSView() scrollWheel:wheelEvent1]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host->GetAndResetDispatchedMessages(); @@ -1352,7 +1353,7 @@ // mouse_wheel_end_dispatch_timer_ will start. NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); - [view->cocoa_view() scrollWheel:wheelEvent2]; + [view->GetInProcessNSView() scrollWheel:wheelEvent2]; base::RunLoop().RunUntilIdle(); events = host->GetAndResetDispatchedMessages(); ASSERT_EQ(0U, events.size()); @@ -1391,7 +1392,7 @@ // Send an initial wheel event for scrolling by 3 lines. NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); - [view->cocoa_view() scrollWheel:wheelEvent1]; + [view->GetInProcessNSView() scrollWheel:wheelEvent1]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host->GetAndResetDispatchedMessages(); @@ -1408,7 +1409,7 @@ // mouse_wheel_end_dispatch_timer_ will start. NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); - [view->cocoa_view() scrollWheel:wheelEvent2]; + [view->GetInProcessNSView() scrollWheel:wheelEvent2]; base::RunLoop().RunUntilIdle(); events = host->GetAndResetDispatchedMessages(); ASSERT_EQ(0U, events.size()); @@ -1419,7 +1420,7 @@ NSEvent* wheelEvent3 = MockScrollWheelEventWithMomentumPhase(@selector(phaseBegan), 3); ASSERT_TRUE(wheelEvent3); - [view->cocoa_view() scrollWheel:wheelEvent3]; + [view->GetInProcessNSView() scrollWheel:wheelEvent3]; base::RunLoop().RunUntilIdle(); events = host->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events)); @@ -1447,7 +1448,7 @@ // Send an initial wheel event for scrolling by 3 lines. NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); - [view->cocoa_view() scrollWheel:wheelEvent1]; + [view->GetInProcessNSView() scrollWheel:wheelEvent1]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = host->GetAndResetDispatchedMessages(); @@ -1464,7 +1465,7 @@ // mouse_wheel_end_dispatch_timer_ will start. NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded), 0); - [view->cocoa_view() scrollWheel:wheelEvent2]; + [view->GetInProcessNSView() scrollWheel:wheelEvent2]; base::RunLoop().RunUntilIdle(); events = host->GetAndResetDispatchedMessages(); ASSERT_EQ(0U, events.size()); @@ -1476,7 +1477,7 @@ NSEvent* wheelEvent3 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); ASSERT_TRUE(wheelEvent3); - [view->cocoa_view() scrollWheel:wheelEvent3]; + [view->GetInProcessNSView() scrollWheel:wheelEvent3]; base::RunLoop().RunUntilIdle(); events = host->GetAndResetDispatchedMessages(); ASSERT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events)); @@ -1705,7 +1706,7 @@ // Send an initial wheel event for scrolling by 3 lines. // Verify that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly. NSEvent* wheelEvent = MockScrollWheelEventWithPhase(@selector(phaseBegan),3); - [rwhv_mac_->cocoa_view() scrollWheel:wheelEvent]; + [rwhv_mac_->GetInProcessNSView() scrollWheel:wheelEvent]; histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1); } @@ -1773,11 +1774,13 @@ } RenderWidgetHostViewMac* tab_view() { return rwhv_mac_; } RenderWidgetHostImpl* tab_widget() { return host_.get(); } - RenderWidgetHostViewCocoa* tab_cocoa_view() { return rwhv_cocoa_.get(); } + RenderWidgetHostViewCocoa* tab_GetInProcessNSView() { + return rwhv_cocoa_.get(); + } API_AVAILABLE(macos(10.12.2)) NSCandidateListTouchBarItem* candidate_list_item() { - return [tab_cocoa_view().touchBar + return [tab_GetInProcessNSView().touchBar itemForIdentifier:NSTouchBarItemIdentifierCandidateList]; } @@ -1801,7 +1804,7 @@ // tests as well). We should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() unmarkText]; + [tab_GetInProcessNSView() unmarkText]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = child_widget_->GetAndResetDispatchedMessages(); @@ -1810,7 +1813,7 @@ // Repeat the same steps for the tab's view . SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() unmarkText]; + [tab_GetInProcessNSView() unmarkText]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); EXPECT_EQ("FinishComposingText", GetMessageNames(events)); @@ -1829,9 +1832,9 @@ // should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = child_widget_->GetAndResetDispatchedMessages(); @@ -1840,9 +1843,9 @@ // Repeat the same steps for the tab's view. SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); EXPECT_EQ("SetComposition", GetMessageNames(events)); @@ -1860,7 +1863,7 @@ // should observe an IPC being sent to the |child_widget_|. SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() insertText:text replacementRange:replacementRange]; + [tab_GetInProcessNSView() insertText:text replacementRange:replacementRange]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = child_widget_->GetAndResetDispatchedMessages(); @@ -1869,7 +1872,7 @@ // Repeat the same steps for the tab's view. SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() insertText:text replacementRange:replacementRange]; + [tab_GetInProcessNSView() insertText:text replacementRange:replacementRange]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); EXPECT_EQ("CommitText", GetMessageNames(events)); @@ -1892,10 +1895,10 @@ // we will first call setMarkedText on cocoa view. This would lead to a set // composition IPC in the sink, but it doesn't matter since we will be looking // for a finish composing text IPC for this test. - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; - [tab_cocoa_view() finishComposingText]; + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + [tab_GetInProcessNSView() finishComposingText]; base::RunLoop().RunUntilIdle(); MockWidgetInputHandler::MessageVector events = child_widget_->GetAndResetDispatchedMessages(); @@ -1904,10 +1907,10 @@ // Repeat the same steps for the tab's view. SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; - [tab_cocoa_view() finishComposingText]; + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + [tab_GetInProcessNSView() finishComposingText]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); EXPECT_EQ("SetComposition FinishComposingText", GetMessageNames(events)); @@ -1922,7 +1925,7 @@ EXPECT_CALL(*host_, Focus()).Times(::testing::AnyNumber()); EXPECT_CALL(*host_, Blur()).Times(::testing::AnyNumber()); - [window_ makeFirstResponder:tab_view()->cocoa_view()]; + [window_ makeFirstResponder:tab_view()->GetInProcessNSView()]; // Shouldn't enable secure input if it's not a password textfield. tab_view()->SetActive(true); @@ -1952,20 +1955,20 @@ NSRange replacementRange = NSMakeRange(0, 1); // Make Cocoa view assume there is marked text. - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; - EXPECT_TRUE([tab_cocoa_view() hasMarkedText]); + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + EXPECT_TRUE([tab_GetInProcessNSView() hasMarkedText]); child_view_->ImeCancelComposition(); - EXPECT_FALSE([tab_cocoa_view() hasMarkedText]); + EXPECT_FALSE([tab_GetInProcessNSView() hasMarkedText]); // Repeat for the tab's view. - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; - EXPECT_TRUE([tab_cocoa_view() hasMarkedText]); + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + EXPECT_TRUE([tab_GetInProcessNSView() hasMarkedText]); tab_view()->ImeCancelComposition(); - EXPECT_FALSE([tab_cocoa_view() hasMarkedText]); + EXPECT_FALSE([tab_GetInProcessNSView() hasMarkedText]); } // This test verifies that calling FocusedNodeChanged() on @@ -1977,12 +1980,12 @@ NSRange selectedRange = NSMakeRange(0, 1); NSRange replacementRange = NSMakeRange(0, 1); - [tab_cocoa_view() setMarkedText:text - selectedRange:selectedRange - replacementRange:replacementRange]; - EXPECT_TRUE([tab_cocoa_view() hasMarkedText]); + [tab_GetInProcessNSView() setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + EXPECT_TRUE([tab_GetInProcessNSView() hasMarkedText]); tab_view()->FocusedNodeChanged(true, gfx::Rect()); - EXPECT_FALSE([tab_cocoa_view() hasMarkedText]); + EXPECT_FALSE([tab_GetInProcessNSView() hasMarkedText]); } // This test verifies that when a RenderWidgetHostView changes its @@ -1994,7 +1997,7 @@ // method RWHVMac::HasFocus() returns true. Then we can make sure that as long // as there is some TextInputState of non-NONE, the corresponding widget will // be asked to start monitoring composition info. - [window_ makeFirstResponder:tab_cocoa_view()]; + [window_ makeFirstResponder:tab_GetInProcessNSView()]; EXPECT_TRUE(tab_view()->HasFocus()); TextInputState state; @@ -2070,7 +2073,7 @@ if (@available(macOS 10.12.2, *)) { base::scoped_nsobject<FakeSpellChecker> spellChecker( [[FakeSpellChecker alloc] init]); - tab_cocoa_view().spellCheckerForTesting = + tab_GetInProcessNSView().spellCheckerForTesting = static_cast<NSSpellChecker*>(spellChecker.get()); SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); @@ -2117,8 +2120,8 @@ ASSERT_EQ("", GetMessageNames(events)); // Now, select that result. - [tab_cocoa_view() candidateListTouchBarItem:candidate_list_item() - endSelectingCandidateAtIndex:0]; + [tab_GetInProcessNSView() candidateListTouchBarItem:candidate_list_item() + endSelectingCandidateAtIndex:0]; base::RunLoop().RunUntilIdle(); events = host_->GetAndResetDispatchedMessages(); ASSERT_EQ("CommitText", GetMessageNames(events)); @@ -2133,7 +2136,7 @@ if (@available(macOS 10.12.2, *)) { base::scoped_nsobject<FakeSpellChecker> spellChecker( [[FakeSpellChecker alloc] init]); - tab_cocoa_view().spellCheckerForTesting = + tab_GetInProcessNSView().spellCheckerForTesting = static_cast<NSSpellChecker*>(spellChecker.get()); SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); @@ -2262,7 +2265,7 @@ } TEST_F(RenderWidgetHostViewMacTest, AccessibilityParentTest) { - NSView* view = rwhv_mac_->cocoa_view(); + NSView* view = rwhv_mac_->GetInProcessNSView(); // NSBox so it participates in the a11y hierarchy. base::scoped_nsobject<NSView> parent_view([[NSBox alloc] init]); @@ -2288,7 +2291,7 @@ // Tests that when entering mouse lock, the cursor will lock to window center. TEST_F(RenderWidgetHostViewMacTest, PointerLockCenterPosition) { - NSView* view = rwhv_mac_->cocoa_view(); + NSView* view = rwhv_mac_->GetInProcessNSView(); NSRect bound = NSMakeRect(123, 234, 456, 678); [view setFrame:bound];
diff --git a/content/browser/site_per_process_mac_browsertest.mm b/content/browser/site_per_process_mac_browsertest.mm index 919275be..0398390 100644 --- a/content/browser/site_per_process_mac_browsertest.mm +++ b/content/browser/site_per_process_mac_browsertest.mm
@@ -255,7 +255,7 @@ RenderWidgetHostViewBase*& router_touchpad_gesture_target, RenderWidgetHostViewBase* expected_target) { auto* root_view_mac = static_cast<RenderWidgetHostViewMac*>(root_view); - RenderWidgetHostViewCocoa* cocoa_view = root_view_mac->cocoa_view(); + RenderWidgetHostViewCocoa* cocoa_view = root_view_mac->GetInProcessNSView(); NSEvent* pinchBeginEvent = MockGestureEvent(NSEventTypeMagnify, 0, gesture_point.x(),
diff --git a/content/browser/tracing/cast_tracing_agent.cc b/content/browser/tracing/cast_tracing_agent.cc index 1e48580..eafb905 100644 --- a/content/browser/tracing/cast_tracing_agent.cc +++ b/content/browser/tracing/cast_tracing_agent.cc
@@ -20,7 +20,7 @@ #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
diff --git a/content/browser/tracing/cros_tracing_agent.cc b/content/browser/tracing/cros_tracing_agent.cc index 60de0db..173c1f7 100644 --- a/content/browser/tracing/cros_tracing_agent.cc +++ b/content/browser/tracing/cros_tracing_agent.cc
@@ -23,7 +23,7 @@ #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
diff --git a/content/browser/tracing/perfetto_file_tracer.cc b/content/browser/tracing/perfetto_file_tracer.cc index 2f2f3f7..a9744ab4 100644 --- a/content/browser/tracing/perfetto_file_tracer.cc +++ b/content/browser/tracing/perfetto_file_tracer.cc
@@ -19,7 +19,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/tracing/public/cpp/perfetto/perfetto_config.h" #include "services/tracing/public/mojom/constants.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" #include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h" namespace content {
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h index 1b577ea..35da7e5 100644 --- a/content/browser/web_contents/web_contents_view_mac.h +++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -30,7 +30,6 @@ namespace content { class RenderWidgetHostViewMac; -class WebContentsNSViewBridge; class WebContentsImpl; class WebContentsViewDelegate; class WebContentsViewMac; @@ -40,6 +39,10 @@ class Vector2d; } +namespace remote_cocoa { +class WebContentsNSViewBridge; +} // remote_cocoa + namespace content { // Mac-specific implementation of the WebContentsView. It owns an NSView that @@ -47,7 +50,7 @@ class WebContentsViewMac : public WebContentsView, public RenderViewHostDelegateView, public PopupMenuHelper::Delegate, - public mojom::WebContentsNSViewClient, + public remote_cocoa::mojom::WebContentsNSViewHost, public ui::ViewsHostableView { public: // The corresponding WebContentsImpl is passed in the constructor, and manages @@ -137,19 +140,21 @@ RenderWidgetHostViewCreateFunction create_render_widget_host_view); private: - WebContentsViewCocoa* cocoa_view() const; + WebContentsViewCocoa* GetInProcessNSView() const; - // mojom::WebContentsNSViewClient: + // remote_cocoa::mojom::WebContentsNSViewHost: void OnMouseEvent(bool motion, bool exited) override; - void OnBecameFirstResponder(mojom::SelectionDirection direction) override; - void OnWindowVisibilityChanged(mojom::Visibility visibility) override; + void OnBecameFirstResponder( + remote_cocoa::mojom::SelectionDirection direction) override; + void OnWindowVisibilityChanged( + remote_cocoa::mojom::Visibility visibility) override; void SetDropData(const DropData& drop_data) override; - bool DraggingEntered(mojom::DraggingInfoPtr dragging_info, + bool DraggingEntered(remote_cocoa::mojom::DraggingInfoPtr dragging_info, uint32_t* out_result) override; void DraggingExited() override; - bool DraggingUpdated(mojom::DraggingInfoPtr dragging_info, + bool DraggingUpdated(remote_cocoa::mojom::DraggingInfoPtr dragging_info, uint32_t* out_result) override; - bool PerformDragOperation(mojom::DraggingInfoPtr dragging_info, + bool PerformDragOperation(remote_cocoa::mojom::DraggingInfoPtr dragging_info, bool* out_result) override; bool DragPromisedFileTo(const base::FilePath& file_path, const DropData& drop_data, @@ -159,12 +164,12 @@ const gfx::PointF& local_point, const gfx::PointF& screen_point) override; - // mojom::WebContentsNSViewClient, synchronous methods: - void DraggingEntered(mojom::DraggingInfoPtr dragging_info, + // remote_cocoa::mojom::WebContentsNSViewHost, synchronous methods: + void DraggingEntered(remote_cocoa::mojom::DraggingInfoPtr dragging_info, DraggingEnteredCallback callback) override; - void DraggingUpdated(mojom::DraggingInfoPtr dragging_info, + void DraggingUpdated(remote_cocoa::mojom::DraggingInfoPtr dragging_info, DraggingUpdatedCallback callback) override; - void PerformDragOperation(mojom::DraggingInfoPtr dragging_info, + void PerformDragOperation(remote_cocoa::mojom::DraggingInfoPtr dragging_info, PerformDragOperationCallback callback) override; void DragPromisedFileTo(const base::FilePath& file_path, const DropData& drop_data, @@ -208,12 +213,13 @@ // The WebContentsViewCocoa that lives in the NSView hierarchy in this // process. This is always non-null, even when the view is being displayed // in another process. - std::unique_ptr<WebContentsNSViewBridge> ns_view_bridge_local_; + std::unique_ptr<remote_cocoa::WebContentsNSViewBridge> + in_process_ns_view_bridge_; // Mojo bindings for an out of process instance of this NSView. - mojom::WebContentsNSViewBridgeAssociatedPtr ns_view_bridge_remote_; - mojo::AssociatedBinding<mojom::WebContentsNSViewClient> - ns_view_client_binding_; + remote_cocoa::mojom::WebContentsNSViewAssociatedPtr remote_ns_view_; + mojo::AssociatedBinding<remote_cocoa::mojom::WebContentsNSViewHost> + remote_ns_view_host_binding_; // Used by CloseTabAfterEventTrackingIfNeeded. base::WeakPtrFactory<WebContentsViewMac> deferred_close_weak_ptr_factory_;
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index c9af9d83..1d1f44d 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -37,6 +37,8 @@ using blink::WebDragOperation; using blink::WebDragOperationsMask; +using remote_cocoa::mojom::DraggingInfoPtr; +using remote_cocoa::mojom::SelectionDirection; // Ensure that the blink::WebDragOperation enum values stay in sync with // NSDragOperation constants, since the code below static_casts between 'em. @@ -90,22 +92,23 @@ : web_contents_(web_contents), delegate_(delegate), ns_view_id_(remote_cocoa::GetNewNSViewId()), - ns_view_client_binding_(this), + remote_ns_view_host_binding_(this), deferred_close_weak_ptr_factory_(this) {} WebContentsViewMac::~WebContentsViewMac() { if (views_host_) views_host_->OnHostableViewDestroying(); DCHECK(!views_host_); - ns_view_bridge_local_.reset(); + in_process_ns_view_bridge_.reset(); } -WebContentsViewCocoa* WebContentsViewMac::cocoa_view() const { - return ns_view_bridge_local_ ? ns_view_bridge_local_->cocoa_view() : nil; +WebContentsViewCocoa* WebContentsViewMac::GetInProcessNSView() const { + return in_process_ns_view_bridge_ ? in_process_ns_view_bridge_->GetNSView() + : nil; } gfx::NativeView WebContentsViewMac::GetNativeView() const { - return cocoa_view(); + return GetInProcessNSView(); } gfx::NativeView WebContentsViewMac::GetContentNativeView() const { @@ -116,16 +119,16 @@ } gfx::NativeWindow WebContentsViewMac::GetTopLevelNativeWindow() const { - NSWindow* window = [cocoa_view() window]; + NSWindow* window = [GetInProcessNSView() window]; return window ? window : delegate_->GetNativeWindow(); } void WebContentsViewMac::GetContainerBounds(gfx::Rect* out) const { - NSWindow* window = [cocoa_view() window]; - NSRect bounds = [cocoa_view() bounds]; + NSWindow* window = [GetInProcessNSView() window]; + NSRect bounds = [GetInProcessNSView() bounds]; if (window) { // Convert bounds to window coordinate space. - bounds = [cocoa_view() convertRect:bounds toView:nil]; + bounds = [GetInProcessNSView() convertRect:bounds toView:nil]; // Convert bounds to screen coordinate space. bounds = [window convertRectToScreen:bounds]; @@ -156,13 +159,12 @@ [drag_dest_ setDragStartTrackersForProcess:source_rwh->GetProcess()->GetID()]; drag_source_start_rwh_ = source_rwh->GetWeakPtr(); - if (ns_view_bridge_remote_) { + if (remote_ns_view_) { // TODO(https://crbug.com/898608): Non-trivial gfx::ImageSkias fail to // serialize. - ns_view_bridge_remote_->StartDrag(drop_data, mask, gfx::ImageSkia(), - image_offset); + remote_ns_view_->StartDrag(drop_data, mask, gfx::ImageSkia(), image_offset); } else { - ns_view_bridge_local_->StartDrag(drop_data, mask, image, image_offset); + in_process_ns_view_bridge_->StartDrag(drop_data, mask, image, image_offset); } } @@ -262,12 +264,12 @@ if (delegate() && delegate()->TakeFocus(reverse)) return; if (reverse) { - [[cocoa_view() window] selectPreviousKeyView:cocoa_view()]; + [[GetInProcessNSView() window] selectPreviousKeyView:GetInProcessNSView()]; } else { - [[cocoa_view() window] selectNextKeyView:cocoa_view()]; + [[GetInProcessNSView() window] selectNextKeyView:GetInProcessNSView()]; } - if (ns_view_bridge_remote_) - ns_view_bridge_remote_->TakeFocus(reverse); + if (remote_ns_view_) + remote_ns_view_->TakeFocus(reverse); } void WebContentsViewMac::ShowContextMenu( @@ -305,17 +307,19 @@ } gfx::Rect WebContentsViewMac::GetViewBounds() const { - NSRect window_bounds = [cocoa_view() convertRect:[cocoa_view() bounds] - toView:nil]; + NSRect window_bounds = + [GetInProcessNSView() convertRect:[GetInProcessNSView() bounds] + toView:nil]; window_bounds.origin = ui::ConvertPointFromWindowToScreen( - [cocoa_view() window], window_bounds.origin); + [GetInProcessNSView() window], window_bounds.origin); return gfx::ScreenRectFromNSRect(window_bounds); } void WebContentsViewMac::CreateView( const gfx::Size& initial_size, gfx::NativeView context) { - ns_view_bridge_local_ = - std::make_unique<WebContentsNSViewBridge>(ns_view_id_, this); + in_process_ns_view_bridge_ = + std::make_unique<remote_cocoa::WebContentsNSViewBridge>(ns_view_id_, + this); drag_dest_.reset([[WebDragDest alloc] initWithWebContentsImpl:web_contents_]); if (delegate_) @@ -362,18 +366,20 @@ // to make sure the content area is on the bottom so other things draw over // it. NSView* view_view = view->GetNativeView().GetNativeNSView(); - [view_view setFrame:[cocoa_view() bounds]]; + [view_view setFrame:[GetInProcessNSView() bounds]]; [view_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; // Add the new view below all other views; this also keeps it below any // overlay view installed. - [cocoa_view() addSubview:view_view positioned:NSWindowBelow relativeTo:nil]; + [GetInProcessNSView() addSubview:view_view + positioned:NSWindowBelow + relativeTo:nil]; // For some reason known only to Cocoa, the autorecalculation of the key view // loop set on the window doesn't set the next key view when the subview is // added. On 10.6 things magically work fine; on 10.5 they fail // <http://crbug.com/61493>. Digging into Cocoa key view loop code yielded // madness; TODO(avi,rohit): look at this again and figure out what's really // going on. - [cocoa_view() setNextKeyView:view_view]; + [GetInProcessNSView() setNextKeyView:view_view]; return view; } @@ -446,7 +452,7 @@ } //////////////////////////////////////////////////////////////////////////////// -// WebContentsViewMac, mojom::WebContentsNSViewClient: +// WebContentsViewMac, mojom::WebContentsNSViewHost: void WebContentsViewMac::OnMouseEvent(bool motion, bool exited) { if (!web_contents_ || !web_contents_->GetDelegate()) @@ -456,32 +462,31 @@ exited); } -void WebContentsViewMac::OnBecameFirstResponder( - mojom::SelectionDirection direction) { +void WebContentsViewMac::OnBecameFirstResponder(SelectionDirection direction) { if (!web_contents_) return; - if (direction == mojom::SelectionDirection::kDirect) + if (direction == SelectionDirection::kDirect) return; web_contents_->FocusThroughTabTraversal(direction == - mojom::SelectionDirection::kReverse); + SelectionDirection::kReverse); } void WebContentsViewMac::OnWindowVisibilityChanged( - mojom::Visibility mojo_visibility) { + remote_cocoa::mojom::Visibility mojo_visibility) { if (!web_contents_ || web_contents_->IsBeingDestroyed()) return; // TODO: make content use the mojo type for visibility. Visibility visibility = Visibility::VISIBLE; switch (mojo_visibility) { - case mojom::Visibility::kVisible: + case remote_cocoa::mojom::Visibility::kVisible: visibility = Visibility::VISIBLE; break; - case mojom::Visibility::kOccluded: + case remote_cocoa::mojom::Visibility::kOccluded: visibility = Visibility::OCCLUDED; break; - case mojom::Visibility::kHidden: + case remote_cocoa::mojom::Visibility::kHidden: visibility = Visibility::HIDDEN; break; } @@ -493,7 +498,7 @@ [drag_dest_ setDropData:drop_data]; } -bool WebContentsViewMac::DraggingEntered(mojom::DraggingInfoPtr dragging_info, +bool WebContentsViewMac::DraggingEntered(DraggingInfoPtr dragging_info, uint32_t* out_result) { *out_result = [drag_dest_ draggingEntered:dragging_info.get()]; return true; @@ -503,15 +508,14 @@ [drag_dest_ draggingExited]; } -bool WebContentsViewMac::DraggingUpdated(mojom::DraggingInfoPtr dragging_info, +bool WebContentsViewMac::DraggingUpdated(DraggingInfoPtr dragging_info, uint32_t* out_result) { *out_result = [drag_dest_ draggingUpdated:dragging_info.get()]; return true; } -bool WebContentsViewMac::PerformDragOperation( - mojom::DraggingInfoPtr dragging_info, - bool* out_result) { +bool WebContentsViewMac::PerformDragOperation(DraggingInfoPtr dragging_info, + bool* out_result) { *out_result = [drag_dest_ performDragOperation:dragging_info.get()]; return true; } @@ -585,14 +589,14 @@ drag_source_start_rwh_.get()); } -void WebContentsViewMac::DraggingEntered(mojom::DraggingInfoPtr dragging_info, +void WebContentsViewMac::DraggingEntered(DraggingInfoPtr dragging_info, DraggingEnteredCallback callback) { uint32_t result = 0; DraggingEntered(std::move(dragging_info), &result); std::move(callback).Run(result); } -void WebContentsViewMac::DraggingUpdated(mojom::DraggingInfoPtr dragging_info, +void WebContentsViewMac::DraggingUpdated(DraggingInfoPtr dragging_info, DraggingUpdatedCallback callback) { uint32_t result = false; DraggingUpdated(std::move(dragging_info), &result); @@ -600,7 +604,7 @@ } void WebContentsViewMac::PerformDragOperation( - mojom::DraggingInfoPtr dragging_info, + DraggingInfoPtr dragging_info, PerformDragOperationCallback callback) { bool result = false; PerformDragOperation(std::move(dragging_info), &result); @@ -620,41 +624,42 @@ //////////////////////////////////////////////////////////////////////////////// // WebContentsViewMac, ViewsHostableView: -void WebContentsViewMac::ViewsHostableAttach(ViewsHostableView::Host* host) { - views_host_ = host; +void WebContentsViewMac::ViewsHostableAttach( + ViewsHostableView::Host* views_host) { + views_host_ = views_host; // Create an NSView in the target process, if one exists. auto* remote_cocoa_application = views_host_->GetRemoteCocoaApplication(); if (remote_cocoa_application) { - mojom::WebContentsNSViewClientAssociatedPtr client; - ns_view_client_binding_.Bind(mojo::MakeRequest(&client)); - mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request = - mojo::MakeRequest(&ns_view_bridge_remote_); + remote_cocoa::mojom::WebContentsNSViewHostAssociatedPtr host; + remote_ns_view_host_binding_.Bind(mojo::MakeRequest(&host)); + remote_cocoa::mojom::WebContentsNSViewAssociatedRequest ns_view_request = + mojo::MakeRequest(&remote_ns_view_); - // Cast from mojom::WebContentsNSViewClientPtr and + // Cast from mojom::WebContentsNSViewHostPtr and // mojom::WebContentsNSViewBridgeRequest to the public interfaces // accepted by the application. // TODO(ccameron): Remove the need for this cast. // https://crbug.com/888290 mojo::AssociatedInterfacePtrInfo<remote_cocoa::mojom::StubInterface> - stub_client(client.PassInterface().PassHandle(), 0); - remote_cocoa::mojom::StubInterfaceAssociatedRequest stub_bridge_request( - bridge_request.PassHandle()); + stub_host(host.PassInterface().PassHandle(), 0); + remote_cocoa::mojom::StubInterfaceAssociatedRequest stub_ns_view_request( + ns_view_request.PassHandle()); remote_cocoa_application->CreateWebContentsNSView( - ns_view_id_, std::move(stub_client), std::move(stub_bridge_request)); - ns_view_bridge_remote_->SetParentNSView(views_host_->GetNSViewId()); + ns_view_id_, std::move(stub_host), std::move(stub_ns_view_request)); + remote_ns_view_->SetParentNSView(views_host_->GetNSViewId()); // Because this view is being displayed from a remote process, reset the // in-process NSView's client pointer, so that the in-process NSView will // not call back into |this|. - [cocoa_view() setClient:nullptr]; + [GetInProcessNSView() setHost:nullptr]; } // TODO(https://crbug.com/933679): WebContentsNSViewBridge::SetParentView // will look up the parent NSView by its id, but this has been observed to // fail in the field, so assume that the caller handles updating the NSView // hierarchy. - // ns_view_bridge_local_->SetParentNSView(views_host_->GetNSViewId()); + // in_process_ns_view_bridge_->SetParentNSView(views_host_->GetNSViewId()); for (auto* rwhv_mac : GetChildViews()) { rwhv_mac->MigrateNSViewBridge(remote_cocoa_application, ns_view_id_); @@ -666,16 +671,16 @@ DCHECK(views_host_); // Disconnect from the remote bridge, if it exists. This will have the effect // of destroying the associated bridge instance with its NSView. - if (ns_view_bridge_remote_) { - ns_view_bridge_remote_->SetVisible(false); - ns_view_bridge_remote_->ResetParentNSView(); - ns_view_client_binding_.Close(); - ns_view_bridge_remote_.reset(); + if (remote_ns_view_) { + remote_ns_view_->SetVisible(false); + remote_ns_view_->ResetParentNSView(); + remote_ns_view_host_binding_.Close(); + remote_ns_view_.reset(); // Permit the in-process NSView to call back into |this| again. - [cocoa_view() setClient:this]; + [GetInProcessNSView() setHost:this]; } - ns_view_bridge_local_->SetVisible(false); - ns_view_bridge_local_->ResetParentNSView(); + in_process_ns_view_bridge_->SetVisible(false); + in_process_ns_view_bridge_->ResetParentNSView(); views_host_ = nullptr; for (auto* rwhv_mac : GetChildViews()) { @@ -688,24 +693,24 @@ void WebContentsViewMac::ViewsHostableSetBounds( const gfx::Rect& bounds_in_window) { // Update both the in-process and out-of-process NSViews' bounds. - ns_view_bridge_local_->SetBounds(bounds_in_window); - if (ns_view_bridge_remote_) - ns_view_bridge_remote_->SetBounds(bounds_in_window); + in_process_ns_view_bridge_->SetBounds(bounds_in_window); + if (remote_ns_view_) + remote_ns_view_->SetBounds(bounds_in_window); } void WebContentsViewMac::ViewsHostableSetVisible(bool visible) { // Update both the in-process and out-of-process NSViews' visibility. - ns_view_bridge_local_->SetVisible(visible); - if (ns_view_bridge_remote_) - ns_view_bridge_remote_->SetVisible(visible); + in_process_ns_view_bridge_->SetVisible(visible); + if (remote_ns_view_) + remote_ns_view_->SetVisible(visible); } void WebContentsViewMac::ViewsHostableMakeFirstResponder() { // Only make the true NSView become the first responder. - if (ns_view_bridge_remote_) - ns_view_bridge_remote_->MakeFirstResponder(); + if (remote_ns_view_) + remote_ns_view_->MakeFirstResponder(); else - ns_view_bridge_local_->MakeFirstResponder(); + in_process_ns_view_bridge_->MakeFirstResponder(); } void WebContentsViewMac::ViewsHostableSetParentAccessible(
diff --git a/content/browser/web_contents/web_contents_view_mac_unittest.mm b/content/browser/web_contents/web_contents_view_mac_unittest.mm index 0124707..08226ed6 100644 --- a/content/browser/web_contents/web_contents_view_mac_unittest.mm +++ b/content/browser/web_contents/web_contents_view_mac_unittest.mm
@@ -19,12 +19,11 @@ namespace { -class WebContentsViewCocoaTest : public ui::CocoaTest { -}; +class WebContentsNSViewTest : public ui::CocoaTest {}; } // namespace -TEST_F(WebContentsViewCocoaTest, NonWebDragSourceTest) { +TEST_F(WebContentsNSViewTest, NonWebDragSourceTest) { // The designated initializer is private but init should be fine in this case. base::scoped_nsobject<WebContentsViewCocoa> view( [[WebContentsViewCocoa alloc] init]);
diff --git a/content/browser/web_contents/web_drag_dest_mac.h b/content/browser/web_contents/web_drag_dest_mac.h index 6e6ed54..28bdcc4 100644 --- a/content/browser/web_contents/web_drag_dest_mac.h +++ b/content/browser/web_contents/web_drag_dest_mac.h
@@ -20,14 +20,17 @@ class RenderWidgetHostImpl; class WebContentsImpl; class WebDragDestDelegate; -namespace mojom { -class DraggingInfo; -} // namespace mojom } // namespace content // A typedef for a RenderViewHost used for comparison purposes only. typedef content::RenderViewHost* RenderViewHostIdentifier; +namespace remote_cocoa { +namespace mojom { +class DraggingInfo; +} // namespace mojom +} // namespace remote_cocoa + namespace content { // Given |data|, which should not be nil, fill it in using the contents of the @@ -98,10 +101,12 @@ // Messages to send during the tracking of a drag, ususally upon receiving // calls from the view system. Communicates the drag messages to WebCore. - (void)setDropData:(const content::DropData&)dropData; -- (NSDragOperation)draggingEntered:(const content::mojom::DraggingInfo*)info; +- (NSDragOperation)draggingEntered: + (const remote_cocoa::mojom::DraggingInfo*)info; - (void)draggingExited; -- (NSDragOperation)draggingUpdated:(const content::mojom::DraggingInfo*)info; -- (BOOL)performDragOperation:(const content::mojom::DraggingInfo*)info; +- (NSDragOperation)draggingUpdated: + (const remote_cocoa::mojom::DraggingInfo*)info; +- (BOOL)performDragOperation:(const remote_cocoa::mojom::DraggingInfo*)info; // Helper to call WebWidgetHostInputEventRouter::GetRenderWidgetHostAtPoint(). - (content::RenderWidgetHostImpl*)
diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm index f425000..c4638ac6e 100644 --- a/content/browser/web_contents/web_drag_dest_mac.mm +++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -28,11 +28,11 @@ #include "ui/gfx/geometry/point.h" using blink::WebDragOperationsMask; -using content::mojom::DraggingInfo; using content::DropData; using content::OpenURLParams; using content::Referrer; using content::WebContentsImpl; +using remote_cocoa::mojom::DraggingInfo; namespace {
diff --git a/content/browser/web_contents/web_drag_source_mac_unittest.mm b/content/browser/web_contents/web_drag_source_mac_unittest.mm index 962a7343..10f6ddc 100644 --- a/content/browser/web_contents/web_drag_source_mac_unittest.mm +++ b/content/browser/web_contents/web_drag_source_mac_unittest.mm
@@ -26,7 +26,7 @@ scoped_refptr<ui::UniquePasteboard> pasteboard1 = new ui::UniquePasteboard; base::scoped_nsobject<WebDragSource> source([[WebDragSource alloc] - initWithClient:nullptr + initWithHost:nullptr view:view dropData:dropData.get() image:nil
diff --git a/content/common/render_widget_host_ns_view.mojom b/content/common/render_widget_host_ns_view.mojom index 48c46bd..5659d670 100644 --- a/content/common/render_widget_host_ns_view.mojom +++ b/content/common/render_widget_host_ns_view.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module remote_cocoa.mojom; import "content/common/native_types.mojom"; import "content/common/input/input_handler.mojom"; @@ -19,7 +19,7 @@ // RenderWidgetHostViewMac, sends messages to the app shim process, targeting // the RenderWidgetHostViewCocoa NSView. No synchronous communication is allowed // in this direction. -interface RenderWidgetHostNSViewBridge { +interface RenderWidgetHostNSView { // Specify that the NSView will a popup (e.g, date/time picker) that will // create its own NSWindow. InitAsPopup(gfx.mojom.Rect content_rect); @@ -69,7 +69,7 @@ SetShowingContextMenu(bool showing); // Set the cursor type to display. - DisplayCursor(WebCursor cursor); + DisplayCursor(content.mojom.WebCursor cursor); // Lock or unlock the cursor. SetCursorLocked(bool locked); @@ -80,7 +80,7 @@ // Open the dictionary overlay for the specified string at the specified // point. - ShowDictionaryOverlay(EncodedAttributedString attributed_string, + ShowDictionaryOverlay(content.mojom.EncodedAttributedString attributed_string, gfx.mojom.Point baseline_point); // Start intercepting keyboard events for the specified codes. @@ -94,11 +94,11 @@ // shim process communicates to the RenderWidgetHostViewMac in the browser // process. Synchronous calls are allowed to be made through this interface. // TODO(ccameron): This corresponds almost one-to-one with the -// content::RenderWidgetHostNSViewClient interface. It may be possible to merge +// content::RenderWidgetHostNSViewHost interface. It may be possible to merge // these two interfaces, though that may come at the cost of extra work (e.g, // de-serializing and re-serializing all events). // https://crbug.com/821651 -interface RenderWidgetHostNSViewClient { +interface RenderWidgetHostNSViewHost { // Synchronously query if the RenderWidgetHostView is for a main frame, and // return the result as |is_for_main_frame|. [Sync] @@ -137,29 +137,29 @@ // Forward a keyboard event to the RenderWidgetHost that is currently handling // the key-down event. - ForwardKeyboardEvent(Event event, bool skip_in_browser); + ForwardKeyboardEvent(content.mojom.Event event, bool skip_in_browser); ForwardKeyboardEventWithCommands( - Event event, + content.mojom.Event event, bool skip_in_browser, array<content.mojom.EditCommand> commands); // Forward events to the renderer or the input router, as appropriate. - RouteOrProcessMouseEvent(Event event); - RouteOrProcessTouchEvent(Event event); - RouteOrProcessWheelEvent(Event event); + RouteOrProcessMouseEvent(content.mojom.Event event); + RouteOrProcessTouchEvent(content.mojom.Event event); + RouteOrProcessWheelEvent(content.mojom.Event event); // Special case forwarding of synthetic events to the renderer. - ForwardMouseEvent(Event event); - ForwardWheelEvent(Event event); + ForwardMouseEvent(content.mojom.Event event); + ForwardWheelEvent(content.mojom.Event event); // Handling pinch gesture events. Note that for GestureBegin, the type of the // event is ignored, and is inferred from subsequent GestureUpdate calls. - GestureBegin(Event event, bool is_synthetically_injected); - GestureUpdate(Event event); - GestureEnd(Event event); + GestureBegin(content.mojom.Event event, bool is_synthetically_injected); + GestureUpdate(content.mojom.Event event); + GestureEnd(content.mojom.Event event); // Handle a double-tap magnify event. - SmartMagnify(Event event); + SmartMagnify(content.mojom.Event event); // Forward the corresponding Ime commands to the appropriate RenderWidgetHost. // Appropriate, has two meanings here. If this is during a key-down event,
diff --git a/content/common/web_contents_ns_view_bridge.mojom b/content/common/web_contents_ns_view_bridge.mojom index d4190a8a..3ab01e0 100644 --- a/content/common/web_contents_ns_view_bridge.mojom +++ b/content/common/web_contents_ns_view_bridge.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module remote_cocoa.mojom; import "content/public/common/drop_data.mojom"; import "mojo/public/mojom/base/file_path.mojom"; @@ -12,7 +12,7 @@ // Interface through which a WebContentsViewMac communicates with its NSView in // another process. -interface WebContentsNSViewBridge { +interface WebContentsNSView { // Set this to be a child NSView of the NSView mapped to by // |parent_ns_view_id|. SetParentNSView(uint64 parent_ns_view_id); @@ -35,7 +35,7 @@ TakeFocus(bool reverse); // Initiate a drag from the web contents area. - StartDrag(DropData drop_data, + StartDrag(content.mojom.DropData drop_data, uint32 operation_mask, gfx.mojom.ImageSkia? image, gfx.mojom.Vector2d image_offset); @@ -83,7 +83,7 @@ // Interface through which the NSView in another process communicates with its // owning WebContentsViewMac. This interface has no methods yet, but is included // for symmetry and future use. -interface WebContentsNSViewClient { +interface WebContentsNSViewHost { // Notification that there was a mouse event, along with the type of event. // If |motion| is true, this is a normal motion event. If |exited| is true, // the pointer left the contents area. @@ -99,7 +99,7 @@ // Transmit the data that is being dropped on the NSView. This is called prior // to DraggingEntered. - SetDropData(DropData drop_data); + SetDropData(content.mojom.DropData drop_data); // Called in response to the -[NSDraggingDestination draggingEntered] method // being called on the NSView. Returns the resulting operation in |result|. @@ -126,7 +126,7 @@ // destination file. [Sync] DragPromisedFileTo(mojo_base.mojom.FilePath file_path, - DropData drop_data, + content.mojom.DropData drop_data, url.mojom.Url download_url) => (mojo_base.mojom.FilePath file_path);
diff --git a/content/public/browser/remote_cocoa.h b/content/public/browser/remote_cocoa.h index 5506c5e..e514e0b 100644 --- a/content/public/browser/remote_cocoa.h +++ b/content/public/browser/remote_cocoa.h
@@ -8,7 +8,7 @@ #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" -namespace content { +namespace remote_cocoa { // Create the NSView for a RenderWidgetHostView or WebContentsView. This is // called in the app shim process through an interface in remote_cocoa. These @@ -24,6 +24,6 @@ mojo::ScopedInterfaceEndpointHandle host_handle, mojo::ScopedInterfaceEndpointHandle view_request_handle); -} // namespace content +} // namespace remote_cocoa #endif // CONTENT_PUBLIC_BROWSER_REMOTE_COCOA_H_
diff --git a/content/public/test/content_browser_test_utils_mac.mm b/content/public/test/content_browser_test_utils_mac.mm index 156c8299..57fec6a 100644 --- a/content/public/test/content_browser_test_utils_mac.mm +++ b/content/public/test/content_browser_test_utils_mac.mm
@@ -56,7 +56,7 @@ if (!contents->GetBrowserPluginGuest()) { RenderWidgetHostViewMac* rwhv_mac = static_cast<RenderWidgetHostViewMac*>( contents->GetRenderWidgetHostView()); - if (rwhv_mac->cocoa_view() == object) + if (rwhv_mac->GetInProcessNSView() == object) return rwhv_mac; } } @@ -179,10 +179,10 @@ return; NSRect bounds_in_cocoa_view = - [view convertRect:view.bounds toView:rwhv_mac->cocoa_view()]; + [view convertRect:view.bounds toView:rwhv_mac->GetInProcessNSView()]; gfx::Rect rect = - [rwhv_mac->cocoa_view() flipNSRectToRect:bounds_in_cocoa_view]; + [rwhv_mac->GetInProcessNSView() flipNSRectToRect:bounds_in_cocoa_view]; observer->DidAddSubviewWillBeDismissed(rect);
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index e8b4342..95cabb2 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -110,6 +110,7 @@ crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/random_separate_triangles.html [ Failure ] crbug.com/680754 [ d3d11 win nvidia-0x1cb3 ] deqp/functional/gles3/transformfeedback/interpolation_flat.html [ Failure ] crbug.com/966143 [ d3d11 win7 nvidia-0x1cb3 ] conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html [ RetryOnFailure ] +crbug.com/966143 [ d3d11 win7 nvidia-0x1cb3 ] conformance/attribs/gl-vertex-attrib-zero-issues.html [ RetryOnFailure ] crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ] crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] crbug.com/728670 [ d3d11 win nvidia-0x1cb3 ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ] @@ -753,6 +754,7 @@ crbug.com/906739 [ android qualcomm ] conformance2/extensions/ovr_multiview2.html [ Failure ] crbug.com/906742 [ android qualcomm ] conformance2/glsl3/compare-structs-containing-arrays.html [ Failure ] crbug.com/906735 [ android qualcomm ] conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ] +crbug.com/949321 [ android qualcomm ] deqp/functional/gles3/framebufferblit/default_framebuffer_02.html [ RetryOnFailure ] # This test is failing on Android Pixel 2 and 3 (Qualcomm) # Seems to be an OpenGL ES bug.
diff --git a/device/bluetooth/bluetooth_adapter_winrt.cc b/device/bluetooth/bluetooth_adapter_winrt.cc index d3b8d7829..48bd0eda 100644 --- a/device/bluetooth/bluetooth_adapter_winrt.cc +++ b/device/bluetooth/bluetooth_adapter_winrt.cc
@@ -21,6 +21,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" +#include "base/scoped_native_library.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -467,13 +468,6 @@ ExtractManufacturerData(advertisement.Get())); } -decltype(&::RoGetAgileReference) LoadGetAgileReference() { - auto funcptr = reinterpret_cast<decltype(&::RoGetAgileReference)>( - ::GetProcAddress(::GetModuleHandle(L"Ole32.dll"), "RoGetAgileReference")); - CHECK(funcptr); - return funcptr; -} - } // namespace std::string BluetoothAdapterWinrt::GetAddress() const { @@ -686,27 +680,10 @@ if (!radio_statics) statics.radio_statics->Resolve(IID_IRadioStatics, &radio_statics); - auto getAgileReferenceFunc = LoadGetAgileReference(); - - ComPtr<IAgileReference> radio_statics_agileref; - HRESULT hr = - getAgileReferenceFunc(AGILEREFERENCE_DEFAULT, IID_IRadioStatics, - radio_statics.Get(), &radio_statics_agileref); - DCHECK(SUCCEEDED(hr)); - ComPtr<IAgileReference> device_information_statics_agileref; - hr = getAgileReferenceFunc( - AGILEREFERENCE_DEFAULT, IID_IDeviceInformationStatics, - device_information_statics.Get(), &device_information_statics_agileref); - DCHECK(SUCCEEDED(hr)); - ComPtr<IAgileReference> adapter_statics_agileref; - hr = getAgileReferenceFunc( - AGILEREFERENCE_DEFAULT, IID_IBluetoothAdapterStatics, - bluetooth_adapter_statics.Get(), &adapter_statics_agileref); - DCHECK(SUCCEEDED(hr)); - CompleteInitAgile(std::move(init_cb), - StaticsInterfaces(adapter_statics_agileref, - device_information_statics_agileref, - radio_statics_agileref)); + StaticsInterfaces agile_statics = GetAgileReferencesForStatics( + std::move(bluetooth_adapter_statics), + std::move(device_information_statics), std::move(radio_statics)); + CompleteInitAgile(std::move(init_cb), std::move(agile_statics)); } // static @@ -746,34 +723,51 @@ return BluetoothAdapterWinrt::StaticsInterfaces(); } - auto getAgileReferenceFunc = LoadGetAgileReference(); + return GetAgileReferencesForStatics(std::move(adapter_statics), + std::move(device_information_statics), + std::move(radio_statics)); +} - ComPtr<IAgileReference> radio_statics_agileref; - hr = getAgileReferenceFunc(AGILEREFERENCE_DEFAULT, - ABI::Windows::Devices::Radios::IID_IRadioStatics, - radio_statics.Get(), &radio_statics_agileref); - if (FAILED(hr)) - return BluetoothAdapterWinrt::StaticsInterfaces(); +// static +BluetoothAdapterWinrt::StaticsInterfaces +BluetoothAdapterWinrt::GetAgileReferencesForStatics( + ComPtr<IBluetoothAdapterStatics> adapter_statics, + ComPtr<IDeviceInformationStatics> device_information_statics, + ComPtr<IRadioStatics> radio_statics) { + base::ScopedNativeLibrary ole32_library(base::FilePath(L"Ole32.dll")); + CHECK(ole32_library.is_valid()); - ComPtr<IAgileReference> device_information_statics_agileref; - hr = getAgileReferenceFunc( - AGILEREFERENCE_DEFAULT, - ABI::Windows::Devices::Enumeration::IID_IDeviceInformationStatics, - device_information_statics.Get(), &device_information_statics_agileref); - if (FAILED(hr)) - return BluetoothAdapterWinrt::StaticsInterfaces(); + auto ro_get_agile_reference = + reinterpret_cast<decltype(&::RoGetAgileReference)>( + ole32_library.GetFunctionPointer("RoGetAgileReference")); + CHECK(ro_get_agile_reference); ComPtr<IAgileReference> adapter_statics_agileref; - hr = getAgileReferenceFunc( + HRESULT hr = ro_get_agile_reference( AGILEREFERENCE_DEFAULT, ABI::Windows::Devices::Bluetooth::IID_IBluetoothAdapterStatics, adapter_statics.Get(), &adapter_statics_agileref); if (FAILED(hr)) - return BluetoothAdapterWinrt::StaticsInterfaces(); + return StaticsInterfaces(); - return BluetoothAdapterWinrt::StaticsInterfaces( - adapter_statics_agileref, device_information_statics_agileref, - radio_statics_agileref); + ComPtr<IAgileReference> device_information_statics_agileref; + hr = ro_get_agile_reference( + AGILEREFERENCE_DEFAULT, + ABI::Windows::Devices::Enumeration::IID_IDeviceInformationStatics, + device_information_statics.Get(), &device_information_statics_agileref); + if (FAILED(hr)) + return StaticsInterfaces(); + + ComPtr<IAgileReference> radio_statics_agileref; + hr = ro_get_agile_reference(AGILEREFERENCE_DEFAULT, + ABI::Windows::Devices::Radios::IID_IRadioStatics, + radio_statics.Get(), &radio_statics_agileref); + if (FAILED(hr)) + return StaticsInterfaces(); + + return StaticsInterfaces(std::move(adapter_statics_agileref), + std::move(device_information_statics_agileref), + std::move(radio_statics_agileref)); } void BluetoothAdapterWinrt::CompleteInitAgile(InitCallback init_cb,
diff --git a/device/bluetooth/bluetooth_adapter_winrt.h b/device/bluetooth/bluetooth_adapter_winrt.h index 0ad217c..87dcade 100644 --- a/device/bluetooth/bluetooth_adapter_winrt.h +++ b/device/bluetooth/bluetooth_adapter_winrt.h
@@ -136,6 +136,15 @@ }; static StaticsInterfaces PerformSlowInitTasks(); + static StaticsInterfaces GetAgileReferencesForStatics( + Microsoft::WRL::ComPtr< + ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics> + adapter_statics, + Microsoft::WRL::ComPtr< + ABI::Windows::Devices::Enumeration::IDeviceInformationStatics> + device_information_statics, + Microsoft::WRL::ComPtr<ABI::Windows::Devices::Radios::IRadioStatics> + radio_statics); // CompleteInitAgile is a proxy to CompleteInit that resolves agile // references.
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc index b066add..6bfa269 100644 --- a/headless/app/headless_shell.cc +++ b/headless/app/headless_shell.cc
@@ -70,7 +70,8 @@ bool ParseWindowSize(const std::string& window_size, gfx::Size* parsed_window_size) { - int width, height = 0; + int width = 0; + int height = 0; if (sscanf(window_size.c_str(), "%d%*[x,]%d", &width, &height) >= 2 && width >= 0 && height >= 0) { parsed_window_size->set_width(width); @@ -140,7 +141,7 @@ #endif } -#endif +#endif // !defined(CHROME_MULTIPLE_DLL_CHILD) int RunContentMain( HeadlessBrowser::Options options, @@ -159,17 +160,63 @@ // TODO(skyostil): Implement custom message pumps. DCHECK(!options.message_pump); -#if !defined(CHROME_MULTIPLE_DLL_CHILD) - std::unique_ptr<HeadlessBrowserImpl> browser(new HeadlessBrowserImpl( - std::move(on_browser_start_callback), std::move(options))); - HeadlessContentMainDelegate delegate(std::move(browser)); -#else +#if defined(CHROME_MULTIPLE_DLL_CHILD) HeadlessContentMainDelegate delegate(std::move(options)); +#else + auto browser = std::make_unique<HeadlessBrowserImpl>( + std::move(on_browser_start_callback), std::move(options)); + HeadlessContentMainDelegate delegate(std::move(browser)); #endif params.delegate = &delegate; return content::ContentMain(params); } +bool ValidateCommandLine(const base::CommandLine& command_line) { + if (!command_line.HasSwitch(switches::kRemoteDebuggingPort) && + !command_line.HasSwitch(switches::kRemoteDebuggingPipe)) { + if (command_line.GetArgs().size() <= 1) + return true; + LOG(ERROR) << "Open multiple tabs is only supported when " + << "remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kDefaultBackgroundColor)) { + LOG(ERROR) << "Setting default background color is disabled " + << "when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kDumpDom)) { + LOG(ERROR) << "Dump DOM is disabled when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kPrintToPDF)) { + LOG(ERROR) << "Print to PDF is disabled " + << "when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kRepl)) { + LOG(ERROR) << "Evaluate Javascript is disabled " + << "when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kScreenshot)) { + LOG(ERROR) << "Capture screenshot is disabled " + << "when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kTimeout)) { + LOG(ERROR) << "Navigation timeout is disabled " + << "when remote debugging is enabled."; + return false; + } + if (command_line.HasSwitch(switches::kVirtualTimeBudget)) { + LOG(ERROR) << "Virtual time budget is disabled " + << "when remote debugging is enabled."; + return false; + } + return true; +} + } // namespace HeadlessShell::HeadlessShell() : weak_factory_(this) {} @@ -589,52 +636,6 @@ command_line.HasSwitch(switches::kRemoteDebuggingPipe)); } -bool ValidateCommandLine(const base::CommandLine& command_line) { - if (!command_line.HasSwitch(switches::kRemoteDebuggingPort) && - !command_line.HasSwitch(switches::kRemoteDebuggingPipe)) { - if (command_line.GetArgs().size() <= 1) - return true; - LOG(ERROR) << "Open multiple tabs is only supported when " - << "remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kDefaultBackgroundColor)) { - LOG(ERROR) << "Setting default background color is disabled " - << "when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kDumpDom)) { - LOG(ERROR) << "Dump DOM is disabled when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kPrintToPDF)) { - LOG(ERROR) << "Print to PDF is disabled " - << "when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kRepl)) { - LOG(ERROR) << "Evaluate Javascript is disabled " - << "when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kScreenshot)) { - LOG(ERROR) << "Capture screenshot is disabled " - << "when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kTimeout)) { - LOG(ERROR) << "Navigation timeout is disabled " - << "when remote debugging is enabled."; - return false; - } - if (command_line.HasSwitch(switches::kVirtualTimeBudget)) { - LOG(ERROR) << "Virtual time budget is disabled " - << "when remote debugging is enabled."; - return false; - } - return true; -} - #if defined(OS_WIN) int HeadlessShellMain(HINSTANCE instance, sandbox::SandboxInterfaceInfo* sandbox_info) {
diff --git a/ios/chrome/browser/signin/feature_flags.mm b/ios/chrome/browser/signin/feature_flags.mm index b7e2e5e..21f76c8 100644 --- a/ios/chrome/browser/signin/feature_flags.mm +++ b/ios/chrome/browser/signin/feature_flags.mm
@@ -16,7 +16,7 @@ "UseNSURLSessionForGaiaSigninRequests", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kIdentityDisc{"IdentityDisc", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; bool IsIdentityDiscFeatureEnabled() { // Checks feature flag and any dependencies. Display of Identity Disc depends
diff --git a/ios/testing/earl_grey/BUILD.gn b/ios/testing/earl_grey/BUILD.gn index 7a5367b..22cf840 100644 --- a/ios/testing/earl_grey/BUILD.gn +++ b/ios/testing/earl_grey/BUILD.gn
@@ -15,6 +15,8 @@ ] sources = [ + "app_launch_manager.h", + "app_launch_manager.mm", "base_earl_grey_test_case.h", "base_earl_grey_test_case.mm", "base_eg_test_helper_impl.h", @@ -59,6 +61,8 @@ testonly = true sources = [ + "app_launch_manager.h", + "app_launch_manager.mm", "base_earl_grey_test_case.h", "base_earl_grey_test_case.mm", "base_eg_test_helper_impl.h",
diff --git a/ios/testing/earl_grey/app_launch_manager.h b/ios/testing/earl_grey/app_launch_manager.h new file mode 100644 index 0000000..b03205e8 --- /dev/null +++ b/ios/testing/earl_grey/app_launch_manager.h
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium 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_TESTING_EARL_GREY_APP_LAUNCH_MANAGER_H_ +#define IOS_TESTING_EARL_GREY_APP_LAUNCH_MANAGER_H_ + +#import <Foundation/Foundation.h> + +// Provides control of the single application-under-test to EarlGrey 2 tests. +@interface AppLaunchManager : NSObject + +// Returns the singleton instance of this class. ++ (AppLaunchManager*)sharedManager; + +- (instancetype)init NS_UNAVAILABLE; + +// Makes sure the app has been started with the appropriate |arguments|. +// In EG2, will launch the app if any of the following conditions are met: +// * The app is not running +// * The app is currently running with different arguments. +// * |forceRestart| is YES +// Otherwise, the app will be activated instead of (re)launched. +// Will wait until app is activated or launched, and fail the test if it +// fails to do so. +// In EG1, this method is a no-op. +- (void)ensureAppLaunchedWithArgs:(NSArray<NSString*>*)arguments + forceRestart:(BOOL)forceRestart; + +@end + +#endif // IOS_TESTING_EARL_GREY_APP_LAUNCH_MANAGER_H_
diff --git a/ios/testing/earl_grey/app_launch_manager.mm b/ios/testing/earl_grey/app_launch_manager.mm new file mode 100644 index 0000000..7164036c --- /dev/null +++ b/ios/testing/earl_grey/app_launch_manager.mm
@@ -0,0 +1,65 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/testing/earl_grey/app_launch_manager.h" + +#import <XCTest/XCTest.h> + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#if defined(CHROME_EARL_GREY_2) // avoid unused function warning in EG1 +namespace { +// Checks if two pairs of launch arguments are equivalent. +bool LaunchArgumentsAreEqual(NSArray<NSString*>* args1, + NSArray<NSString*>* args2) { + // isEqualToArray will only return true if both arrays are non-nil, + // so first check if both arrays are empty or nil + if (!args1.count && !args2.count) { + return true; + } + + return [args1 isEqualToArray:args2]; +} +} // namespace +#endif + +@interface AppLaunchManager () +@property(nonatomic) XCUIApplication* runningApplication; +@property(nonatomic) NSArray<NSString*>* currentLaunchArgs; +@end + +@implementation AppLaunchManager + ++ (AppLaunchManager*)sharedManager { + static AppLaunchManager* instance = nil; + static dispatch_once_t guard; + dispatch_once(&guard, ^{ + instance = [[AppLaunchManager alloc] init]; + }); + return instance; +} + +- (void)ensureAppLaunchedWithArgs:(NSArray<NSString*>*)arguments + forceRestart:(BOOL)forceRestart { +#if defined(CHROME_EARL_GREY_2) + bool appNeedsLaunching = + forceRestart || !self.runningApplication || + !LaunchArgumentsAreEqual(arguments, self.currentLaunchArgs); + + if (!appNeedsLaunching) { + [self.runningApplication activate]; + return; + } + + XCUIApplication* application = [[XCUIApplication alloc] init]; + application.launchArguments = arguments; + + [application launch]; + self.runningApplication = application; + self.currentLaunchArgs = arguments; +#endif +} +@end
diff --git a/ios/testing/earl_grey/base_earl_grey_test_case.mm b/ios/testing/earl_grey/base_earl_grey_test_case.mm index fe496a9..cb4f8a3 100644 --- a/ios/testing/earl_grey/base_earl_grey_test_case.mm +++ b/ios/testing/earl_grey/base_earl_grey_test_case.mm
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> #import <objc/runtime.h> +#import "ios/testing/earl_grey/app_launch_manager.h" #import "ios/testing/earl_grey/coverage_utils.h" #import "ios/testing/earl_grey/earl_grey_test.h" @@ -41,11 +42,8 @@ } - (void)launchAppForTestMethod { - static dispatch_once_t launchAppToken; - dispatch_once(&launchAppToken, ^{ - XCUIApplication* application = [[XCUIApplication alloc] init]; - [application launch]; - }); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithArgs:nil + forceRestart:false]; } // Prevents tests inheriting from this class from putting logic in +setUp.
diff --git a/ios/web/find_in_page/BUILD.gn b/ios/web/find_in_page/BUILD.gn index 51fc333..41665c5 100644 --- a/ios/web/find_in_page/BUILD.gn +++ b/ios/web/find_in_page/BUILD.gn
@@ -18,6 +18,8 @@ "find_in_page_manager_delegate_bridge.mm", "find_in_page_manager_impl.h", "find_in_page_manager_impl.mm", + "find_in_page_request.h", + "find_in_page_request.mm", ] configs += [ "//build/config/compiler:enable_arc" ] @@ -40,6 +42,7 @@ sources = [ "find_in_page_manager_delegate_bridge_unittest.mm", "find_in_page_manger_impl_unittest.mm", + "find_in_page_request_unittest.mm", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.h b/ios/web/find_in_page/find_in_page_manager_impl.h index c80d9c6..ac5e357 100644 --- a/ios/web/find_in_page/find_in_page_manager_impl.h +++ b/ios/web/find_in_page/find_in_page_manager_impl.h
@@ -5,11 +5,10 @@ #ifndef IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_ #define IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_MANAGER_IMPL_H_ -#include <list> -#include <map> #include <string> #include "base/memory/weak_ptr.h" +#import "ios/web/find_in_page/find_in_page_request.h" #import "ios/web/public/find_in_page/find_in_page_manager.h" #include "ios/web/public/web_state/web_state_observer.h" @@ -37,92 +36,6 @@ private: friend class web::WebStateUserData<FindInPageManagerImpl>; - // Keeps track of the state of an ongoing Find() request. - struct FindRequest { - FindRequest(); - ~FindRequest(); - // Clears properties and sets new |query| and |pending_frame_call_count|. - void Reset(NSString* query, int pending_frame_call_count); - int GetTotalMatchCount() const; - int GetRequestId() const; - NSString* GetRequestQuery() const; - // Returns the index of the currently selected match for all matches on the - // page. If no match is selected, then returns -1. - int GetCurrentSelectedMatchPageIndex(); - // Sets |index| as the currently selected index relative to the selected - // frame. - void SetCurrentSelectedMatchFrameIndex(int index); - // Returns the index of the currently selected match relative to the matches - // within its frame. If no match is selected, then returns -1. - int GetCurrentSelectedMatchFrameIndex() const; - // Returns the number of matches in |selected_frame_id|. If no match is - // currently selected, then returns -1; - int GetMatchCountForSelectedFrame(); - // Returns the number of matches in |frame_id|. If |frame_id| is invalid, - // then returns -1. - int GetMatchCountForFrame(const std::string& frame_id); - // Sets |match_count| for |selected_frame_id|. - void SetMatchCountForSelectedFrame(int match_count); - // Sets |match_count| for |frame_id|. - void SetMatchCountForFrame(int match_count, const std::string& frame_id); - // Returns the id of the WebFrame containing the currently selected match. - // Returns empty string if no currently selected match. - std::string GetSelectedFrameId(); - // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to - // the first match on the page. No-op if no known matches exist. Returns - // true if selected a match, false otherwise. - bool GoToFirstMatch(); - // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to - // the next match on the page. No-op if no known matches exist. Returns true - // if selected a match, false otherwise. - bool GoToNextMatch(); - // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to - // the previous match on the page. No-op if no known matches exist. Returns - // true if selected a match, false otherwise. - bool GoToPreviousMatch(); - // Removes frame with Id |frame_id| from |frame_order| and - // |frame_match_count|. Resets |selected_frame_id| and - // |selected_match_index_in_selected_frame| if the frame with |frame_id| - // contains the currently selected match. - void RemoveFrame(const std::string& frame_id); - // Adds new frame to |frame_order_| and |frame_match_count_|. - void AddFrame(WebFrame* web_frame); - // After each frame's Find request has finished, call this method to - // decrement |pending_frame_counts| to indicate to the receiver of the - // request completion. - void DidReceiveFindResponseFromOneFrame(); - // Returns true if there are no more pending Find requests, false - // otherwise. - bool AreAllFindResponsesReturned(); - // Unique identifier for each find used to check that it is the most recent - // find. This ensures that an old find doesn't decrement - // |pending_frame_calls_count| after it has been reset by the new find. - int unique_id = 0; - // Query string of find request. NSString type to ensure query passed to - // delegate methods is the same type as what is passed into Find(). - NSString* query = nil; - // Counter to keep track of pending frame JavaScript calls. - int pending_frame_call_count = 0; - // Holds number of matches found for each frame keyed by frame_id. - std::map<std::string, int> frame_match_count; - // List of frame_ids used for sorting matches. - std::list<std::string> frame_order; - // Id of frame which has the currently selected match. Set to - // frame_order.end() if there is no currently selected match. All matches - // from the last find will be highlighted. However, the match at - // |selected_match_index_in_selected_frame| will be highlighted in a - // visually unique manner. This match is referred to as the "selected match" - // and can be changed with the FindInPageNext and FindInPagePrevious - // commands. - std::list<std::string>::iterator selected_frame_id = frame_order.end(); - // Index of the currently selected match or -1 if there is none. - int selected_match_index_in_selected_frame = -1; - - private: - // Returns true if |frame_id| contains the currently selected match, false - // otherwise. - bool IsSelectedFrame(const std::string& frame_id); - }; // Executes find logic for |FindInPageSearch| option. void StartSearch(NSString* query); @@ -156,7 +69,7 @@ void WebStateDestroyed(WebState* web_state) override; // Holds the state of the most recent find in page request. - FindRequest last_find_request_; + FindInPageRequest last_find_request_; FindInPageManagerDelegate* delegate_ = nullptr; web::WebState* web_state_ = nullptr; base::WeakPtrFactory<FindInPageManagerImpl> weak_factory_;
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.mm b/ios/web/find_in_page/find_in_page_manager_impl.mm index b402152..5a89a7bb 100644 --- a/ios/web/find_in_page/find_in_page_manager_impl.mm +++ b/ios/web/find_in_page/find_in_page_manager_impl.mm
@@ -63,211 +63,6 @@ delegate_ = delegate; } -FindInPageManagerImpl::FindRequest::FindRequest() {} - -FindInPageManagerImpl::FindRequest::~FindRequest() {} - -void FindInPageManagerImpl::FindRequest::Reset( - NSString* new_query, - int new_pending_frame_call_count) { - unique_id++; - selected_frame_id = frame_order.end(); - selected_match_index_in_selected_frame = -1; - query = [new_query copy]; - pending_frame_call_count = new_pending_frame_call_count; - for (auto& pair : frame_match_count) { - pair.second = 0; - } -} - -int FindInPageManagerImpl::FindRequest::GetTotalMatchCount() const { - int matches = 0; - for (auto pair : frame_match_count) { - matches += pair.second; - } - return matches; -} - -int FindInPageManagerImpl::FindRequest::GetRequestId() const { - return unique_id; -} - -NSString* FindInPageManagerImpl::FindRequest::GetRequestQuery() const { - return query; -} - -int FindInPageManagerImpl::FindRequest::GetCurrentSelectedMatchPageIndex() { - if (selected_match_index_in_selected_frame == -1) { - return -1; - } - // Count all matches in frames that come before frame with id - // |selected_frame_id|. - int total_match_index = selected_match_index_in_selected_frame; - for (auto it = frame_order.begin(); it != selected_frame_id; ++it) { - total_match_index += frame_match_count[*it]; - } - return total_match_index; -} - -void FindInPageManagerImpl::FindRequest::SetCurrentSelectedMatchFrameIndex( - int index) { - selected_match_index_in_selected_frame = index; -} - -int FindInPageManagerImpl::FindRequest::GetCurrentSelectedMatchFrameIndex() - const { - return selected_match_index_in_selected_frame; -} - -void FindInPageManagerImpl::FindRequest::DidReceiveFindResponseFromOneFrame() { - pending_frame_call_count--; -} - -bool FindInPageManagerImpl::FindRequest::AreAllFindResponsesReturned() { - return pending_frame_call_count == 0; -} - -int FindInPageManagerImpl::FindRequest::GetMatchCountForSelectedFrame() { - if (selected_frame_id == frame_order.end()) { - return -1; - } - return frame_match_count[*selected_frame_id]; -} - -int FindInPageManagerImpl::FindRequest::GetMatchCountForFrame( - const std::string& frame_id) { - if (frame_match_count.find(frame_id) == frame_match_count.end()) { - return -1; - } - return frame_match_count[frame_id]; -} - -bool FindInPageManagerImpl::FindRequest::GoToFirstMatch() { - for (auto frame_id = frame_order.begin(); frame_id != frame_order.end(); - ++frame_id) { - if (frame_match_count[*frame_id] > 0) { - selected_frame_id = frame_id; - selected_match_index_in_selected_frame = 0; - return true; - } - } - return false; -} - -bool FindInPageManagerImpl::FindRequest::GoToNextMatch() { - if (GetTotalMatchCount() == 0) { - return false; - } - // No currently selected match, but there are matches. Move iterator to - // beginning. This can happen if a frame containing the currently selected - // match is removed from the page. - if (selected_frame_id == frame_order.end()) { - selected_frame_id = frame_order.begin(); - } - - bool next_match_is_in_selected_frame = - selected_match_index_in_selected_frame + 1 < - frame_match_count[*selected_frame_id]; - if (next_match_is_in_selected_frame) { - selected_match_index_in_selected_frame++; - } else { - // Since the function returns early if there are no matches, an infinite - // loop should not be a risk. - do { - if (selected_frame_id == --frame_order.end()) { - selected_frame_id = frame_order.begin(); - } else { - selected_frame_id++; - } - } while (frame_match_count[*selected_frame_id] == 0); - // Should have found new frame. - selected_match_index_in_selected_frame = 0; - } - return true; -} - -bool FindInPageManagerImpl::FindRequest::GoToPreviousMatch() { - if (GetTotalMatchCount() == 0) { - return false; - } - // No currently selected match, but there are matches. Move iterator to - // beginning. This can happen if a frame containing the currently selected - // matchs is removed from the page. - if (selected_frame_id == frame_order.end()) { - selected_frame_id = frame_order.begin(); - } - - bool previous_match_is_in_selected_frame = - selected_match_index_in_selected_frame - 1 >= 0; - if (previous_match_is_in_selected_frame) { - selected_match_index_in_selected_frame--; - } else { - // Since the function returns early if there are no matches, an infinite - // loop should not be a risk. - do { - if (selected_frame_id == frame_order.begin()) { - selected_frame_id = --frame_order.end(); - } else { - selected_frame_id--; - } - } while (frame_match_count[*selected_frame_id] == 0); - // Should have found new frame. - selected_match_index_in_selected_frame = - frame_match_count[*selected_frame_id] - 1; - } - return true; -} - -void FindInPageManagerImpl::FindRequest::RemoveFrame( - const std::string& frame_id) { - if (IsSelectedFrame(frame_id)) { - // If currently selecting match in frame that will become unavailable, - // there will no longer be a selected match. Reset to unselected match - // state. - selected_frame_id = frame_order.end(); - selected_match_index_in_selected_frame = -1; - } - frame_order.remove(frame_id); - frame_match_count.erase(frame_id); -} - -void FindInPageManagerImpl::FindRequest::AddFrame(WebFrame* web_frame) { - frame_match_count[web_frame->GetFrameId()] = 0; - if (web_frame->IsMainFrame()) { - // Main frame matches should show up first. - frame_order.push_front(web_frame->GetFrameId()); - } else { - // The order of iframes is not important. - frame_order.push_back(web_frame->GetFrameId()); - } -} - -void FindInPageManagerImpl::FindRequest::SetMatchCountForSelectedFrame( - int match_count) { - frame_match_count[*selected_frame_id] = match_count; -} - -void FindInPageManagerImpl::FindRequest::SetMatchCountForFrame( - int match_count, - const std::string& frame_id) { - frame_match_count[frame_id] = match_count; -} - -std::string FindInPageManagerImpl::FindRequest::GetSelectedFrameId() { - if (selected_frame_id == frame_order.end()) { - return std::string(); - } - return *selected_frame_id; -} - -bool FindInPageManagerImpl::FindRequest::IsSelectedFrame( - const std::string& frame_id) { - if (selected_frame_id == frame_order.end()) { - return false; - } - return *selected_frame_id == frame_id; -} - void FindInPageManagerImpl::WebFrameDidBecomeAvailable(WebState* web_state, WebFrame* web_frame) { const std::string frame_id = web_frame->GetFrameId();
diff --git a/ios/web/find_in_page/find_in_page_request.h b/ios/web/find_in_page/find_in_page_request.h new file mode 100644 index 0000000..4a15183 --- /dev/null +++ b/ios/web/find_in_page/find_in_page_request.h
@@ -0,0 +1,117 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_REQUEST_H_ +#define IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_REQUEST_H_ + +#include <list> +#include <map> +#include <string> + +#import <Foundation/Foundation.h> + +@class NSString; + +namespace web { + +class WebFrame; + +// Keeps track of the state of a FindInPageManager::Find() request. +class FindInPageRequest { + public: + FindInPageRequest(); + ~FindInPageRequest(); + // Clears properties and sets new |query| and |pending_frame_call_count|. + void Reset(NSString* query, int pending_frame_call_count); + int GetTotalMatchCount() const; + int GetRequestId() const; + NSString* GetRequestQuery() const; + + // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to + // the first match on the page. No-op if no known matches exist. Returns + // true if selected a match, false otherwise. + bool GoToFirstMatch(); + // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to + // the next match on the page. No-op if no known matches exist. Returns true + // if selected a match, false otherwise. + bool GoToNextMatch(); + // Sets |selected_frame_id| and |selected_match_index_in_selected_frame| to + // the previous match on the page. No-op if no known matches exist. Returns + // true if selected a match, false otherwise. + bool GoToPreviousMatch(); + + // Returns the number of matches in |selected_frame_id|. If no match is + // currently selected, then returns -1; + int GetMatchCountForSelectedFrame(); + // Sets |match_count| for |selected_frame_id|, if one exists. + void SetMatchCountForSelectedFrame(int match_count); + + // Returns the index of the currently selected match for all matches on the + // page. If no match is selected, then returns -1. + int GetCurrentSelectedMatchPageIndex(); + // Returns the id of the WebFrame containing the currently selected match. + // Returns empty string if no currently selected match. + std::string GetSelectedFrameId(); + + // Returns the index of the currently selected match relative to the matches + // within its frame. If no match is selected, then returns -1. + int GetCurrentSelectedMatchFrameIndex() const; + // Sets |index| as the currently selected index relative to the selected + // frame. + void SetCurrentSelectedMatchFrameIndex(int index); + + // Returns the number of matches in |frame_id|. If |frame_id| is invalid, + // then returns -1. + int GetMatchCountForFrame(const std::string& frame_id); + // Sets |match_count| for |frame_id|. + void SetMatchCountForFrame(int match_count, const std::string& frame_id); + + // Removes frame with Id |frame_id| from |frame_order| and + // |frame_match_count|. Resets |selected_frame_id| and + // |selected_match_index_in_selected_frame| if the frame with |frame_id| + // contains the currently selected match. + void RemoveFrame(const std::string& frame_id); + // Adds new frame to |frame_order_| and |frame_match_count_|. + void AddFrame(WebFrame* web_frame); + + // After each frame's Find request has finished, call this method to + // decrement |pending_frame_counts| to indicate to the receiver of the + // request completion. + void DidReceiveFindResponseFromOneFrame(); + // Returns true if there are no more pending Find requests, false + // otherwise. + bool AreAllFindResponsesReturned(); + + private: + // Unique identifier for each find used to check that it is the most recent + // find. This ensures that an old find doesn't decrement + // |pending_frame_calls_count| after it has been reset by the new find. + int unique_id_ = 0; + // Query string of find request. NSString type to ensure query passed to + // delegate methods is the same type as what is passed into Find(). + NSString* query_ = nil; + // Counter to keep track of pending frame JavaScript calls. + int pending_frame_call_count_ = 0; + // Holds number of matches found for each frame keyed by frame_id. + std::map<std::string, int> frame_match_count_; + // List of frame_ids used for sorting matches. + std::list<std::string> frame_order_; + // Id of frame which has the currently selected match. Set to + // frame_order.end() if there is no currently selected match. All matches + // from the last find will be highlighted. However, the match at + // |selected_match_index_in_selected_frame| will be highlighted in a + // visually unique manner. This match is referred to as the "selected match" + // and can be changed with the FindInPageNext and FindInPagePrevious + // commands. + std::list<std::string>::iterator selected_frame_id_ = frame_order_.end(); + // Index of the currently selected match or -1 if there is none. + int selected_match_index_in_selected_frame_ = -1; + // Returns true if |frame_id| contains the currently selected match, false + // otherwise. + bool IsSelectedFrame(const std::string& frame_id); +}; + +} // namespace web + +#endif // IOS_WEB_FIND_IN_PAGE_FIND_IN_PAGE_REQUEST_H_
diff --git a/ios/web/find_in_page/find_in_page_request.mm b/ios/web/find_in_page/find_in_page_request.mm new file mode 100644 index 0000000..83493fd --- /dev/null +++ b/ios/web/find_in_page/find_in_page_request.mm
@@ -0,0 +1,216 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/find_in_page/find_in_page_request.h" + +#import <Foundation/Foundation.h> + +#import "ios/web/public/js_messaging/web_frame.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace web { + +FindInPageRequest::FindInPageRequest() {} + +FindInPageRequest::~FindInPageRequest() {} + +void FindInPageRequest::Reset(NSString* new_query_, + int new_pending_frame_call_count) { + unique_id_++; + selected_frame_id_ = frame_order_.end(); + selected_match_index_in_selected_frame_ = -1; + query_ = [new_query_ copy]; + pending_frame_call_count_ = new_pending_frame_call_count; + for (auto& pair : frame_match_count_) { + pair.second = 0; + } +} + +int FindInPageRequest::GetTotalMatchCount() const { + int matches = 0; + for (auto pair : frame_match_count_) { + matches += pair.second; + } + return matches; +} + +int FindInPageRequest::GetRequestId() const { + return unique_id_; +} +NSString* FindInPageRequest::GetRequestQuery() const { + return query_; +} + +bool FindInPageRequest::GoToFirstMatch() { + for (auto frame_id = frame_order_.begin(); frame_id != frame_order_.end(); + ++frame_id) { + if (frame_match_count_[*frame_id] > 0) { + selected_frame_id_ = frame_id; + selected_match_index_in_selected_frame_ = 0; + return true; + } + } + return false; +} + +bool FindInPageRequest::GoToNextMatch() { + if (GetTotalMatchCount() == 0) { + return false; + } + // No currently selected match, but there are matches. Move iterator to + // beginning. This can happen if a frame containing the currently selected + // match is removed from the page. + if (selected_frame_id_ == frame_order_.end()) { + selected_frame_id_ = frame_order_.begin(); + } + + bool next_match_is_in_selected_frame = + selected_match_index_in_selected_frame_ + 1 < + frame_match_count_[*selected_frame_id_]; + if (next_match_is_in_selected_frame) { + selected_match_index_in_selected_frame_++; + } else { + // Since the function returns early if there are no matches, an infinite + // loop should not be a risk. + do { + if (selected_frame_id_ == --frame_order_.end()) { + selected_frame_id_ = frame_order_.begin(); + } else { + selected_frame_id_++; + } + } while (frame_match_count_[*selected_frame_id_] == 0); + // Should have found new frame. + selected_match_index_in_selected_frame_ = 0; + } + return true; +} + +bool FindInPageRequest::GoToPreviousMatch() { + if (GetTotalMatchCount() == 0) { + return false; + } + // No currently selected match, but there are matches. Move iterator to + // beginning. This can happen if a frame containing the currently selected + // matchs is removed from the page. + if (selected_frame_id_ == frame_order_.end()) { + selected_frame_id_ = frame_order_.begin(); + } + + bool previous_match_is_in_selected_frame = + selected_match_index_in_selected_frame_ - 1 >= 0; + if (previous_match_is_in_selected_frame) { + selected_match_index_in_selected_frame_--; + } else { + // Since the function returns early if there are no matches, an infinite + // loop should not be a risk. + do { + if (selected_frame_id_ == frame_order_.begin()) { + selected_frame_id_ = --frame_order_.end(); + } else { + selected_frame_id_--; + } + } while (frame_match_count_[*selected_frame_id_] == 0); + // Should have found new frame. + selected_match_index_in_selected_frame_ = + frame_match_count_[*selected_frame_id_] - 1; + } + return true; +} + +int FindInPageRequest::GetMatchCountForFrame(const std::string& frame_id) { + if (frame_match_count_.find(frame_id) == frame_match_count_.end()) { + return -1; + } + return frame_match_count_[frame_id]; +} + +void FindInPageRequest::SetMatchCountForFrame(int match_count, + const std::string& frame_id) { + frame_match_count_[frame_id] = match_count; +} + +int FindInPageRequest::GetMatchCountForSelectedFrame() { + if (selected_frame_id_ == frame_order_.end()) { + return -1; + } + return frame_match_count_[*selected_frame_id_]; +} + +void FindInPageRequest::SetMatchCountForSelectedFrame(int match_count) { + if (selected_frame_id_ == frame_order_.end()) { + return; + } + frame_match_count_[*selected_frame_id_] = match_count; +} + +int FindInPageRequest::GetCurrentSelectedMatchPageIndex() { + if (selected_match_index_in_selected_frame_ == -1) { + return -1; + } + // Count all matches in frames that come before frame with id + // |selected_frame_id|. + int total_match_index = selected_match_index_in_selected_frame_; + for (auto it = frame_order_.begin(); it != selected_frame_id_; ++it) { + total_match_index += frame_match_count_[*it]; + } + return total_match_index; +} + +std::string FindInPageRequest::GetSelectedFrameId() { + if (selected_frame_id_ == frame_order_.end()) { + return std::string(); + } + return *selected_frame_id_; +} + +int FindInPageRequest::GetCurrentSelectedMatchFrameIndex() const { + return selected_match_index_in_selected_frame_; +} + +void FindInPageRequest::SetCurrentSelectedMatchFrameIndex(int index) { + selected_match_index_in_selected_frame_ = index; +} + +void FindInPageRequest::RemoveFrame(const std::string& frame_id) { + if (IsSelectedFrame(frame_id)) { + // If currently selecting match in frame that will become unavailable, + // there will no longer be a selected match. Reset to unselected match + // state. + selected_frame_id_ = frame_order_.end(); + selected_match_index_in_selected_frame_ = -1; + } + frame_order_.remove(frame_id); + frame_match_count_.erase(frame_id); +} + +void FindInPageRequest::AddFrame(WebFrame* web_frame) { + frame_match_count_[web_frame->GetFrameId()] = 0; + if (web_frame->IsMainFrame()) { + // Main frame matches should show up first. + frame_order_.push_front(web_frame->GetFrameId()); + } else { + // The order of iframes is not important. + frame_order_.push_back(web_frame->GetFrameId()); + } +} + +void FindInPageRequest::DidReceiveFindResponseFromOneFrame() { + pending_frame_call_count_--; +} + +bool FindInPageRequest::AreAllFindResponsesReturned() { + return pending_frame_call_count_ == 0; +} + +bool FindInPageRequest::IsSelectedFrame(const std::string& frame_id) { + if (selected_frame_id_ == frame_order_.end()) { + return false; + } + return *selected_frame_id_ == frame_id; +} + +} // namespace web
diff --git a/ios/web/find_in_page/find_in_page_request_unittest.mm b/ios/web/find_in_page/find_in_page_request_unittest.mm new file mode 100644 index 0000000..87b0f31 --- /dev/null +++ b/ios/web/find_in_page/find_in_page_request_unittest.mm
@@ -0,0 +1,195 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/web/find_in_page/find_in_page_request.h" + +#include "ios/web/public/test/fakes/fake_web_frame.h" +#include "ios/web/public/test/web_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +const char kOneMatchFrameId[] = "frame_with_one_match"; +const char kTwoMatchesFrameId[] = "frame_with_two_matches"; +} // namespace + +namespace web { + +class FindInPageRequestTest : public WebTest { + protected: + // Returns a FakeWebFrame with id |frame_id|. + std::unique_ptr<FakeWebFrame> CreateWebFrame(const std::string& frame_id, + bool is_main_frame) { + return std::make_unique<FakeWebFrame>(frame_id, is_main_frame, + GURL::EmptyGURL()); + } + + FindInPageRequestTest() { + auto main_frame = CreateWebFrame(kOneMatchFrameId, + /*is_main_frame=*/true); + request_.AddFrame(main_frame.get()); + auto frame_with_two_matches = + CreateWebFrame(kTwoMatchesFrameId, /*is_main_frame=*/false); + request_.AddFrame(frame_with_two_matches.get()); + request_.Reset(@"foo", 2); + request_.SetMatchCountForFrame(1, kOneMatchFrameId); + request_.SetMatchCountForFrame(2, kTwoMatchesFrameId); + } + FindInPageRequest request_; +}; + +// Tests that FindInPageRequest properly clears its properties in respond to a +// Reset() call. +TEST_F(FindInPageRequestTest, Reset) { + EXPECT_EQ(3, request_.GetTotalMatchCount()); + + EXPECT_TRUE(request_.GoToFirstMatch()); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(1, request_.GetMatchCountForSelectedFrame()); + + int request_id = request_.GetRequestId(); + request_.Reset(@"foobar", 2); + + EXPECT_GE(request_.GetRequestId(), request_id); + EXPECT_EQ(-1, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(@"foobar", request_.GetRequestQuery()); + EXPECT_EQ(0, request_.GetTotalMatchCount()); + EXPECT_EQ(-1, request_.GetMatchCountForSelectedFrame()); +} + +// Tests that FindinPageRequest properly decrements |pending_frame_call_count_| +// properly. +TEST_F(FindInPageRequestTest, AllFindResponsesReturned) { + request_.DidReceiveFindResponseFromOneFrame(); + EXPECT_FALSE(request_.AreAllFindResponsesReturned()); + + request_.DidReceiveFindResponseFromOneFrame(); + EXPECT_TRUE(request_.AreAllFindResponsesReturned()); +} + +// Tests that FindInPageRequest GoToNextMatch() is able to traverse all matches +// in multiple frames. +TEST_F(FindInPageRequestTest, GoToNext) { + request_.GoToFirstMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(0, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToNextMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(1, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToNextMatch(); + + EXPECT_EQ(1, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(2, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToNextMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(0, request_.GetCurrentSelectedMatchPageIndex()); +} + +// Tests that FindInPageRequest GoToPreviousMatch() is able to traverse all +// matches in multiple frames. +TEST_F(FindInPageRequestTest, GoToPrevious) { + request_.GoToFirstMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(0, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToPreviousMatch(); + + EXPECT_EQ(1, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(2, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToPreviousMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(1, request_.GetCurrentSelectedMatchPageIndex()); + + request_.GoToPreviousMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(0, request_.GetCurrentSelectedMatchPageIndex()); +} + +// Tests that FindInPageRequest returns the correct relative match count within +// a frame and total match count when traversing matches in multiple frames. +TEST_F(FindInPageRequestTest, RelativeMatchCount) { + request_.GoToFirstMatch(); + + EXPECT_EQ(3, request_.GetTotalMatchCount()); + EXPECT_EQ(1, request_.GetMatchCountForSelectedFrame()); + + request_.GoToNextMatch(); + + EXPECT_EQ(3, request_.GetTotalMatchCount()); + EXPECT_EQ(2, request_.GetMatchCountForSelectedFrame()); +} + +// Tests that FindInPageRequest returns the correct relative match count within +// a frame and total match count when a frame is removed. Also tests that going +// to the next match after removing the currently selected frame produces the +// expected relative and total selected match index. +TEST_F(FindInPageRequestTest, RemoveFrame) { + request_.GoToFirstMatch(); + + EXPECT_EQ(3, request_.GetTotalMatchCount()); + EXPECT_EQ(1, request_.GetMatchCountForSelectedFrame()); + + request_.RemoveFrame(kOneMatchFrameId); + + EXPECT_EQ(2, request_.GetTotalMatchCount()); + + request_.GoToNextMatch(); + + EXPECT_EQ(0, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(0, request_.GetCurrentSelectedMatchPageIndex()); +} + +// Tests that FindInPageRequest returns the correct relative match count within +// a frame and total match count when the match count for the currently selected +// frame changes. +TEST_F(FindInPageRequestTest, SetMatchCountForSelectedFrame) { + request_.GoToFirstMatch(); + request_.SetMatchCountForSelectedFrame(5); + + EXPECT_EQ(7, request_.GetTotalMatchCount()); + EXPECT_EQ(5, request_.GetMatchCountForSelectedFrame()); +} + +// Tests that FindInPageRequest returns the currently selected match index +// relative to the frame and the total are correct when the total matches and +// the relative match index change. +TEST_F(FindInPageRequestTest, SetCurrentSelectedMatchIndex) { + request_.GoToFirstMatch(); + request_.SetMatchCountForSelectedFrame(5); + request_.SetCurrentSelectedMatchFrameIndex(1); + + EXPECT_EQ(1, request_.GetCurrentSelectedMatchFrameIndex()); + EXPECT_EQ(1, request_.GetCurrentSelectedMatchPageIndex()); +} + +// Tests that FindInPageRequest returns the correct match count within +// a frame and total match count when the match count for a not currently +// selected frame changes. +TEST_F(FindInPageRequestTest, SetMatchCountForFrame) { + request_.GoToFirstMatch(); + + EXPECT_EQ(3, request_.GetTotalMatchCount()); + EXPECT_EQ(1, request_.GetMatchCountForSelectedFrame()); + + request_.SetMatchCountForFrame(5, kTwoMatchesFrameId); + + EXPECT_EQ(6, request_.GetTotalMatchCount()); + EXPECT_EQ(1, request_.GetMatchCountForSelectedFrame()); +} + +} // namespace web
diff --git a/media/filters/frame_processor.cc b/media/filters/frame_processor.cc index 3d4e312..7de3796 100644 --- a/media/filters/frame_processor.cc +++ b/media/filters/frame_processor.cc
@@ -653,6 +653,8 @@ << "us"; // Mark the overlapping portion of the buffer for discard. + // TODO(wolenetz): Is this correct to ignore any pre-existing discard + // padding (e.g. WebM discard padding)? See https://crbug.com/969195. buffer->set_discard_padding(std::make_pair( append_window_start - buffer->timestamp(), base::TimeDelta())); @@ -678,6 +680,8 @@ : ""); // Mark the overlapping portion of the buffer for discard. + // TODO(wolenetz): Is this correct to ignore any pre-existing discard + // padding (e.g. WebM discard padding)? See https://crbug.com/969195. buffer->set_discard_padding( std::make_pair(buffer->discard_padding().first, frame_end_timestamp - append_window_end));
diff --git a/media/formats/webm/webm_cluster_parser.cc b/media/formats/webm/webm_cluster_parser.cc index 52cca8b..e2d7d95 100644 --- a/media/formats/webm/webm_cluster_parser.cc +++ b/media/formats/webm/webm_cluster_parser.cc
@@ -422,8 +422,11 @@ // Read in the big-endian integer. discard_padding_ = static_cast<int8_t>(data[0]); - for (int i = 1; i < size; ++i) - discard_padding_ = (discard_padding_ << 8) | data[i]; + for (int i = 1; i < size; ++i) { + // Multiplying instead of shifting, since the padding may be negative, + // and shifting a negative value is undefined. + discard_padding_ = (discard_padding_ * 256) | data[i]; + } return true; } @@ -611,6 +614,8 @@ buffer->set_duration(track->default_duration()); } + // TODO(wolenetz): Is this correct for negative |discard_padding|? See + // https://crbug.com/969195. if (discard_padding != 0) { buffer->set_discard_padding(std::make_pair( base::TimeDelta(),
diff --git a/media/formats/webm/webm_colour_parser.cc b/media/formats/webm/webm_colour_parser.cc index c8b65f0..a804931 100644 --- a/media/formats/webm/webm_colour_parser.cc +++ b/media/formats/webm/webm_colour_parser.cc
@@ -190,17 +190,25 @@ color_metadata.color_space = VideoColorSpace( primaries_, transfer_characteristics_, matrix_coefficients_, range_id); - if (max_content_light_level_ != -1) - color_metadata.hdr_metadata.max_content_light_level = - max_content_light_level_; + if (max_content_light_level_ != -1 || max_frame_average_light_level_ != -1 || + mastering_metadata_parsed_) { + color_metadata.hdr_metadata = HDRMetadata(); - if (max_frame_average_light_level_ != -1) - color_metadata.hdr_metadata.max_frame_average_light_level = - max_frame_average_light_level_; + if (max_content_light_level_ != -1) { + color_metadata.hdr_metadata->max_content_light_level = + max_content_light_level_; + } - if (mastering_metadata_parsed_) - color_metadata.hdr_metadata.mastering_metadata = - mastering_metadata_parser_.GetMasteringMetadata(); + if (max_frame_average_light_level_ != -1) { + color_metadata.hdr_metadata->max_frame_average_light_level = + max_frame_average_light_level_; + } + + if (mastering_metadata_parsed_) { + color_metadata.hdr_metadata->mastering_metadata = + mastering_metadata_parser_.GetMasteringMetadata(); + } + } return color_metadata; }
diff --git a/media/formats/webm/webm_colour_parser.h b/media/formats/webm/webm_colour_parser.h index 636bdc9..af05479 100644 --- a/media/formats/webm/webm_colour_parser.h +++ b/media/formats/webm/webm_colour_parser.h
@@ -6,6 +6,7 @@ #define MEDIA_FORMATS_WEBM_WEBM_COLOUR_PARSER_H_ #include "base/macros.h" +#include "base/optional.h" #include "media/base/hdr_metadata.h" #include "media/base/video_color_space.h" #include "media/formats/webm/webm_parser.h" @@ -25,7 +26,7 @@ VideoColorSpace color_space; - HDRMetadata hdr_metadata; + base::Optional<HDRMetadata> hdr_metadata; WebMColorMetadata(); WebMColorMetadata(const WebMColorMetadata& rhs);
diff --git a/media/formats/webm/webm_video_client.cc b/media/formats/webm/webm_video_client.cc index d2e5b8c8..9a986ba 100644 --- a/media/formats/webm/webm_video_client.cc +++ b/media/formats/webm/webm_video_client.cc
@@ -13,14 +13,15 @@ namespace { // Tries to parse |data| to extract the VP9 Profile ID, or returns Profile 0. -media::VideoCodecProfile GetVP9CodecProfile(const std::vector<uint8_t>& data) { +media::VideoCodecProfile GetVP9CodecProfile(const std::vector<uint8_t>& data, + bool is_probably_10bit) { // VP9 CodecPrivate (http://wiki.webmproject.org/vp9-codecprivate) might have // Profile information in the first field, if present. constexpr uint8_t kVP9ProfileFieldId = 0x01; constexpr uint8_t kVP9ProfileFieldLength = 1; if (data.size() < 3 || data[0] != kVP9ProfileFieldId || data[1] != kVP9ProfileFieldLength || data[2] > 3) { - return VP9PROFILE_PROFILE0; + return is_probably_10bit ? VP9PROFILE_PROFILE2 : VP9PROFILE_PROFILE0; } return static_cast<VideoCodecProfile>( @@ -56,6 +57,16 @@ VideoDecoderConfig* config) { DCHECK(config); + bool is_8bit = true; + VideoColorSpace color_space = VideoColorSpace::REC709(); + if (colour_parsed_) { + WebMColorMetadata color_metadata = colour_parser_.GetWebMColorMetadata(); + color_space = color_metadata.color_space; + if (color_metadata.hdr_metadata.has_value()) + config->set_hdr_metadata(*color_metadata.hdr_metadata); + is_8bit = color_metadata.BitsPerChannel <= 8; + } + VideoCodec video_codec = kUnknownVideoCodec; VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; if (codec_id == "V_VP8") { @@ -63,7 +74,9 @@ profile = VP8PROFILE_ANY; } else if (codec_id == "V_VP9") { video_codec = kCodecVP9; - profile = GetVP9CodecProfile(codec_private); + profile = GetVP9CodecProfile( + codec_private, color_space.ToGfxColorSpace().IsHDR() || + config->hdr_metadata().has_value() || !is_8bit); #if BUILDFLAG(ENABLE_AV1_DECODER) } else if (codec_id == "V_AV1") { // TODO(dalecurtis): AV1 profiles in WebM are not finalized, this needs @@ -121,12 +134,6 @@ } gfx::Size natural_size = gfx::Size(display_width_, display_height_); - VideoColorSpace color_space = VideoColorSpace::REC709(); - if (colour_parsed_) { - WebMColorMetadata color_metadata = colour_parser_.GetWebMColorMetadata(); - color_space = color_metadata.color_space; - config->set_hdr_metadata(color_metadata.hdr_metadata); - } config->Initialize(video_codec, profile, format, color_space, kNoTransformation, coded_size, visible_rect, natural_size, codec_private, encryption_scheme);
diff --git a/media/formats/webm/webm_video_client_unittest.cc b/media/formats/webm/webm_video_client_unittest.cc index d9f2dd7..b3ebf0b 100644 --- a/media/formats/webm/webm_video_client_unittest.cc +++ b/media/formats/webm/webm_video_client_unittest.cc
@@ -41,12 +41,93 @@ webm_video_client_.OnUInt(kWebMIdPixelHeight, kCodedSize.height()); } + WebMParserClient* OnListStart(int id) { + return webm_video_client_.OnListStart(id); + } + + void OnListEnd(int id) { webm_video_client_.OnListEnd(id); } + testing::StrictMock<MockMediaLog> media_log_; WebMVideoClient webm_video_client_; DISALLOW_COPY_AND_ASSIGN(WebMVideoClientTest); }; +TEST_P(WebMVideoClientTest, AutodetectVp9Profile2NoDetection) { + const bool has_valid_codec_private = GetParam().codec_private.size() > 3; + + auto* parser = OnListStart(kWebMIdColour); + // Set 8bit and SDR fields. + parser->OnUInt(kWebMIdBitsPerChannel, 8); + parser->OnUInt(kWebMIdTransferCharacteristics, + static_cast<int64_t>(VideoColorSpace::TransferID::BT709)); + OnListEnd(kWebMIdColour); + + VideoDecoderConfig config; + EXPECT_TRUE(webm_video_client_.InitializeConfig( + "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); + + if (!has_valid_codec_private) + EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE0); + else + EXPECT_EQ(config.profile(), GetParam().profile); +} + +TEST_P(WebMVideoClientTest, AutodetectVp9Profile2BitsPerChannel) { + const bool has_valid_codec_private = GetParam().codec_private.size() > 3; + + auto* parser = OnListStart(kWebMIdColour); + parser->OnUInt(kWebMIdBitsPerChannel, 10); + OnListEnd(kWebMIdColour); + + VideoDecoderConfig config; + EXPECT_TRUE(webm_video_client_.InitializeConfig( + "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); + + if (!has_valid_codec_private) + EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); + else + EXPECT_EQ(config.profile(), GetParam().profile); +} + +TEST_P(WebMVideoClientTest, AutodetectVp9Profile2HDRMetaData) { + const bool has_valid_codec_private = GetParam().codec_private.size() > 3; + + auto* color_parser = OnListStart(kWebMIdColour); + auto* metadata_parser = color_parser->OnListStart(kWebMIdMasteringMetadata); + metadata_parser->OnFloat(kWebMIdPrimaryRChromaticityX, 1.0); + color_parser->OnListEnd(kWebMIdMasteringMetadata); + OnListEnd(kWebMIdColour); + + VideoDecoderConfig config; + EXPECT_TRUE(webm_video_client_.InitializeConfig( + "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); + + if (!has_valid_codec_private) + EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); + else + EXPECT_EQ(config.profile(), GetParam().profile); +} + +TEST_P(WebMVideoClientTest, AutodetectVp9Profile2HDRColorSpace) { + const bool has_valid_codec_private = GetParam().codec_private.size() > 3; + + auto* parser = OnListStart(kWebMIdColour); + parser->OnUInt( + kWebMIdTransferCharacteristics, + static_cast<int64_t>(VideoColorSpace::TransferID::SMPTEST2084)); + OnListEnd(kWebMIdColour); + + VideoDecoderConfig config; + EXPECT_TRUE(webm_video_client_.InitializeConfig( + "V_VP9", GetParam().codec_private, EncryptionScheme(), &config)); + + if (!has_valid_codec_private) + EXPECT_EQ(config.profile(), VP9PROFILE_PROFILE2); + else + EXPECT_EQ(config.profile(), GetParam().profile); +} + TEST_P(WebMVideoClientTest, InitializeConfigVP9Profiles) { const std::string kCodecId = "V_VP9"; const VideoCodecProfile profile = GetParam().profile;
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index 4bd4b2f..0bb051f 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -241,12 +241,13 @@ // on the given |video_device|. bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, const GUID& decoder_guid, - ID3D11VideoDevice* video_device) { + ID3D11VideoDevice* video_device, + DXGI_FORMAT format) { D3D11_VIDEO_DECODER_DESC desc = { decoder_guid, // Guid resolution_to_test.width(), // SampleWidth resolution_to_test.height(), // SampleHeight - DXGI_FORMAT_NV12 // OutputFormat + format // OutputFormat }; // We've chosen the least expensive test for identifying if a given resolution @@ -273,7 +274,8 @@ const gfx::Size& default_max, ID3D11VideoDevice* video_device, const std::vector<GUID>& valid_guids, - const std::vector<gfx::Size>& resolutions_to_test) { + const std::vector<gfx::Size>& resolutions_to_test, + DXGI_FORMAT format = DXGI_FORMAT_NV12) { TRACE_EVENT0("gpu,startup", "GetMaxResolutionsForGUIDs"); ResolutionPair result(default_max, gfx::Size()); @@ -300,16 +302,20 @@ })); for (const auto& res : resolutions_to_test) { - if (!IsResolutionSupportedForDevice(res, decoder_guid, video_device)) + if (!IsResolutionSupportedForDevice(res, decoder_guid, video_device, + format)) { break; + } result.first = res; } // The max supported portrait resolution should be just be a w/h flip of the // max supported landscape resolution. gfx::Size flipped(result.first.height(), result.first.width()); - if (IsResolutionSupportedForDevice(flipped, decoder_guid, video_device)) + if (IsResolutionSupportedForDevice(flipped, decoder_guid, video_device, + format)) { result.second = flipped; + } return result; } @@ -1447,7 +1453,8 @@ {D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2}, {gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(7680, 4320), gfx::Size(8192, 4320), - gfx::Size(8192, 8192)}); + gfx::Size(8192, 8192)}, + DXGI_FORMAT_P010); } } }
diff --git a/net/base/network_change_notifier_fuchsia.cc b/net/base/network_change_notifier_fuchsia.cc index f3d4853..7670814 100644 --- a/net/base/network_change_notifier_fuchsia.cc +++ b/net/base/network_change_notifier_fuchsia.cc
@@ -36,6 +36,7 @@ // and routing table synchronously to populate the initial state. fuchsia::netstack::NetstackSyncPtr sync_netstack; sync_netstack.Bind(netstack.Unbind()); + DCHECK(sync_netstack); // Manually fetch the interfaces and routes. std::vector<fuchsia::netstack::NetInterface> interfaces; @@ -48,6 +49,7 @@ // Re-wrap Netstack back into an asynchronous pointer. netstack_.Bind(sync_netstack.Unbind()); + DCHECK(netstack_); netstack_.set_error_handler([](zx_status_t status) { // TODO(https://crbug.com/901092): Unit tests that use NetworkService are // crashing because NetworkService does not clean up properly, and the
diff --git a/remoting/host/disconnect_window_mac.h b/remoting/host/disconnect_window_mac.h index 7fd6115..f9be334 100644 --- a/remoting/host/disconnect_window_mac.h +++ b/remoting/host/disconnect_window_mac.h
@@ -16,13 +16,13 @@ @private base::Closure disconnect_callback_; base::string16 username_; - IBOutlet NSTextField* connectedToField_; - IBOutlet NSButton* disconnectButton_; } - (id)initWithCallback:(const base::Closure&)disconnect_callback - username:(const std::string&)username; -- (IBAction)stopSharing:(id)sender; + username:(const std::string&)username + window:(NSWindow*)window; +- (void)initializeWindow; +- (void)stopSharing:(id)sender; @end // A floating window with a custom border. The custom border and background
diff --git a/remoting/host/disconnect_window_mac.mm b/remoting/host/disconnect_window_mac.mm index 66c8a45..90358e1 100644 --- a/remoting/host/disconnect_window_mac.mm +++ b/remoting/host/disconnect_window_mac.mm
@@ -23,6 +23,8 @@ @interface DisconnectWindowController() - (BOOL)isRToL; - (void)Hide; +@property(nonatomic, retain) NSTextField* connectedToField; +@property(nonatomic, retain) NSButton* disconnectButton; @end const int kMaximumConnectedNameWidthInPixels = 600; @@ -69,9 +71,18 @@ client_session_control, protocol::OK); std::string client_jid = client_session_control->client_jid(); std::string username = client_jid.substr(0, client_jid.find('/')); + + NSRect frame = NSMakeRect(0, 0, 466, 40); + DisconnectWindow* window = + [[[DisconnectWindow alloc] initWithContentRect:frame + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO] autorelease]; window_controller_ = [[DisconnectWindowController alloc] initWithCallback:disconnect_callback - username:username]; + username:username + window:window]; + [window_controller_ initializeWindow]; [window_controller_ showWindow:nil]; } @@ -83,9 +94,13 @@ } // namespace remoting @implementation DisconnectWindowController +@synthesize connectedToField = connectedToField_; +@synthesize disconnectButton = disconnectButton_; + - (id)initWithCallback:(const base::Closure&)disconnect_callback - username:(const std::string&)username { - self = [super initWithWindowNibName:@"disconnect_window"]; + username:(const std::string&)username + window:(NSWindow*)window { + self = [super initWithWindow:(NSWindow*)window]; if (self) { disconnect_callback_ = disconnect_callback; username_ = base::UTF8ToUTF16(username); @@ -112,7 +127,27 @@ [self close]; } -- (void)windowDidLoad { +- (void)initializeWindow { + self.window.contentView = [[[DisconnectView alloc] + initWithFrame:self.window.contentView.frame] autorelease]; + + self.connectedToField = [[[NSTextField alloc] + initWithFrame:NSMakeRect(26, 13, 240, 14)] autorelease]; + self.connectedToField.drawsBackground = NO; + self.connectedToField.bezeled = NO; + self.connectedToField.editable = NO; + self.connectedToField.font = [NSFont systemFontOfSize:11]; + [self.window.contentView addSubview:self.connectedToField]; + + self.disconnectButton = [[[NSButton alloc] + initWithFrame:NSMakeRect(271, 9, 182, 22)] autorelease]; + self.disconnectButton.buttonType = NSButtonTypeMomentaryPushIn; + self.disconnectButton.bezelStyle = NSBezelStyleRegularSquare; + self.disconnectButton.font = [NSFont systemFontOfSize:11]; + self.disconnectButton.action = @selector(stopSharing:); + self.disconnectButton.target = self; + [self.window.contentView addSubview:self.disconnectButton]; + [connectedToField_ setStringValue:l10n_util::GetNSStringF(IDS_MESSAGE_SHARED, username_)]; [disconnectButton_ setTitle:l10n_util::GetNSString(IDS_STOP_SHARING_BUTTON)]; @@ -137,6 +172,8 @@ // Move the disconnect button appropriately. disconnectFrame.origin.x += newConnectedWidth - oldConnectedWidth; + disconnectFrame.origin.y = + (NSHeight(self.window.contentView.frame) - NSHeight(disconnectFrame)) / 2; [disconnectButton_ setFrame:disconnectFrame]; // Then resize the window appropriately
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index 6e17980..fc9e95f8 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc
@@ -41,8 +41,13 @@ base::TimeDelta::FromSeconds(30); constexpr base::TimeDelta kResendDelayOnHostNotFound = base::TimeDelta::FromSeconds(10); +constexpr base::TimeDelta kResendDelayOnUnauthenticated = + base::TimeDelta::FromSeconds(10); -const int kMaxResendOnHostNotFoundCount = 12; // 2 minutes (12 x 10 seconds). +constexpr int kMaxResendOnHostNotFoundCount = + 12; // 2 minutes (12 x 10 seconds). +constexpr int kMaxResendOnUnauthenticatedCount = + 6; // 1 minute (10 x 6 seconds). const net::BackoffEntry::Policy kBackoffPolicy = { // Number of initial errors (in sequence) to ignore before applying @@ -105,17 +110,14 @@ void HeartbeatSender::HeartbeatClient::Heartbeat( const apis::v1::HeartbeatRequest& request, HeartbeatResponseCallback callback) { - HOST_LOG << "Sending outgoing heartbeat:\n" - << "signature: " << request.signature() << "\n" - << "host_id: " << request.host_id() << "\n" - << "jabber_id: " << request.jabber_id() << "\n" - << "tachyon_id: " << request.tachyon_id() << "\n" - << "sequence_id: " << request.sequence_id() << "\n" - << "host_version: " << request.host_version() << "\n" - << "host_offline_reason: " << request.host_offline_reason() << "\n" - << "host_os_name: " << request.host_os_name() << "\n" - << "host_os_version: " << request.host_os_version() << "\n" - << "========================================================="; + std::string host_offline_reason_or_empty_log = + request.has_host_offline_reason() + ? (", host_offline_reason: " + request.host_offline_reason()) + : ""; + HOST_LOG << "Sending outgoing heartbeat." + << " jabber_id: " << request.jabber_id() + << ", tachyon_id: " << request.tachyon_id() + << host_offline_reason_or_empty_log; auto client_context = std::make_unique<grpc::ClientContext>(); auto async_request = CreateGrpcAsyncUnaryRequest( @@ -141,6 +143,7 @@ HeartbeatSender::HeartbeatSender( base::OnceClosure on_heartbeat_successful_callback, base::OnceClosure on_unknown_host_id_error, + base::OnceClosure on_auth_error, const std::string& host_id, MuxingSignalStrategy* signal_strategy, const scoped_refptr<const RsaKeyPair>& host_key_pair, @@ -149,11 +152,13 @@ : on_heartbeat_successful_callback_( std::move(on_heartbeat_successful_callback)), on_unknown_host_id_error_(std::move(on_unknown_host_id_error)), + on_auth_error_(std::move(on_auth_error)), host_id_(host_id), signal_strategy_(signal_strategy), host_key_pair_(host_key_pair), client_(std::make_unique<HeartbeatClient>(oauth_token_getter)), log_to_server_(log_to_server), + oauth_token_getter_(oauth_token_getter), backoff_(&kBackoffPolicy) { DCHECK(host_key_pair_.get()); DCHECK(log_to_server_); @@ -294,6 +299,16 @@ return; } + if (status.error_code() == grpc::StatusCode::UNAUTHENTICATED) { + oauth_token_getter_->InvalidateCache(); + if (backoff_.failure_count() > kMaxResendOnUnauthenticatedCount) { + if (on_auth_error_) { + std::move(on_auth_error_).Run(); + } + return; + } + } + // Calculate delay before sending the next message. base::TimeDelta delay; // See CoreErrorDomainTranslator.java for the mapping @@ -310,8 +325,9 @@ case grpc::StatusCode::NOT_FOUND: delay = kResendDelayOnHostNotFound; break; - // TODO(yuweih): Handle sequence ID mismatch case. This is not implemented - // in the server yet. + case grpc::StatusCode::UNAUTHENTICATED: + delay = kResendDelayOnUnauthenticated; + break; default: delay = backoff_.GetTimeUntilRelease(); LOG(ERROR) << "Heartbeat failed due to unexpected error: "
diff --git a/remoting/host/heartbeat_sender.h b/remoting/host/heartbeat_sender.h index fcacf5b5..fb1bfac 100644 --- a/remoting/host/heartbeat_sender.h +++ b/remoting/host/heartbeat_sender.h
@@ -70,8 +70,12 @@ // // |on_unknown_host_id_error| is invoked when the host ID is permanently not // recognized by the server. + // + // |on_auth_error| is invoked when the heartbeat sender permanently fails to + // authenticate the requests. HeartbeatSender(base::OnceClosure on_heartbeat_successful_callback, base::OnceClosure on_unknown_host_id_error, + base::OnceClosure on_auth_error, const std::string& host_id, MuxingSignalStrategy* signal_strategy, const scoped_refptr<const RsaKeyPair>& host_key_pair, @@ -120,11 +124,13 @@ base::OnceClosure on_heartbeat_successful_callback_; base::OnceClosure on_unknown_host_id_error_; + base::OnceClosure on_auth_error_; std::string host_id_; MuxingSignalStrategy* const signal_strategy_; scoped_refptr<const RsaKeyPair> host_key_pair_; std::unique_ptr<HeartbeatClient> client_; LogToServer* const log_to_server_; + OAuthTokenGetter* const oauth_token_getter_; base::OneShotTimer heartbeat_timer_;
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index ca06acd0..a2ece81 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -138,7 +138,8 @@ heartbeat_sender_ = std::make_unique<HeartbeatSender>( mock_heartbeat_successful_callback_.Get(), - mock_unknown_host_id_error_callback_.Get(), kHostId, + mock_unknown_host_id_error_callback_.Get(), + mock_unauthenticated_error_callback_.Get(), kHostId, muxing_signal_strategy_.get(), key_pair, &oauth_token_getter_, this); heartbeat_sender_->SetGrpcChannelForTest( test_server_.CreateInProcessChannel()); @@ -160,6 +161,7 @@ base::MockCallback<base::OnceClosure> mock_heartbeat_successful_callback_; base::MockCallback<base::OnceClosure> mock_unknown_host_id_error_callback_; + base::MockCallback<base::OnceClosure> mock_unauthenticated_error_callback_; std::vector<ServerLogEntry> received_log_entries_; @@ -462,4 +464,34 @@ ASSERT_EQ(0, GetBackoff().failure_count()); } +TEST_F(HeartbeatSenderTest, Unauthenticated) { + base::RunLoop run_loop; + + int heartbeat_count = 0; + EXPECT_CALL(*test_server_, Heartbeat(_, _, _)) + .WillRepeatedly([&](grpc::ServerContext*, + const apis::v1::HeartbeatRequest* request, + apis::v1::HeartbeatResponse* response) { + ValidateHeartbeat(*request, /* ftl */ true, /* xmpp */ true, + kExpectedSequenceIdUnset); + heartbeat_count++; + return grpc::Status(grpc::StatusCode::UNAUTHENTICATED, + "unauthenticated"); + }); + + EXPECT_CALL(mock_unauthenticated_error_callback_, Run()).WillOnce([&]() { + run_loop.Quit(); + }); + + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + ftl_signal_strategy_->Connect(); + xmpp_signal_strategy_->Connect(); + })); + run_loop.Run(); + + // Should retry heartbeating at least once. + ASSERT_LT(1, heartbeat_count); +} + } // namespace remoting
diff --git a/remoting/host/installer/mac/BUILD.gn b/remoting/host/installer/mac/BUILD.gn index 357b1f5..9949223 100644 --- a/remoting/host/installer/mac/BUILD.gn +++ b/remoting/host/installer/mac/BUILD.gn
@@ -137,7 +137,6 @@ deps = [ ":remoting_host_uninstaller_resources", - ":remoting_host_uninstaller_xibs", "//base", "//remoting/host:remoting_infoplist_strings", "//remoting/host/mac:constants", @@ -148,12 +147,6 @@ } } -mac_xib_bundle_data("remoting_host_uninstaller_xibs") { - sources = [ - "uninstaller/remoting_uninstaller.xib", - ] -} - bundle_data("remoting_host_uninstaller_resources") { sources = [ "uninstaller/remoting_uninstaller.icns",
diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist index 864a4ca..158bdf7 100644 --- a/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist +++ b/remoting/host/installer/mac/uninstaller/remoting_uninstaller-Info.plist
@@ -22,8 +22,6 @@ <string>${VERSION_FULL}</string> <key>LSMinimumSystemVersion</key> <string>${MACOSX_DEPLOYMENT_TARGET}</string> - <key>NSMainNibFile</key> - <string>remoting_uninstaller</string> <key>NSPrincipalClass</key> <string>NSApplication</string> </dict>
diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller.xib b/remoting/host/installer/mac/uninstaller/remoting_uninstaller.xib deleted file mode 100644 index 71e2b81..0000000 --- a/remoting/host/installer/mac/uninstaller/remoting_uninstaller.xib +++ /dev/null
@@ -1,169 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F1077" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> - <dependencies> - <deployment version="1060" identifier="macosx"/> - <development version="5100" identifier="xcode"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/> - </dependencies> - <objects> - <customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> - <connections> - <outlet property="delegate" destination="494" id="495"/> - </connections> - </customObject> - <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> - <customObject id="-3" userLabel="Application"/> - <menu title="AMainMenu" systemMenu="main" id="29"> - <items> - <menuItem title="Chrome Remote Desktop Host Uninstaller" id="56"> - <menu key="submenu" title="Chrome Remote Desktop Host Uninstaller" systemMenu="apple" id="57"> - <items> - <menuItem title="About Chrome Remote Desktop Uninstaller" id="58"> - <modifierMask key="keyEquivalentModifierMask"/> - <connections> - <action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="236"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Preferences…" keyEquivalent="," id="129"/> - <menuItem isSeparatorItem="YES" id="143"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Services" id="131"> - <menu key="submenu" title="Services" systemMenu="services" id="130"/> - </menuItem> - <menuItem isSeparatorItem="YES" id="144"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Hide Chrome Remote Desktop Uninstaller" keyEquivalent="h" id="134"> - <connections> - <action selector="hide:" target="-1" id="367"/> - </connections> - </menuItem> - <menuItem title="Hide Others" keyEquivalent="h" id="145"> - <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> - <connections> - <action selector="hideOtherApplications:" target="-1" id="368"/> - </connections> - </menuItem> - <menuItem title="Show All" id="150"> - <connections> - <action selector="unhideAllApplications:" target="-1" id="370"/> - </connections> - </menuItem> - <menuItem isSeparatorItem="YES" id="149"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Quit Chrome Remote Desktop Uninstaller" keyEquivalent="q" id="136"> - <connections> - <action selector="terminate:" target="-3" id="449"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="File" id="83"> - <menu key="submenu" title="File" id="81"> - <items> - <menuItem title="New" keyEquivalent="n" id="82"/> - <menuItem title="Open…" keyEquivalent="o" id="72"/> - <menuItem isSeparatorItem="YES" id="79"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Close" keyEquivalent="w" id="73"> - <connections> - <action selector="handleMenuClose:" target="494" id="544"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - <menuItem title="Edit" id="217"> - <menu key="submenu" title="Edit" id="205"> - <items> - <menuItem title="Undo" keyEquivalent="z" id="207"/> - <menuItem title="Redo" keyEquivalent="Z" id="215"> - <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/> - </menuItem> - <menuItem isSeparatorItem="YES" id="206"> - <modifierMask key="keyEquivalentModifierMask" command="YES"/> - </menuItem> - <menuItem title="Cut" keyEquivalent="x" id="199"/> - <menuItem title="Copy" keyEquivalent="c" id="197"/> - <menuItem title="Paste" keyEquivalent="v" id="203"/> - </items> - </menu> - </menuItem> - <menuItem title="Help" id="490"> - <modifierMask key="keyEquivalentModifierMask"/> - <menu key="submenu" title="Help" systemMenu="help" id="491"> - <items> - <menuItem title="Chrome Remote Desktop Uninstaller Help" keyEquivalent="?" id="492"> - <connections> - <action selector="showHelp:" target="-1" id="493"/> - </connections> - </menuItem> - </items> - </menu> - </menuItem> - </items> - </menu> - <window title="Chrome Remote Desktop Uninstaller" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="371"> - <windowStyleMask key="styleMask" titled="YES" closable="YES"/> - <rect key="contentRect" x="335" y="863" width="499" height="112"/> - <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1578"/> - <view key="contentView" id="372"> - <rect key="frame" x="0.0" y="0.0" width="499" height="112"/> - <autoresizingMask key="autoresizingMask"/> - <subviews> - <textField verticalHuggingPriority="750" id="533"> - <rect key="frame" x="103" y="75" width="379" height="17"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="This will completely remove Chrome Remote Desktop Host." id="534"> - <font key="font" metaFont="system"/> - <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> - </textFieldCell> - </textField> - <button verticalHuggingPriority="750" id="537"> - <rect key="frame" x="390" y="13" width="95" height="32"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <buttonCell key="cell" type="push" title="Uninstall" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="538"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> - </buttonCell> - <connections> - <action selector="uninstall:" target="494" id="541"/> - </connections> - </button> - <button verticalHuggingPriority="750" id="539"> - <rect key="frame" x="308" y="13" width="82" height="32"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> - <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="540"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="system"/> - <string key="keyEquivalent" base64-UTF8="YES"> -Gw -</string> - </buttonCell> - <connections> - <action selector="cancel:" target="494" id="542"/> - </connections> - </button> - <imageView id="548"> - <rect key="frame" x="8" y="24" width="76" height="68"/> - <autoresizingMask key="autoresizingMask"/> - <imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="NSApplicationIcon" id="549"/> - </imageView> - </subviews> - </view> - </window> - <customObject id="494" customClass="RemotingUninstallerAppDelegate"/> - <customObject id="420" customClass="NSFontManager"/> - </objects> - <resources> - <image name="NSApplicationIcon" width="128" height="128"/> - </resources> -</document>
diff --git a/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm b/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm index 7724eb5c..ec4b931 100644 --- a/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm +++ b/remoting/host/installer/mac/uninstaller/remoting_uninstaller_app.mm
@@ -11,22 +11,100 @@ #include "remoting/host/installer/mac/uninstaller/remoting_uninstaller.h" #include "ui/base/l10n/l10n_util_mac.h" +namespace { + +base::scoped_nsobject<NSMenu> BuildMainMenu() { + base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:@""]); + + NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:@"" + action:NULL + keyEquivalent:@""] autorelease]; + + // The title is not used, as the title will always be the name of the App. + item.submenu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + [item.submenu addItem:[[[NSMenuItem alloc] initWithTitle:@"Close" + action:@selector(terminate:) + keyEquivalent:@"w"] autorelease]]; + [item.submenu + addItem:[[[NSMenuItem alloc] + initWithTitle:@"Quit Chrome Remote Desktop Uninstaller" + action:@selector(terminate:) + keyEquivalent:@"q"] autorelease]]; + [main_menu addItem:item]; + + return main_menu; +} + +} // namespace + +@interface RemotingUninstallerAppDelegate () <NSApplicationDelegate> +@property(nonatomic, retain) NSWindow* window; +@end + @implementation RemotingUninstallerAppDelegate +@synthesize window = _window; - (void)dealloc { [super dealloc]; } - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { + base::scoped_nsobject<NSMenu> main_menu = BuildMainMenu(); + [[NSApplication sharedApplication] setMainMenu:main_menu]; + + NSRect frame = NSMakeRect(0, 0, 499, 112); + self.window = [[[NSWindow alloc] initWithContentRect:frame + styleMask:NSTitledWindowMask + backing:NSBackingStoreBuffered + defer:NO] autorelease]; + self.window.title = @"Chrome Remote Desktop Uninstaller"; + + NSTextField* title = [[[NSTextField alloc] + initWithFrame:NSMakeRect(103, 75, 379, 17)] autorelease]; + title.stringValue = + @"This will completely remove Chrome Remote Desktop Host."; + title.drawsBackground = NO; + title.bezeled = NO; + title.editable = NO; + title.font = [NSFont systemFontOfSize:13]; + [self.window.contentView addSubview:title]; + + NSImageView* icon = [[[NSImageView alloc] + initWithFrame:NSMakeRect(8, 24, 76, 68)] autorelease]; + icon.image = [[NSApplication sharedApplication] applicationIconImage]; + [self.window.contentView addSubview:icon]; + + NSButton* cancelButton = [[[NSButton alloc] + initWithFrame:NSMakeRect(308, 13, 82, 32)] autorelease]; + cancelButton.buttonType = NSButtonTypeMomentaryPushIn; + cancelButton.bezelStyle = NSRoundedBezelStyle; + cancelButton.title = @"Cancel"; + cancelButton.action = @selector(cancel:); + cancelButton.target = self; + [self.window.contentView addSubview:cancelButton]; + + NSButton* uninstallButton = [[[NSButton alloc] + initWithFrame:NSMakeRect(390, 13, 95, 32)] autorelease]; + uninstallButton.buttonType = NSButtonTypeMomentaryPushIn; + uninstallButton.bezelStyle = NSRoundedBezelStyle; + uninstallButton.title = @"Uninstall"; + uninstallButton.action = @selector(uninstall:); + uninstallButton.target = self; + [self.window.contentView addSubview:uninstallButton]; + + [self.window makeKeyAndOrderFront:NSApp]; + [self.window center]; } -- (void)showSuccess:(bool)success withMessage:(NSString*) message { +- (void)showSuccess:(bool)success withMessage:(NSString*)message { NSString* summary = success ? @"Uninstall succeeded" : @"Uninstall failed"; base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); [alert setMessageText:summary]; [alert setInformativeText:message]; [alert setAlertStyle:(success ? NSInformationalAlertStyle : NSCriticalAlertStyle)]; + // This line crashes the app because ui::ResourceBundle::GetSharedInstance() + // cannot find a shared instance. https://crbug.com/968257. [alert addButtonWithTitle:l10n_util::GetNSString(IDS_OK)]; [alert runModal]; } @@ -53,14 +131,13 @@ } else { [NSException raise:@"AuthorizationCopyRights Failure" format:@"Error during AuthorizationCopyRights status=%d", - static_cast<int>(status)]; + static_cast<int>(status)]; } if (message != nullptr) { NSLog(@"Uninstall %s: %@", success ? "succeeded" : "failed", message); [self showSuccess:success withMessage:message]; } - } - @catch (NSException* exception) { + } @catch (NSException* exception) { NSLog(@"Exception %@ %@", [exception name], [exception reason]); NSString* message = @"Error! Unable to uninstall Chrome Remote Desktop Host."; @@ -80,13 +157,12 @@ @end -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { // The no-ui option skips the UI confirmation dialogs. This is provided as // a convenience for our automated testing. // There will still be an elevation prompt unless the command is run as root. - if (argc == 2 && !strcmp(argv[1], "--no-ui")) { - @autoreleasepool { + @autoreleasepool { + if (argc == 2 && !strcmp(argv[1], "--no-ui")) { NSLog(@"Chrome Remote Desktop uninstall starting."); NSLog(@"--no-ui : Suppressing UI"); @@ -97,9 +173,16 @@ NSLog(@"Chrome Remote Desktop Host uninstall complete."); NSLog(@"Status = %d", static_cast<int>(status)); return status != errAuthorizationSuccess; + } else { + RemotingUninstallerAppDelegate* delegate = + [[[RemotingUninstallerAppDelegate alloc] init] autorelease]; + + [NSApplication sharedApplication]; + [NSApp setDelegate:delegate]; + [NSApp activateIgnoringOtherApps:YES]; + [NSApp run]; + + return EXIT_SUCCESS; } - } else { - return NSApplicationMain(argc, (const char**)argv); } } -
diff --git a/remoting/host/it2me/BUILD.gn b/remoting/host/it2me/BUILD.gn index 39dc4673..473ce933 100644 --- a/remoting/host/it2me/BUILD.gn +++ b/remoting/host/it2me/BUILD.gn
@@ -170,12 +170,6 @@ } } - mac_xib_bundle_data("remote_assistance_host_xibs") { - sources = [ - "//remoting/host/mac/disconnect_window.xib", - ] - } - if (icu_use_data_file) { bundle_data("remote_assistance_host_resources") { sources = [ @@ -238,7 +232,6 @@ } deps += [ ":remote_assistance_host_dialog_icon", - ":remote_assistance_host_xibs", "//remoting/host:remoting_infoplist_strings", "//remoting/resources:copy_locales", ]
diff --git a/remoting/host/mac/BUILD.gn b/remoting/host/mac/BUILD.gn index 780de15..ba7dfe8 100644 --- a/remoting/host/mac/BUILD.gn +++ b/remoting/host/mac/BUILD.gn
@@ -32,12 +32,6 @@ } } -mac_xib_bundle_data("remoting_host_xibs") { - sources = [ - "disconnect_window.xib", - ] -} - bundle_data("remoting_host_resources") { sources = [ "$root_gen_dir/remoting/CREDITS.txt", @@ -94,7 +88,6 @@ } deps += [ ":remoting_host_resources", - ":remoting_host_xibs", "//remoting/host:remoting_infoplist_strings", "//remoting/resources:copy_locales", ]
diff --git a/remoting/host/mac/disconnect_window.xib b/remoting/host/mac/disconnect_window.xib deleted file mode 100644 index 9791a5fe..0000000 --- a/remoting/host/mac/disconnect_window.xib +++ /dev/null
@@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F1077" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none"> - <dependencies> - <deployment version="1060" identifier="macosx"/> - <development version="5100" identifier="xcode"/> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/> - </dependencies> - <objects> - <customObject id="-2" userLabel="File's Owner" customClass="DisconnectWindowController"> - <connections> - <outlet property="connectedToField_" destination="23" id="25"/> - <outlet property="disconnectButton_" destination="13" id="26"/> - <outlet property="window" destination="3" id="17"/> - </connections> - </customObject> - <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> - <customObject id="-3" userLabel="Application"/> - <window title="Remoting" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" visibleAtLaunch="NO" animationBehavior="default" id="3" customClass="DisconnectWindow"> - <windowStyleMask key="styleMask" titled="YES" utility="YES"/> - <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> - <rect key="contentRect" x="247" y="517" width="466" height="40"/> - <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1578"/> - <view key="contentView" id="4" customClass="DisconnectView"> - <rect key="frame" x="0.0" y="0.0" width="466" height="40"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <button id="13"> - <rect key="frame" x="271" y="9" width="182" height="22"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> - <buttonCell key="cell" type="square" title="<disconnect>" bezelStyle="shadowlessSquare" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="14"> - <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> - <font key="font" metaFont="smallSystem"/> - </buttonCell> - <connections> - <action selector="stopSharing:" target="-2" id="18"/> - </connections> - </button> - <textField verticalHuggingPriority="750" id="23"> - <rect key="frame" x="26" y="13" width="240" height="14"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> - <textFieldCell key="cell" controlSize="small" truncatesLastVisibleLine="YES" enabled="NO" sendsActionOnEndEditing="YES" title="<connected-to>" id="24"> - <font key="font" metaFont="smallSystem"/> - <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> - <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> - </textFieldCell> - </textField> - </subviews> - </view> - <connections> - <outlet property="delegate" destination="-2" id="22"/> - </connections> - </window> - </objects> -</document>
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index acab392..59bdbd6 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc
@@ -1510,6 +1510,7 @@ base::Unretained(this)), base::BindOnce(&HostProcess::OnUnknownHostIdError, base::Unretained(this)), + base::BindOnce(&HostProcess::OnAuthFailed, base::Unretained(this)), host_id_, muxing_signal_strategy.get(), key_pair_, oauth_token_getter_.get(), log_to_server_.get()); ftl_host_change_notification_listener_ =
diff --git a/services/BUILD.gn b/services/BUILD.gn index 773980e..d3e9aaf 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -76,6 +76,11 @@ # standalone services must be added here. deps += [ "//services/video_capture:tests" ] } + + if (is_fuchsia) { + # Enable the test HTTP server for use by NetworkServiceTestWithService.* + use_test_server = true + } } if (!is_ios) {
diff --git a/services/network/http_cache_data_counter_unittest.cc b/services/network/http_cache_data_counter_unittest.cc index b82764e9..0f4a804 100644 --- a/services/network/http_cache_data_counter_unittest.cc +++ b/services/network/http_cache_data_counter_unittest.cc
@@ -215,7 +215,8 @@ // Return the sensible thing (0 bytes used) when there is no cache. TEST(HttpCacheDataCounterTestNoCache, BeSensible) { - base::test::ScopedTaskEnvironment scoped_task_environment; + base::test::ScopedTaskEnvironment scoped_task_environment( + base::test::ScopedTaskEnvironment::MainThreadType::IO); std::unique_ptr<NetworkService> network_service( NetworkService::CreateForTesting()); std::unique_ptr<NetworkContext> network_context;
diff --git a/services/network/public/cpp/network_quality_tracker_unittest.cc b/services/network/public/cpp/network_quality_tracker_unittest.cc index 9029ddf..e0e5eb74 100644 --- a/services/network/public/cpp/network_quality_tracker_unittest.cc +++ b/services/network/public/cpp/network_quality_tracker_unittest.cc
@@ -166,7 +166,9 @@ class NetworkQualityTrackerTest : public testing::Test { public: - NetworkQualityTrackerTest() { + NetworkQualityTrackerTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) { network::mojom::NetworkServicePtr network_service_ptr; network::mojom::NetworkServiceRequest network_service_request = mojo::MakeRequest(&network_service_ptr);
diff --git a/services/test/run_all_unittests.cc b/services/test/run_all_unittests.cc index 864c7183..12e1abc99 100644 --- a/services/test/run_all_unittests.cc +++ b/services/test/run_all_unittests.cc
@@ -49,7 +49,7 @@ #if defined(OS_ANDROID) ASSERT_TRUE(base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &path)); #else - ASSERT_TRUE(base::PathService::Get(base::DIR_MODULE, &path)); + ASSERT_TRUE(base::PathService::Get(base::DIR_ASSETS, &path)); #endif base::FilePath bluetooth_test_strings = path.Append(FILE_PATH_LITERAL("bluetooth_test_strings.pak"));
diff --git a/services/tracing/perfetto/consumer_host.cc b/services/tracing/perfetto/consumer_host.cc index a8b515f..974dbad 100644 --- a/services/tracing/perfetto/consumer_host.cc +++ b/services/tracing/perfetto/consumer_host.cc
@@ -24,10 +24,10 @@ #include "services/tracing/perfetto/perfetto_service.h" #include "services/tracing/perfetto/track_event_json_exporter.h" #include "services/tracing/public/cpp/trace_event_args_whitelist.h" -#include "third_party/perfetto/include/perfetto/tracing/core/observable_events.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_stats.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/observable_events.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_stats.h" #include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h" namespace tracing {
diff --git a/services/tracing/perfetto/consumer_host.h b/services/tracing/perfetto/consumer_host.h index afb26770..7cf3cb2 100644 --- a/services/tracing/perfetto/consumer_host.h +++ b/services/tracing/perfetto/consumer_host.h
@@ -16,8 +16,8 @@ #include "base/timer/timer.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/consumer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/consumer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace service_manager { struct BindSourceInfo;
diff --git a/services/tracing/perfetto/consumer_host_unittest.cc b/services/tracing/perfetto/consumer_host_unittest.cc index 2670a78d..f3cd37dd 100644 --- a/services/tracing/perfetto/consumer_host_unittest.cc +++ b/services/tracing/perfetto/consumer_host_unittest.cc
@@ -25,8 +25,8 @@ #include "services/tracing/perfetto/perfetto_service.h" #include "services/tracing/perfetto/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h" #include "third_party/perfetto/protos/perfetto/trace/trace.pb.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
diff --git a/services/tracing/perfetto/json_exporter_main.cc b/services/tracing/perfetto/json_exporter_main.cc index ff2ba4d..50057ff6 100644 --- a/services/tracing/perfetto/json_exporter_main.cc +++ b/services/tracing/perfetto/json_exporter_main.cc
@@ -10,7 +10,7 @@ #include "base/logging.h" #include "services/tracing/perfetto/json_trace_exporter.h" #include "services/tracing/perfetto/track_event_json_exporter.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/protos/perfetto/trace/trace.pbzero.h" // Tool to convert a given proto trace into json.
diff --git a/services/tracing/perfetto/json_trace_exporter.cc b/services/tracing/perfetto/json_trace_exporter.cc index cf6dc4c..0b9d58e 100644 --- a/services/tracing/perfetto/json_trace_exporter.cc +++ b/services/tracing/perfetto/json_trace_exporter.cc
@@ -11,7 +11,7 @@ #include "base/json/json_writer.h" #include "base/json/string_escape.h" #include "base/trace_event/trace_event.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_packet.pb.h"
diff --git a/services/tracing/perfetto/json_trace_exporter.h b/services/tracing/perfetto/json_trace_exporter.h index b682dd2e..596d778d 100644 --- a/services/tracing/perfetto/json_trace_exporter.h +++ b/services/tracing/perfetto/json_trace_exporter.h
@@ -15,7 +15,7 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/values.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" namespace perfetto { namespace protos {
diff --git a/services/tracing/perfetto/json_trace_exporter_unittest.cc b/services/tracing/perfetto/json_trace_exporter_unittest.cc index 9da5bb20..15a3bc9 100644 --- a/services/tracing/perfetto/json_trace_exporter_unittest.cc +++ b/services/tracing/perfetto/json_trace_exporter_unittest.cc
@@ -20,8 +20,8 @@ #include "base/values.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pb.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
diff --git a/services/tracing/perfetto/perfetto_service.cc b/services/tracing/perfetto/perfetto_service.cc index 980aec9..b521b04c 100644 --- a/services/tracing/perfetto/perfetto_service.cc +++ b/services/tracing/perfetto/perfetto_service.cc
@@ -15,7 +15,7 @@ #include "services/tracing/perfetto/consumer_host.h" #include "services/tracing/perfetto/producer_host.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" -#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace tracing {
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.cc b/services/tracing/perfetto/perfetto_tracing_coordinator.cc index f12f6a1..62204988 100644 --- a/services/tracing/perfetto/perfetto_tracing_coordinator.cc +++ b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
@@ -24,10 +24,10 @@ #include "services/tracing/public/cpp/trace_event_args_whitelist.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/consumer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_stats.h" -#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/consumer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_stats.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace tracing {
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc index a8150a51..8fdd6e6 100644 --- a/services/tracing/perfetto/producer_host.cc +++ b/services/tracing/perfetto/producer_host.cc
@@ -12,9 +12,9 @@ #include "services/tracing/public/cpp/perfetto/producer_client.h" #include "services/tracing/public/cpp/perfetto/shared_memory.h" #include "services/tracing/public/cpp/tracing_features.h" -#include "third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h" -#include "third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/data_source_descriptor.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" namespace tracing {
diff --git a/services/tracing/perfetto/producer_host.h b/services/tracing/perfetto/producer_host.h index 9fe4616..91bb082 100644 --- a/services/tracing/perfetto/producer_host.h +++ b/services/tracing/perfetto/producer_host.h
@@ -13,8 +13,8 @@ #include "base/macros.h" #include "services/tracing/perfetto/producer_host.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/producer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/producer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace perfetto { class CommitDataRequest;
diff --git a/services/tracing/perfetto/test_utils.cc b/services/tracing/perfetto/test_utils.cc index 9ba987d9..b50d399 100644 --- a/services/tracing/perfetto/test_utils.cc +++ b/services/tracing/perfetto/test_utils.cc
@@ -8,10 +8,10 @@ #include "base/bind.h" #include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h" #include "third_party/perfetto/protos/perfetto/trace/test_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h"
diff --git a/services/tracing/perfetto/test_utils.h b/services/tracing/perfetto/test_utils.h index 4838507..37ef3f8 100644 --- a/services/tracing/perfetto/test_utils.h +++ b/services/tracing/perfetto/test_utils.h
@@ -13,7 +13,7 @@ #include "services/tracing/perfetto/producer_host.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/producer_client.h" -#include "third_party/perfetto/include/perfetto/tracing/core/consumer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/consumer.h" namespace tracing {
diff --git a/services/tracing/perfetto/track_event_json_exporter.cc b/services/tracing/perfetto/track_event_json_exporter.cc index 01fbca4..8b18c30 100644 --- a/services/tracing/perfetto/track_event_json_exporter.cc +++ b/services/tracing/perfetto/track_event_json_exporter.cc
@@ -316,13 +316,15 @@ switch (thread.chrome_thread_type()) { // TODO(nuskos): As we add more thread types we will add handling here to // switch the enum to a string and call |emit_thread_name()| - case perfetto::protos::ThreadDescriptor::THREAD_UNSPECIFIED: + case perfetto::protos::ThreadDescriptor::THREAD_TYPE_UNSPECIFIED: // No thread type enum so check to see if a explicit thread name was // provided.. if (thread.has_thread_name()) { emit_thread_name(thread.thread_name().c_str()); } break; + default: + break; } }
diff --git a/services/tracing/perfetto/track_event_json_exporter_unittest.cc b/services/tracing/perfetto/track_event_json_exporter_unittest.cc index 6524eec..fd3c5a280 100644 --- a/services/tracing/perfetto/track_event_json_exporter_unittest.cc +++ b/services/tracing/perfetto/track_event_json_exporter_unittest.cc
@@ -18,8 +18,8 @@ #include "base/values.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_packet.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h" @@ -494,9 +494,9 @@ std::vector<perfetto::protos::TracePacket> trace_packet_protos; trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, base::nullopt, - kReferenceTimeUs, kReferenceThreadTimeUs, - &trace_packet_protos); + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, + base::nullopt, kReferenceTimeUs, + kReferenceThreadTimeUs, &trace_packet_protos); FinalizePackets(trace_packet_protos); // No traceEvents or data was emitted but a thread descriptor should be an // empty array and not cause crashes. @@ -507,8 +507,9 @@ std::vector<perfetto::protos::TracePacket> trace_packet_protos; trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket( - /* sort_index = */ 2, ThreadDescriptor::THREAD_UNSPECIFIED, base::nullopt, - kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); + /* sort_index = */ 2, ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, + base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, + &trace_packet_protos); FinalizePackets(trace_packet_protos); ASSERT_EQ(1u, trace_analyzer()->FindEvents( @@ -526,9 +527,9 @@ std::vector<perfetto::protos::TracePacket> trace_packet_protos; trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, kThreadName, - kReferenceTimeUs, kReferenceThreadTimeUs, - &trace_packet_protos); + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, + kThreadName, kReferenceTimeUs, + kReferenceThreadTimeUs, &trace_packet_protos); FinalizePackets(trace_packet_protos); ASSERT_EQ(1u, trace_analyzer()->FindEvents( Query(Query::EVENT_NAME) == Query::String("thread_name"), @@ -545,22 +546,23 @@ std::vector<perfetto::protos::TracePacket> trace_packet_protos; trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket( - /* sort_index = */ 2, ThreadDescriptor::THREAD_UNSPECIFIED, kThreadName, - kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); + /* sort_index = */ 2, ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, + kThreadName, kReferenceTimeUs, kReferenceThreadTimeUs, + &trace_packet_protos); // This packet will be ignored because we've already emitted the sort_index of // 2 and thread_name kThreadName so we suppress this metadata because it // isn't supposed to have changed (even if reset). ASSERT_NE("different_thread_name", kThreadName); AddThreadDescriptorPacket( - /* sort_index = */ 3, ThreadDescriptor::THREAD_UNSPECIFIED, + /* sort_index = */ 3, ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, "different_thread_name", kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); trace_packet_protos.back().set_incremental_state_cleared(true); // Empty packet doesn't change anything. AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, base::nullopt, - kReferenceTimeUs, kReferenceThreadTimeUs, - &trace_packet_protos); + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, + base::nullopt, kReferenceTimeUs, + kReferenceThreadTimeUs, &trace_packet_protos); FinalizePackets(trace_packet_protos); ASSERT_EQ(2u, trace_analyzer()->FindEvents( Query(Query::EVENT_CATEGORY) == Query::String("__metadata"), @@ -697,7 +699,7 @@ // This provides the pid & tid, as well as the timestamps reference points. AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); // To correctly use the state the thread descriptor has to come @@ -730,7 +732,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -768,7 +770,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -803,7 +805,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -833,7 +835,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -914,7 +916,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -953,7 +955,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -999,7 +1001,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1038,7 +1040,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1083,7 +1085,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1130,7 +1132,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1187,7 +1189,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1241,7 +1243,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1267,7 +1269,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1308,7 +1310,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1343,7 +1345,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1378,7 +1380,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1424,7 +1426,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1458,7 +1460,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1492,7 +1494,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1560,7 +1562,7 @@ trace_analyzer::TraceEventVector events; AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "legacy_event_name_3", &trace_packet_protos); @@ -1730,7 +1732,7 @@ // timestamps and one with an absolute timestamps 1 us further than the delta // events. AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(1, "sequence_1", &trace_packet_protos); @@ -1755,7 +1757,7 @@ // Sequence 2 alternates between emitting an event dropping packets and // clearing incremental state. AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(2, "sequence_2", &trace_packet_protos); @@ -1780,7 +1782,8 @@ // Reset the state. AddThreadDescriptorPacket( - /* sort_index = */ base::nullopt, ThreadDescriptor::THREAD_UNSPECIFIED, + /* sort_index = */ base::nullopt, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs + 4 * 3, kReferenceThreadTimeUs + 3 * 3, &trace_packet_protos); trace_packet_protos.back().set_incremental_state_cleared(true); @@ -1799,7 +1802,7 @@ // Sequence 3 emits a single event to ensure that sequence 2 doesn't prevent // these events from being emitted. AddThreadDescriptorPacket(/* sort_index = */ base::nullopt, - ThreadDescriptor::THREAD_UNSPECIFIED, + ThreadDescriptor::THREAD_TYPE_UNSPECIFIED, /* thread_name = */ base::nullopt, kReferenceTimeUs, kReferenceThreadTimeUs, &trace_packet_protos); AddInternedLegacyEventName(3, "sequence_3", &trace_packet_protos);
diff --git a/services/tracing/public/cpp/perfetto/dummy_producer.h b/services/tracing/public/cpp/perfetto/dummy_producer.h index a79383f4..898507c0 100644 --- a/services/tracing/public/cpp/perfetto/dummy_producer.h +++ b/services/tracing/public/cpp/perfetto/dummy_producer.h
@@ -6,7 +6,7 @@ #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_DUMMY_PRODUCER_H_ #include "services/tracing/public/cpp/perfetto/system_producer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/producer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/producer.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/perfetto_config.h b/services/tracing/public/cpp/perfetto/perfetto_config.h index b461678..32ae0b6f 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_config.h +++ b/services/tracing/public/cpp/perfetto/perfetto_config.h
@@ -6,7 +6,7 @@ #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PERFETTO_CONFIG_H_ #include "base/component_export.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" namespace base { namespace trace_event {
diff --git a/services/tracing/public/cpp/perfetto/perfetto_producer.cc b/services/tracing/public/cpp/perfetto/perfetto_producer.cc index f5a5952..ee87551 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_producer.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_producer.cc
@@ -4,9 +4,9 @@ #include "services/tracing/public/cpp/perfetto/perfetto_producer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/shared_memory_arbiter.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer_registry.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/perfetto_producer.h b/services/tracing/public/cpp/perfetto/perfetto_producer.h index d5a18aaf..b9dc035a 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_producer.h +++ b/services/tracing/public/cpp/perfetto/perfetto_producer.h
@@ -9,7 +9,7 @@ #include "base/component_export.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" -#include "third_party/perfetto/include/perfetto/tracing/core/tracing_service.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/tracing_service.h" namespace perfetto { class SharedMemoryArbiter;
diff --git a/services/tracing/public/cpp/perfetto/producer_client.cc b/services/tracing/public/cpp/perfetto/producer_client.cc index c6509fb0..8f274e00 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.cc +++ b/services/tracing/public/cpp/perfetto/producer_client.cc
@@ -13,10 +13,10 @@ #include "services/tracing/public/cpp/perfetto/shared_memory.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/mojom/constants.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h" -#include "third_party/perfetto/include/perfetto/tracing/core/shared_memory_arbiter.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer_registry.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/shared_memory.cc b/services/tracing/public/cpp/perfetto/shared_memory.cc index 84907fe..e2fa2c8a5 100644 --- a/services/tracing/public/cpp/perfetto/shared_memory.cc +++ b/services/tracing/public/cpp/perfetto/shared_memory.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "third_party/perfetto/include/perfetto/tracing/core/shared_memory.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/shared_memory.h b/services/tracing/public/cpp/perfetto/shared_memory.h index 2542cdf..548e64d 100644 --- a/services/tracing/public/cpp/perfetto/shared_memory.h +++ b/services/tracing/public/cpp/perfetto/shared_memory.h
@@ -10,7 +10,7 @@ #include "base/component_export.h" #include "base/macros.h" #include "mojo/public/cpp/system/platform_handle.h" -#include "third_party/perfetto/include/perfetto/tracing/core/shared_memory.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/system_producer.h b/services/tracing/public/cpp/perfetto/system_producer.h index e37274c..247afc03 100644 --- a/services/tracing/public/cpp/perfetto/system_producer.h +++ b/services/tracing/public/cpp/perfetto/system_producer.h
@@ -6,7 +6,7 @@ #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_SYSTEM_PRODUCER_H_ #include "services/tracing/public/cpp/perfetto/perfetto_producer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/producer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/producer.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/thread_local_event_sink.cc index 0aa7890..7ffdc56 100644 --- a/services/tracing/public/cpp/perfetto/thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/thread_local_event_sink.cc
@@ -7,7 +7,7 @@ #include <utility> #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer.h" namespace tracing {
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index 7ea0561..157ebe42 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -25,10 +25,10 @@ #include "services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h" #include "services/tracing/public/cpp/trace_event_args_whitelist.h" #include "services/tracing/public/mojom/constants.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/shared_memory_arbiter.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer_registry.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/shared_memory_arbiter.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer_registry.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index a6e6847..67d6e02 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -20,9 +20,9 @@ #include "components/tracing/common/tracing_switches.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/include/perfetto/protozero/scattered_stream_null_delegate.h" #include "third_party/perfetto/include/perfetto/protozero/scattered_stream_writer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc index 93b3e14..6bb3dec 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.cc
@@ -12,7 +12,7 @@ #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/producer_client.h" #include "services/tracing/public/cpp/perfetto/traced_value_proto_writer.h" -#include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/startup_trace_writer.h" #include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h" #include "third_party/perfetto/protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h index 7cae3bd7..4582cec 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
@@ -14,8 +14,8 @@ #include "base/time/time.h" #include "services/tracing/public/cpp/perfetto/interning_index.h" #include "services/tracing/public/cpp/perfetto/thread_local_event_sink.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_writer.h" #include "third_party/perfetto/include/perfetto/protozero/message_handle.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_writer.h" namespace perfetto { class StartupTraceWriter;
diff --git a/services/tracing/public/mojom/chrome_config_mojom_traits.h b/services/tracing/public/mojom/chrome_config_mojom_traits.h index 1deafb3..ccdbba9 100644 --- a/services/tracing/public/mojom/chrome_config_mojom_traits.h +++ b/services/tracing/public/mojom/chrome_config_mojom_traits.h
@@ -12,7 +12,7 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/chrome_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/chrome_config.h" namespace mojo { template <>
diff --git a/services/tracing/public/mojom/commit_data_request_mojom_traits.h b/services/tracing/public/mojom/commit_data_request_mojom_traits.h index 8b5c468..e10f485 100644 --- a/services/tracing/public/mojom/commit_data_request_mojom_traits.h +++ b/services/tracing/public/mojom/commit_data_request_mojom_traits.h
@@ -13,7 +13,7 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h" namespace mojo {
diff --git a/services/tracing/public/mojom/data_source_config_mojom_traits.h b/services/tracing/public/mojom/data_source_config_mojom_traits.h index e749282..4e357412 100644 --- a/services/tracing/public/mojom/data_source_config_mojom_traits.h +++ b/services/tracing/public/mojom/data_source_config_mojom_traits.h
@@ -12,8 +12,8 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/chrome_config.h" -#include "third_party/perfetto/include/perfetto/tracing/core/data_source_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/chrome_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/data_source_config.h" namespace mojo { template <>
diff --git a/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h index b98db41..56c7992 100644 --- a/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h +++ b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h
@@ -12,7 +12,7 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/data_source_descriptor.h" namespace mojo { template <>
diff --git a/services/tracing/public/mojom/perfetto_service.typemap b/services/tracing/public/mojom/perfetto_service.typemap index ac29824..58a062b 100644 --- a/services/tracing/public/mojom/perfetto_service.typemap +++ b/services/tracing/public/mojom/perfetto_service.typemap
@@ -1,10 +1,10 @@ mojom = "//services/tracing/public/mojom/perfetto_service.mojom" public_headers = [ - "//third_party/perfetto/include/perfetto/tracing/core/commit_data_request.h", - "//third_party/perfetto/include/perfetto/tracing/core/data_source_config.h", - "//third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h", - "//third_party/perfetto/include/perfetto/tracing/core/chrome_config.h", - "//third_party/perfetto/include/perfetto/tracing/core/trace_config.h", + "//third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h", + "//third_party/perfetto/include/perfetto/ext/tracing/core/data_source_config.h", + "//third_party/perfetto/include/perfetto/ext/tracing/core/data_source_descriptor.h", + "//third_party/perfetto/include/perfetto/ext/tracing/core/chrome_config.h", + "//third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h", ] traits_headers = [ "//services/tracing/public/mojom/commit_data_request_mojom_traits.h",
diff --git a/services/tracing/public/mojom/trace_config_mojom_traits.h b/services/tracing/public/mojom/trace_config_mojom_traits.h index 49fefba..bbd3b530 100644 --- a/services/tracing/public/mojom/trace_config_mojom_traits.h +++ b/services/tracing/public/mojom/trace_config_mojom_traits.h
@@ -13,7 +13,7 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "services/tracing/public/mojom/perfetto_service.mojom.h" -#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" +#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_config.h" namespace mojo {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 601e006c9..a2c2d5b 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -4672,6 +4672,19 @@ "test": "service_manager_unittests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "services_unittests" + }, + { "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5063,6 +5076,24 @@ "test": "service_manager_unittests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "services_unittests" + }, + { "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5502,6 +5533,24 @@ "test": "service_manager_unittests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1" + } + ] + }, + "test": "services_unittests" + }, + { "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 73632a7..335afe2 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -67,6 +67,7 @@ "//testing/buildbot/filters/fuchsia.mojo_unittests.filter", "//testing/buildbot/filters/fuchsia.net_perftests.filter", "//testing/buildbot/filters/fuchsia.net_unittests.filter", + "//testing/buildbot/filters/fuchsia.services_unittests.filter", "//testing/buildbot/filters/fuchsia.ui_base_unittests.filter", ] }
diff --git a/testing/buildbot/filters/fuchsia.services_unittests.filter b/testing/buildbot/filters/fuchsia.services_unittests.filter new file mode 100644 index 0000000..b496cdb --- /dev/null +++ b/testing/buildbot/filters/fuchsia.services_unittests.filter
@@ -0,0 +1,25 @@ +# https://crbug.com/925652 - There are no |services_|. +-HidServiceTest.GetDevices + +# https://crbug.com/925652 - |num_sockets| expectations mismatch. +-NetworkContextTest.PreconnectFour +-NetworkContextTest.PreconnectTwo + +# https://crbug.com/925652 - Fails FillOSMemoryDump(). +-OSMetricsTest.GivesNonZeroResults + +# https://crbug.com/925653 - IsTracingEnabled() expectations not met. +-TracingConsumerTest.NotifiesOnTracingEnabledWaitsFor* + +# https://crbug.com/925653 - Flaky OOM and virtual method crashes. +-TracingConsumerTest.FlushProducers +-TracingConsumerTest.LargeDataSize +-TracingConsumerTest.PrivacyFilterConfig +-TracingConsumerTest.PrivacyFilterConfigInJson +-TracingConsumerTest.TestConsumerPriority + +# https://crbug.com/925653 - Second socket receives too many packets. +-UDPSocketTest.JoinMulticastGroup + +# https://crbug.com/925653 - Unexpected address-in-use. +-TCPBoundSocketTest.ListenError
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 14a0007a..c4a0cd3 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1232,6 +1232,8 @@ # chromium.gpu.fyi # The face and barcode detection tests fail on the Mac Pros. 'Mac Pro FYI Release (AMD)', + # chromium.linux + 'Fuchsia x64', # chromium.memory 'Linux ChromiumOS MSan Tests', # https://crbug.com/831676 'Linux MSan Tests', # https://crbug.com/831676
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 84207b4..aa72baf 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -2670,6 +2670,11 @@ }, 'perfetto_unittests': {}, 'service_manager_unittests': {}, + 'services_unittests': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter', + ], + }, 'skia_unittests': {}, 'sql_unittests': {}, 'ui_base_unittests': {
diff --git a/third_party/blink/perf_tests/OWNERS b/third_party/blink/perf_tests/OWNERS index 2ffc6398..7ae8de90 100644 --- a/third_party/blink/perf_tests/OWNERS +++ b/third_party/blink/perf_tests/OWNERS
@@ -4,7 +4,6 @@ haraken@chromium.org hayato@chromium.org kojii@chromium.org -nednguyen@google.com crouleau@chromium.org # Team: benchmarking-dev@chromium.org
diff --git a/third_party/blink/public/platform/web_prerender.h b/third_party/blink/public/platform/web_prerender.h index 4a3317ce..17f016c 100644 --- a/third_party/blink/public/platform/web_prerender.h +++ b/third_party/blink/public/platform/web_prerender.h
@@ -36,6 +36,7 @@ #include "third_party/blink/public/platform/web_private_ptr.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" +#include "url/origin.h" namespace blink { @@ -68,6 +69,7 @@ BLINK_PLATFORM_EXPORT WebURL Url() const; BLINK_PLATFORM_EXPORT WebString GetReferrer() const; + BLINK_PLATFORM_EXPORT url::Origin SecurityOrigin() const; BLINK_PLATFORM_EXPORT unsigned RelTypes() const; BLINK_PLATFORM_EXPORT network::mojom::ReferrerPolicy GetReferrerPolicy() const;
diff --git a/third_party/blink/renderer/core/animation/css/css_animations_test.cc b/third_party/blink/renderer/core/animation/css/css_animations_test.cc index d029e8a..2047d1e 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations_test.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations_test.cc
@@ -81,13 +81,13 @@ element->setAttribute(html_names::kClassAttr, "contrast2"); GetPage().Animator().ServiceScriptedAnimations(CurrentTimeTicks()); UpdateAllLifecyclePhasesForTest(); - EXPECT_NEAR(0.6, GetContrastFilterAmount(element), 0.00000000001); + EXPECT_NEAR(0.6, GetContrastFilterAmount(element), 0.0000000001); // As it has been retargeted, advancing halfway should go to 0.3. AdvanceClockSeconds(0.5); GetPage().Animator().ServiceScriptedAnimations(CurrentTimeTicks()); UpdateAllLifecyclePhasesForTest(); - EXPECT_NEAR(0.3, GetContrastFilterAmount(element), 0.00000000001); + EXPECT_NEAR(0.3, GetContrastFilterAmount(element), 0.0000000001); } // Test that when an incompatible in progress compositor transition
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc index f6c4696..69184f84f 100644 --- a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc +++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -207,7 +207,8 @@ if (!BackgroundLayerMayBeSprite(*background_layer)) { if (element_->GetDocument() .GetFrame() - ->IsAutomaticLazyLoadingImageAllowed()) { + ->GetLazyLoadImageEnabledState() == + LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic) { image_request_optimization = FetchParameters::kDeferImageLoad; } else { image_request_optimization = FetchParameters::kAllowPlaceholder;
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc index 2d6f4196..4eee2b2 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -80,7 +80,7 @@ weak_factory_(this) { // TODO(https://crbug.com/957651): Change this into a DCHECK once we figured // out where code is passing in a null task runner, - DCHECK(task_runner_); + CHECK(task_runner_); } FileReaderLoader::~FileReaderLoader() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 4851cb4..06f9c9f 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1290,25 +1290,23 @@ request, Client()->GetPreviewsStateForFrame()); } -bool LocalFrame::IsExplicitLazyLoadingImageAllowed() const { +LocalFrame::LazyLoadImageEnabledState LocalFrame::GetLazyLoadImageEnabledState() + const { DCHECK(GetSettings()); - return RuntimeEnabledFeatures::LazyImageLoadingEnabled() && - GetSettings()->GetLazyLoadEnabled(); -} - -bool LocalFrame::IsAutomaticLazyLoadingImageAllowed() const { - if (!IsExplicitLazyLoadingImageAllowed()) - return false; + if (!RuntimeEnabledFeatures::LazyImageLoadingEnabled() || + !GetSettings()->GetLazyLoadEnabled()) { + return LocalFrame::LazyLoadImageEnabledState::kDisabled; + } if (!RuntimeEnabledFeatures::AutomaticLazyImageLoadingEnabled()) - return false; + return LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit; if (RuntimeEnabledFeatures:: RestrictAutomaticLazyImageLoadingToDataSaverEnabled() && !is_save_data_enabled_) { - return false; + return LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit; } if (Owner() && !Owner()->ShouldLazyLoadChildren()) - return false; - return true; + return LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit; + return LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic; } WebURLLoaderFactory* LocalFrame::GetURLLoaderFactory() {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 44765c1..784ff44b 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -317,9 +317,13 @@ // Returns true if Client Lo-Fi should be used for this request. bool IsClientLoFiAllowed(const ResourceRequest&) const; - // Returns true if lazyloading the image is possible. - bool IsExplicitLazyLoadingImageAllowed() const; - bool IsAutomaticLazyLoadingImageAllowed() const; + enum class LazyLoadImageEnabledState { + kDisabled, + kEnabledExplicit, + kEnabledAutomatic + }; + // Returns the enabled state of lazyloading of images. + LazyLoadImageEnabledState GetLazyLoadImageEnabledState() const; // The returned value is a off-heap raw-ptr and should not be stored. WebURLLoaderFactory* GetURLLoaderFactory();
diff --git a/third_party/blink/renderer/core/frame/local_frame_test.cc b/third_party/blink/renderer/core/frame/local_frame_test.cc index 4eb379e..7bf062b 100644 --- a/third_party/blink/renderer/core/frame/local_frame_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_test.cc
@@ -187,8 +187,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_FALSE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_FALSE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kDisabled, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithSettingDisabled) { @@ -196,8 +196,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &DisableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_FALSE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_FALSE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kDisabled, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithAutomaticDisabled) { @@ -207,8 +207,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_TRUE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_FALSE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWhenNotRestricted) { @@ -221,8 +221,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_TRUE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_TRUE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, @@ -236,8 +236,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_TRUE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_FALSE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, @@ -251,8 +251,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndEnableDataSaverHoldbackInSettings); - EXPECT_TRUE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_FALSE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kEnabledExplicit, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } TEST_F(LocalFrameTest, @@ -266,8 +266,8 @@ auto page_holder = std::make_unique<DummyPageHolder>( IntSize(800, 600), nullptr, nullptr, &EnableLazyLoadAndDisableDataSaverHoldbackInSettings); - EXPECT_TRUE(page_holder->GetFrame().IsExplicitLazyLoadingImageAllowed()); - EXPECT_TRUE(page_holder->GetFrame().IsAutomaticLazyLoadingImageAllowed()); + EXPECT_EQ(LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic, + page_holder->GetFrame().GetLazyLoadImageEnabledState()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/reporting_context.cc b/third_party/blink/renderer/core/frame/reporting_context.cc index 2702288..064cdaa 100644 --- a/third_party/blink/renderer/core/frame/reporting_context.cc +++ b/third_party/blink/renderer/core/frame/reporting_context.cc
@@ -43,7 +43,7 @@ // Buffer the report. if (!report_buffer_.Contains(report->type())) - report_buffer_.insert(report->type(), HeapListHashSet<Member<Report>>()); + report_buffer_.insert(report->type(), HeapLinkedHashSet<Member<Report>>()); report_buffer_.find(report->type())->value.insert(report); // Only the most recent 100 reports will remain buffered, per report type.
diff --git a/third_party/blink/renderer/core/frame/reporting_context.h b/third_party/blink/renderer/core/frame/reporting_context.h index fab504ba..8a0b98f3 100644 --- a/third_party/blink/renderer/core/frame/reporting_context.h +++ b/third_party/blink/renderer/core/frame/reporting_context.h
@@ -53,8 +53,8 @@ // Send |report| via the Reporting API to |endpoint|. void SendToReportingAPI(Report* report, const String& endpoint) const; - HeapListHashSet<Member<ReportingObserver>> observers_; - HeapHashMap<String, HeapListHashSet<Member<Report>>> report_buffer_; + HeapLinkedHashSet<Member<ReportingObserver>> observers_; + HeapHashMap<String, HeapLinkedHashSet<Member<Report>>> report_buffer_; Member<ExecutionContext> execution_context_; // This is declared mutable so that the service endpoint can be cached by
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index 5941d76..c5f40e72 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -870,29 +870,38 @@ // Minimum height or width of the image to start lazyloading. constexpr int kMinDimensionToLazyLoad = 10; -bool HTMLImageElement::IsDimensionSmallAndAbsoluteForLazyLoad( +HTMLImageElement::LazyLoadDimensionType +HTMLImageElement::GetAttributeLazyLoadDimensionType( const String& attribute_value) { HTMLDimension dimension; - return ParseDimensionValue(attribute_value, dimension) && - dimension.IsAbsolute() && dimension.Value() <= kMinDimensionToLazyLoad; + if (ParseDimensionValue(attribute_value, dimension) && + dimension.IsAbsolute()) { + return dimension.Value() <= kMinDimensionToLazyLoad + ? LazyLoadDimensionType::kAbsoluteSmall + : LazyLoadDimensionType::kAbsoluteNotSmall; + } + return LazyLoadDimensionType::kNotAbsolute; } -bool HTMLImageElement::IsInlineStyleDimensionsSmall( +HTMLImageElement::LazyLoadDimensionType +HTMLImageElement::GetInlineStyleDimensionsType( const CSSPropertyValueSet* property_set) { if (!property_set) - return false; + return LazyLoadDimensionType::kNotAbsolute; const CSSValue* height = property_set->GetPropertyCSSValue(CSSPropertyID::kHeight); const CSSValue* width = property_set->GetPropertyCSSValue(CSSPropertyID::kWidth); const auto* width_prim = DynamicTo<CSSPrimitiveValue>(width); const auto* height_prim = DynamicTo<CSSPrimitiveValue>(height); - if (!width_prim || !height_prim) - return false; - return height_prim->IsPx() && - (height_prim->GetDoubleValue() <= kMinDimensionToLazyLoad) && - width_prim->IsPx() && - (width_prim->GetDoubleValue() <= kMinDimensionToLazyLoad); + if (!width_prim || !height_prim || !width_prim->IsPx() || + !height_prim->IsPx()) { + return LazyLoadDimensionType::kNotAbsolute; + } + return (height_prim->GetDoubleValue() <= kMinDimensionToLazyLoad) && + (width_prim->GetDoubleValue() <= kMinDimensionToLazyLoad) + ? LazyLoadDimensionType::kAbsoluteSmall + : LazyLoadDimensionType::kAbsoluteNotSmall; } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_image_element.h b/third_party/blink/renderer/core/html/html_image_element.h index b876101..25a0bb32 100644 --- a/third_party/blink/renderer/core/html/html_image_element.h +++ b/third_party/blink/renderer/core/html/html_image_element.h
@@ -67,6 +67,19 @@ unsigned width, unsigned height); + // Returns dimension type of the attribute value or inline dimensions usable + // for LazyLoad, whether the dimension is absolute or not and if the absolute + // value is small enough to be skipped for lazyloading. + enum class LazyLoadDimensionType { + kNotAbsolute, + kAbsoluteNotSmall, + kAbsoluteSmall, + }; + static LazyLoadDimensionType GetAttributeLazyLoadDimensionType( + const String& attribute_value); + static LazyLoadDimensionType GetInlineStyleDimensionsType( + const CSSPropertyValueSet* property_set); + HTMLImageElement(Document&, const CreateElementFlags); explicit HTMLImageElement(Document&, bool created_by_parser = false); ~HTMLImageElement() override; @@ -159,10 +172,6 @@ return *visible_load_time_metrics_; } - static bool IsDimensionSmallAndAbsoluteForLazyLoad( - const String& attribute_value); - static bool IsInlineStyleDimensionsSmall(const CSSPropertyValueSet*); - // Updates if any optimized image policy is violated. When any policy is // violated, the image should be rendered as a placeholder image. void SetImagePolicyViolated() {
diff --git a/third_party/blink/renderer/core/html/html_image_element_test.cc b/third_party/blink/renderer/core/html/html_image_element_test.cc index 55f39e8..cffc20f 100644 --- a/third_party/blink/renderer/core/html/html_image_element_test.cc +++ b/third_party/blink/renderer/core/html/html_image_element_test.cc
@@ -6,6 +6,8 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/css_property_value_set.h" +#include "third_party/blink/renderer/core/css/parser/css_parser.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" @@ -44,4 +46,63 @@ EXPECT_EQ(250, image->SourceSize(*image)); } +TEST_F(HTMLImageElementTest, attributeLazyLoadDimensionType) { + struct TestCase { + const char* attribute_value; + HTMLImageElement::LazyLoadDimensionType expected_dimension_type; + }; + const TestCase test_cases[] = { + {"", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"invalid", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"10px", HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall}, + {"10", HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall}, + {"100px", HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall}, + {"100", HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall}, + }; + for (const auto& test : test_cases) { + EXPECT_EQ(test.expected_dimension_type, + HTMLImageElement::GetAttributeLazyLoadDimensionType( + test.attribute_value)); + } +} + +TEST_F(HTMLImageElementTest, inlineStyleLazyLoadDimensionType) { + struct TestCase { + const char* inline_style; + HTMLImageElement::LazyLoadDimensionType expected_dimension_type; + }; + const TestCase test_cases[] = { + {"", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"invalid", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"height: 1px", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"width: 1px", HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"height: 1; width: 1", + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"height: 50%; width: 50%", + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"height: 1px; width: 1px", + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall}, + {"height: 10px; width: 10px", + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall}, + {"height: 100px; width: 10px", + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall}, + {"height: 10px; width: 100px", + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall}, + {"height: 100px; width: 100px", + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall}, + {"height: 100; width: 100", + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + {"height: 100%; width: 100%", + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute}, + }; + for (const auto& test : test_cases) { + const ImmutableCSSPropertyValueSet* property_set = + CSSParser::ParseInlineStyleDeclaration( + test.inline_style, kHTMLStandardMode, + SecureContextMode::kInsecureContext); + EXPECT_EQ(test.expected_dimension_type, + HTMLImageElement::GetInlineStyleDimensionsType(property_set)); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc index 7610f15..6eb71c3 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -38,29 +38,22 @@ ->CopyAs<Vector<char>>(); } -class LazyLoadCSSImagesTest : public SimTest { +class LazyLoadImagesSimTest : public ::testing::WithParamInterface<bool>, + public SimTest { protected: - LazyLoadCSSImagesTest() - : scoped_lazy_image_loading_for_test_(true), - scoped_automatic_lazy_image_loading_for_test_(true) {} + LazyLoadImagesSimTest() + : scoped_lazy_image_loading_for_test_(GetParam()), + scoped_automatic_lazy_image_loading_for_test_(GetParam()) {} + void SetLazyLoadEnabled(bool enabled) { WebView().GetPage()->GetSettings().SetLazyLoadEnabled(enabled); } - void LoadMainResource() { + void LoadMainResource(const String& html_body) { SimRequest main_resource("https://example.com/", "text/html"); LoadURL("https://example.com/"); - main_resource.Complete(String::Format(R"HTML( - <style> - #deferred_image { - height:200px; - background-image: url('img.png'); - } - </style> - <div style='height:10000px;'></div> - <div id="deferred_image"></div> - )HTML")); + main_resource.Complete(html_body); GetDocument().UpdateStyleAndLayoutTree(); } @@ -82,40 +75,108 @@ EXPECT_TRUE(is_background_image_found); } + void VerifyImageElementWithDimensionDeferred(const char* img_attribute) { + bool is_lazyload_image_enabled = GetParam(); + SetLazyLoadEnabled(is_lazyload_image_enabled); + SimRequest image_resource("https://example.com/img.png", "image/png"); + LoadMainResource(String::Format(R"HTML( + <body onload='console.log("main body onload");'> + <div style='height:10000px;'></div> + <img src="img.png" %s + onload= 'console.log("deferred_image onload");'> + </body>)HTML", + img_attribute)); + + if (!is_lazyload_image_enabled) + image_resource.Complete(ReadTestImage()); + + Compositor().BeginFrame(); + test::RunPendingTasks(); + + EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); + if (!is_lazyload_image_enabled) + EXPECT_TRUE(ConsoleMessages().Contains("deferred_image onload")); + + if (is_lazyload_image_enabled) { + // Scroll down until the image element is visible. + GetDocument().View()->LayoutViewport()->SetScrollOffset( + ScrollOffset(0, 10000), kProgrammaticScroll); + Compositor().BeginFrame(); + test::RunPendingTasks(); + image_resource.Complete(ReadTestImage()); + test::RunPendingTasks(); + EXPECT_TRUE(ConsoleMessages().Contains("deferred_image onload")); + } + } + private: ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test_; ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test_; }; -TEST_F(LazyLoadCSSImagesTest, CSSBackgroundImageLoadedWithoutLazyLoad) { - SetLazyLoadEnabled(false); +TEST_P(LazyLoadImagesSimTest, CSSBackgroundImage) { + bool is_lazyload_image_enabled = GetParam(); + SetLazyLoadEnabled(is_lazyload_image_enabled); SimRequest image_resource("https://example.com/img.png", "image/png"); - LoadMainResource(); - image_resource.Complete(ReadTestImage()); + LoadMainResource(String::Format(R"HTML( + <style> + #deferred_image { + height:200px; + background-image: url('img.png'); + } + </style> + <div style='height:10000px;'></div> + <div id="deferred_image"></div> + )HTML")); + + if (!is_lazyload_image_enabled) + image_resource.Complete(ReadTestImage()); + Compositor().BeginFrame(); test::RunPendingTasks(); - ExpectCSSBackgroundImageDeferredState(false); + ExpectCSSBackgroundImageDeferredState(is_lazyload_image_enabled); + + if (is_lazyload_image_enabled) { + // Scroll down until the background image is visible. + GetDocument().View()->LayoutViewport()->SetScrollOffset( + ScrollOffset(0, 10000), kProgrammaticScroll); + Compositor().BeginFrame(); + test::RunPendingTasks(); + image_resource.Complete(ReadTestImage()); + ExpectCSSBackgroundImageDeferredState(false); + } } -TEST_F(LazyLoadCSSImagesTest, CSSBackgroundImageDeferredWithLazyLoad) { - SetLazyLoadEnabled(true); - LoadMainResource(); - Compositor().BeginFrame(); - test::RunPendingTasks(); - - ExpectCSSBackgroundImageDeferredState(true); - - // Scroll down until the background image is visible. - GetDocument().View()->LayoutViewport()->SetScrollOffset( - ScrollOffset(0, 10000), kProgrammaticScroll); - SimRequest image_resource("https://example.com/img.png", "image/png"); - Compositor().BeginFrame(); - test::RunPendingTasks(); - image_resource.Complete(ReadTestImage()); - ExpectCSSBackgroundImageDeferredState(false); +TEST_P(LazyLoadImagesSimTest, LargeImageHeight100Width100) { + VerifyImageElementWithDimensionDeferred("height='100px' width='100px'"); } +TEST_P(LazyLoadImagesSimTest, LargeImageHeight1Width100) { + VerifyImageElementWithDimensionDeferred("height='1px' width='100px'"); +} + +TEST_P(LazyLoadImagesSimTest, LargeImageHeight100Width1) { + VerifyImageElementWithDimensionDeferred("height='100px' width='1px'"); +} + +TEST_P(LazyLoadImagesSimTest, LargeImageStyleHeight100Width100) { + VerifyImageElementWithDimensionDeferred( + "style='height: 100px; width: 100px;'"); +} + +TEST_P(LazyLoadImagesSimTest, LargeImageStyleHeight100Width1) { + VerifyImageElementWithDimensionDeferred("style='height: 100px; width: 1px;'"); +} + +TEST_P(LazyLoadImagesSimTest, LargeImageStyleHeight1Width100) { + VerifyImageElementWithDimensionDeferred("style='height: 1px; width: 100px;'"); +} + +INSTANTIATE_TEST_SUITE_P(, + LazyLoadImagesSimTest, + ::testing::Bool() /*is_lazyload_image_enabled*/); + SimRequestBase::Params BuildRequestParamsForRangeResponse() { SimRequestBase::Params params; params.response_http_headers = {{"content-range", "bytes 0-2047/9311"}}; @@ -614,6 +675,30 @@ EXPECT_FALSE(ConsoleMessages().Contains("image onload")); } + void TestLoadImageExpectingLazyLoadWithoutPlaceholder( + const char* image_attributes) { + SimSubresourceRequest full_resource("https://example.com/image.png", + "image/png"); + + LoadMainResourceWithImageFarFromViewport(image_attributes); + + EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); + EXPECT_FALSE(ConsoleMessages().Contains("image onload")); + + // Scrolling down should trigger the fetch of the image. + GetDocument().View()->LayoutViewport()->SetScrollOffset( + ScrollOffset(0, kLoadingDistanceThreshold + kViewportHeight), + kProgrammaticScroll); + Compositor().BeginFrame(); + full_resource.Complete(ReadTestImage()); + ExpectResourceIsFullImage(GetDocument().Fetcher()->CachedResource( + KURL("https://example.com/image.png"))); + test::RunPendingTasks(); + + EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); + EXPECT_TRUE(ConsoleMessages().Contains("image onload")); + } + void TestLoadImageExpectingFullImageLoad(const char* image_attributes) { SimSubresourceRequest full_resource("https://example.com/image.png", "image/png"); @@ -729,7 +814,7 @@ } TEST_F(LazyLoadAutomaticImagesTest, TinyImageWidth1Height11) { - TestLoadImageExpectingLazyLoad("width='1px' height='11px'"); + TestLoadImageExpectingLazyLoadWithoutPlaceholder("width='1px' height='11px'"); } TEST_F(LazyLoadAutomaticImagesTest, TinyImageViaStyleWidth1Height1) { @@ -741,7 +826,8 @@ } TEST_F(LazyLoadAutomaticImagesTest, TinyImageViaStyleWidth11Height1) { - TestLoadImageExpectingLazyLoad("style='width:11px;height:1px;'"); + TestLoadImageExpectingLazyLoadWithoutPlaceholder( + "style='width:11px;height:1px;'"); } TEST_F(LazyLoadAutomaticImagesTest, JavascriptCreatedImageFarFromViewport) {
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index a29dc57e..826124fb 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -52,6 +52,7 @@ #include "third_party/blink/renderer/core/html/parser/html_tokenizer.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input_type_names.h" +#include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/importance_attribute.h" #include "third_party/blink/renderer/core/loader/preload_helper.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" @@ -151,9 +152,12 @@ integrity_attr_set_(false), integrity_features_(features), loading_attr_value_(LoadingAttrValue::kAuto), - width_attr_small_absolute_(false), - height_attr_small_absolute_(false), - inline_style_dimensions_small_(false), + width_attr_dimension_type_( + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute), + height_attr_dimension_type_( + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute), + inline_style_dimensions_type_( + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute), scanner_type_(scanner_type), priority_hints_origin_trial_enabled_( priority_hints_origin_trial_enabled) { @@ -295,26 +299,44 @@ document_parameters.lazyload_policy_enforced) { effective_loading_attr_value = LoadingAttrValue::kAuto; } + bool is_lazy_load_image_enabled = false; switch (effective_loading_attr_value) { case LoadingAttrValue::kEager: - request->SetLazyLoadImageEligibility( - PreloadRequest::LazyLoadImageEligibility::kDisabled); + is_lazy_load_image_enabled = false; break; case LoadingAttrValue::kLazy: - request->SetLazyLoadImageEligibility( - PreloadRequest::LazyLoadImageEligibility::kEnabledExplicit); + is_lazy_load_image_enabled = + document_parameters.lazy_load_image_enabled_state != + LocalFrame::LazyLoadImageEnabledState::kDisabled; break; case LoadingAttrValue::kAuto: - if ((width_attr_small_absolute_ && height_attr_small_absolute_) || - inline_style_dimensions_small_) { - request->SetLazyLoadImageEligibility( - PreloadRequest::LazyLoadImageEligibility::kDisabled); + if ((width_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall && + height_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall) || + inline_style_dimensions_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall) { + is_lazy_load_image_enabled = false; } else { - request->SetLazyLoadImageEligibility( - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic); + is_lazy_load_image_enabled = + document_parameters.lazy_load_image_enabled_state == + LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic; } break; } + // LazyLoad: Do not preload if absolute dimensions are mentioned in width + // and height attributes or in the inline style, and the dimensions are not + // small enough. + if (is_lazy_load_image_enabled && + ((width_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall && + height_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall) || + inline_style_dimensions_type_ == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall)) { + return nullptr; + } + request->SetIsLazyLoadImageEnabled(is_lazy_load_image_enabled); // The only link tags that should keep the integrity metadata are // stylesheets until crbug.com/677022 is resolved. @@ -395,19 +417,20 @@ : EqualIgnoringASCIICase(attribute_value, "lazy") ? LoadingAttrValue::kLazy : LoadingAttrValue::kAuto; - } else if (!width_attr_small_absolute_ && + } else if (width_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute && Match(attribute_name, kWidthAttr) && RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { - width_attr_small_absolute_ = - HTMLImageElement::IsDimensionSmallAndAbsoluteForLazyLoad( - attribute_value); - } else if (!height_attr_small_absolute_ && + width_attr_dimension_type_ = + HTMLImageElement::GetAttributeLazyLoadDimensionType(attribute_value); + } else if (height_attr_dimension_type_ == + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute && Match(attribute_name, kHeightAttr) && RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { - height_attr_small_absolute_ = - HTMLImageElement::IsDimensionSmallAndAbsoluteForLazyLoad( - attribute_value); - } else if (!inline_style_dimensions_small_ && + height_attr_dimension_type_ = + HTMLImageElement::GetAttributeLazyLoadDimensionType(attribute_value); + } else if (inline_style_dimensions_type_ == + HTMLImageElement::LazyLoadDimensionType::kNotAbsolute && Match(attribute_name, kStyleAttr) && RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { CSSParserMode mode = @@ -415,8 +438,8 @@ const ImmutableCSSPropertyValueSet* property_set = CSSParser::ParseInlineStyleDeclaration( attribute_value, mode, SecureContextMode::kInsecureContext); - inline_style_dimensions_small_ = - HTMLImageElement::IsInlineStyleDimensionsSmall(property_set); + inline_style_dimensions_type_ = + HTMLImageElement::GetInlineStyleDimensionsType(property_set); } } @@ -717,9 +740,9 @@ IntegrityMetadataSet integrity_metadata_; SubresourceIntegrity::IntegrityFeatures integrity_features_; LoadingAttrValue loading_attr_value_; - bool width_attr_small_absolute_; - bool height_attr_small_absolute_; - bool inline_style_dimensions_small_; + HTMLImageElement::LazyLoadDimensionType width_attr_dimension_type_; + HTMLImageElement::LazyLoadDimensionType height_attr_dimension_type_; + HTMLImageElement::LazyLoadDimensionType inline_style_dimensions_type_; TokenPreloadScanner::ScannerType scanner_type_; // For explanation, see TokenPreloadScanner's declaration. bool priority_hints_origin_trial_enabled_; @@ -1063,6 +1086,13 @@ referrer_policy = document->GetReferrerPolicy(); integrity_features = SubresourceIntegrityHelper::GetFeatures(document); lazyload_policy_enforced = document->IsLazyLoadPolicyEnforced(); + if (document->Loader() && document->Loader()->GetFrame()) { + lazy_load_image_enabled_state = + document->Loader()->GetFrame()->GetLazyLoadImageEnabledState(); + } else { + lazy_load_image_enabled_state = + LocalFrame::LazyLoadImageEnabledState::kDisabled; + } } } // namespace blink
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.h b/third_party/blink/renderer/core/html/parser/html_preload_scanner.h index 45f6493..90c3cfc8 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.h +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.h
@@ -35,6 +35,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/media_values_cached.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/parser/compact_html_token.h" #include "third_party/blink/renderer/core/html/parser/css_preload_scanner.h" #include "third_party/blink/renderer/core/html/parser/html_token.h" @@ -55,6 +56,12 @@ USING_FAST_MALLOC(CachedDocumentParameters); public: + enum class LazyLoadImageEnabledState { + kDisabled, + kEnabledExplicit, + kEnabledAutomatic + }; + explicit CachedDocumentParameters(Document*); CachedDocumentParameters() = default; @@ -65,6 +72,7 @@ network::mojom::ReferrerPolicy referrer_policy; SubresourceIntegrity::IntegrityFeatures integrity_features; bool lazyload_policy_enforced; + LocalFrame::LazyLoadImageEnabledState lazy_load_image_enabled_state; }; class TokenPreloadScanner {
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index ab17347..81c536a 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -88,7 +88,7 @@ struct LazyLoadImageTestCase { const char* input_html; - PreloadRequest::LazyLoadImageEligibility lazy_load_image_eligibility; + bool lazy_load_image_enabled; }; class HTMLMockHTMLResourcePreloader : public ResourcePreloader { @@ -191,11 +191,10 @@ } } - void LazyLoadImageEligibilityVerification( - PreloadRequest::LazyLoadImageEligibility expected_eligibility) { + void LazyLoadImageEnabledVerification(bool expected_enabled) { ASSERT_TRUE(preload_request_.get()); - EXPECT_EQ(expected_eligibility, - preload_request_->GetLazyLoadImageEligibilityForTesting()); + EXPECT_EQ(expected_enabled, + preload_request_->IsLazyLoadImageEnabledForTesting()); } protected: @@ -374,8 +373,8 @@ PreloadRequestStream requests = scanner_->Scan(base_url, nullptr, seen_csp_meta_tag_); preloader.TakeAndPreload(requests); - preloader.LazyLoadImageEligibilityVerification( - test_case.lazy_load_image_eligibility); + preloader.LazyLoadImageEnabledVerification( + test_case.lazy_load_image_enabled); } private: @@ -1212,54 +1211,142 @@ Test(test_case); } -TEST_F(HTMLPreloadScannerTest, LazyLoadImageDisabledForSmallImages) { +TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisabledForSmallImages) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + ScopedAutomaticLazyImageLoadingForTest + scoped_automatic_lazy_image_loading_for_test(true); + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { - {"<img src='foo.jpg'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' height='1px' width='1px'>", - PreloadRequest::LazyLoadImageEligibility::kDisabled}, - {"<img src='foo.jpg' style='height: 1px; width: 1px'>", - PreloadRequest::LazyLoadImageEligibility::kDisabled}, - {"<img src='foo.jpg' height='10px' width='10px'>", - PreloadRequest::LazyLoadImageEligibility::kDisabled}, - {"<img src='foo.jpg' style='height: 10px; width: 10px'>", - PreloadRequest::LazyLoadImageEligibility::kDisabled}, - {"<img src='foo.jpg' height='20px' width='20px'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' style='height: 20px; width: 20px'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' height='1px'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' style='height: 1px;'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' width='1px'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' style='width: 1px;'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, + {"<img src='foo.jpg'>", true}, + {"<img src='foo.jpg' height='1px' width='1px'>", false}, + {"<img src='foo.jpg' style='height: 1px; width: 1px'>", false}, + {"<img src='foo.jpg' height='10px' width='10px'>", false}, + {"<img src='foo.jpg' style='height: 10px; width: 10px'>", false}, + {"<img src='foo.jpg' height='1px'>", true}, + {"<img src='foo.jpg' style='height: 1px;'>", true}, + {"<img src='foo.jpg' width='1px'>", true}, + {"<img src='foo.jpg' style='width: 1px;'>", true}, }; for (const auto& test_case : test_cases) Test(test_case); } -TEST_F(HTMLPreloadScannerTest, LazyLoadImageAttributePassed) { - ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); +TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureDisabledWithAttribute) { + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { - {"<img src='foo.jpg' loading='auto'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledAutomatic}, - {"<img src='foo.jpg' loading='lazy'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledExplicit}, - {"<img src='foo.jpg' loading='eager'>", - PreloadRequest::LazyLoadImageEligibility::kDisabled}, - // loading=lazy should override other conditions. - {"<img src='foo.jpg' style='height: 1px;' loading='lazy'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledExplicit}, - {"<img src='foo.jpg' style='height: 1px; width: 1px' loading='lazy'>", - PreloadRequest::LazyLoadImageEligibility::kEnabledExplicit}, + {"<img src='foo.jpg' loading='auto'>", false}, + {"<img src='foo.jpg' loading='lazy'>", false}, + {"<img src='foo.jpg' loading='eager'>", false}, }; for (const auto& test_case : test_cases) Test(test_case); } +TEST_F(HTMLPreloadScannerTest, + LazyLoadImage_FeatureAutomaticEnabledWithAttribute) { + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + ScopedAutomaticLazyImageLoadingForTest + scoped_automatic_lazy_image_loading_for_test(true); + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); + LazyLoadImageTestCase test_cases[] = { + {"<img src='foo.jpg' loading='auto'>", true}, + {"<img src='foo.jpg' loading='lazy'>", true}, + {"<img src='foo.jpg' loading='eager'>", false}, + // loading=lazy should override other conditions. + {"<img src='foo.jpg' style='height: 1px;' loading='lazy'>", true}, + {"<img src='foo.jpg' style='height: 1px; width: 1px' loading='lazy'>", + true}, + }; + for (const auto& test_case : test_cases) + Test(test_case); +} + +TEST_F(HTMLPreloadScannerTest, + LazyLoadImage_FeatureExplicitEnabledWithAttribute) { + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); + LazyLoadImageTestCase test_cases[] = { + {"<img src='foo.jpg' loading='auto'>", false}, + {"<img src='foo.jpg' loading='lazy'>", true}, + {"<img src='foo.jpg' loading='eager'>", false}, + }; + for (const auto& test_case : test_cases) + Test(test_case); +} + +TEST_F(HTMLPreloadScannerTest, + LazyLoadImage_FeatureAutomaticPreloadForLargeImages) { + // Large images should not be preloaded, when loading is auto or lazy. + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + ScopedAutomaticLazyImageLoadingForTest + scoped_automatic_lazy_image_loading_for_test(true); + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); + PreloadScannerTestCase test_cases[] = { + {"http://example.test", "<img src='foo.jpg' height='20px' width='20px'>", + nullptr, "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' style='height: 20px; width: 20px'>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' height='20px' width='20px' loading='lazy'>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' height='20px' width='20px' loading='auto'>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' style='height: 20px; width: 20px' loading='lazy'>", + nullptr, "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' style='height: 20px; width: 20px' loading='auto'>", + nullptr, "http://example.test/", ResourceType::kImage, 0}, + }; + for (const auto& test_case : test_cases) + Test(test_case); + + // When loading is eager, lazyload is disabled and preload happens. + LazyLoadImageTestCase test_cases_that_preload[] = { + {"<img src='foo.jpg' height='20px' width='20px' loading='eager'>", false}, + {"<img src='foo.jpg' style='height: 20px; width: 20px' loading='eager'>", + false}, + }; + for (const auto& test_case : test_cases_that_preload) + Test(test_case); +} + +TEST_F(HTMLPreloadScannerTest, + LazyLoadImage_FeatureExplicitPreloadForLargeImages) { + // Large images should not be preloaded, when loading is lazy. + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + RunSetUp(kViewportEnabled); + PreloadScannerTestCase test_cases[] = { + {"http://example.test", + "<img src='foo.jpg' height='20px' width='20px' loading='lazy'>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<img src='foo.jpg' style='height: 20px; width: 20px' loading='lazy'>", + nullptr, "http://example.test/", ResourceType::kImage, 0}, + }; + for (const auto& test_case : test_cases) + Test(test_case); + + // When loading is eager or auto, lazyload is disabled and preload happens. + LazyLoadImageTestCase test_cases_that_preload[] = { + {"<img src='foo.jpg' height='20px' width='20px' loading='eager'>", false}, + {"<img src='foo.jpg' style='height: 20px; width: 20px' loading='eager'>", + false}, + {"<img src='foo.jpg' height='20px' width='20px' loading='auto'>", false}, + {"<img src='foo.jpg' style='height: 20px; width: 20px' loading='auto'>", + false}, + }; + for (const auto& test_case : test_cases_that_preload) + Test(test_case); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc index e61101f3..8302279 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.cc +++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -108,12 +108,7 @@ if (const auto* frame = document->Loader()->GetFrame()) { if (frame->IsClientLoFiAllowed(params.GetResourceRequest())) { params.SetClientLoFiPlaceholder(); - } else if ((lazy_load_image_eligibility_ == - LazyLoadImageEligibility::kEnabledExplicit && - frame->IsExplicitLazyLoadingImageAllowed()) || - (lazy_load_image_eligibility_ == - LazyLoadImageEligibility::kEnabledAutomatic && - frame->IsAutomaticLazyLoadingImageAllowed())) { + } else if (is_lazy_load_image_enabled_) { params.SetLazyImagePlaceholder(); } }
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.h b/third_party/blink/renderer/core/html/parser/preload_request.h index 03206745..4894623 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.h +++ b/third_party/blink/renderer/core/html/parser/preload_request.h
@@ -126,16 +126,11 @@ return is_image_set_ == ResourceFetcher::kImageIsImageSet; } - enum class LazyLoadImageEligibility { - kDisabled, - kEnabledExplicit, - kEnabledAutomatic - }; - void SetLazyLoadImageEligibility(LazyLoadImageEligibility eligibility) { - lazy_load_image_eligibility_ = eligibility; + void SetIsLazyLoadImageEnabled(bool is_enabled) { + is_lazy_load_image_enabled_ = is_enabled; } - LazyLoadImageEligibility GetLazyLoadImageEligibilityForTesting() const { - return lazy_load_image_eligibility_; + bool IsLazyLoadImageEnabledForTesting() { + return is_lazy_load_image_enabled_; } private: @@ -166,7 +161,7 @@ referrer_source_(referrer_source), from_insertion_scanner_(false), is_image_set_(is_image_set), - lazy_load_image_eligibility_(LazyLoadImageEligibility::kDisabled) {} + is_lazy_load_image_enabled_(false) {} KURL CompleteURL(Document*); @@ -189,7 +184,7 @@ IntegrityMetadataSet integrity_metadata_; bool from_insertion_scanner_; ResourceFetcher::IsImageSet is_image_set_; - LazyLoadImageEligibility lazy_load_image_eligibility_; + bool is_lazy_load_image_enabled_; }; typedef Vector<std::unique_ptr<PreloadRequest>> PreloadRequestStream;
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index a903962..4ece221 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -2362,8 +2362,9 @@ LayoutTreeSnapshot layout # The post-layout inline text nodes. TextBoxSnapshot textBoxes - # Scroll offsets. + # Horizontal scroll offset. optional number scrollOffsetX + # Vertical scroll offset. optional number scrollOffsetY # Table containing nodes. @@ -2402,12 +2403,12 @@ # The url of the script (if any) that generates this node. optional RareStringData originURL - # Details of an element in the DOM tree with a LayoutObject. + # Table of details of an element in the DOM tree with a LayoutObject. type LayoutTreeSnapshot extends object properties - # The index of the related DOM node in the `domNodes` array returned by `getSnapshot`. + # Index of the corresponding node in the `NodeTreeSnapshot` array returned by `captureSnapshot`. array of integer nodeIndex - # Index into the `computedStyles` array returned by `captureSnapshot`. + # Array of indexes specifying computed style strings, filtered according to the `computedStyles` parameter passed to `captureSnapshot`. array of ArrayOfStrings styles # The absolute position bounding box. array of Rectangle bounds @@ -2416,11 +2417,11 @@ # Stacking context information. RareBooleanData stackingContexts - # Details of post layout rendered text positions. The exact layout should not be regarded as + # Table of details of the post layout rendered text positions. The exact layout should not be regarded as # stable and may change between versions. type TextBoxSnapshot extends object properties - # Intex of th elayout tree node that owns this box collection. + # Index of the layout tree node that owns this box collection. array of integer layoutIndex # The absolute position bounding box. array of Rectangle bounds
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index b9ba0d0..39f4f0a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -640,6 +640,10 @@ if (space <= 0) return false; + // Can't justify an empty string. + if (end_offset == line_info->StartOffset()) + return false; + // Construct the line text to compute spacing for. StringBuilder line_text_builder; line_text_builder.Append(StringView(line_info->ItemsData().text_content, @@ -656,6 +660,8 @@ // Compute the spacing to justify. String line_text = line_text_builder.ToString(); + DCHECK_GT(line_text.length(), 0u); + ShapeResultSpacing<String> spacing(line_text); spacing.SetExpansion(space, line_info->BaseDirection(), line_info->LineStyle().GetTextJustify());
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index da591db..0ecee4c 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -101,21 +101,45 @@ // Avoid automatically lazyloading if width and height attributes are small. // This heuristic helps avoid double fetching tracking pixels. - if (HTMLImageElement::IsDimensionSmallAndAbsoluteForLazyLoad( - html_image.FastGetAttribute(html_names::kWidthAttr)) && - HTMLImageElement::IsDimensionSmallAndAbsoluteForLazyLoad( - html_image.FastGetAttribute(html_names::kHeightAttr))) { + if (HTMLImageElement::GetAttributeLazyLoadDimensionType( + html_image.FastGetAttribute(html_names::kWidthAttr)) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall && + HTMLImageElement::GetAttributeLazyLoadDimensionType( + html_image.FastGetAttribute(html_names::kHeightAttr)) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall) { return LazyLoadImageEligibility::kDisabled; } // Avoid automatically lazyloading if width or height is specified in inline // style and is small enough. This heuristic helps avoid double fetching // tracking pixels. - if (HTMLImageElement::IsInlineStyleDimensionsSmall(html_image.InlineStyle())) + if (HTMLImageElement::GetInlineStyleDimensionsType( + html_image.InlineStyle()) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteSmall) { return LazyLoadImageEligibility::kDisabled; + } return LazyLoadImageEligibility::kEnabledAutomatic; } +// Returns true if absolute dimension is specified in the width and height +// attributes or in the inline style. +bool IsDimensionAbsoluteLarge(const HTMLImageElement& html_image) { + if (HTMLImageElement::GetAttributeLazyLoadDimensionType( + html_image.FastGetAttribute(html_names::kWidthAttr)) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall || + HTMLImageElement::GetAttributeLazyLoadDimensionType( + html_image.FastGetAttribute(html_names::kHeightAttr)) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall) { + return true; + } + if (HTMLImageElement::GetInlineStyleDimensionsType( + html_image.InlineStyle()) == + HTMLImageElement::LazyLoadDimensionType::kAbsoluteNotSmall) { + return true; + } + return false; +} + bool CheckForUnoptimizedImagePolicy(const Document& document, ImageResourceContent* new_image) { if (!new_image) @@ -538,14 +562,22 @@ const LazyLoadImageEligibility lazy_load_image_eligibility = DetermineLazyLoadImageEligibility(*frame, *html_image, params.Url()); + const auto lazy_load_image_enabled_state = + frame->GetLazyLoadImageEnabledState(); if ((lazy_load_image_eligibility == LazyLoadImageEligibility::kEnabledExplicit && - frame->IsExplicitLazyLoadingImageAllowed()) || + lazy_load_image_enabled_state != + LocalFrame::LazyLoadImageEnabledState::kDisabled) || (lazy_load_image_eligibility == LazyLoadImageEligibility::kEnabledAutomatic && - frame->IsAutomaticLazyLoadingImageAllowed())) { - params.SetLazyImagePlaceholder(); + lazy_load_image_enabled_state == + LocalFrame::LazyLoadImageEnabledState::kEnabledAutomatic)) { + if (IsDimensionAbsoluteLarge(*html_image)) { + params.SetLazyImageDeferred(); + } else { + params.SetLazyImagePlaceholder(); + } lazy_image_load_state_ = LazyImageLoadState::kDeferred; }
diff --git a/third_party/blink/renderer/core/loader/image_loader.h b/third_party/blink/renderer/core/loader/image_loader.h index 1cde362..26093ff 100644 --- a/third_party/blink/renderer/core/loader/image_loader.h +++ b/third_party/blink/renderer/core/loader/image_loader.h
@@ -143,9 +143,10 @@ // https://docs.google.com/document/d/1Ym0EOwyZJmaB5afnCVPu0SFb8EWLBj_facm2fK9kgC0/ enum class LazyImageLoadState { kNone, // LazyImages not active. - kDeferred, // Placeholder is loading/loaded. Full image load not started. - // Once the placeholder is loaded, document load event is - // unblocked, but image load event is not fired yet. + kDeferred, // Full image load not started, and image load event will not be + // fired. If image dimensions is present, document load event + // will be unblocked. Otherwise placeholder fetch will start, + // and once its done document load event is unblocked. kFullImage // Full image is loading/loaded, due to element coming near the // viewport or if a placeholder load actually fetched the full // image. image_complete_ can differentiate if the fetch is
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/third_party/blink/renderer/core/loader/private/prerender_handle.cc index bc1ccb7..dfc2381 100644 --- a/third_party/blink/renderer/core/loader/private/prerender_handle.cc +++ b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -54,7 +54,8 @@ auto* prerender = MakeGarbageCollected<Prerender>( client, url, prerender_rel_types, SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(), url, - document.OutgoingReferrer())); + document.OutgoingReferrer()), + document.GetSecurityOrigin()); PrerendererClient* prerenderer_client = PrerendererClient::From(document.GetPage());
diff --git a/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc b/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc index fb614bf4..73b6145 100644 --- a/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc +++ b/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/paint/ellipsis_box_painter.h" #include "third_party/blink/renderer/core/content_capture/content_holder.h" +#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h" #include "third_party/blink/renderer/core/layout/api/line_layout_item.h" #include "third_party/blink/renderer/core/layout/line/ellipsis_box.h" #include "third_party/blink/renderer/core/layout/line/root_inline_box.h" @@ -74,20 +75,15 @@ // TODO(npm): Check that there are non-whitespace characters. See // crbug.com/788444. context.GetPaintController().SetTextPainted(); - // We should consider using the text node as the tracking node, instead of - // the line layout item. - Node* node = ellipsis_box_.GetLineLayoutItem().GetNode(); - if (!node) - return; - if ((RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || - RuntimeEnabledFeatures::ElementTimingEnabled(&node->GetDocument()))) { + if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || + RuntimeEnabledFeatures::ElementTimingEnabled( + &LineLayoutAPIShim::LayoutObjectFrom( + ellipsis_box_.GetLineLayoutItem()) + ->GetDocument())) { if (!font.ShouldSkipDrawing() && - paint_info.phase == PaintPhase::kForeground) { - PaintTimingDetector::NotifyTextPaint( - *node->GetLayoutObject(), paint_info.context.GetPaintController() - .CurrentPaintChunkProperties()); - } + paint_info.phase == PaintPhase::kForeground) + PaintTimingDetector::NotifyTextPaint(ellipsis_box_.VisualRect()); } }
diff --git a/third_party/blink/renderer/core/paint/file_upload_control_painter.cc b/third_party/blink/renderer/core/paint/file_upload_control_painter.cc index e1325355..7e1e094 100644 --- a/third_party/blink/renderer/core/paint/file_upload_control_painter.cc +++ b/third_party/blink/renderer/core/paint/file_upload_control_painter.cc
@@ -81,13 +81,14 @@ if ((RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || RuntimeEnabledFeatures::ElementTimingEnabled( &layout_file_upload_control_.GetDocument()))) { - base::Optional<ScopedPaintTimingDetectorBlockPaintHook> - scoped_paint_timing_detector_block_paint_hook( - layout_file_upload_control_); if (!font.ShouldSkipDrawing()) { + ScopedPaintTimingDetectorBlockPaintHook + scoped_paint_timing_detector_block_paint_hook( + layout_file_upload_control_, + paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); PaintTimingDetector::NotifyTextPaint( - layout_file_upload_control_, paint_info.context.GetPaintController() - .CurrentPaintChunkProperties()); + layout_file_upload_control_.FragmentsVisualRectBoundingBox()); } } }
diff --git a/third_party/blink/renderer/core/paint/inline_painter.cc b/third_party/blink/renderer/core/paint/inline_painter.cc index aa37ff2f..316a720 100644 --- a/third_party/blink/renderer/core/paint/inline_painter.cc +++ b/third_party/blink/renderer/core/paint/inline_painter.cc
@@ -35,8 +35,11 @@ if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || RuntimeEnabledFeatures::ElementTimingEnabled( &layout_inline_.GetDocument())) { - if (paint_info.phase == PaintPhase::kForeground) - scoped_paint_timing_detector_block_paint_hook.emplace(layout_inline_); + if (paint_info.phase == PaintPhase::kForeground) { + scoped_paint_timing_detector_block_paint_hook.emplace( + layout_inline_, paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); + } } if (layout_inline_.IsInLayoutNGInlineFormattingContext()) {
diff --git a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc index c0d4cd2..e52b149 100644 --- a/third_party/blink/renderer/core/paint/inline_text_box_painter.cc +++ b/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
@@ -435,11 +435,8 @@ RuntimeEnabledFeatures::ElementTimingEnabled( &InlineLayoutObject().GetDocument()))) { if (!font.ShouldSkipDrawing() && - paint_info.phase == PaintPhase::kForeground) { - PaintTimingDetector::NotifyTextPaint( - InlineLayoutObject(), paint_info.context.GetPaintController() - .CurrentPaintChunkProperties()); - } + paint_info.phase == PaintPhase::kForeground) + PaintTimingDetector::NotifyTextPaint(inline_text_box_.VisualRect()); } }
diff --git a/third_party/blink/renderer/core/paint/line_box_list_painter.cc b/third_party/blink/renderer/core/paint/line_box_list_painter.cc index 1cb080a3..fc0b419 100644 --- a/third_party/blink/renderer/core/paint/line_box_list_painter.cc +++ b/third_party/blink/renderer/core/paint/line_box_list_painter.cc
@@ -67,8 +67,11 @@ if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || RuntimeEnabledFeatures::ElementTimingEnabled( &layout_object.GetDocument())) { - if (paint_info.phase == PaintPhase::kForeground) - scoped_paint_timing_detector_block_paint_hook.emplace(layout_object); + if (paint_info.phase == PaintPhase::kForeground) { + scoped_paint_timing_detector_block_paint_hook.emplace( + layout_object, paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); + } } // See if our root lines intersect with the dirty rect. If so, then we paint
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 664392f..8a08e1e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -720,7 +720,9 @@ if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || RuntimeEnabledFeatures::ElementTimingEnabled( &layout_block.GetDocument())) { - scoped_paint_timing_detector_block_paint_hook.emplace(layout_block); + scoped_paint_timing_detector_block_paint_hook.emplace( + layout_block, + paint_info.context.GetPaintController().CurrentPaintChunkProperties()); } const bool is_horizontal = box_fragment_.Style().IsHorizontalWritingMode();
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc index 9270910..711f7e66 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -386,8 +386,8 @@ // 2. Now paint the foreground, including text and decorations. int ascent = font_data ? font_data->GetFontMetrics().Ascent() : 0; PhysicalOffset text_origin(box_origin.left, box_origin.top + ascent); - NGTextPainter text_painter(context, font, text_fragment, text_origin, - box_rect, text_fragment.IsHorizontal()); + NGTextPainter text_painter(context, font, fragment_, text_origin, box_rect, + text_fragment.IsHorizontal()); if (style.GetTextEmphasisMark() != TextEmphasisMark::kNone) { text_painter.SetEmphasisMark(style.TextEmphasisMarkString(),
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc index 7e15476..39369dbe 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
@@ -64,15 +64,11 @@ // TODO(npm): Check that there are non-whitespace characters. See // crbug.com/788444. graphics_context_.GetPaintController().SetTextPainted(); - const LayoutObject& layout_object = *fragment_.GetLayoutObject(); - if ((RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || - RuntimeEnabledFeatures::ElementTimingEnabled( - &layout_object.GetDocument()))) { - if (!font_.ShouldSkipDrawing()) { - PaintTimingDetector::NotifyTextPaint( - layout_object, graphics_context_.GetPaintController() - .CurrentPaintChunkProperties()); - } + if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || + RuntimeEnabledFeatures::ElementTimingEnabled( + &fragment_.GetLayoutObject()->GetDocument())) { + if (!font_.ShouldSkipDrawing()) + PaintTimingDetector::NotifyTextPaint(paint_fragment_.VisualRect()); } } }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter.h b/third_party/blink/renderer/core/paint/ng/ng_text_painter.h index a98af6a..4e448d1 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_painter.h +++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/content_capture/content_holder.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h" #include "third_party/blink/renderer/core/paint/text_painter_base.h" namespace blink { @@ -25,12 +26,14 @@ public: NGTextPainter(GraphicsContext& context, const Font& font, - const NGPhysicalTextFragment& text_fragment, + const NGPaintFragment& paint_fragment, const PhysicalOffset& text_origin, const PhysicalRect& text_bounds, bool horizontal) : TextPainterBase(context, font, text_origin, text_bounds, horizontal), - fragment_(text_fragment) {} + paint_fragment_(paint_fragment), + fragment_( + To<NGPhysicalTextFragment>(paint_fragment.PhysicalFragment())) {} ~NGTextPainter() = default; void ClipDecorationsStripe(float upper, @@ -66,6 +69,7 @@ void PaintEmphasisMarkForCombinedText(); + const NGPaintFragment& paint_fragment_; const NGPhysicalTextFragment& fragment_; };
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/paint_timing_detector.cc index e6dd493..dbd1867 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -112,20 +112,6 @@ } } -// static -void PaintTimingDetector::NotifyTextPaint( - const LayoutObject& object, - const PropertyTreeState& current_paint_chunk_properties) { - LocalFrameView* frame_view = object.GetFrameView(); - if (!frame_view) - return; - PaintTimingDetector& detector = frame_view->GetPaintTimingDetector(); - if (!detector.GetTextPaintTimingDetector()) - return; - detector.GetTextPaintTimingDetector()->AggregateText( - object, current_paint_chunk_properties); -} - void PaintTimingDetector::NotifyNodeRemoved(const LayoutObject& object) { DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(object.GetNode()); if (node_id == kInvalidDOMNodeId) @@ -260,27 +246,31 @@ return FloatRect(layout_visual_rect); } +ScopedPaintTimingDetectorBlockPaintHook* + ScopedPaintTimingDetectorBlockPaintHook::top_ = nullptr; + ScopedPaintTimingDetectorBlockPaintHook:: ScopedPaintTimingDetectorBlockPaintHook( - const LayoutBoxModelObject& text_aggregating_block) - : text_aggregating_block_(text_aggregating_block), - frame_view_(text_aggregating_block_.GetFrameView()) { - DCHECK(frame_view_); - TextPaintTimingDetector* detector = - frame_view_->GetPaintTimingDetector().GetTextPaintTimingDetector(); - if (!detector) - return; - detector->WillWalkTextAggregatingNode(); -} + const LayoutBoxModelObject& aggregator, + const PropertyTreeState& property_tree_state) + : aggregator_(aggregator), + property_tree_state_(property_tree_state), + // This sets |top_| to |this|, and will restore |top_| to the previous + // value when this object destructs. + reset_top_(&top_, this), + detector_(aggregator.GetFrameView() + ->GetPaintTimingDetector() + .GetTextPaintTimingDetector()), + is_recording_(detector_ && detector_->ShouldWalkObject(aggregator)) {} ScopedPaintTimingDetectorBlockPaintHook:: ~ScopedPaintTimingDetectorBlockPaintHook() { - DCHECK(frame_view_); - TextPaintTimingDetector* detector = - frame_view_->GetPaintTimingDetector().GetTextPaintTimingDetector(); - if (!detector) + DCHECK_EQ(top_, this); + if (!is_recording_ || aggregated_visual_rect_.IsEmpty()) return; - detector->DidWalkTextAggregatingNode(text_aggregating_block_); + + detector_->RecordAggregatedText(aggregator_, aggregated_visual_rect_, + property_tree_state_); } void PaintTimingDetector::Trace(Visitor* visitor) { @@ -288,4 +278,5 @@ visitor->Trace(image_paint_timing_detector_); visitor->Trace(frame_view_); } + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_timing_detector.h b/third_party/blink/renderer/core/paint/paint_timing_detector.h index e7dd1120..7c8f152 100644 --- a/third_party/blink/renderer/core/paint/paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -46,8 +46,8 @@ const IntSize& intrinsic_size, const ImageResourceContent* cached_image, const PropertyTreeState& current_paint_chunk_properties); + inline static void NotifyTextPaint(const IntRect&); - static void NotifyTextPaint(const LayoutObject&, const PropertyTreeState&); void NotifyNodeRemoved(const LayoutObject&); void NotifyBackgroundImageRemoved(const LayoutObject&, const ImageResourceContent*); @@ -107,21 +107,39 @@ // is their descendant. The hook should be placed right before visiting the // subtree of an container node, so that the constructor and the destructor can // tell the start and end of the visit. +// TODO(crbug.com/960946): we should document the text aggregation. class ScopedPaintTimingDetectorBlockPaintHook { STACK_ALLOCATED(); public: - ScopedPaintTimingDetectorBlockPaintHook(const LayoutBoxModelObject&); + ScopedPaintTimingDetectorBlockPaintHook(const LayoutBoxModelObject&, + const PropertyTreeState&); ~ScopedPaintTimingDetectorBlockPaintHook(); private: - const LayoutBoxModelObject& text_aggregating_block_; - Member<LocalFrameView> frame_view_; + friend class PaintTimingDetector; + + const LayoutBoxModelObject& aggregator_; + const PropertyTreeState& property_tree_state_; + IntRect aggregated_visual_rect_; + base::AutoReset<ScopedPaintTimingDetectorBlockPaintHook*> reset_top_; + Member<TextPaintTimingDetector> detector_; + bool is_recording_; + static ScopedPaintTimingDetectorBlockPaintHook* top_; DISALLOW_COPY_AND_ASSIGN(ScopedPaintTimingDetectorBlockPaintHook); }; +// static +inline void PaintTimingDetector::NotifyTextPaint( + const IntRect& text_visual_rect) { + auto* top = ScopedPaintTimingDetectorBlockPaintHook::top_; + DCHECK(top); + if (top->is_recording_) + top->aggregated_visual_rect_.Unite(text_visual_rect); +} + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_TIMING_DETECTOR_H_
diff --git a/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc b/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc index 51d0dd6..03ec29b 100644 --- a/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
@@ -470,13 +470,12 @@ // TODO(npm): Check that there are non-whitespace characters. See // crbug.com/788444. context.GetPaintController().SetTextPainted(); - if ((RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || - RuntimeEnabledFeatures::ElementTimingEnabled( - &InlineLayoutObject().GetDocument()))) { + if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled() || + RuntimeEnabledFeatures::ElementTimingEnabled( + &InlineLayoutObject().GetDocument())) { if (!scaled_font.ShouldSkipDrawing()) { PaintTimingDetector::NotifyTextPaint( - InlineLayoutObject(), paint_info.context.GetPaintController() - .CurrentPaintChunkProperties()); + InlineLayoutObject().FragmentsVisualRectBoundingBox()); } } }
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc index f874ce4..cc6f96a 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -27,7 +27,6 @@ // Calculate metrics candidate every 1 second after the first text pre-paint. static constexpr TimeDelta kTimerDelay = TimeDelta::FromSeconds(1); constexpr size_t kTextNodeNumberLimit = 5000; -constexpr size_t kVisitedTextObjectsLimit = 10000; static bool LargeTextFirst(const base::WeakPtr<TextRecord>& a, const base::WeakPtr<TextRecord>& b) { @@ -165,65 +164,49 @@ awaiting_swap_promise_ = false; } -void TextPaintTimingDetector::AggregateText( - const LayoutObject& object, - const PropertyTreeState& current_paint_chunk_properties) { +bool TextPaintTimingDetector::ShouldWalkObject( + const LayoutBoxModelObject& object) const { if (!is_recording_) - return; - // Text nodes are aggregated with the lowest of either block-level block - // element or self-painting inline-level element. - DCHECK_GT(walking_block_stack_.size(), 0u); - AggregateTextToClosestBlock(object, current_paint_chunk_properties); -} - -void TextPaintTimingDetector::AggregateTextToClosestBlock( - const LayoutObject& text_object, - const PropertyTreeState& current_paint_chunk_properties) { - DCHECK_GT(walking_block_stack_.size(), 0u); - - if (visited_text_objects_.Contains(&text_object) || - visited_text_objects_.size() >= kVisitedTextObjectsLimit) - return; - - IntRect visual_rect = text_object.FragmentsVisualRectBoundingBox(); - if (visual_rect.IsEmpty()) - return; - - visited_text_objects_.insert(&text_object); - FloatRect mapped_visual_rect = - frame_view_->GetPaintTimingDetector().CalculateVisualRect( - visual_rect, current_paint_chunk_properties); - if (mapped_visual_rect.Size().Area() == 0) - return; - walking_block_stack_.back().Aggregate(mapped_visual_rect); + return false; + // TODO(crbug.com/933479): Use LayoutObject::GeneratingNode() to include + // anonymous objects' rect. + Node* node = object.GetNode(); + if (!node) + return false; + DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(node); + if (node_id == kInvalidDOMNodeId) + return true; + // This metric defines the size of a text block by its first size, so we + // should not walk the object if it has been recorded. + return !records_manager_.HasRecorded(node_id); } void TextPaintTimingDetector::RecordAggregatedText( - const LayoutObject& text_aggregating_object, - uint64_t aggregated_size) { - if (!is_recording_) - return; + const LayoutBoxModelObject& aggregator, + const IntRect& aggregated_visual_rect, + const PropertyTreeState& property_tree_state) { + DCHECK(ShouldWalkObject(aggregator)); DCHECK(!records_manager_.HasTooManyNodes()); - // TODO(crbug.com/933479): Use LayoutObject::GeneratingNode() to include - // anonymous objects' rect. - Node* node = text_aggregating_object.GetNode(); - if (!node) - return; + + Node* node = aggregator.GetNode(); + DCHECK(node); DOMNodeId node_id = DOMNodeIds::IdForNode(node); DCHECK_NE(node_id, kInvalidDOMNodeId); records_manager_.MarkNodeReattachedIfNeeded(node_id); - // This metric defines the size of a text block by its first size. So it - // early-returns if the text block has been recorded. - if (records_manager_.HasRecorded(node_id)) - return; + // The caller should check this. + DCHECK(!aggregated_visual_rect.IsEmpty()); + + FloatRect mapped_visual_rect = + frame_view_->GetPaintTimingDetector().CalculateVisualRect( + aggregated_visual_rect, property_tree_state); + uint64_t aggregated_size = mapped_visual_rect.Size().Area(); if (aggregated_size == 0) { records_manager_.RecordInvisibleNode(node_id); } else { - records_manager_.RecordVisibleNode(node_id, aggregated_size, - text_aggregating_object); + records_manager_.RecordVisibleNode(node_id, aggregated_size, aggregator); } if (records_manager_.HasTooManyNodes()) { @@ -376,15 +359,4 @@ visitor->Trace(text_element_timing_); } -void TextPaintTimingDetector::WillWalkTextAggregatingNode() { - walking_block_stack_.push_back(BlockInfo()); -} - -void TextPaintTimingDetector::DidWalkTextAggregatingNode( - const LayoutBoxModelObject& text_aggregating_block) { - uint64_t aggregated_size = walking_block_stack_.back().AggregatedTextSize(); - if (aggregated_size > 0) - RecordAggregatedText(text_aggregating_block, aggregated_size); - walking_block_stack_.pop_back(); -} } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h index eb001778..196e179 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -42,17 +42,6 @@ DISALLOW_COPY_AND_ASSIGN(TextRecord); }; -class BlockInfo { - public: - void Aggregate(FloatRect new_text_rect) { - aggregated_text_rect_.UniteIfNonZero(new_text_rect); - } - uint64_t AggregatedTextSize() { return aggregated_text_rect_.Size().Area(); } - - private: - FloatRect aggregated_text_rect_; -}; - class TextRecordsManager { DISALLOW_NEW(); using TextRecordSetComparator = bool (*)(const base::WeakPtr<TextRecord>&, @@ -146,11 +135,10 @@ public: TextPaintTimingDetector(LocalFrameView* frame_view); - // TODO(crbug.com/960946): we should document the text aggregation. - void AggregateText(const LayoutObject&, const PropertyTreeState&); - void WillWalkTextAggregatingNode(); - void DidWalkTextAggregatingNode( - const LayoutBoxModelObject& text_aggregating_block); + bool ShouldWalkObject(const LayoutBoxModelObject&) const; + void RecordAggregatedText(const LayoutBoxModelObject& aggregator, + const IntRect& aggregated_visual_rect, + const PropertyTreeState&); void OnPaintFinished(); void NotifyNodeRemoved(DOMNodeId); TextRecord* FindLargestPaintCandidate(); @@ -163,13 +151,9 @@ void Trace(blink::Visitor*); private: - void AggregateTextToClosestBlock(const LayoutObject&, - const PropertyTreeState&); void PopulateTraceValue(TracedValue&, const TextRecord& first_text_paint); void TimerFired(TimerBase*); void UpdateCandidate(); - void RecordAggregatedText(const LayoutObject& aggregating_object, - uint64_t aggregated_size); void ReportSwapTime(WebWidgetClient::SwapResult result, base::TimeTicks timestamp); @@ -189,10 +173,6 @@ bool has_records_changed_ = true; bool need_update_timing_at_frame_end_ = false; - HashSet<const LayoutObject*> visited_text_objects_; - - Vector<BlockInfo> walking_block_stack_; - TaskRunnerTimer<TextPaintTimingDetector> timer_; Member<LocalFrameView> frame_view_;
diff --git a/third_party/blink/renderer/modules/payments/can_make_payment_test.cc b/third_party/blink/renderer/modules/payments/can_make_payment_test.cc index 07946ba..6b19d75 100644 --- a/third_party/blink/renderer/modules/payments/can_make_payment_test.cc +++ b/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/modules/payments/payment_request.h" #include "third_party/blink/renderer/modules/payments/payment_test_helper.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { namespace { @@ -17,11 +18,12 @@ using payments::mojom::blink::PaymentErrorReason; using payments::mojom::blink::PaymentRequestClient; -class HasEnrolledInstrumentTest : public testing::Test { - void SetUp() override { - testing::Test::SetUp(); - RuntimeEnabledFeatures::SetPaymentRequestHasEnrolledInstrumentEnabled(true); - } +class HasEnrolledInstrumentTest + : public testing::Test, + private ScopedPaymentRequestHasEnrolledInstrumentForTest { + public: + HasEnrolledInstrumentTest() + : ScopedPaymentRequestHasEnrolledInstrumentForTest(true) {} }; TEST_F(HasEnrolledInstrumentTest, RejectPromiseOnUserCancel) { @@ -123,12 +125,12 @@ class CanMakePaymentTest : public testing::Test, - public testing::WithParamInterface<HasEnrolledInstrumentEnabled> { - void SetUp() override { - testing::Test::SetUp(); - RuntimeEnabledFeatures::SetPaymentRequestHasEnrolledInstrumentEnabled( - GetParam() == HasEnrolledInstrumentEnabled::kYes); - } + public testing::WithParamInterface<HasEnrolledInstrumentEnabled>, + private ScopedPaymentRequestHasEnrolledInstrumentForTest { + public: + CanMakePaymentTest() + : ScopedPaymentRequestHasEnrolledInstrumentForTest( + GetParam() == HasEnrolledInstrumentEnabled::kYes) {} }; TEST_P(CanMakePaymentTest, RejectPromiseOnUserCancel) {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 76ed331e..5941232 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -29,6 +29,9 @@ if (webgpu_enum == "uniform-buffer") { return DAWN_BINDING_TYPE_UNIFORM_BUFFER; } + if (webgpu_enum == "dynamic-uniform-buffer") { + return DAWN_BINDING_TYPE_DYNAMIC_UNIFORM_BUFFER; + } NOTREACHED(); return DAWN_BINDING_TYPE_FORCE32; }
diff --git a/third_party/blink/renderer/platform/exported/web_prerender.cc b/third_party/blink/renderer/platform/exported/web_prerender.cc index fbe19674..36f7daee 100644 --- a/third_party/blink/renderer/platform/exported/web_prerender.cc +++ b/third_party/blink/renderer/platform/exported/web_prerender.cc
@@ -35,6 +35,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/prerender.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" namespace blink { @@ -90,6 +91,11 @@ return private_->GetReferrer(); } +url::Origin WebPrerender::SecurityOrigin() const { + auto* security_origin = private_->GetSecurityOrigin(); + return security_origin ? security_origin->ToUrlOrigin() : url::Origin(); +} + network::mojom::ReferrerPolicy WebPrerender::GetReferrerPolicy() const { return private_->GetReferrerPolicy(); }
diff --git a/third_party/blink/renderer/platform/prerender.cc b/third_party/blink/renderer/platform/prerender.cc index 610275eb..5f2e2ce8 100644 --- a/third_party/blink/renderer/platform/prerender.cc +++ b/third_party/blink/renderer/platform/prerender.cc
@@ -40,8 +40,13 @@ Prerender::Prerender(PrerenderClient* client, const KURL& url, const unsigned rel_types, - const Referrer& referrer) - : client_(client), url_(url), rel_types_(rel_types), referrer_(referrer) {} + const Referrer& referrer, + const SecurityOrigin* security_origin) + : client_(client), + url_(url), + rel_types_(rel_types), + referrer_(referrer), + security_origin_(security_origin) {} Prerender::~Prerender() = default;
diff --git a/third_party/blink/renderer/platform/prerender.h b/third_party/blink/renderer/platform/prerender.h index f5cf53f..753ee9a 100644 --- a/third_party/blink/renderer/platform/prerender.h +++ b/third_party/blink/renderer/platform/prerender.h
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/referrer.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -56,7 +57,11 @@ virtual ~ExtraData() = default; }; - Prerender(PrerenderClient*, const KURL&, unsigned rel_types, const Referrer&); + Prerender(PrerenderClient*, + const KURL&, + unsigned rel_types, + const Referrer&, + const SecurityOrigin* security_origin); ~Prerender(); void Trace(blink::Visitor*); @@ -72,6 +77,7 @@ network::mojom::ReferrerPolicy GetReferrerPolicy() const { return referrer_.referrer_policy; } + const SecurityOrigin* GetSecurityOrigin() const { return security_origin_; } void SetExtraData(scoped_refptr<ExtraData> extra_data) { extra_data_ = std::move(extra_data); @@ -93,6 +99,7 @@ const KURL url_; const unsigned rel_types_; const Referrer referrer_; + const SecurityOrigin* const security_origin_; scoped_refptr<ExtraData> extra_data_; };
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG index 5f29b19..3c9327d 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -244,7 +244,7 @@ crbug.com/591099 external/wpt/css/css-writing-modes/available-size-017.html [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/baseline-with-orthogonal-flow-001.html [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-009.xht [ Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/img-intrinsic-size-contribution-002.html [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/img-intrinsic-size-contribution-002.html [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/inline-box-border-vlr-001.html [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/line-box-direction-vrl-009.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/line-box-height-vlr-021.xht [ Pass ] @@ -263,7 +263,6 @@ crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html [ Failure ] crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html [ Failure ] crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html [ Failure ] -crbug.com/591099 external/wpt/css/filter-effects/backdrop-filter-clipped.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-writing-mode-011.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/ib-split/emptyspan-1.html [ Pass ] @@ -286,11 +285,10 @@ crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-padding-box-border-radius-002.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html [ Pass ] crbug.com/591099 external/wpt/fetch/api/request/request-keepalive-quota.html?include=slow-2 [ Pass ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] crbug.com/591099 external/wpt/html/user-activation/activation-transfer-without-click.tentative.html [ Pass ] crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-pan-x-css_touch.html [ Pass ] crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-pan-y-css_touch.html [ Pass ] -crbug.com/591099 external/wpt/portals/portal-non-http-navigation.html [ Failure Pass ] crbug.com/845902 external/wpt/quirks/line-height-trailing-collapsable-whitespace.html [ Pass ] crbug.com/591099 external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Pass ] crbug.com/591099 external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Pass ] @@ -309,7 +307,7 @@ crbug.com/591099 fast/css/outline-offset-large.html [ Failure ] crbug.com/855279 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Pass ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under.html [ Failure ] -crbug.com/591099 fast/events/before-unload-return-value-from-listener.html [ Pass Timeout ] +crbug.com/591099 fast/events/before-unload-return-value-from-listener.html [ Pass ] crbug.com/591099 fast/events/pointerevents/multi-touch-events.html [ Failure Pass ] crbug.com/591099 fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ] crbug.com/591099 fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ] @@ -335,7 +333,7 @@ crbug.com/591099 http/tests/devtools/tracing-session-id.js [ Pass ] crbug.com/591099 http/tests/devtools/tracing/console-timeline.js [ Pass ] crbug.com/591099 http/tests/media/video-load-metadata-decode-error.html [ Pass ] -crbug.com/591099 http/tests/security/inactive-document-with-empty-security-origin.html [ Pass Timeout ] +crbug.com/591099 http/tests/security/inactive-document-with-empty-security-origin.html [ Pass ] crbug.com/591099 images/feature-policy-oversized-images-resize.html [ Pass ] crbug.com/591099 media/video-object-fit-change.html [ Failure Pass ] crbug.com/591099 paint/invalidation/flexbox/scrollbars-changed.html [ Failure ] @@ -346,12 +344,13 @@ crbug.com/591099 paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ] crbug.com/591099 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ] crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Pass ] -crbug.com/591099 svg/zoom/page/zoom-svg-float-border-padding.xml [ Failure Pass ] crbug.com/591099 tables/mozilla/bugs/bug14159-1.html [ Pass ] +crbug.com/591099 virtual/android/fullscreen/api/document-exit-fullscreen-vs-request.html [ Pass ] crbug.com/591099 virtual/android/rootscroller/set-root-scroller.html [ Pass ] crbug.com/591099 virtual/android/rootscroller/set-rootscroller-before-load.html [ Pass ] crbug.com/916511 virtual/composite-after-paint/paint/background/scrolling-background-with-negative-z-child.html [ Crash ] crbug.com/591099 virtual/composite-after-paint/paint/invalidation/box/margin.html [ Failure Pass ] +crbug.com/591099 virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/scrollbar-button-gesture-target.html [ Failure Pass ] Bug(none) virtual/disable-blink-gen-property-trees/ [ Skip ] crbug.com/591099 virtual/exotic-color-space/ [ Skip ] crbug.com/591099 virtual/fractional_scrolling_threaded/fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Failure Pass ] @@ -368,8 +367,6 @@ crbug.com/591099 virtual/gpu/fast/canvas/canvas-filter-stroke-paint-pattern.html [ Pass ] crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/multi-touch-events.html [ Failure Pass ] -crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-in-slop-region.html [ Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
diff --git a/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash-expected.txt b/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash-expected.txt deleted file mode 100644 index 7ef22e9..0000000 --- a/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash-expected.txt +++ /dev/null
@@ -1 +0,0 @@ -PASS
diff --git a/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash.html b/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash.html deleted file mode 100644 index 4047f73..0000000 --- a/third_party/blink/web_tests/editing/pasteboard/copy-standalone-image-crash.html +++ /dev/null
@@ -1,68 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script> - -var actionitems; - -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function doClick() { - for (var i = 0; i < actionitems.length; i++) - { - var title = actionitems[i].title; - - if (!title) - break; - - title = title.replace(/_/g,''); - - if (title.match("Copy Image")) { - actionitems[i].click(); - break; - } - } - - document.body.innerHTML = "PASS"; - - testRunner.notifyDone(); -} - -function hideDiv() { - document.getElementById("DIV").style.display="none"; -} - -function doTest() { - if (!window.testRunner) { - document.body.addEventListener('mousedown', function () {setTimeout(hideDiv, 100)}, false); - return; - } - - var image = document.getElementById("IMG"); - - x = image.offsetLeft + 10; - y = image.offsetTop + 10; - - eventSender.mouseMoveTo(x, y); - actionitems = eventSender.contextClick(); - - hideDiv(); - - setTimeout(doClick, 10); -} - -</script> -</head> -<body onload="doTest()"> -This is an automated test case for bug <a href="https://bugs.webkit.org/show_bug.cgi?id=31721">31721</a><br> -If you wish to test manually, mouseover to image, activate context menu, wait for the image to disappear and then click copy image.<br> -There should be no crash. -<div ID="DIV"> - <img id="IMG" src="resources/apple.gif"/> - </div> -</body> - -</html>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 6b82a4a..a1c6d3f 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -42379,6 +42379,18 @@ {} ] ], + "css/css-flexbox/flex-item-and-percentage-abspos.html": [ + [ + "css/css-flexbox/flex-item-and-percentage-abspos.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/flex-items-flexibility.html": [ [ "css/css-flexbox/flex-items-flexibility.html", @@ -85233,6 +85245,18 @@ {} ] ], + "css/css-ui/outline-022.html": [ + [ + "css/css-ui/outline-022.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "css/css-ui/outline-color-001.html": [ [ "css/css-ui/outline-color-001.html", @@ -114651,6 +114675,18 @@ {} ] ], + "svg/extensibility/foreignObject/composited-inside-object.html": [ + [ + "svg/extensibility/foreignObject/composited-inside-object.html", + [ + [ + "/svg/extensibility/foreignObject/composited-inside-object-ref.html", + "==" + ] + ], + {} + ] + ], "svg/extensibility/foreignObject/compositing-backface-visibility.html": [ [ "svg/extensibility/foreignObject/compositing-backface-visibility.html", @@ -177434,6 +177470,11 @@ {} ] ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-expected.txt": [ + [ + {} + ] + ], "html/editing/editing-0/spelling-and-grammar-checking/OWNERS": [ [ {} @@ -182839,11 +182880,6 @@ {} ] ], - "imagebitmap-renderingcontext/context-creation-with-alpha-expected.txt": [ - [ - {} - ] - ], "images/META.yml": [ [ {} @@ -187659,6 +187695,11 @@ {} ] ], + "portals/portals-referrer-inherit-header.html.headers": [ + [ + {} + ] + ], "portals/references/portals-rendering.html": [ [ {} @@ -196144,6 +196185,11 @@ {} ] ], + "svg/extensibility/foreignObject/composited-inside-object-ref.html": [ + [ + {} + ] + ], "svg/extensibility/foreignObject/compositing-backface-visibility-ref.html": [ [ {} @@ -240916,6 +240962,24 @@ {} ] ], + "css/css-transforms/parsing/backface-visibility-computed.html": [ + [ + "css/css-transforms/parsing/backface-visibility-computed.html", + {} + ] + ], + "css/css-transforms/parsing/backface-visibility-invalid.html": [ + [ + "css/css-transforms/parsing/backface-visibility-invalid.html", + {} + ] + ], + "css/css-transforms/parsing/backface-visibility-valid.html": [ + [ + "css/css-transforms/parsing/backface-visibility-valid.html", + {} + ] + ], "css/css-transforms/parsing/perspective-origin-parsing-invalid.html": [ [ "css/css-transforms/parsing/perspective-origin-parsing-invalid.html", @@ -249653,6 +249717,12 @@ {} ] ], + "editing/other/non-html-document.html": [ + [ + "editing/other/non-html-document.html", + {} + ] + ], "editing/other/restoration.html": [ [ "editing/other/restoration.html", @@ -267558,6 +267628,18 @@ {} ] ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg": [ + [ + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg", + {} + ] + ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml": [ + [ + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml", + {} + ] + ], "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html": [ [ "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html", @@ -278655,6 +278737,18 @@ {} ] ], + "imagebitmap-renderingcontext/context-creation-offscreen-with-alpha.html": [ + [ + "imagebitmap-renderingcontext/context-creation-offscreen-with-alpha.html", + {} + ] + ], + "imagebitmap-renderingcontext/context-creation-offscreen.html": [ + [ + "imagebitmap-renderingcontext/context-creation-offscreen.html", + {} + ] + ], "imagebitmap-renderingcontext/context-creation-with-alpha.html": [ [ "imagebitmap-renderingcontext/context-creation-with-alpha.html", @@ -278673,6 +278767,30 @@ {} ] ], + "imagebitmap-renderingcontext/toBlob-origin-clean-offscreen.sub.html": [ + [ + "imagebitmap-renderingcontext/toBlob-origin-clean-offscreen.sub.html", + {} + ] + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-ToBlob-offscreen.html": [ + [ + "imagebitmap-renderingcontext/tranferFromImageBitmap-ToBlob-offscreen.html", + {} + ] + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-TransferToImageBitmap-offscreen.html": [ + [ + "imagebitmap-renderingcontext/tranferFromImageBitmap-TransferToImageBitmap-offscreen.html", + {} + ] + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-null-offscreen.html": [ + [ + "imagebitmap-renderingcontext/tranferFromImageBitmap-null-offscreen.html", + {} + ] + ], "imagebitmap-renderingcontext/tranferFromImageBitmap-null.html": [ [ "imagebitmap-renderingcontext/tranferFromImageBitmap-null.html", @@ -296031,12 +296149,6 @@ {} ] ], - "portals/portals-no-referrer.html": [ - [ - "portals/portals-no-referrer.html", - {} - ] - ], "portals/portals-post-message.sub.html": [ [ "portals/portals-post-message.sub.html", @@ -296046,6 +296158,24 @@ } ] ], + "portals/portals-referrer-inherit-header.html": [ + [ + "portals/portals-referrer-inherit-header.html", + {} + ] + ], + "portals/portals-referrer-inherit-meta.html": [ + [ + "portals/portals-referrer-inherit-meta.html", + {} + ] + ], + "portals/portals-referrer.html": [ + [ + "portals/portals-referrer.html", + {} + ] + ], "preload/avoid-delaying-onload-link-preload.html": [ [ "preload/avoid-delaying-onload-link-preload.html", @@ -379528,6 +379658,10 @@ "04a3041ed5c5f9382d89d572fceaeb249b4e69f1", "reftest" ], + "css/css-flexbox/flex-item-and-percentage-abspos.html": [ + "76bdff21b8658a34f10e3784951372ad3eb3a879", + "reftest" + ], "css/css-flexbox/flex-items-flexibility.html": [ "0f7cbe725284cef1dcfcaab6992c5971958c1f31", "reftest" @@ -410864,6 +410998,18 @@ "6c368b3c1bd0a5d5afcd57a5da505178b4ba1a66", "reftest" ], + "css/css-transforms/parsing/backface-visibility-computed.html": [ + "281186ae985ec80e20d2a1f61a9f0642573d4cfe", + "testharness" + ], + "css/css-transforms/parsing/backface-visibility-invalid.html": [ + "c6c563124a92f2b4b2a318e64b4969281b4a88a1", + "testharness" + ], + "css/css-transforms/parsing/backface-visibility-valid.html": [ + "eb7431078c42e08dbfe07e6de2e154ba9ecb2297", + "testharness" + ], "css/css-transforms/parsing/perspective-origin-parsing-invalid.html": [ "2ed6721e091702a436217086eebd81172f359339", "testharness" @@ -418808,6 +418954,10 @@ "02e96ea9a67de331cdaf8962155ec4c0e02217b5", "reftest" ], + "css/css-ui/outline-022.html": [ + "84cb516459471a1556e9f2b39d2f4190cfa3f02b", + "reftest" + ], "css/css-ui/outline-color-001.html": [ "4245b2ceb7393a73850a223e498987e0e1bc4aa3", "reftest" @@ -440364,6 +440514,10 @@ "2cd1232d00b8bdcf3a48ba01b3f2cfd05e27f094", "testharness" ], + "editing/other/non-html-document.html": [ + "5c4786e2fc1645f0b0c2f47a68736e55920cb610", + "testharness" + ], "editing/other/restoration-expected.txt": [ "a8d74b3eb1e0a59f0c5b5989c60349720487a00b", "support" @@ -451593,7 +451747,7 @@ "support" ], "html/dom/interfaces.worker-expected.txt": [ - "c2e30c2ea7e56bf6e4864ca4bb552e331e16ea48", + "74aec360f4de29a59765273e7dbfc517889fe3d2", "support" ], "html/dom/interfaces.worker.js": [ @@ -455148,8 +455302,20 @@ "8b7c4b838c26b55b2bf21bf23d6d08634399f63a", "support" ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-expected.txt": [ + "dc65bb6f7616c13751ea6578e794ae49700a4f6c", + "support" + ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg": [ + "6fb8a054481386dbaa160f0cab575b0bff0ccdb2", + "testharness" + ], + "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml": [ + "ea02ecdfd39e974877ddc4bd85ac0704ef560304", + "testharness" + ], "html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html": [ - "f73ea73260e3c7250fac5af172d894c81be3d165", + "79d2dc8ba0d0bb2bab5dc2e3fd46f25a7635877e", "testharness" ], "html/editing/editing-0/spelling-and-grammar-checking/OWNERS": [ @@ -467344,12 +467510,16 @@ "21c5ea48ad4cadff96c401972594083958f447f3", "testharness" ], - "imagebitmap-renderingcontext/context-creation-with-alpha-expected.txt": [ - "f4a8ae2398153c9cb61dcc17e9ada6959624c221", - "support" + "imagebitmap-renderingcontext/context-creation-offscreen-with-alpha.html": [ + "b565def964d0eb422702bc73054b6c4dfa0a3cb3", + "testharness" + ], + "imagebitmap-renderingcontext/context-creation-offscreen.html": [ + "41cc6dc02a239cf26ea37bbdca1a252f19917ee7", + "testharness" ], "imagebitmap-renderingcontext/context-creation-with-alpha.html": [ - "4354b9ac4188cd904f7e941001e724f78b0bde54", + "2c8fa08b9d340c9c0f1cb446a7a445fdc08cfff0", "testharness" ], "imagebitmap-renderingcontext/context-creation.html": [ @@ -467360,8 +467530,24 @@ "eca7afe9ddd18f23e14f9cb2b16208713af7974b", "testharness" ], + "imagebitmap-renderingcontext/toBlob-origin-clean-offscreen.sub.html": [ + "0a0e203249f13f45198cbc05316b81694377d588", + "testharness" + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-ToBlob-offscreen.html": [ + "6a555fe25aad6b823a87282472345acb7d9dbf78", + "testharness" + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-TransferToImageBitmap-offscreen.html": [ + "9f9c3395733a8a39de61ce8a616c3871e20e7e4f", + "testharness" + ], + "imagebitmap-renderingcontext/tranferFromImageBitmap-null-offscreen.html": [ + "e05a623a2fe1d1e290391ca4688285b14b9537b5", + "testharness" + ], "imagebitmap-renderingcontext/tranferFromImageBitmap-null.html": [ - "c12a8c93fdb0f83c371982958838b8fa29c4f91d", + "19d2f17ed3aff43da03836b8a62272e20bf12e55", "testharness" ], "imagebitmap-renderingcontext/transferFromImageBitmap-detached.html": [ @@ -468549,7 +468735,7 @@ "support" ], "interfaces/html.idl": [ - "5ae46f742922f4c455380745f124769399086eb9", + "b36c301428914e6b167e89fdf874c29a5fc8ea0e", "support" ], "interfaces/image-capture.idl": [ @@ -482652,14 +482838,26 @@ "9d8d09be9b104b7fa0c58f58c5b19d641db6c0eb", "testharness" ], - "portals/portals-no-referrer.html": [ - "1bd68a1c4a21ed3d2db559f7d7c62c187215e40c", - "testharness" - ], "portals/portals-post-message.sub.html": [ "b37e8afa6db05218d8e128ce1bc352ed1f892273", "testharness" ], + "portals/portals-referrer-inherit-header.html": [ + "0207474f37dea658ed9edb4352bd4e0719465558", + "testharness" + ], + "portals/portals-referrer-inherit-header.html.headers": [ + "7ffbf17d6be5a59e5b3636adc0eb14f3e2e528c2", + "support" + ], + "portals/portals-referrer-inherit-meta.html": [ + "cf0493fb6224233396f6169b59641c866096a82d", + "testharness" + ], + "portals/portals-referrer.html": [ + "cb08f56def7dfecaf3f5ed83cd668ed7f3ab663a", + "testharness" + ], "portals/portals-rendering.html": [ "0eae0ddfd6ef1e9de2251f50914a855f4142b9d5", "reftest" @@ -499332,8 +499530,16 @@ "120941444a4898197d6b6001f9908a6cd48b62ba", "support" ], + "svg/extensibility/foreignObject/composited-inside-object-ref.html": [ + "079662bc745689e576fca029074fd8cfee987664", + "support" + ], + "svg/extensibility/foreignObject/composited-inside-object.html": [ + "caa613bb46d35aeb72b18866c67c08b4e41b926d", + "reftest" + ], "svg/extensibility/foreignObject/compositing-backface-visibility-ref.html": [ - "b0f504974a552545053a1a5d7c1e55eefa527fdb", + "790e90c635042a21626bd885fe8b773312b8bfab", "support" ], "svg/extensibility/foreignObject/compositing-backface-visibility.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-empty-inline.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-empty-inline.html new file mode 100644 index 0000000..07dcb3b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-empty-inline.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>Tests justification of empty inline element</title> +<link rel="author" title="Emil A Eklund" href="eae@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-align-last-property" title="6.3. Last Line Alignment: the text-align-last property"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + #justify { + text-align-last: justify; + margin-bottom: 5px; + } + #justify > span, #reference > span { + padding: 1px; + background: black; + } +</style> +<body> + <div id="justify"><span></span></div> + <div id="reference"><span></span></div> + <p> + The two black line segments above should align. + </p> +</body> +<script> +test(function() { + const justify_element = document.getElementById('justify'); + const justify_rect = justify_element.firstElementChild.getBoundingClientRect(); + const ref_element = document.getElementById('reference'); + const ref_rect = ref_element.firstElementChild.getBoundingClientRect(); + assert_equals(justify_rect.left, ref_rect.left); + assert_equals(justify_rect.right, ref_rect.right); +}, 'Left and right edges of empty inlines should align.'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-computed.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-computed.html new file mode 100644 index 0000000..281186ae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-computed.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transform Module Level 2: getComputedValue().backfaceVisibility</title> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#backface-visibility-property"> +<meta name="assert" content="backface-visibility computed value is as specified."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<script> +test_computed_value("backface-visibility", "visible"); +test_computed_value("backface-visibility", "hidden"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-invalid.html new file mode 100644 index 0000000..c6c5631 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-invalid.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transform Module Level 2: parsing backface-visibility with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#backface-visibility-property"> +<meta name="assert" content="backface-visibility supports only the grammar 'visible | hidden'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("backface-visibility", "auto"); +test_invalid_value("backface-visibility", "visible hidden"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-valid.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-valid.html new file mode 100644 index 0000000..eb74310 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/backface-visibility-valid.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transform Module Level 2: parsing backface-visibility with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#backface-visibility-property"> +<meta name="assert" content="backface-visibility supports the full grammar 'visible | hidden'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("backface-visibility", "visible"); +test_valid_value("backface-visibility", "hidden"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/non-html-document.html b/third_party/blink/web_tests/external/wpt/editing/other/non-html-document.html new file mode 100644 index 0000000..5c4786e2f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/editing/other/non-html-document.html
@@ -0,0 +1,24 @@ +<!doctype html> +<meta charset=utf-8> +<title>Non-HTML document tests</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + +test(function() { + let xmldoc = + document.implementation.createDocument("http://www.w3.org/1999/xlink", + "html", null); + for (let f of [ + () => xmldoc.execCommand("bold"), + () => xmldoc.queryCommandEnabled("bold"), + () => xmldoc.queryCommandIndeterm("bold"), + () => xmldoc.queryCommandState("bold"), + () => xmldoc.queryCommandSupported("bold"), + () => xmldoc.queryCommandValue("bold"), + ]) { + assert_throws("InvalidStateError", f); + } +}, "editing APIs on an XML document should be disabled"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-expected.txt b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-expected.txt new file mode 100644 index 0000000..dc65bb6f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS initial designMode attribute +FAIL set designMode = "on" assert_true: expected true got false +PASS set designMode = "off" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg new file mode 100644 index 0000000..6fb8a054 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-svg.svg
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<svg:svg xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/1999/xhtml" + width="100%" height="100%" viewBox="0 0 800 600"> + <svg:title>Editing: designMode attribute test</svg:title> + <head> + <link rel="author" title="Baidu" href="mailto: guopengcheng@baidu.com"/> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#making-entire-documents-editable:-the-designmode-idl-attribute"/> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <div id="log"></div> + </head> + <body> + <script type="text/javascript"><![CDATA[ + test(function() { + assert_equals(document.designMode, "off", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "initial designMode attribute"); + document.designMode="on"; + test(function() { + assert_equals(document.designMode, "on", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "set designMode = \"on\""); + document.designMode="off"; + test(function() { + assert_equals(document.designMode,"off", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "set designMode = \"off\""); + ]]></script> + </body> +</svg:svg>
diff --git a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml new file mode 100644 index 0000000..ea02ecd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode-xml.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Editing: designMode attribute test</title> + <link rel="author" title="Baidu" href="mailto: guopengcheng@baidu.com"/> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#making-entire-documents-editable:-the-designmode-idl-attribute"/> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <div id="log"></div> + </head> + <body> + <script type="text/javascript"><![CDATA[ + test(function() { + assert_equals(document.designMode, "off", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "initial designMode attribute"); + document.designMode="on"; + test(function() { + assert_equals(document.designMode, "on", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "set designMode = \"on\""); + document.designMode="off"; + test(function() { + assert_equals(document.designMode,"off", "check for designMode value"); + assert_throws("InvalidStateError", function() { document.queryCommandSupported("delete") }); + assert_throws("InvalidStateError", function() { document.queryCommandEnabled("delete") }); + }, "set designMode = \"off\""); + ]]></script> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html index f73ea732..79d2dc8 100644 --- a/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html +++ b/third_party/blink/web_tests/external/wpt/html/editing/editing-0/making-entire-documents-editable-the-designmode-idl-attribute/user-interaction-editing-designMode.html
@@ -12,14 +12,20 @@ <script type="text/javascript"> test(function() { assert_equals(document.designMode, "off", "check for designMode value"); + assert_true(document.queryCommandSupported("delete")); + assert_false(document.queryCommandEnabled("delete")); }, "initial designMode attribute"); document.designMode="on"; test(function() { assert_equals(document.designMode, "on", "check for designMode value"); + assert_true(document.queryCommandSupported("delete")); + assert_true(document.queryCommandEnabled("delete")); }, "set designMode = \"on\""); document.designMode="off"; test(function() { assert_equals(document.designMode,"off", "check for designMode value"); + assert_true(document.queryCommandSupported("delete")); + assert_false(document.queryCommandEnabled("delete")); }, "set designMode = \"off\""); </script> </body>
diff --git a/third_party/libusb/BUILD.gn b/third_party/libusb/BUILD.gn index 4e0e07f..5bb0b03 100644 --- a/third_party/libusb/BUILD.gn +++ b/third_party/libusb/BUILD.gn
@@ -11,6 +11,18 @@ include_dirs = [ "src/libusb" ] } +config("libusb_linker_config") { + if (is_win) { + ldflags = [ + "/DELAYLOAD:advapi32.dll", + "/DELAYLOAD:cfgmgr32.dll", + "/DELAYLOAD:ole32.dll", + "/DELAYLOAD:setupapi.dll", + "/DELAYLOAD:winusb.dll", + ] + } +} + config("libusb_warnings") { visibility = [ ":*" ] if (is_clang) { @@ -71,6 +83,7 @@ ] public_configs = [ ":libusb_config" ] + all_dependent_configs = [ ":libusb_linker_config" ] if (is_posix) { defines = [ @@ -137,7 +150,12 @@ "src/libusb/os/poll_posix.c", "src/libusb/os/threads_posix.c", ] - libs = [ "setupapi.lib" ] + libs = [ + "advapi32.lib", + "ole32.lib", + "setupapi.lib", + "winusb.lib", + ] } else { include_dirs += [ "src" ] sources -= [
diff --git a/third_party/libusb/src/libusb/os/windows_common.h b/third_party/libusb/src/libusb/os/windows_common.h index 1da72bd9..1ca688c 100644 --- a/third_party/libusb/src/libusb/os/windows_common.h +++ b/third_party/libusb/src/libusb/os/windows_common.h
@@ -61,48 +61,3 @@ #define ERR_BUFFER_SIZE 256 #define TIMER_REQUEST_RETRY_MS 100 #define MAX_TIMER_SEMAPHORES 128 - - -/* - * API macros - from libusb-win32 1.x - */ -#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \ - typedef ret (api * __dll_##name##_t)args; \ - static __dll_##name##_t prefixname = NULL - -#ifndef _WIN32_WCE -#define DLL_STRINGIFY(dll) #dll -#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll)) -#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll)) -#else -#define DLL_STRINGIFY(dll) L#dll -#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll)) -#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll)) -#endif - -#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \ - do { \ - HMODULE h = DLL_GET_MODULE_HANDLE(dll); \ - if (!h) \ - h = DLL_LOAD_LIBRARY(dll); \ - if (!h) { \ - if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \ - else { break; } \ - } \ - prefixname = (__dll_##name##_t)GetProcAddress(h, \ - DLL_STRINGIFY(name)); \ - if (prefixname) break; \ - prefixname = (__dll_##name##_t)GetProcAddress(h, \ - DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \ - if (prefixname) break; \ - prefixname = (__dll_##name##_t)GetProcAddress(h, \ - DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \ - if (prefixname) break; \ - if(ret_on_failure) \ - return LIBUSB_ERROR_NOT_FOUND; \ - } while(0) - -#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args) -#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure) -#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args) -#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
diff --git a/third_party/libusb/src/libusb/os/windows_usb.c b/third_party/libusb/src/libusb/os/windows_usb.c index 9caab76..481bfd3 100644 --- a/third_party/libusb/src/libusb/os/windows_usb.c +++ b/third_party/libusb/src/libusb/os/windows_usb.c
@@ -22,9 +22,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define INITGUID #include <config.h> #include <windows.h> +#include <cfgmgr32.h> #include <setupapi.h> +#include <usbioctl.h> +#include <winusb.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> @@ -99,9 +103,6 @@ HANDLE timer_request[2] = { NULL, NULL }; HANDLE timer_response = NULL; // API globals -#define CHECK_WINUSBX_AVAILABLE(sub_api) do { if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; \ - if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0) -static struct winusb_interface WinUSBX[SUB_API_MAX]; const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES; static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) { @@ -206,30 +207,6 @@ } /* - * Cfgmgr32, OLE32 and SetupAPI DLL functions - */ -static int init_dlls(void) -{ - DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE); - DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE); - DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE); - DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE); - // Prefixed to avoid conflict with header files - DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE); - DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE); - DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE); - DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE); - return LIBUSB_SUCCESS; -} - -/* * enumerate interfaces for the whole USB class * * Parameters: @@ -246,19 +223,19 @@ HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index) { if (_index <= 0) { - *dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); + *dev_info = SetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); if (*dev_info == INVALID_HANDLE_VALUE) { return false; } } dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); - if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { usbi_err(ctx, "Could not obtain device info data for index %u: %s", _index, windows_error_str(0)); } - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return false; } @@ -286,35 +263,35 @@ DWORD size; if (_index <= 0) { - *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); + *dev_info = SetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); } if (dev_info_data != NULL) { dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); - if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { usbi_err(ctx, "Could not obtain device info data for index %u: %s", _index, windows_error_str(0)); } - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL; } } dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { + if (!SetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { usbi_err(ctx, "Could not obtain interface data for index %u: %s", _index, windows_error_str(0)); } - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL; } // Read interface data (dummy + actual) to access the device path - if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { usbi_err(ctx, "could not access interface data (dummy) for index %u: %s", @@ -332,7 +309,7 @@ } dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); - if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, + if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, &size, NULL)) { usbi_err(ctx, "could not access interface data (actual) for index %u: %s", _index, windows_error_str(0)); @@ -341,7 +318,7 @@ return dev_interface_details; err_exit: - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL; } @@ -353,32 +330,32 @@ SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; DWORD size; if (_index <= 0) { - *dev_info = pSetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); + *dev_info = SetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); } if (dev_info_data != NULL) { dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA); - if (!pSetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { + if (!SetupDiEnumDeviceInfo(*dev_info, _index, dev_info_data)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { usbi_err(ctx, "Could not obtain device info data for index %u: %s", _index, windows_error_str(0)); } - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL; } } dev_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - if (!pSetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { + if (!SetupDiEnumDeviceInterfaces(*dev_info, NULL, guid, _index, &dev_interface_data)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { usbi_err(ctx, "Could not obtain interface data for index %u: %s", _index, windows_error_str(0)); } - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL; } // Read interface data (dummy + actual) to access the device path - if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { + if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, NULL, 0, &size, NULL)) { // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { usbi_err(ctx, "could not access interface data (dummy) for index %u: %s", @@ -394,20 +371,20 @@ goto err_exit; } dev_interface_details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); - if (!pSetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, + if (!SetupDiGetDeviceInterfaceDetailA(*dev_info, &dev_interface_data, dev_interface_details, size, &size, NULL)) { usbi_err(ctx, "could not access interface data (actual) for index %u: %s", _index, windows_error_str(0)); } // [trobinso] lookup the libusb0 symbolic index. if (dev_interface_details) { - HKEY hkey_device_interface=pSetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ); + HKEY hkey_device_interface=SetupDiOpenDeviceInterfaceRegKey(*dev_info,&dev_interface_data,0,KEY_READ); if (hkey_device_interface != INVALID_HANDLE_VALUE) { DWORD libusb0_symboliclink_index=0; DWORD value_length=sizeof(DWORD); DWORD value_type=0; LONG status; - status = pRegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type, + status = RegQueryValueExW(hkey_device_interface, L"LUsb0", NULL, &value_type, (LPBYTE) &libusb0_symboliclink_index, &value_length); if (status == ERROR_SUCCESS) { if (libusb0_symboliclink_index < 256) { @@ -419,12 +396,12 @@ // libusb0.sys was connected to this device instance at one time; but not anymore. } } - pRegCloseKey(hkey_device_interface); + RegCloseKey(hkey_device_interface); } } return dev_interface_details; err_exit: - pSetupDiDestroyDeviceInfoList(*dev_info); + SetupDiDestroyDeviceInfoList(*dev_info); *dev_info = INVALID_HANDLE_VALUE; return NULL;} @@ -836,12 +813,6 @@ // Initialize pollable file descriptors init_polling(); - // Load DLL imports - if (init_dlls() != LIBUSB_SUCCESS) { - usbi_err(ctx, "could not resolve DLL functions"); - return LIBUSB_ERROR_NOT_FOUND; - } - // Initialize the low level APIs (we don't care about errors at this stage) for (i=0; i<USB_API_MAX; i++) { usb_api_backend[i].init(SUB_API_NOTSET, ctx); @@ -1194,7 +1165,7 @@ *sub_api = SUB_API_NOTSET; // Check the service & filter names to know the API we should use for (k=0; k<3; k++) { - if (pSetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop, + if (SetupDiGetDeviceRegistryPropertyA(*dev_info, dev_info_data, lookup[k].reg_prop, ®_type, (BYTE*)lookup[k].list, MAX_KEY_LENGTH, &size)) { // Turn the REG_SZ SPDRP_SERVICE into REG_MULTI_SZ if (lookup[k].reg_prop == SPDRP_SERVICE) { @@ -1399,7 +1370,7 @@ // The SPDRP_ADDRESS for USB devices is the device port number on the hub port_nr = 0; if ((pass >= HUB_PASS) && (pass <= GEN_PASS)) { - if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS, + if ( (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ADDRESS, ®_type, (BYTE*)&port_nr, 4, &size)) || (size != 4) ) { usbi_warn(ctx, "could not retrieve port number for device '%s', skipping: %s", @@ -1417,18 +1388,18 @@ case GEN_PASS: // We use the GEN pass to detect driverless devices... size = sizeof(strbuf); - if (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER, + if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_DRIVER, ®_type, (BYTE*)strbuf, size, &size)) { usbi_info(ctx, "The following device has no driver: '%s'", dev_id_path); usbi_info(ctx, "libusbx will not be able to access it."); } // ...and to add the additional device interface GUIDs - key = pSetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + key = SetupDiOpenDevRegKey(dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (key != INVALID_HANDLE_VALUE) { size = sizeof(guid_string_w); - s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type, + s = RegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, ®_type, (BYTE*)guid_string_w, &size); - pRegCloseKey(key); + RegCloseKey(key); if (s == ERROR_SUCCESS) { if (nb_guids >= MAX_ENUM_GUIDS) { // If this assert is ever reported, grow a GUID table dynamically @@ -1436,7 +1407,7 @@ LOOP_BREAK(LIBUSB_ERROR_OVERFLOW); } if_guid = (GUID*) calloc(1, sizeof(GUID)); - pCLSIDFromString(guid_string_w, if_guid); + CLSIDFromString(guid_string_w, if_guid); guid[nb_guids++] = if_guid; usbi_dbg("extra GUID: %s", guid_to_string(if_guid)); } @@ -1444,7 +1415,7 @@ break; default: // Get the API type (after checking that the driver installation is OK) - if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE, + if ( (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE, ®_type, (BYTE*)&install_state, 4, &size)) || (size != 4) ){ usbi_warn(ctx, "could not detect installation state of driver for '%s': %s", @@ -2405,79 +2376,9 @@ /* * WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions */ -#define WinUSBX_Set(fn) do { if (native_winusb) WinUSBX[i].fn = (WinUsb_##fn##_t) GetProcAddress(h, "WinUsb_" #fn); \ - else pLibK_GetProcAddress((PVOID*)&WinUSBX[i].fn, i, KUSB_FNID_##fn); } while (0) static int winusbx_init(int sub_api, struct libusb_context *ctx) { - HMODULE h = NULL; - bool native_winusb = false; - int i; - KLIB_VERSION LibK_Version; - LibK_GetProcAddress_t pLibK_GetProcAddress = NULL; - LibK_GetVersion_t pLibK_GetVersion = NULL; - - h = GetModuleHandleA("libusbK"); - if (h == NULL) { - h = LoadLibraryA("libusbK"); - } - if (h == NULL) { - usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB"); - h = GetModuleHandleA("WinUSB"); - if (h == NULL) { - h = LoadLibraryA("WinUSB"); - } if (h == NULL) { - usbi_warn(ctx, "WinUSB DLL is not available either,\n" - "you will not be able to access devices outside of enumeration"); - return LIBUSB_ERROR_NOT_FOUND; - } - } else { - usbi_dbg("using libusbK DLL for universal access"); - pLibK_GetVersion = (LibK_GetVersion_t) GetProcAddress(h, "LibK_GetVersion"); - if (pLibK_GetVersion != NULL) { - pLibK_GetVersion(&LibK_Version); - usbi_dbg("libusbK version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor, - LibK_Version.Micro, LibK_Version.Nano); - } - pLibK_GetProcAddress = (LibK_GetProcAddress_t) GetProcAddress(h, "LibK_GetProcAddress"); - if (pLibK_GetProcAddress == NULL) { - usbi_err(ctx, "LibK_GetProcAddress() not found in libusbK DLL"); - return LIBUSB_ERROR_NOT_FOUND; - } - } - native_winusb = (pLibK_GetProcAddress == NULL); - for (i=SUB_API_LIBUSBK; i<SUB_API_MAX; i++) { - WinUSBX_Set(AbortPipe); - WinUSBX_Set(ControlTransfer); - WinUSBX_Set(FlushPipe); - WinUSBX_Set(Free); - WinUSBX_Set(GetAssociatedInterface); - WinUSBX_Set(GetCurrentAlternateSetting); - WinUSBX_Set(GetDescriptor); - WinUSBX_Set(GetOverlappedResult); - WinUSBX_Set(GetPipePolicy); - WinUSBX_Set(GetPowerPolicy); - WinUSBX_Set(Initialize); - WinUSBX_Set(QueryDeviceInformation); - WinUSBX_Set(QueryInterfaceSettings); - WinUSBX_Set(QueryPipe); - WinUSBX_Set(ReadPipe); - WinUSBX_Set(ResetPipe); - WinUSBX_Set(SetCurrentAlternateSetting); - WinUSBX_Set(SetPipePolicy); - WinUSBX_Set(SetPowerPolicy); - WinUSBX_Set(WritePipe); - if (!native_winusb) { - WinUSBX_Set(ResetDevice); - } - if (WinUSBX[i].Initialize != NULL) { - WinUSBX[i].initialized = true; - usbi_dbg("initalized sub API %s", sub_api_name[i]); - } else { - usbi_warn(ctx, "Failed to initalize sub API %s", sub_api_name[i]); - WinUSBX[i].initialized = false; - } - } return LIBUSB_SUCCESS; } @@ -2498,8 +2399,6 @@ HANDLE file_handle; int i; - CHECK_WINUSBX_AVAILABLE(sub_api); - // WinUSB requires a seperate handle for each interface for (i = 0; i < USB_MAXINTERFACES; i++) { if ( (priv->usb_interface[i].path != NULL) @@ -2533,8 +2432,6 @@ if (sub_api == SUB_API_NOTSET) sub_api = priv->sub_api; - if (!WinUSBX[sub_api].initialized) - return; for (i = 0; i < USB_MAXINTERFACES; i++) { if (priv->usb_interface[i].apib->id == USB_API_WINUSBX) { @@ -2556,13 +2453,11 @@ uint8_t endpoint_address; int i; - CHECK_WINUSBX_AVAILABLE(sub_api); - // With handle and enpoints set (in parent), we can setup the default pipe properties // see http://download.microsoft.com/download/D/1/D/D1DD7745-426B-4CC3-A269-ABBBE427C0EF/DVC-T705_DDC08.pptx for (i=-1; i<priv->usb_interface[iface].nb_endpoints; i++) { endpoint_address =(i==-1)?0:priv->usb_interface[iface].endpoint[i]; - if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout)) { usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address); } @@ -2570,22 +2465,22 @@ continue; // Other policies don't apply to control endpoint or libusb0 } policy = false; - if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy)) { usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address); } - if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy)) { usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address); } policy = true; /* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See: https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */ - if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy)) { usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address); } - if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address, + if (!WinUsb_SetPipePolicy(winusb_handle, endpoint_address, AUTO_CLEAR_STALL, sizeof(UCHAR), &policy)) { usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address); } @@ -2610,8 +2505,6 @@ char filter_path[] = "\\\\.\\libusb0-0000"; bool found_filter = false; - CHECK_WINUSBX_AVAILABLE(sub_api); - // If the device is composite, but using the default Windows composite parent driver (usbccgp) // or if it's the first WinUSB-like interface, we get a handle through Initialize(). if ((is_using_usbccgp) || (iface == 0)) { @@ -2621,7 +2514,7 @@ return LIBUSB_ERROR_NOT_FOUND; } - if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + if (!WinUsb_Initialize(file_handle, &winusb_handle)) { handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; err = GetLastError(); switch(err) { @@ -2647,8 +2540,8 @@ if (file_handle == INVALID_HANDLE_VALUE) { usbi_err(ctx, "could not open device %s: %s", filter_path, windows_error_str(0)); } else { - WinUSBX[sub_api].Free(winusb_handle); - if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + WinUsb_Free(winusb_handle); + if (!WinUsb_Initialize(file_handle, &winusb_handle)) { continue; } found_filter = true; @@ -2670,7 +2563,7 @@ // must first claim the first interface before you claim the others if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) { file_handle = handle_priv->interface_handle[0].dev_handle; - if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) { + if (WinUsb_Initialize(file_handle, &winusb_handle)) { handle_priv->interface_handle[0].api_handle = winusb_handle; usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface); } else { @@ -2678,7 +2571,7 @@ return LIBUSB_ERROR_ACCESS; } } - if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1), + if (!WinUsb_GetAssociatedInterface(winusb_handle, (UCHAR)(iface-1), &handle_priv->interface_handle[iface].api_handle)) { handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; switch(GetLastError()) { @@ -2706,14 +2599,12 @@ struct windows_device_priv *priv = _device_priv(dev_handle->dev); HANDLE winusb_handle; - CHECK_WINUSBX_AVAILABLE(sub_api); - winusb_handle = handle_priv->interface_handle[iface].api_handle; if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) { return LIBUSB_ERROR_NOT_FOUND; } - WinUSBX[sub_api].Free(winusb_handle); + WinUsb_Free(winusb_handle); handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE; return LIBUSB_SUCCESS; @@ -2782,8 +2673,6 @@ int current_interface; struct winfd wfd; - CHECK_WINUSBX_AVAILABLE(sub_api); - transfer_priv->pollable_fd = INVALID_WINFD; size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; @@ -2807,9 +2696,9 @@ } // Sending of set configuration control requests from WinUSB creates issues - if ( ((setup->request_type & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD) - && (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) { - if (setup->value != priv->active_config) { + if ( ((setup->RequestType & (0x03 << 5)) == LIBUSB_REQUEST_TYPE_STANDARD) + && (setup->Request == LIBUSB_REQUEST_SET_CONFIGURATION) ) { + if (setup->Value != priv->active_config) { usbi_warn(ctx, "cannot set configuration other than the default one"); usbi_free_fd(&wfd); return LIBUSB_ERROR_INVALID_PARAM; @@ -2817,7 +2706,7 @@ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; wfd.overlapped->InternalHigh = 0; } else { - if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) { + if (!WinUsb_ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) { if(GetLastError() != ERROR_IO_PENDING) { usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0)); usbi_free_fd(&wfd); @@ -2843,8 +2732,6 @@ struct windows_device_priv *priv = _device_priv(dev_handle->dev); HANDLE winusb_handle; - CHECK_WINUSBX_AVAILABLE(sub_api); - if (altsetting > 255) { return LIBUSB_ERROR_INVALID_PARAM; } @@ -2855,7 +2742,7 @@ return LIBUSB_ERROR_NOT_FOUND; } - if (!WinUSBX[sub_api].SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) { + if (!WinUsb_SetCurrentAlternateSetting(winusb_handle, (UCHAR)altsetting)) { usbi_err(ctx, "SetCurrentAlternateSetting failed: %s", windows_error_str(0)); return LIBUSB_ERROR_IO; } @@ -2875,8 +2762,6 @@ int current_interface; struct winfd wfd; - CHECK_WINUSBX_AVAILABLE(sub_api); - transfer_priv->pollable_fd = INVALID_WINFD; current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); @@ -2897,10 +2782,10 @@ if (IS_XFERIN(transfer)) { usbi_dbg("reading %d bytes", transfer->length); - ret = WinUSBX[sub_api].ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + ret = WinUsb_ReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); } else { usbi_dbg("writing %d bytes", transfer->length); - ret = WinUSBX[sub_api].WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); + ret = WinUsb_WritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, wfd.overlapped); } if (!ret) { if(GetLastError() != ERROR_IO_PENDING) { @@ -2927,8 +2812,6 @@ HANDLE winusb_handle; int current_interface; - CHECK_WINUSBX_AVAILABLE(sub_api); - current_interface = interface_by_endpoint(priv, handle_priv, endpoint); if (current_interface < 0) { usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); @@ -2938,7 +2821,7 @@ usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface); winusb_handle = handle_priv->interface_handle[current_interface].api_handle; - if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) { + if (!WinUsb_ResetPipe(winusb_handle, endpoint)) { usbi_err(ctx, "ResetPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } @@ -2968,8 +2851,6 @@ HANDLE winusb_handle; int current_interface; - CHECK_WINUSBX_AVAILABLE(sub_api); - current_interface = transfer_priv->interface_number; if ((current_interface < 0) || (current_interface >= USB_MAXINTERFACES)) { usbi_err(ctx, "program assertion failed: invalid interface_number"); @@ -2979,7 +2860,7 @@ winusb_handle = handle_priv->interface_handle[current_interface].api_handle; - if (!WinUSBX[sub_api].AbortPipe(winusb_handle, transfer->endpoint)) { + if (!WinUsb_AbortPipe(winusb_handle, transfer->endpoint)) { usbi_err(ctx, "AbortPipe failed: %s", windows_error_str(0)); return LIBUSB_ERROR_NO_DEVICE; } @@ -3005,8 +2886,6 @@ HANDLE winusb_handle; int i, j; - CHECK_WINUSBX_AVAILABLE(sub_api); - // Reset any available pipe (except control) for (i=0; i<USB_MAXINTERFACES; i++) { winusb_handle = handle_priv->interface_handle[i].api_handle; @@ -3021,17 +2900,17 @@ if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) { for (j=0; j<priv->usb_interface[i].nb_endpoints; j++) { usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]); - if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { + if (!WinUsb_AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { usbi_err(ctx, "AbortPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } // FlushPipe seems to fail on OUT pipes if (IS_EPIN(priv->usb_interface[i].endpoint[j]) - && (!WinUSBX[sub_api].FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) { + && (!WinUsb_FlushPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) ) { usbi_err(ctx, "FlushPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } - if (!WinUSBX[sub_api].ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { + if (!WinUsb_ResetPipe(winusb_handle, priv->usb_interface[i].endpoint[j])) { usbi_err(ctx, "ResetPipe (pipe address %02X) failed: %s", priv->usb_interface[i].endpoint[j], windows_error_str(0)); } @@ -3039,13 +2918,6 @@ } } - // libusbK & libusb0 have the ability to issue an actual device reset - if (WinUSBX[sub_api].ResetDevice != NULL) { - winusb_handle = handle_priv->interface_handle[0].api_handle; - if ( (winusb_handle != 0) && (winusb_handle != INVALID_HANDLE_VALUE)) { - WinUSBX[sub_api].ResetDevice(winusb_handle); - } - } return LIBUSB_SUCCESS; }
diff --git a/third_party/libusb/src/libusb/os/windows_usb.h b/third_party/libusb/src/libusb/os/windows_usb.h index 97c8047c..e02a6dc 100644 --- a/third_party/libusb/src/libusb/os/windows_usb.h +++ b/third_party/libusb/src/libusb/os/windows_usb.h
@@ -58,18 +58,6 @@ #define LIST_SEPARATOR ';' #define HTAB_SIZE 1021 -// http://msdn.microsoft.com/en-us/library/ff545978.aspx -// http://msdn.microsoft.com/en-us/library/ff545972.aspx -// http://msdn.microsoft.com/en-us/library/ff545982.aspx -#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER) -const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} }; -#endif -#if !defined(GUID_DEVINTERFACE_USB_DEVICE) -const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} }; -#endif -#if !defined(GUID_DEVINTERFACE_USB_HUB) -const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} }; -#endif #if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER) const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} }; #endif @@ -136,7 +124,6 @@ #define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN) #define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type)) -typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; struct windows_device_priv { uint8_t depth; // distance to HCD uint8_t port; // port number on the hub @@ -229,24 +216,6 @@ const char* designation; // internal designation (for debug output) }; -/* OLE32 dependency */ -DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID)); - -/* SetupAPI dependencies */ -DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD)); -DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA)); -DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA, - const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA)); -DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, - PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA)); -DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO)); -DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM)); -DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO, - PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD)); -DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD)); -DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)); -DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY)); - /* * Windows DDK API definitions. Most of it copied from MinGW's includes */ @@ -255,27 +224,6 @@ typedef DWORD RETURN_TYPE; typedef RETURN_TYPE CONFIGRET; -#define CR_SUCCESS 0x00000000 -#define CR_NO_SUCH_DEVNODE 0x0000000D - -#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE -#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG -#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING -#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE -#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT - -#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS -#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE -#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE -#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS -#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR -#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR -#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION -#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION -#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE -#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE -#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME - #define USB_GET_NODE_INFORMATION 258 #define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260 #define USB_GET_NODE_CONNECTION_NAME 261 @@ -305,32 +253,6 @@ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) #endif -typedef enum USB_CONNECTION_STATUS { - NoDeviceConnected, - DeviceConnected, - DeviceFailedEnumeration, - DeviceGeneralFailure, - DeviceCausedOvercurrent, - DeviceNotEnoughPower, - DeviceNotEnoughBandwidth, - DeviceHubNestedTooDeeply, - DeviceInLegacyHub -} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS; - -typedef enum USB_HUB_NODE { - UsbHub, - UsbMIParent -} USB_HUB_NODE; - -/* Cfgmgr32.dll interface */ -DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG)); -DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG)); -DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG)); -DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG)); - -#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \ - CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) - #define IOCTL_USB_GET_HUB_CAPABILITIES \ CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS) @@ -355,397 +277,23 @@ // Most of the structures below need to be packed #pragma pack(push, 1) -typedef struct USB_INTERFACE_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bInterfaceNumber; - UCHAR bAlternateSetting; - UCHAR bNumEndpoints; - UCHAR bInterfaceClass; - UCHAR bInterfaceSubClass; - UCHAR bInterfaceProtocol; - UCHAR iInterface; -} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; - -typedef struct USB_CONFIGURATION_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT wTotalLength; - UCHAR bNumInterfaces; - UCHAR bConfigurationValue; - UCHAR iConfiguration; - UCHAR bmAttributes; - UCHAR MaxPower; -} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; - typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT { - struct { - ULONG ConnectionIndex; - struct { - UCHAR bmRequest; - UCHAR bRequest; - USHORT wValue; - USHORT wIndex; - USHORT wLength; - } SetupPacket; - } req; - USB_CONFIGURATION_DESCRIPTOR data; + struct { + ULONG ConnectionIndex; + struct { + UCHAR bmRequest; + UCHAR bRequest; + USHORT wValue; + USHORT wIndex; + USHORT wLength; + } SetupPacket; + } req; + USB_CONFIGURATION_DESCRIPTOR data; } USB_CONFIGURATION_DESCRIPTOR_SHORT; -typedef struct USB_ENDPOINT_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bEndpointAddress; - UCHAR bmAttributes; - USHORT wMaxPacketSize; - UCHAR bInterval; -} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; - -typedef struct USB_DESCRIPTOR_REQUEST { - ULONG ConnectionIndex; - struct { - UCHAR bmRequest; - UCHAR bRequest; - USHORT wValue; - USHORT wIndex; - USHORT wLength; - } SetupPacket; -// UCHAR Data[0]; -} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST; - -typedef struct USB_HUB_DESCRIPTOR { - UCHAR bDescriptorLength; - UCHAR bDescriptorType; - UCHAR bNumberOfPorts; - USHORT wHubCharacteristics; - UCHAR bPowerOnToPowerGood; - UCHAR bHubControlCurrent; - UCHAR bRemoveAndPowerMask[64]; -} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR; - -typedef struct USB_ROOT_HUB_NAME { - ULONG ActualLength; - WCHAR RootHubName[1]; -} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME; - typedef struct USB_ROOT_HUB_NAME_FIXED { ULONG ActualLength; WCHAR RootHubName[MAX_PATH_LENGTH]; } USB_ROOT_HUB_NAME_FIXED; -typedef struct USB_NODE_CONNECTION_NAME { - ULONG ConnectionIndex; - ULONG ActualLength; - WCHAR NodeName[1]; -} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME; - -typedef struct USB_NODE_CONNECTION_NAME_FIXED { - ULONG ConnectionIndex; - ULONG ActualLength; - WCHAR NodeName[MAX_PATH_LENGTH]; -} USB_NODE_CONNECTION_NAME_FIXED; - -typedef struct USB_HUB_NAME_FIXED { - union { - USB_ROOT_HUB_NAME_FIXED root; - USB_NODE_CONNECTION_NAME_FIXED node; - } u; -} USB_HUB_NAME_FIXED; - -typedef struct USB_HUB_INFORMATION { - USB_HUB_DESCRIPTOR HubDescriptor; - BOOLEAN HubIsBusPowered; -} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION; - -typedef struct USB_MI_PARENT_INFORMATION { - ULONG NumberOfInterfaces; -} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION; - -typedef struct USB_NODE_INFORMATION { - USB_HUB_NODE NodeType; - union { - USB_HUB_INFORMATION HubInformation; - USB_MI_PARENT_INFORMATION MiParentInformation; - } u; -} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION; - -typedef struct USB_PIPE_INFO { - USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; - ULONG ScheduleOffset; -} USB_PIPE_INFO, *PUSB_PIPE_INFO; - -typedef struct USB_NODE_CONNECTION_INFORMATION_EX { - ULONG ConnectionIndex; - USB_DEVICE_DESCRIPTOR DeviceDescriptor; - UCHAR CurrentConfigurationValue; - UCHAR Speed; - BOOLEAN DeviceIsHub; - USHORT DeviceAddress; - ULONG NumberOfOpenPipes; - USB_CONNECTION_STATUS ConnectionStatus; -// USB_PIPE_INFO PipeList[0]; -} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX; - -typedef struct USB_HUB_CAP_FLAGS { - ULONG HubIsHighSpeedCapable:1; - ULONG HubIsHighSpeed:1; - ULONG HubIsMultiTtCapable:1; - ULONG HubIsMultiTt:1; - ULONG HubIsRoot:1; - ULONG HubIsArmedWakeOnConnect:1; - ULONG ReservedMBZ:26; -} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS; - -typedef struct USB_HUB_CAPABILITIES { - ULONG HubIs2xCapable : 1; -} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES; - -typedef struct USB_HUB_CAPABILITIES_EX { - USB_HUB_CAP_FLAGS CapabilityFlags; -} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX; - #pragma pack(pop) - -/* winusb.dll interface */ - -#define SHORT_PACKET_TERMINATE 0x01 -#define AUTO_CLEAR_STALL 0x02 -#define PIPE_TRANSFER_TIMEOUT 0x03 -#define IGNORE_SHORT_PACKETS 0x04 -#define ALLOW_PARTIAL_READS 0x05 -#define AUTO_FLUSH 0x06 -#define RAW_IO 0x07 -#define MAXIMUM_TRANSFER_SIZE 0x08 -#define AUTO_SUSPEND 0x81 -#define SUSPEND_DELAY 0x83 -#define DEVICE_SPEED 0x01 -#define LowSpeed 0x01 -#define FullSpeed 0x02 -#define HighSpeed 0x03 - -typedef enum USBD_PIPE_TYPE { - UsbdPipeTypeControl, - UsbdPipeTypeIsochronous, - UsbdPipeTypeBulk, - UsbdPipeTypeInterrupt -} USBD_PIPE_TYPE; - -typedef struct { - USBD_PIPE_TYPE PipeType; - UCHAR PipeId; - USHORT MaximumPacketSize; - UCHAR Interval; -} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION; - -#pragma pack(1) -typedef struct { - UCHAR request_type; - UCHAR request; - USHORT value; - USHORT index; - USHORT length; -} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET; -#pragma pack() - -typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE; - -typedef BOOL (WINAPI *WinUsb_AbortPipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID -); -typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - WINUSB_SETUP_PACKET SetupPacket, - PUCHAR Buffer, - ULONG BufferLength, - PULONG LengthTransferred, - LPOVERLAPPED Overlapped -); -typedef BOOL (WINAPI *WinUsb_FlushPipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID -); -typedef BOOL (WINAPI *WinUsb_Free_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle -); -typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR AssociatedInterfaceIndex, - PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle -); -typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - PUCHAR AlternateSetting -); -typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR DescriptorType, - UCHAR Index, - USHORT LanguageID, - PUCHAR Buffer, - ULONG BufferLength, - PULONG LengthTransferred -); -typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpNumberOfBytesTransferred, - BOOL bWait -); -typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID, - ULONG PolicyType, - PULONG ValueLength, - PVOID Value -); -typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - ULONG PolicyType, - PULONG ValueLength, - PVOID Value -); -typedef BOOL (WINAPI *WinUsb_Initialize_t)( - HANDLE DeviceHandle, - PWINUSB_INTERFACE_HANDLE InterfaceHandle -); -typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - ULONG InformationType, - PULONG BufferLength, - PVOID Buffer -); -typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR AlternateSettingNumber, - PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor -); -typedef BOOL (WINAPI *WinUsb_QueryPipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR AlternateInterfaceNumber, - UCHAR PipeIndex, - PWINUSB_PIPE_INFORMATION PipeInformation -); -typedef BOOL (WINAPI *WinUsb_ReadPipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID, - PUCHAR Buffer, - ULONG BufferLength, - PULONG LengthTransferred, - LPOVERLAPPED Overlapped -); -typedef BOOL (WINAPI *WinUsb_ResetPipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID -); -typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR AlternateSetting -); -typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID, - ULONG PolicyType, - ULONG ValueLength, - PVOID Value -); -typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - ULONG PolicyType, - ULONG ValueLength, - PVOID Value -); -typedef BOOL (WINAPI *WinUsb_WritePipe_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle, - UCHAR PipeID, - PUCHAR Buffer, - ULONG BufferLength, - PULONG LengthTransferred, - LPOVERLAPPED Overlapped -); -typedef BOOL (WINAPI *WinUsb_ResetDevice_t)( - WINUSB_INTERFACE_HANDLE InterfaceHandle -); - -/* /!\ These must match the ones from the official libusbk.h */ -typedef enum _KUSB_FNID -{ - KUSB_FNID_Init, - KUSB_FNID_Free, - KUSB_FNID_ClaimInterface, - KUSB_FNID_ReleaseInterface, - KUSB_FNID_SetAltInterface, - KUSB_FNID_GetAltInterface, - KUSB_FNID_GetDescriptor, - KUSB_FNID_ControlTransfer, - KUSB_FNID_SetPowerPolicy, - KUSB_FNID_GetPowerPolicy, - KUSB_FNID_SetConfiguration, - KUSB_FNID_GetConfiguration, - KUSB_FNID_ResetDevice, - KUSB_FNID_Initialize, - KUSB_FNID_SelectInterface, - KUSB_FNID_GetAssociatedInterface, - KUSB_FNID_Clone, - KUSB_FNID_QueryInterfaceSettings, - KUSB_FNID_QueryDeviceInformation, - KUSB_FNID_SetCurrentAlternateSetting, - KUSB_FNID_GetCurrentAlternateSetting, - KUSB_FNID_QueryPipe, - KUSB_FNID_SetPipePolicy, - KUSB_FNID_GetPipePolicy, - KUSB_FNID_ReadPipe, - KUSB_FNID_WritePipe, - KUSB_FNID_ResetPipe, - KUSB_FNID_AbortPipe, - KUSB_FNID_FlushPipe, - KUSB_FNID_IsoReadPipe, - KUSB_FNID_IsoWritePipe, - KUSB_FNID_GetCurrentFrameNumber, - KUSB_FNID_GetOverlappedResult, - KUSB_FNID_GetProperty, - KUSB_FNID_COUNT, -} KUSB_FNID; - -typedef struct _KLIB_VERSION { - INT Major; - INT Minor; - INT Micro; - INT Nano; -} KLIB_VERSION; -typedef KLIB_VERSION* PKLIB_VERSION; - -typedef BOOL (WINAPI *LibK_GetProcAddress_t)( - PVOID* ProcAddress, - ULONG DriverID, - ULONG FunctionID -); - -typedef VOID (WINAPI *LibK_GetVersion_t)( - PKLIB_VERSION Version -); - -struct winusb_interface { - bool initialized; - WinUsb_AbortPipe_t AbortPipe; - WinUsb_ControlTransfer_t ControlTransfer; - WinUsb_FlushPipe_t FlushPipe; - WinUsb_Free_t Free; - WinUsb_GetAssociatedInterface_t GetAssociatedInterface; - WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting; - WinUsb_GetDescriptor_t GetDescriptor; - WinUsb_GetOverlappedResult_t GetOverlappedResult; - WinUsb_GetPipePolicy_t GetPipePolicy; - WinUsb_GetPowerPolicy_t GetPowerPolicy; - WinUsb_Initialize_t Initialize; - WinUsb_QueryDeviceInformation_t QueryDeviceInformation; - WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings; - WinUsb_QueryPipe_t QueryPipe; - WinUsb_ReadPipe_t ReadPipe; - WinUsb_ResetPipe_t ResetPipe; - WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting; - WinUsb_SetPipePolicy_t SetPipePolicy; - WinUsb_SetPowerPolicy_t SetPowerPolicy; - WinUsb_WritePipe_t WritePipe; - WinUsb_ResetDevice_t ResetDevice; -}; \ No newline at end of file
diff --git a/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js index 74089a2a..72abdd0 100644 --- a/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js +++ b/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js
@@ -79,6 +79,11 @@ this.debounce('show ripple', function() { this.__showRipple(e); }, 1); }, + clear: function() { + this.__hideRipple(); + this.holdDown = false; + }, + showAndHoldDown: function() { this.ripples.forEach(ripple => { ripple.remove();
diff --git a/tools/md_browser/gitiles_autolink.py b/tools/md_browser/gitiles_autolink.py index 5cfeb213..eb77ebb51 100644 --- a/tools/md_browser/gitiles_autolink.py +++ b/tools/md_browser/gitiles_autolink.py
@@ -6,14 +6,20 @@ This extention auto links basic URLs that aren't bracketed by <...>. -https://gerrit.googlesource.com/gitiles/+/master/gitiles-servlet/src/main/java/com/google/gitiles/Linkifier.java +https://gerrit.googlesource.com/gitiles/+/master/java/com/google/gitiles/Linkifier.java """ from markdown.inlinepatterns import (AutolinkPattern, Pattern) from markdown.extensions import Extension -AUTOLINK_RE = r'([Hh][Tt][Tt][Pp][Ss]?://[^>]*)' +# Best effort attempt to match URLs without matching past the end of the URL. +# The first "[]" is copied from Linkifier.java (safe, reserved, and unsafe +# characters). The second "[]" is similar to the first, but with English +# punctuation removed, since the gitiles parser treats these as punction in the +# sentence, rather than the final character of the URL. +AUTOLINK_RE = (r'(https?://[a-zA-Z0-9$_.+!*\',%;:@=?#/~<>-]+' + r'[a-zA-Z0-9$_+*\'%@=#/~<-])') class _GitilesSmartQuotesExtension(Extension):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d63be05b..71f5907 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -4434,6 +4434,7 @@ <int value="0" label="WRLHH_LOGGING_STOPPED_BAD_STATE"/> <int value="1" label="PPH_EXTRA_PREVIEW_MESSAGE"/> + <int value="2" label="PMF_INVALID_INITIATOR_ORIGIN"/> </enum> <enum name="BadMessageReasonContent">
diff --git a/tools/perf/contrib/cluster_telemetry/OWNERS b/tools/perf/contrib/cluster_telemetry/OWNERS index 36e9836..b913167 100644 --- a/tools/perf/contrib/cluster_telemetry/OWNERS +++ b/tools/perf/contrib/cluster_telemetry/OWNERS
@@ -5,6 +5,5 @@ per-file loading_ct.py=dproy@chromium.org per-file repaint*=wkorman@chromium.org per-file leak_detection_ct.py=yuzus@chromium.org -per-file memory_ct.py=nednguyen@google.com per-file memory_ct.py=erikchen@chromium.org per-file memory_ct.py=perezju@chromium.org
diff --git a/tools/perf/contrib/media_router_benchmarks/BUILD.gn b/tools/perf/contrib/media_router_benchmarks/BUILD.gn index 5d1554b..3026eb8 100644 --- a/tools/perf/contrib/media_router_benchmarks/BUILD.gn +++ b/tools/perf/contrib/media_router_benchmarks/BUILD.gn
@@ -2,12 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -copy("media_router_telemetry_extension") { +copy("telemetry_extension_resources") { sources = [ "extension/manifest.json", "extension/script.js", ] outputs = [ - "$root_out_dir/media_router/media_router_telemetry_extension/{{source_file_part}}", + "$root_out_dir/media_router/telemetry_extension/{{source_file_part}}", ] }
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc index c7acadf7..01be576b 100644 --- a/ui/aura/test/test_screen.cc +++ b/ui/aura/test/test_screen.cc
@@ -7,6 +7,7 @@ #include <stdint.h> #include "base/logging.h" +#include "build/build_config.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" @@ -17,6 +18,10 @@ #include "ui/gfx/native_widget_types.h" #include "ui/platform_window/platform_window_init_properties.h" +#if defined(OS_FUCHSIA) +#include "ui/platform_window/fuchsia/initialize_presenter_api_view.h" +#endif + namespace aura { namespace { @@ -42,9 +47,12 @@ WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() { DCHECK(!host_); - host_ = WindowTreeHost::Create(ui::PlatformWindowInitProperties{gfx::Rect( - GetPrimaryDisplay().GetSizeInPixel())}) - .release(); + ui::PlatformWindowInitProperties properties( + gfx::Rect(GetPrimaryDisplay().GetSizeInPixel())); +#if defined(OS_FUCHSIA) + ui::fuchsia::InitializeViewTokenAndPresentView(&properties); +#endif + host_ = WindowTreeHost::Create(std::move(properties)).release(); // Some tests don't correctly manage window focus/activation states. // Makes sure InputMethod is default focused so that IME basics can work. host_->GetInputMethod()->OnFocus();
diff --git a/ui/events/ozone/evdev/input_controller_evdev.cc b/ui/events/ozone/evdev/input_controller_evdev.cc index 400c1c6..0fe1851 100644 --- a/ui/events/ozone/evdev/input_controller_evdev.cc +++ b/ui/events/ozone/evdev/input_controller_evdev.cc
@@ -179,6 +179,12 @@ std::move(reply).Run(std::vector<base::FilePath>()); } +void InputControllerEvdev::GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request) { + if (input_device_factory_) + input_device_factory_->GetGesturePropertiesService(std::move(request)); +} + void InputControllerEvdev::ScheduleUpdateDeviceSettings() { if (!input_device_factory_ || settings_update_pending_) return;
diff --git a/ui/events/ozone/evdev/input_controller_evdev.h b/ui/events/ozone/evdev/input_controller_evdev.h index 947e84c..bddfbc6c 100644 --- a/ui/events/ozone/evdev/input_controller_evdev.h +++ b/ui/events/ozone/evdev/input_controller_evdev.h
@@ -67,6 +67,8 @@ void SetTouchscreensEnabled(bool enabled) override; void SetInternalKeyboardFilter(bool enable_filter, std::vector<DomCode> allowed_keys) override; + void GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request) override; private: // Post task to update settings.
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index 8d9714a..2aead6ff4 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -295,6 +295,14 @@ #endif } +void InputDeviceFactoryEvdev::GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request) { +#if defined(USE_EVDEV_GESTURES) + gesture_properties_service_ = std::make_unique<GesturePropertiesService>( + gesture_property_provider_.get(), std::move(request)); +#endif +} + base::WeakPtr<InputDeviceFactoryEvdev> InputDeviceFactoryEvdev::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.h b/ui/events/ozone/evdev/input_device_factory_evdev.h index 085908f3..b078fb2 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.h +++ b/ui/events/ozone/evdev/input_device_factory_evdev.h
@@ -23,6 +23,10 @@ #include "ui/events/ozone/evdev/input_device_settings_evdev.h" #include "ui/ozone/public/input_controller.h" +#if defined(USE_EVDEV_GESTURES) +#include "ui/events/ozone/chromeos/gesture_properties_service.h" +#endif + namespace ui { class CursorDelegateEvdev; @@ -62,6 +66,9 @@ void GetTouchEventLog(const base::FilePath& out_dir, InputController::GetTouchEventLogReply reply); + void GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request); + base::WeakPtr<InputDeviceFactoryEvdev> GetWeakPtr(); private: @@ -106,6 +113,7 @@ #if defined(USE_EVDEV_GESTURES) // Gesture library property provider (used by touchpads/mice). std::unique_ptr<GesturePropertyProvider> gesture_property_provider_; + std::unique_ptr<GesturePropertiesService> gesture_properties_service_; #endif // Dispatcher for events.
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc index af6a0f7..02822e2 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc
@@ -98,4 +98,12 @@ std::move(reply)))); } +void InputDeviceFactoryEvdevProxy::GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&InputDeviceFactoryEvdev::GetGesturePropertiesService, + input_device_factory_, std::move(request))); +} + } // namespace ui
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h index c7c07070..30739e1 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h +++ b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h
@@ -46,6 +46,8 @@ void GetTouchDeviceStatus(InputController::GetTouchDeviceStatusReply reply); void GetTouchEventLog(const base::FilePath& out_dir, InputController::GetTouchEventLogReply reply); + void GetGesturePropertiesService( + ozone::mojom::GesturePropertiesServiceRequest request); private: scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn index 24d7a0c..66463bc9 100644 --- a/ui/ozone/BUILD.gn +++ b/ui/ozone/BUILD.gn
@@ -117,6 +117,7 @@ "//ui/gfx/ipc/geometry", "//ui/gfx/ipc/skia", "//ui/gl", + "//ui/ozone/public/interfaces:gesture_properties_service", ] if (enable_vulkan) {
diff --git a/ui/ozone/public/input_controller.cc b/ui/ozone/public/input_controller.cc index daacfbb..e7443f8 100644 --- a/ui/ozone/public/input_controller.cc +++ b/ui/ozone/public/input_controller.cc
@@ -56,6 +56,8 @@ void SetTouchscreensEnabled(bool enabled) override {} void SetInternalKeyboardFilter(bool enable_filter, std::vector<DomCode> allowed_keys) override {} + void GetGesturePropertiesService( + ui::ozone::mojom::GesturePropertiesServiceRequest request) override {} private: DISALLOW_COPY_AND_ASSIGN(StubInputController);
diff --git a/ui/ozone/public/input_controller.h b/ui/ozone/public/input_controller.h index f791a8b..711ee67 100644 --- a/ui/ozone/public/input_controller.h +++ b/ui/ozone/public/input_controller.h
@@ -14,6 +14,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "ui/ozone/ozone_base_export.h" +#include "ui/ozone/public/interfaces/gesture_properties_service.mojom.h" namespace base { class TimeDelta; @@ -88,6 +89,9 @@ virtual void SetInternalKeyboardFilter(bool enable_filter, std::vector<DomCode> allowed_keys) = 0; + virtual void GetGesturePropertiesService( + ui::ozone::mojom::GesturePropertiesServiceRequest request) = 0; + private: DISALLOW_COPY_AND_ASSIGN(InputController); };
diff --git a/ui/webui/resources/cr_elements/cr_button/cr_button.html b/ui/webui/resources/cr_elements/cr_button/cr_button.html index ee4fa7b..9ea3a2b 100644 --- a/ui/webui/resources/cr_elements/cr_button/cr_button.html +++ b/ui/webui/resources/cr_elements/cr_button/cr_button.html
@@ -64,6 +64,7 @@ color: var(--text-color); cursor: pointer; display: inline-flex; + flex-shrink: 0; font-weight: 500; height: var(--cr-button-height); min-width: 5.14em; @@ -71,7 +72,6 @@ padding: 8px 16px; position: relative; user-select: none; - white-space: nowrap; } :host-context(.focus-outline-visible):host(:focus) {
diff --git a/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.js b/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.js index 87ddccae..886ad1c 100644 --- a/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.js +++ b/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.js
@@ -85,12 +85,12 @@ /** @private */ showRipple_: function() { - this.getRipple().holdDown = true; + this.getRipple().showAndHoldDown(); }, /** @private */ hideRipple_: function() { - this.getRipple().holdDown = false; + this.getRipple().clear(); }, /**
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html index c1686cb..605b2567 100644 --- a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html +++ b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.html
@@ -13,10 +13,11 @@ var(--cr-icon-button-icon-size)) / 2); --cr-icon-button-icon-size: 20px; --cr-icon-button-size: 36px; + /* Copied from paper-fab.html. Prevents square touch highlight. */ + -webkit-tap-highlight-color: transparent; background-position: center; background-repeat: no-repeat; background-size: var(--cr-icon-button-icon-size); - border-radius: var(--cr-icon-button-border-radius); color: var(--cr-icon-button-color); cursor: pointer; display: inline-flex; @@ -54,7 +55,6 @@ } #icon { - border-radius: var(--cr-icon-button-border-radius); display: flex; height: var(--cr-icon-button-size); /* The |_rippleContainer| must be position relative. */ @@ -65,7 +65,6 @@ iron-icon { --iron-icon-height: var(--cr-icon-button-icon-size); --iron-icon-width: var(--cr-icon-button-icon-size); - border-radius: var(--cr-icon-button-border-radius); padding: var(--cr-icon-button-icon-padding); } </style>
diff --git a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js index af92b8a..c55bd02 100644 --- a/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js +++ b/ui/webui/resources/cr_elements/cr_icon_button/cr_icon_button.js
@@ -64,7 +64,7 @@ /** @private */ hideRipple_: function() { - this.getRipple().holdDown = false; + this.getRipple().clear(); }, /** @private */
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js index e8ed45e2..8ccc382 100644 --- a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js
@@ -35,22 +35,20 @@ }, listeners: { - blur: 'cancelRipple_', + blur: 'hideRipple_', focus: 'onFocus_', - pointerup: 'cancelRipple_', + up: 'hideRipple_', }, /** @private */ onFocus_: function() { - this.ensureRipple(); - this.$$('paper-ripple').holdDown = true; + this.getRipple().showAndHoldDown(); this.$.button.focus(); }, /** @private */ - cancelRipple_: function() { - this.ensureRipple(); - this.$$('paper-ripple').holdDown = false; + hideRipple_: function() { + this.getRipple().clear(); }, /** @private */
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html index a45cc16..14ede13 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -161,7 +161,7 @@ } :host(:hover) #label, - :host([hold-down_]) #label { + :host([show-label_]) #label { opacity: 1; }
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js index 1169812..e73ea04e 100644 --- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.js +++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.js
@@ -138,20 +138,19 @@ }, /** @private */ - holdDown_: { - type: Boolean, - value: false, - observer: 'onHoldDownChanged_', - reflectToAttribute: true, - }, - - /** @private */ label_: { type: String, value: '', }, /** @private */ + showLabel_: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, + + /** @private */ isRtl_: { type: Boolean, value: false, @@ -184,8 +183,8 @@ ], listeners: { - focus: 'onFocus_', - blur: 'onBlur_', + blur: 'hideRipple_', + focus: 'showRipple_', keydown: 'onKeyDown_', keyup: 'onKeyUp_', pointerdown: 'onPointerDown_', @@ -260,16 +259,19 @@ this.draggingEventTracker_.removeAll(); this.releasePointerCapture(pointerId); this.dragging = false; - // If there is a ripple animation in progress, setTimeout will hold off - // on updating |holdDown_|. - setTimeout(() => { - this.holdDown_ = false; - }); + this.hideRipple_(); }, /** @private */ - onBlur_: function() { - this.holdDown_ = false; + hideRipple_: function() { + this.getRipple().clear(); + this.showLabel_ = false; + }, + + /** @private */ + showRipple_: function() { + this.getRipple().showAndHoldDown(); + this.showLabel_ = true; }, /** @private */ @@ -278,20 +280,6 @@ this.blur(); }, - /** @private */ - onFocus_: function() { - this.holdDown_ = true; - - if (this.shadowRoot.activeElement == this.$.knob) { - return; - } - }, - - /** @private */ - onHoldDownChanged_: function() { - this.getRipple().holdDown = this.holdDown_; - }, - /** * @param {!Event} event * @private @@ -325,9 +313,7 @@ } event.preventDefault(); event.stopPropagation(); - setTimeout(() => { - this.holdDown_ = true; - }); + this.showRipple_(); }, /** @@ -358,12 +344,7 @@ this.dragging = true; this.transiting_ = true; this.updateValueFromClientX_(event.clientX); - // If there is a ripple animation in progress, setTimeout will hold off on - // updating |holdDown_|. - setTimeout(() => { - this.$.knob.focus(); - this.holdDown_ = true; - }); + this.showRipple_(); this.setPointerCapture(event.pointerId); const stopDragging = this.stopDragging_.bind(this, event.pointerId);
diff --git a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.js b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.js index 092a31b..3f0f7e6b 100644 --- a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.js +++ b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.js
@@ -38,12 +38,12 @@ }, listeners: { - 'pointerdown': 'onPointerDown_', - 'pointerup': 'onPointerUp_', - 'click': 'onTap_', - 'keypress': 'onKeyPress_', - 'focus': 'onFocus_', - 'blur': 'onBlur_', + blur: 'hideRipple_', + click: 'onClick_', + focus: 'onFocus_', + keypress: 'onKeyPress_', + pointerdown: 'onPointerDown_', + pointerup: 'onPointerUp_', }, /** @private {?Function} */ @@ -101,19 +101,18 @@ /** @private */ onFocus_: function() { - this.ensureRipple(); - this.$$('paper-ripple').holdDown = true; + this.getRipple().showAndHoldDown(); }, /** @private */ - onBlur_: function() { - this.ensureRipple(); - this.$$('paper-ripple').holdDown = false; + hideRipple_: function() { + this.getRipple().clear(); }, /** @private */ - onPointerUp_: function(e) { + onPointerUp_: function() { this.removeEventListener('pointermove', this.boundPointerMove_); + this.hideRipple_(); }, /** @@ -134,8 +133,11 @@ this.addEventListener('pointermove', this.boundPointerMove_); }, - /** @private */ - onTap_: function(e) { + /** + * @param {!Event} e + * @private + */ + onClick_: function(e) { // Prevent |click| event from bubbling. It can cause parents of this // elements to erroneously re-toggle this control. e.stopPropagation(); @@ -166,8 +168,7 @@ this.checked = !this.checked; if (!fromKeyboard) { - this.ensureRipple(); - this.$$('paper-ripple').holdDown = false; + this.hideRipple_(); } this.fire('change', this.checked);
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd index 4307d81..4afe117 100644 --- a/ui/webui/resources/webui_resources.grd +++ b/ui/webui/resources/webui_resources.grd
@@ -327,9 +327,6 @@ <structure name="IDR_WEBUI_JS_CR_UI_ARRAY_DATA_MODEL" file="js/cr/ui/array_data_model.js" type="chrome_html" compress="gzip" flattenhtml="true" /> - <structure name="IDR_WEBUI_JS_CR_UI_AUTOCOMPLETE_LIST" - file="js/cr/ui/autocomplete_list.js" - type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_BUBBLE" file="js/cr/ui/bubble.js" type="chrome_html" compress="gzip" /> @@ -414,23 +411,6 @@ type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_GRID" file="js/cr/ui/grid.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE" - file="js/cr/ui/table.js" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE_COLUMN" - file="js/cr/ui/table/table_column.js" - type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE_COLUMN_MODEL" - file="js/cr/ui/table/table_column_model.js" - type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE_HEADER" - file="js/cr/ui/table/table_header.js" - type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE_LIST" - file="js/cr/ui/table/table_list.js" - type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_JS_CR_UI_TABLE_SPLITTER" - file="js/cr/ui/table/table_splitter.js" - type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_TABS" file="js/cr/ui/tabs.js" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_JS_CR_UI_TREE"