diff --git a/DEPS b/DEPS index ca2645f4..7a1e48bbf 100644 --- a/DEPS +++ b/DEPS
@@ -299,11 +299,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': '829713eee0db84e93568166fc456e727845fe928', + 'skia_revision': '1af98858ffe5def5bbfde4ea333bc6eb4ba9b193', # 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': 'd82424c091f8fc8ee1ae3e5fecddc8185d726099', + 'v8_revision': '31403c7ff321dc9cabe519cfebea378b11c1ca8e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -315,7 +315,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': '3ec4d6508e42a727430426d921cf21cf8aa99bcf', + 'pdfium_revision': '807692bc829fc9ac435bd51696b4bce4a2f416f3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -326,7 +326,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. - 'fuchsia_version': 'version:11.20230218.2.1', + 'fuchsia_version': 'version:11.20230219.2.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -386,7 +386,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '0cd138109ca55d2c8d1fbf240ba3ab12902848ac', + 'devtools_frontend_revision': '7805c5a2ecc7279852749e16e6c6b98ea97d5633', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -426,7 +426,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': '79781f26d1fc525fb9c3ba291e5660ea3da6eeb1', + 'dawn_revision': 'e4f947637a3bb45b4d9be9b1cf7cf51461dff800', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -490,7 +490,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '3c25fb0803f2bbcacb777118ee4488ae5694c780', + 'libcxx_revision': '43c39fecf3aa3cd542e41ffa8720720a1629ff41', # GN CIPD package version. 'gn_version': 'git_revision:b25a2f8c2d33f02082f0f258350f5e22c0973108', @@ -764,7 +764,7 @@ 'src/clank': { 'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' + - '39404f15337a2b5f28d6683cdeebf4ef73b0997b', + '1564713d6aa5a88b8f3c349905b1991953caa3c7', 'condition': 'checkout_android and checkout_src_internal', }, @@ -863,7 +863,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'X0kRrUwBYe1ZxB1NhD3fgLJbvrC-8_pr4ZcG_4unODcC', + 'version': 'VcdzPH5Mzkh2V6Ak_aoaecy37122Xw0witGWm7qKHlAC', }, ], 'dep_type': 'cipd', @@ -874,7 +874,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'T2qeiWhknw_0Xm1UYTD4YwQHuWb7a_MIXjmzS6pLYd4C', + 'version': 'jAp-9LRADV2dw2EiiDTXWzlzhVZVdo6JeBxQTkEhGo8C', }, ], 'dep_type': 'cipd', @@ -885,7 +885,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'gfEY7MSFNMChvsRCA2nMv3uryNbkW-AEbULaFVYXJnwC', + 'version': 'Gg3BRf4kHZA0ej8fDnuAYYCtF8ztT3a9BlH3I8VP7GgC', }, ], 'dep_type': 'cipd', @@ -953,7 +953,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'vUTlHbKBLM4krixE17LfiE5TEFoG_oG8PWG2kxuKDKYC', + 'version': 'MZ9_PEpIzKK0mJj-ofqMi2FNv_6yzhVurgpyh5pHkK8C', }, ], 'condition': 'checkout_android', @@ -1212,7 +1212,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '4372bde8db742cf15e98ad9fcef8eac5440e2c34', + 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '23dc3f97a1f38e5207f2e96df67ed99a0dd8fd39', 'condition': 'checkout_src_internal', }, @@ -1939,7 +1939,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4ea603086b46bc5a5a062b181a2749324b496729', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1dcedd63fb07179bcc2c9d64b6ebfec56aaf8749', 'condition': 'checkout_src_internal', }, @@ -1969,7 +1969,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'CRAglEc7y9tUA7jpBzPVYlKMflRsLd99SUZBT6UY37cC', + 'version': 'GWd4BVjiT8R08INGZRLMAdGEM4rr6OOzmri0KbqUI2gC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1991,7 +1991,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'bhyoxLRIRdHIelK4pZaR1SAJRRyrL6XnIN46EsRbo_oC', + 'version': 'JSmkUx6kz9W8m4xkAkN9DlPWar4oxZmMnSgeV1f844EC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/components/arc/arc_prefs.cc b/ash/components/arc/arc_prefs.cc index 80b2380..d575a8f 100644 --- a/ash/components/arc/arc_prefs.cc +++ b/ash/components/arc/arc_prefs.cc
@@ -151,6 +151,11 @@ // A preferece to keep ARC snapshot related info in dictionary. const char kArcSnapshotInfo[] = "arc.snapshot"; +// A time pref indicating the time in microseconds when ARCVM success executed +// vmm swap out. If it never swapped out, the pref holds the default value +// base::Time(). +const char kArcVmmSwapOutTime[] = "arc_vmm_swap_out_time"; + // A preference to keep track of whether or not Android WebView was used in the // current ARC session. const char kWebViewProcessStarted[] = "arc.webview.started"; @@ -161,6 +166,7 @@ registry->RegisterStringPref(kArcSerialNumberSalt, std::string()); registry->RegisterDictionaryPref(kArcSnapshotHours); registry->RegisterDictionaryPref(kArcSnapshotInfo); + registry->RegisterTimePref(kArcVmmSwapOutTime, base::Time()); registry->RegisterDictionaryPref(kStabilityMetrics); registry->RegisterIntegerPref(kAnrPendingCount, 0);
diff --git a/ash/components/arc/arc_prefs.h b/ash/components/arc/arc_prefs.h index 3e9d9c6..1fbdd40c 100644 --- a/ash/components/arc/arc_prefs.h +++ b/ash/components/arc/arc_prefs.h
@@ -55,6 +55,7 @@ ARC_EXPORT extern const char kArcSerialNumberSalt[]; ARC_EXPORT extern const char kArcSnapshotHours[]; ARC_EXPORT extern const char kArcSnapshotInfo[]; +ARC_EXPORT extern const char kArcVmmSwapOutTime[]; ARC_EXPORT extern const char kStabilityMetrics[]; ARC_EXPORT extern const char kWebViewProcessStarted[];
diff --git a/ash/components/arc/mojom/intent_helper.mojom b/ash/components/arc/mojom/intent_helper.mojom index fdba7f8..e657a3e 100644 --- a/ash/components/arc/mojom/intent_helper.mojom +++ b/ash/components/arc/mojom/intent_helper.mojom
@@ -403,7 +403,7 @@ }; // Sends intents to ARC on behalf of Chrome. -// Deprecated method ID: 0, 7, 11, 12, 14, 18 +// Deprecated method ID: 0, 7, 11, 12, 14, 17, 18 // Next method ID: 22 interface IntentHelperInstance { // Sets the given package as a preferred package. The next time an ACTION_VIEW @@ -412,16 +412,6 @@ // When multiple packages are set as preferred, the most recent setting wins. [MinVersion=7] AddPreferredPackage@8(string package_name); - // Sets the given package as a preferred app for the given |intent_filter| - // and |intent_info|. - // The |package_name| is selected by the user on Chrome-side to remember the - // user preference. The |intent_info| is used to generate the components set - // and match for setting the preferred activity. - // This is used to sync the preferred app setting from Chrome OS. - [MinVersion=32] AddPreferredApp@17(string package_name, - IntentFilter intent_filter, - IntentInfo intent_info); - // Set the verified link domain status to either always open (|always_open| is // true) or always ask (|always_open| is false) for the |package_names|. // This method will be called when Chrome OS changes the link capturing
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 36a64302..231caf2 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1276,11 +1276,6 @@ "LacrosProfileMigrationForceOff", base::FEATURE_DISABLED_BY_DEFAULT); -// Disable this to turn off profile migration for non-googlers. -BASE_FEATURE(kLacrosProfileMigrationForAnyUser, - "LacrosProfileMigrationForAnyUser", - base::FEATURE_ENABLED_BY_DEFAULT); - // If enabled, use `MoveMigrator` instead of `CopyMigrator` to migrate data. // `MoveMigrator` moves data from ash to lacros instead of copying them. BASE_FEATURE(kLacrosMoveProfileMigration,
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 21d16ae..f51fa2a 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -369,8 +369,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosSupport); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosWaylandLogging); COMPONENT_EXPORT(ASH_CONSTANTS) -BASE_DECLARE_FEATURE(kLacrosProfileMigrationForAnyUser); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosProfileMigrationForceOff); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kLacrosMoveProfileMigration);
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc index 0a7ae29..747b044 100644 --- a/ash/wm/client_controlled_state_unittest.cc +++ b/ash/wm/client_controlled_state_unittest.cc
@@ -13,6 +13,9 @@ #include "ash/test/ash_test_base.h" #include "ash/wm/desks/desks_util.h" #include "ash/wm/float/float_controller.h" +#include "ash/wm/overview/overview_controller.h" +#include "ash/wm/overview/overview_item.h" +#include "ash/wm/overview/overview_test_util.h" #include "ash/wm/pip/pip_positioner.h" #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/splitview/split_view_controller.h" @@ -32,6 +35,7 @@ #include "ui/aura/client/aura_constants.h" #include "ui/events/test/event_generator.h" #include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -965,4 +969,48 @@ EXPECT_NE(kShellWindowId_FloatContainer, window()->parent()->GetId()); } +TEST_P(ClientControlledStateTestClamshellAndTablet, DragOverviewWindowToSnap) { + auto* const overview_controller = Shell::Get()->overview_controller(); + auto* const split_view_controller = SplitViewController::Get(window()); + + widget_delegate()->EnableSnap(); + + // Create a fake normal window in addition to `window()` (client-controlled + // window) because we need at least two windows to keep overview mode active + // after snapping one of them. + auto fake_uninterested_window = CreateAppWindow(); + + // Enter overview. + ToggleOverview(); + EXPECT_TRUE(overview_controller->InOverviewSession()); + EXPECT_FALSE(split_view_controller->InSplitViewMode()); + + // Drag `window()`'s overview item to snap to left. + auto* const overview_item = GetOverviewItemForWindow(window()); + auto* const event_generator = GetEventGenerator(); + event_generator->set_current_screen_location( + gfx::ToRoundedPoint(overview_item->target_bounds().CenterPoint())); + event_generator->DragMouseTo(0, 0); + + // Ensures the window is in a transitional snapped state. + EXPECT_TRUE(split_view_controller->IsWindowInTransitionalState(window())); + EXPECT_EQ(WindowStateType::kPrimarySnapped, delegate()->new_state()); + EXPECT_FALSE(window_state()->IsSnapped()); + + // Activating window just before accepting the request shouldn't end the + // overview. + widget()->Activate(); + EXPECT_TRUE(overview_controller->InOverviewSession()); + + // Accept the snap request. + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_TRUE(window_state()->IsSnapped()); + EXPECT_TRUE(split_view_controller->InSplitViewMode()); + EXPECT_EQ(split_view_controller->state(), + SplitViewController::State::kPrimarySnapped); + EXPECT_EQ(split_view_controller->primary_window(), window()); + EXPECT_TRUE(overview_controller->InOverviewSession()); +} + } // namespace ash
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 65489963..22605eb 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -875,10 +875,14 @@ // handle the window activation change. Check for split view mode without // using |SplitViewController::state_| which is updated asynchronously when // snapping an ARC window. + // We also check if `gained_active` is to-be-snapped transitional state. In + // the case, the window has not been attached to SplitViewController yet but + // will be very soon. SplitViewController* split_view_controller = SplitViewController::Get(gained_active); if (split_view_controller->primary_window() || - split_view_controller->secondary_window()) { + split_view_controller->secondary_window() || + split_view_controller->IsWindowInTransitionalState(gained_active)) { RestoreWindowActivation(false); return; }
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 667661c..fb52805 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision vars in //DEPS. - libcxx_revision = "3c25fb0803f2bbcacb777118ee4488ae5694c780" + libcxx_revision = "43c39fecf3aa3cd542e41ffa8720720a1629ff41" }
diff --git a/chrome/VERSION b/chrome/VERSION index e7cb759..1d7882b 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=112 MINOR=0 -BUILD=5605 +BUILD=5608 PATCH=0
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb index 63bd823a..3e8b525 100644 --- a/chrome/app/resources/chromium_strings_ms.xtb +++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -31,6 +31,7 @@ <translation id="185970820835152459">Anda boleh mengurus Google Account anda yang dilog masuk. Google Account anda digunakan untuk penyemak imbas Chromium, Play Store, Gmail dan pelbagai lagi. Jika anda ingin menambah akaun untuk orang lain, seperti ahli keluarga, tambahkan sahaja orang baharu pada <ph name="DEVICE_TYPE" /> anda. <ph name="LINK_BEGIN" />Ketahui lebih lanjut<ph name="LINK_END" /></translation> <translation id="1863308913976887472">Laman boleh menyimpan maklumat tentang minat anda menggunakan Chromium. Contohnya, jika anda melawat laman untuk membeli kasut untuk maraton, laman tersebut mungkin mentakrifkan minat anda sebagai larian maraton. Kemudian, jika anda melawati laman lain untuk mendaftar perlumbaan, laman tersebut boleh memaparkan kepada anda iklan kasut untuk berlari berdasarkan minat anda.</translation> <translation id="1881322772814446296">Anda log masuk menggunakan akaun yang terurus dan memberikan pentadbirnya kawalan ke atas profil Chromium anda. Data Chromium anda, seperti apl, penanda halaman, sejarah, kata laluan dan tetapan anda yang lain akan terikat kepada <ph name="USER_NAME" /> secara kekal. Anda akan dapat memadamkan data ini melalui Papan Pemuka Akaun Google, tetapi anda tidak akan dapat mengaitkan data ini dengan akaun lain. Anda boleh memilih untuk membuat profil baharu untuk mengasingkan data Chromium anda yang sedia ada. <ph name="LEARN_MORE" /></translation> +<translation id="1906696617298807388">Apabila anda menaip dalam bar alamat atau kotak carian, Chromium menghantar perkara yang anda taip kepada Google Drive untuk mendapatkan cadangan item. Tetapan ini dimatikan dalam Inkognito.</translation> <translation id="1911763535808217981">Dengan mematikan pilihan ini, anda boleh mengelog masuk ke tapak Google seperti Gmail tanpa perlu mengelog masuk ke Chromium</translation> <translation id="1929939181775079593">Chromium tidak responsif. Lancarkan semula sekarang?</translation> <translation id="193439633299369377">Chromium OS perlu dimulakan semula untuk melaksanakan kemas kini.</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb index 4f14a17..7b172ea 100644 --- a/chrome/app/resources/generated_resources_bs.xtb +++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -69,6 +69,7 @@ <translation id="1059484610606223931">Protokol za prijenos hiperteksta (HTTPs)</translation> <translation id="1059944192885972544">Za upit "<ph name="SEARCH_TEXT" />" je pronađen sljedeći broj kartica: <ph name="NUM" /></translation> <translation id="1060292118287751956">Određuje frekvenciju ažuriranja ekrana</translation> +<translation id="1060570945511946595">Upravljajte kartama</translation> <translation id="1061130374843955397">Dobro došli na uređaj <ph name="DEVICE_TYPE" /></translation> <translation id="1061373870045429865">Kreiraj QR kôd za ovaj link</translation> <translation id="1061904396131502319">Uskoro će vrijeme za odmor</translation> @@ -1125,6 +1126,7 @@ <translation id="1975841812214822307">Ukloni...</translation> <translation id="1976150099241323601">Prijavite se u Sigurnosni uređaj</translation> <translation id="1977965994116744507">Približite telefon da otključate uređaj <ph name="DEVICE_TYPE" />.</translation> +<translation id="1978666928180318515">Uklonite Bruschettu</translation> <translation id="1979095679518582070">Isključivanjem ove funkcije uređaj će i dalje moći slati informacije potrebne za ključne usluge kao što su ažuriranja sistema i sigurnost.</translation> <translation id="1979280758666859181">Prelazite na kanal sa starijom verzijom proizvoda <ph name="PRODUCT_NAME" />. Promjena kanala će se primijeniti kada verzija kanala bude odgovarala verziji koja je trenutno instalirana na vašem uređaju.</translation> <translation id="197989455406964291">KDC ne podržava vrstu šifriranja</translation> @@ -1932,6 +1934,7 @@ <translation id="2672142220933875349">Loš crx fajl, raspakivanje nije uspjelo.</translation> <translation id="2673135533890720193">Čitati vašu historiju pregledanja</translation> <translation id="2674764818721168631">Isključeno</translation> +<translation id="2675570801872027281">Greška prilikom uklanjanja Bruschette. Pokušajte ponovo.</translation> <translation id="2676492189600898281">Slanje povratnih informacija za automatsko popunjavanje</translation> <translation id="2678063897982469759">Ponovo omogući</translation> <translation id="2678100101831051676">Nije moguće emitirati.</translation> @@ -2930,6 +2933,7 @@ <translation id="3593965109698325041">Ograničenja naziva potvrde</translation> <translation id="3596012367874587041">Postavke aplikacije</translation> <translation id="3596414637720633074">Blokirajte kolačiće trećih strana u anonimnom načinu rada</translation> +<translation id="3598010454707842106">Kliknite na "Prilagodite Chrome"</translation> <translation id="3599221874935822507">Podignuto</translation> <translation id="3600051066689725006">Informacije o zahtjevu s weba</translation> <translation id="360180734785106144">Ponudite nove funkcije kada postanu dostupne</translation> @@ -3928,6 +3932,7 @@ <translation id="4497145443434063861">PC i Chromecast na različitim WiFi mrežama (npr. 2,4GHz naspram 5GHz)</translation> <translation id="4500114933761911433">Došlo je do pada dodatka <ph name="PLUGIN_NAME" /></translation> +<translation id="4500647907053779331">&Prevedi odabir na <ph name="LANGUAGE" /></translation> <translation id="450099669180426158">Ikona uzvičnika</translation> <translation id="4501530680793980440">Potvrdite uklanjanje</translation> <translation id="4502423230170890588">Ukloni s ovog uređaja</translation> @@ -5745,6 +5750,7 @@ <translation id="617213288191670920">Nijedan jezik nije dodan</translation> <translation id="6173623053897475761">Unesite ponovo PIN</translation> <translation id="6175314957787328458">GUID Microsoft domene</translation> +<translation id="6177412385419165772">Uklanjanje...</translation> <translation id="6178664161104547336">Odaberite potvrdu</translation> <translation id="6178682841350631965">Vaši podaci za prijavu su ažurirani</translation> <translation id="6180510783007738939">Alat za crtanje linija</translation> @@ -6225,6 +6231,7 @@ <translation id="6619801788773578757">Dodaj aplikaciju za kiosk</translation> <translation id="6619990499523117484">Potvrdite PIN</translation> <translation id="6620254580880484313">Naziv spremnika</translation> +<translation id="6620927550847360014">Ukloniti Bruschettu iz uređaja <ph name="DEVICE_TYPE" />?</translation> <translation id="6621391692573306628">Da pošaljete ovu karticu na drugi uređaj, prijavite se na Chrome na oba uređaja</translation> <translation id="6622980291894852883">Nastavi blokirati slike</translation> <translation id="6624036901798307345">U načinu rada tableta dodirnite dugme alatne trake brojača kartica da otvorite novu traku kartice koja prikazuje sličice svake kartice.</translation> @@ -6442,6 +6449,7 @@ <translation id="6818547713623251698">Pregledajte fotografije, medijski sadržaj, obavještenja i aplikacije telefona</translation> <translation id="6818802132960437751">Ugrađena zaštita od virusa</translation> <translation id="6818920801736417483">Sačuvati lozinke?</translation> +<translation id="6820079682647046800">Autentifikacija Kerberos nije uspjela</translation> <translation id="6823174134746916417">Dodir za klik dodirne podloge</translation> <translation id="6824564591481349393">Kopiraj adresu &e-pošte</translation> <translation id="6824584962142919697">&Provjeri elemente</translation> @@ -6596,6 +6604,7 @@ <translation id="6955698182324067397">Omogućujete funkcije za otklanjanje grešaka na ChromeOS-u kojim će se postaviti sshd daemon i omogućiti pokretanje sistema s USB diskova.</translation> <translation id="6955893174999506273">Dodijeli još 1 prekidač</translation> <translation id="6957044667612803194">Ovaj sigurnosni ključ ne podržava PIN-ove.</translation> +<translation id="6960133692707095572">Posjetite bez karte</translation> <translation id="6960507406838246615">Potrebno je ažurirati Linux</translation> <translation id="6960648667961844909">Preuzimanje fajlova govora na jeziku <ph name="LANGUAGE" /> nije uspjelo. Pokušaj preuzimanja će se izvršiti kasnije. Govor će se poslati Googleu na obradu kad se završi preuzimanje.</translation> <translation id="696103774840402661">Trajno su izbrisani svi fajlovi i lokalni podaci za sve korisnike na ovom uređaju <ph name="DEVICE_TYPE" />.</translation> @@ -8058,6 +8067,7 @@ <translation id="8272443605911821513">Upravljajte svojim ekstenzijama klikom na Ekstenzije u meniju "Više alata".</translation> <translation id="8272786333453048167">Ponovo dozvoli</translation> <translation id="8273905181216423293">Preuzmi sada</translation> +<translation id="827488840488530039">Stranica koju pokušavate posjetiti nije uspjela potvrditi vaše Kerberos karte</translation> <translation id="8274921654076766238">Povećalo prati fokus tastature</translation> <translation id="8274924778568117936">Nemojte gasiti ili zatvarati uređaj <ph name="DEVICE_TYPE" /> prije završetka ažuriranja. Uređaj <ph name="DEVICE_TYPE" /> će se ponovno pokrenuti nakon završetka instalacije.</translation> <translation id="8275038454117074363">Uvezi</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index addd93e..b790ae9 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -1441,6 +1441,7 @@ <translation id="2251809247798634662">חלון חדש לגלישה בסתר</translation> <translation id="2252017960592955005">הגנה מפני צפייה לא רצויה (בטא)</translation> <translation id="225240747099314620">לאפשר מזהים עבור תוכן מוגן (ייתכן שיהיה צורך לאתחל את המחשב)</translation> +<translation id="2253318212986772520">לא ניתן לאחזר את ה-PPD עבור <ph name="PRINTER_NAME" />.</translation> <translation id="2255077166240162850">המכשיר הזה ננעל לצורך שימוש בדומיין או במצב שונה.</translation> <translation id="2255317897038918278">הטבעת חותמת זמן של Microsoft</translation> <translation id="2256115617011615191">יש להפעיל מחדש כעת</translation> @@ -2913,6 +2914,7 @@ <translation id="3582057310199111521">הוזנה באתר מטעה ונמצאה בפרצה באבטחת מידע</translation> <translation id="3582299299336701326">שינוי של מסכים בהירים לכהים ומסכים כהים לבהירים. כדי להפעיל או להשבית את היפוך הצבעים, מקישים על מקש החיפוש + Ctrl + H.</translation> <translation id="3584169441612580296">לקרוא ולשנות קובצי תמונות, מוזיקה ומדיה מסוגים נוספים מהמחשב שלך</translation> +<translation id="3584527007414070635">המשך התהליך עבור <ph name="MODULE_TITLE" /></translation> <translation id="3586787825263265024">כדי להשתמש באפליקציה <ph name="APPLICATION_NAME" /> צריך ששירות OneDrive יהיה זמין.</translation> <translation id="3586806079541226322">לא ניתן לפתוח את הקובץ הזה</translation> <translation id="3587438013689771191">מידע נוסף על: <ph name="SUBPAGE_TITLE" /></translation> @@ -3871,6 +3873,7 @@ <translation id="4443536555189480885">&עזרה</translation> <translation id="4444304522807523469">גישה לסורקי מסמכים המחוברים באמצעות USB או ברשת המקומית</translation> <translation id="4444512841222467874">אם לא מפנים נפח אחסון, ייתכן שמשתמשים ונתונים יוסרו באופן אוטומטי.</translation> +<translation id="4445446646109808714">הסכם רישיון למשתמש קצה: <ph name="EULA_LINK" /></translation> <translation id="4446933390699670756">שיקוף</translation> <translation id="4448914100439890108">הסתרת הסיסמה של <ph name="USERNAME" /> ב-<ph name="DOMAIN" /></translation> <translation id="4449948729197510913">שם המשתמש שלך שייך לחשבון הארגוני של הארגון שלך. כדי לרשום מכשירים בחשבון, תחילה יש לאמת שיש לך בעלות על הדומיין במסוף Admin. נדרשות הרשאות אדמין בחשבון כדי לבצע את האימות.</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index 1277df1..7136e6b 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -379,6 +379,7 @@ <translation id="1339009753652684748">Akses Assistant anda apabila anda menyebut "Ok Google". Untuk menjimatkan bateri, pilih “Hidup (Disyorkan)”. Assistant anda hanya akan memberikan respons apabila peranti anda dipasang palam atau mengecas.</translation> <translation id="13392265090583506">A11y</translation> <translation id="1340527397989195812">Sandarkan media dari peranti menggunakan apl Fail.</translation> +<translation id="1341701348342335220">Bagus!</translation> <translation id="1341871421050612057">Tidak dapat melakukan penyegerakan dengan <ph name="USERNAME" /></translation> <translation id="1343865611738742294">Beri Linux kebenaran apl untuk mengakses peranti USB. Linux tidak akan mengingat peranti USB selepas peranti itu dialih keluar.</translation> <translation id="1343920184519992513">Teruskan dari tempat anda berhenti dan buka set halaman tertentu</translation> @@ -3640,6 +3641,7 @@ <translation id="4232375817808480934">Konfigurasikan Kerberos</translation> <translation id="4235965441080806197">Batalkan log masuk</translation> <translation id="4236163961381003811">Temukan lebih banyak sambungan</translation> +<translation id="4237282663517880406">Tunjukkan cadangan Google Drive</translation> <translation id="4241182343707213132">Mulakan semula peranti untuk mengemas kini apl organisasi</translation> <translation id="4242145785130247982">Sijil pelanggan berbilang tidak disokong</translation> <translation id="4242533952199664413">Buka tetapan</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb index ec957cb7..29eb800 100644 --- a/chrome/app/resources/generated_resources_uz.xtb +++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -69,6 +69,7 @@ <translation id="1059484610606223931">Hypertext Transport Protocol (HTTPS)</translation> <translation id="1059944192885972544"><ph name="NUM" /> ta varaqda “<ph name="SEARCH_TEXT" />” topildi</translation> <translation id="1060292118287751956">Ekranlardagi yangilanish chastotasini aniqlaydi</translation> +<translation id="1060570945511946595">Chiptalarni boshqarish</translation> <translation id="1061130374843955397"><ph name="DEVICE_TYPE" /> qurilmasiga xush kelibsiz!</translation> <translation id="1061373870045429865">Bu havola uchun QR kod yaratish</translation> <translation id="1061904396131502319">Tanaffus qilish vaqti keldi</translation> @@ -1113,6 +1114,7 @@ <translation id="1975841812214822307">O‘chirish...</translation> <translation id="1976150099241323601">Havfsizlik qurilmasiga kirish</translation> <translation id="1977965994116744507"><ph name="DEVICE_TYPE" /> qurilmasini qulfdan chiqarish uchun telefoningizni yaqinlashtiring.</translation> +<translation id="1978666928180318515">Bruschettani olib tashlash</translation> <translation id="1979095679518582070">Bu funksiya faol boʻlmasa ham tizim yangilanishlari va xavfsizlik kabi asosiy xizmatlarni yaxshilash maqsadida qurilma axborotlari yuborilaveradi.</translation> <translation id="1979280758666859181">Siz <ph name="PRODUCT_NAME" />‘ning ancha eski versiyasidan yangilanish kanaliga o‘tyapsiz. O‘zgartirishlar kuchga kirishi uchun kanal versiyasi qurilmangizdagi joriy versiya bilan bir xil bo‘lishi kerak.</translation> <translation id="197989455406964291">KDC bunday shifrlash turi bilan mos emas</translation> @@ -1920,6 +1922,7 @@ <translation id="2672142220933875349">CRX fayli shikastlangan, arxivdan chiqarib bo‘lmadi.</translation> <translation id="2673135533890720193">Kezish tarixini ko‘rish</translation> <translation id="2674764818721168631">Yoqilmagan</translation> +<translation id="2675570801872027281">Bruschetta olib tashlanmadi. Qayta urining.</translation> <translation id="2676492189600898281">Avtomatik kiritish haqida fikr-mulohaza</translation> <translation id="2678063897982469759">Qayta faollashtirish</translation> <translation id="2678100101831051676">Translatsiya qilinmadi.</translation> @@ -2918,6 +2921,7 @@ <translation id="3593965109698325041">Sertifikat nomiga cheklovlar</translation> <translation id="3596012367874587041">Ilova sozlamalari</translation> <translation id="3596414637720633074">Inkognito rejimidagi tashqi cookie fayllarni taqiqlash</translation> +<translation id="3598010454707842106">“Chromeni moslash” ustiga bosing</translation> <translation id="3599221874935822507">Qavariq</translation> <translation id="3600051066689725006">Veb soʻrovi haqida axborot</translation> <translation id="360180734785106144">Yangi funksiyalar ularning chiqishiga taklif qilinadi</translation> @@ -3916,6 +3920,7 @@ <translation id="4497145443434063861">Kompyuter va Chromecast har xil Wi-Fi tarmoqqa ulangan (m-n, 2,4 GGs va 5 GGs)</translation> <translation id="4500114933761911433"><ph name="PLUGIN_NAME" /> ishdan chiqdi</translation> +<translation id="4500647907053779331"><ph name="LANGUAGE" /> tiliga &tarjima qilish</translation> <translation id="450099669180426158">Undov belgisi</translation> <translation id="4501530680793980440">O‘chirishni tasdiqlash</translation> <translation id="4502423230170890588">Shu qurilmadan olib tashlash</translation> @@ -3946,6 +3951,7 @@ <translation id="4522890784888918985">Farzand hisoblari ishlamaydi</translation> <translation id="4523876148417776526">XML saytlar roʻyxati hali olinmadi.</translation> <translation id="4524832533047962394">Ushbu OT versiyasida qaydlash rejimi ishlamaydi. Tizimni oxirgi versiyagacha yangilang.</translation> +<translation id="4526051299161934899">Yashirin saqlangan varaqlar guruhi</translation> <translation id="4526853756266614740">Mavzuni darhol tatbiq qilish uchun rasm tanlang</translation> <translation id="452750746583162491">Sinxronlangan maʼlumotlaringizni tekshiring</translation> <translation id="4527929807707405172">Teskari varaqlashni yoqish. <ph name="LINK_BEGIN" />Batafsil<ph name="LINK_END" /></translation> @@ -5733,6 +5739,7 @@ <translation id="617213288191670920">Hech qaysi til kiritilmagan</translation> <translation id="6173623053897475761">PIN kodni qayta kiriting</translation> <translation id="6175314957787328458">Microsoft domeni GUID identifikatori</translation> +<translation id="6177412385419165772">Olib tashlanmoqda…</translation> <translation id="6178664161104547336">Sertifikatni tanlang</translation> <translation id="6178682841350631965">Kirish maʼlumotlaringiz yangilandi</translation> <translation id="6180510783007738939">Chiziq vositasi</translation> @@ -6209,6 +6216,7 @@ <translation id="6619801788773578757">Kiosk dasturini qo‘shish</translation> <translation id="6619990499523117484">PIN kodni kiriting</translation> <translation id="6620254580880484313">Konteyner nomi</translation> +<translation id="6620927550847360014"><ph name="DEVICE_TYPE" /> qurilmasidan Bruschetta olib tashlansinmi?</translation> <translation id="6621391692573306628">Bu varaqni boshqa qurilmaga yuborish uchun har ikki qurilmada Chrome hisobiga kiring</translation> <translation id="6622980291894852883">Tasvirlar doim bloklansin</translation> <translation id="6624036901798307345">Planshet rejimida har bir varaq eskizi aks etadigan yangi varaqlar qatorini ochish uchun asboblar panelida varaqlar soni tugmasiga bosing.</translation> @@ -6426,6 +6434,7 @@ <translation id="6818547713623251698">Telefondagi suratlar, media fayllar, bildirishnomalar va ilovalarni ochish</translation> <translation id="6818802132960437751">Viruslardan ichki himoya</translation> <translation id="6818920801736417483">Parollar saqlansinmi?</translation> +<translation id="6820079682647046800">Kerberos hisobi tasdiqlanmadi</translation> <translation id="6823174134746916417">Sensorli panelni ohista teginib bosish</translation> <translation id="6824564591481349393">&E-pochta manzilini nusxalash</translation> <translation id="6824584962142919697">&Elementlarni tekshirish</translation> @@ -6580,6 +6589,7 @@ <translation id="6955698182324067397">Siz ChromeOS tuzatish xususiyatlarini ishga tushirmoqdasiz, ular sshd xizmatini o‘rnatib, USB disklardan yuklanishni xususiyatini yoqadi.</translation> <translation id="6955893174999506273">Yana 1 ta kalit tugma tayinlang</translation> <translation id="6957044667612803194">Bu elektron kalitda PIN kodlar ishlamaydi</translation> +<translation id="6960133692707095572">Chiptasiz ochish</translation> <translation id="6960507406838246615">Linuxni yangilash zarur</translation> <translation id="6960648667961844909"><ph name="LANGUAGE" /> nutq fayllari yuklab olinmadi. Keyinroq yuklab olinadi. Yuklab olinguncha nutq qayta ishlanishi uchun Googlega yuborildi.</translation> <translation id="696103774840402661">Ushbu <ph name="DEVICE_TYPE" /> qurilmasidagi barcha fayllar va foydalanuvchi maʼlumotlari butunlay tozalandi.</translation> @@ -8040,6 +8050,7 @@ <translation id="8272443605911821513">Kengaytmalarni “Qo‘shimcha asboblar” menyusidagi “Kengaytmalar” bo‘limidan boshqarish mumkin.</translation> <translation id="8272786333453048167">Yana ruxsat berish</translation> <translation id="8273905181216423293">Yuklab olish</translation> +<translation id="827488840488530039">Siz ochishga uringan sahifa Kerberos chiptangizni tasdiqlay olmadi</translation> <translation id="8274921654076766238">Lupa yoqilganda klaviatura fokuslanadi</translation> <translation id="8274924778568117936">Yangilanish tugamasdan oldin <ph name="DEVICE_TYPE" /> qurilmasini o‘chirmang va yopmang. Yangilanish o‘rnatilishi bilan <ph name="DEVICE_TYPE" /> qayta ishga tushiriladi.</translation> <translation id="8275038454117074363">Import</translation> @@ -8486,6 +8497,7 @@ <translation id="869884720829132584">Ilovalar menyusi</translation> <translation id="869891660844655955">Tugash muddati</translation> <translation id="8699188901396699995"><ph name="PRINTER_NAME" /> uchun PPD</translation> +<translation id="8702278591052316269">Yashirin saqlangan varaqlar guruhi menyusi</translation> <translation id="8702825062053163569"><ph name="DEVICE_TYPE" /> qulflangan.</translation> <translation id="8703346390800944767">Reklamani yopish</translation> <translation id="8705331520020532516">Seriya raqami</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb index 4ccdbc5..51f801d6 100644 --- a/chrome/app/resources/google_chrome_strings_ms.xtb +++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -247,6 +247,7 @@ <translation id="5895138241574237353">Mulakan Semula</translation> <translation id="5903106910045431592"><ph name="PAGE_TITLE" /> - Log Masuk Rangkaian</translation> <translation id="5924017743176219022">Menyambung ke Internet...</translation> +<translation id="5932997892801542621">Apabila anda menaip dalam bar alamat atau kotak carian, Chrome menghantar perkara yang anda taip kepada Google Drive untuk mendapatkan cadangan item. Tetapan ini dimatikan dalam Inkognito.</translation> <translation id="5940385492829620908">Web, penanda halaman dan barangan Chrome anda yang lain tinggal di sini.</translation> <translation id="5941711191222866238">Minimumkan</translation> <translation id="5941830788786076944">Jadikan Google Chrome penyemak imbas lalai</translation>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6ad5e7c..cdfacf4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3649,10 +3649,6 @@ {"uxstudy1", flag_descriptions::kUXStudy1Name, flag_descriptions::kUXStudy1Description, kOsCrOS, MULTI_VALUE_TYPE(kUXStudy1Choices)}, - {"lacros-profile-migration-for-any-user", - flag_descriptions::kLacrosProfileMigrationForAnyUserName, - flag_descriptions::kLacrosProfileMigrationForAnyUserDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kLacrosProfileMigrationForAnyUser)}, {"lacros-move-profile-migration", flag_descriptions::kLacrosMoveProfileMigrationName, flag_descriptions::kLacrosMoveProfileMigrationDescription, kOsCrOS,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc index 2c6c8879..24d6c4b 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -196,19 +196,6 @@ publishers_.erase(app_type); } -void AppServiceProxyBase::OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) { - for (const auto& iter : publishers_) { - iter.second->OnPreferredAppSet( - app_id, intent_filter ? intent_filter->Clone() : nullptr, - intent ? intent->Clone() : nullptr, - CloneIntentFiltersMap(replaced_app_preferences)); - } -} - void AppServiceProxyBase::OnSupportedLinksPreferenceChanged( const std::string& app_id, bool open_in_app) { @@ -572,14 +559,11 @@ return; } - if (apps_util::IsSupportedLinkForApp(app_id, intent_filter)) { - SetSupportedLinksPreference(app_id); - return; - } + // AddPreferredApp currently only supports adding preferences for link + // intents. + DCHECK(apps_util::IsSupportedLinkForApp(app_id, intent_filter)); - preferred_apps_impl_->AddPreferredApp( - app_registry_cache_.GetAppType(app_id), app_id, std::move(intent_filter), - intent->Clone(), /*from_publisher=*/false); + SetSupportedLinksPreference(app_id); } void AppServiceProxyBase::SetSupportedLinksPreference(
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h index bbb9ab7..5a2cbc6 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.h +++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -109,11 +109,6 @@ void UnregisterPublisher(AppType app_type); // PreferredAppsImpl::Host overrides. - void OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) override; void OnSupportedLinksPreferenceChanged(const std::string& app_id, bool open_in_app) override; @@ -245,8 +240,12 @@ std::vector<apps::IntentFilePtr> files); // Adds a preferred app for |url|. + // Deprecated, prefer calling SetSupportedLinksPreference() instead. + // TODO(crbug.com/1416434): Migrate existing users. void AddPreferredApp(const std::string& app_id, const GURL& url); - // Adds a preferred app for |intent|. + // Adds a preferred app for |intent|. Only supports link intents. + // Deprecated, prefer calling SetSupportedLinksPreference() instead. + // TODO(crbug.com/1416434): Migrate existing users. void AddPreferredApp(const std::string& app_id, const IntentPtr& intent); // Sets |app_id| as the preferred app for all of its supported links ('view'
diff --git a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc index fbbcfa16e..58354572 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_unittest.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_unittest.cc
@@ -590,98 +590,34 @@ proxy()->PreferredAppsList().FindPreferredAppForUrl(kTestUrl3)); } -TEST_F(AppServiceProxyPreferredAppsTest, PreferredApps) { - // Test Initialize. - GetPreferredAppsList().Init(); - - const char kAppId1[] = "abcdefg"; - const char kAppId2[] = "aaaaaaa"; - GURL filter_url = GURL("https://www.google.com/abc"); - auto intent_filter = apps_util::MakeIntentFilterForUrlScope(filter_url); - - GetPreferredAppsList().AddPreferredApp(kAppId1, intent_filter); - - FakePublisherForProxyTest pub(proxy(), AppType::kArc, - std::vector<std::string>{kAppId1, kAppId2}); - - // Test sync preferred app to all subscribers. - filter_url = GURL("https://www.abc.com/"); - GURL another_filter_url = GURL("https://www.test.com/"); - intent_filter = apps_util::MakeIntentFilterForUrlScope(filter_url); - auto another_intent_filter = - apps_util::MakeIntentFilterForUrlScope(another_filter_url); - - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(another_filter_url)); - - PreferredAppsImpl()->AddPreferredApp( - AppType::kUnknown, kAppId2, intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url), - /*from_publisher=*/true); - PreferredAppsImpl()->AddPreferredApp( - AppType::kUnknown, kAppId2, another_intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, - another_filter_url), - /*from_publisher=*/true); - EXPECT_EQ(kAppId2, GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(kAppId2, - GetPreferredAppsList().FindPreferredAppForUrl(another_filter_url)); - - // Test that uninstall removes all the settings for the app. - pub.UninstallApps(std::vector<std::string>{kAppId2}); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(another_filter_url)); - - PreferredAppsImpl()->AddPreferredApp( - AppType::kUnknown, kAppId2, intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url), - /*from_publisher=*/true); - PreferredAppsImpl()->AddPreferredApp( - AppType::kUnknown, kAppId2, another_intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, - another_filter_url), - /*from_publisher=*/true); - - EXPECT_EQ(kAppId2, GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(kAppId2, - GetPreferredAppsList().FindPreferredAppForUrl(another_filter_url)); -} - // Tests that writing a preferred app value before the PreferredAppsList is // initialized queues the write for after initialization. TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsWriteBeforeInit) { base::RunLoop run_loop_read; proxy()->ReinitializeForTesting(proxy()->profile(), run_loop_read.QuitClosure()); - GURL filter_url("https://www.abc.com/"); + GURL filter_url1("https://www.abc.com/"); + GURL filter_url2("https://www.def.com/"); std::string kAppId1 = "aaa"; std::string kAppId2 = "bbb"; - PreferredAppsImpl()->AddPreferredApp( - AppType::kArc, kAppId1, - apps_util::MakeIntentFilterForMimeType("image/png"), nullptr, - /*from_publisher=*/false); + IntentFilters filters1; + filters1.push_back(apps_util::MakeIntentFilterForUrlScope(filter_url1)); + proxy()->SetSupportedLinksPreference(kAppId1, std::move(filters1)); - IntentFilters filters; - filters.push_back(apps_util::MakeIntentFilterForUrlScope(filter_url)); - proxy()->SetSupportedLinksPreference(kAppId2, std::move(filters)); + IntentFilters filters2; + filters2.push_back(apps_util::MakeIntentFilterForUrlScope(filter_url2)); + proxy()->SetSupportedLinksPreference(kAppId2, std::move(filters2)); // Wait for the preferred apps list initialization to read from disk. run_loop_read.Run(); // Both changes to the PreferredAppsList should have been applied. - std::vector<GURL> filesystem_urls( - {GURL("filesystem:chrome://foo/image.png")}); - std::vector<std::string> mime_types({"image/png"}); ASSERT_EQ(kAppId1, - GetPreferredAppsList().FindPreferredAppForIntent( - apps_util::MakeShareIntent(filesystem_urls, mime_types))); - ASSERT_EQ(kAppId2, GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); + GetPreferredAppsList().FindPreferredAppForUrl(filter_url1)); + ASSERT_EQ(kAppId2, + GetPreferredAppsList().FindPreferredAppForUrl(filter_url2)); } TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsPersistency) { @@ -695,10 +631,9 @@ run_loop_read.QuitClosure(), run_loop_write.QuitClosure()); run_loop_read.Run(); - PreferredAppsImpl()->AddPreferredApp( - AppType::kUnknown, kAppId1, intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url), - /*from_publisher=*/false); + IntentFilters filters; + filters.push_back(apps_util::MakeIntentFilterForUrlScope(filter_url)); + proxy()->SetSupportedLinksPreference(kAppId1, std::move(filters)); run_loop_write.Run(); } // Create a new impl to initialize preferred apps from the disk. @@ -782,68 +717,6 @@ EXPECT_FALSE(pub.AppHasSupportedLinksPreference(kAppId3)); } -// Test that app with overlapped works properly. -TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsOverlap) { - // Test Initialize. - GetPreferredAppsList().Init(); - - const char kAppId1[] = "abcdefg"; - const char kAppId2[] = "hijklmn"; - - GURL filter_url_1 = GURL("https://www.google.com/abc"); - GURL filter_url_2 = GURL("http://www.google.com.au/abc"); - GURL filter_url_3 = GURL("https://www.abc.com/abc"); - - auto intent_filter_1 = apps_util::MakeIntentFilterForUrlScope(filter_url_1); - apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(), - PatternMatchType::kLiteral, intent_filter_1); - apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(), - PatternMatchType::kLiteral, intent_filter_1); - - auto intent_filter_2 = apps_util::MakeIntentFilterForUrlScope(filter_url_3); - apps_util::AddConditionValue(ConditionType::kScheme, filter_url_2.scheme(), - PatternMatchType::kLiteral, intent_filter_2); - apps_util::AddConditionValue(ConditionType::kHost, filter_url_2.host(), - PatternMatchType::kLiteral, intent_filter_2); - - auto intent_filter_3 = apps_util::MakeIntentFilterForUrlScope(filter_url_1); - - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_1)); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_2)); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_3)); - EXPECT_EQ(0U, GetPreferredAppsList().GetEntrySize()); - EXPECT_EQ(0U, GetPreferredAppsList().GetEntrySize()); - - PreferredAppsImpl()->AddPreferredApp( - AppType::kArc, kAppId1, intent_filter_1->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url_1), - /*from_publisher=*/true); - EXPECT_EQ(kAppId1, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_1)); - EXPECT_EQ(kAppId1, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_2)); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_3)); - EXPECT_EQ(1U, GetPreferredAppsList().GetEntrySize()); - - // Add preferred app with intent filter overlap with existing entry for - // another app will reset the preferred app setting for the other app. - PreferredAppsImpl()->AddPreferredApp( - AppType::kArc, kAppId2, intent_filter_2->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url_1), - /*from_publisher=*/true); - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_1)); - EXPECT_EQ(kAppId2, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_2)); - EXPECT_EQ(kAppId2, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url_3)); - EXPECT_EQ(1U, GetPreferredAppsList().GetEntrySize()); -} - // Test that app with overlapped supported links works properly. TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsOverlapSupportedLink) { // Test Initialize. @@ -932,37 +805,6 @@ EXPECT_EQ(2U, GetPreferredAppsList().GetEntrySize()); } -// Test that duplicated entry will not be added. -TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsDuplicated) { - // Test Initialize. - GetPreferredAppsList().Init(); - - const char kAppId1[] = "abcdefg"; - - GURL filter_url = GURL("https://www.google.com/abc"); - - auto intent_filter = apps_util::MakeIntentFilterForUrlScope(filter_url); - - EXPECT_EQ(absl::nullopt, - GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(0U, GetPreferredAppsList().GetEntrySize()); - - PreferredAppsImpl()->AddPreferredApp( - AppType::kArc, kAppId1, intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url), - /*from_publisher=*/true); - EXPECT_EQ(kAppId1, GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(1U, GetPreferredAppsList().GetEntrySize()); - EXPECT_EQ(1U, GetPreferredAppsList().GetEntrySize()); - - PreferredAppsImpl()->AddPreferredApp( - AppType::kArc, kAppId1, intent_filter->Clone(), - std::make_unique<Intent>(apps_util::kIntentActionView, filter_url), - /*from_publisher=*/true); - EXPECT_EQ(kAppId1, GetPreferredAppsList().FindPreferredAppForUrl(filter_url)); - EXPECT_EQ(1U, GetPreferredAppsList().GetEntrySize()); -} - // Test that duplicated entry will not be added for supported links. TEST_F(AppServiceProxyPreferredAppsTest, PreferredAppsDuplicatedSupportedLink) { // Test Initialize.
diff --git a/chrome/browser/apps/app_service/publishers/app_publisher.h b/chrome/browser/apps/app_service/publishers/app_publisher.h index 91d89d9..62ba9cf 100644 --- a/chrome/browser/apps/app_service/publishers/app_publisher.h +++ b/chrome/browser/apps/app_service/publishers/app_publisher.h
@@ -196,17 +196,6 @@ // available in App Management. virtual void OpenNativeSettings(const std::string& app_id); - // Indicates that the app identified by |app_id| has been set as a preferred - // app for |intent_filter|, and the |replaced_app_preferences| is the apps - // that are no longer preferred apps for their corresponding |intent_filters|. - // This method is used by the App Service to sync the change to publishers. - // |intent| is needed to set the preferred app in ARC. - virtual void OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) {} - // Indicates that the app identified by |app_id| has had its supported links // preference changed, so that all supported link filters are either preferred // (|open_in_app| is true) or not preferred (|open_in_app| is false). This
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc index a417b2c..4a51692 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.cc +++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -59,10 +59,8 @@ #include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/cpp/intent.h" #include "components/services/app_service/public/cpp/intent_filter.h" -#include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/cpp/permission.h" -#include "components/services/app_service/public/cpp/preferred_app.h" #include "components/services/app_service/public/cpp/types_util.h" #include "extensions/grit/extensions_browser_resources.h" #include "mojo/public/cpp/bindings/remote.h" @@ -259,83 +257,6 @@ return user_interaction_type; } -// Check if this intent filter only contains HTTP and HTTPS schemes. -bool IsHttpOrHttpsIntentFilter(const apps::IntentFilterPtr& intent_filter) { - for (const auto& condition : intent_filter->conditions) { - if (condition->condition_type != apps::ConditionType::kScheme) { - continue; - } - for (const auto& condition_value : condition->condition_values) { - if (condition_value->value != url::kHttpScheme && - condition_value->value != url::kHttpsScheme) { - return false; - } - } - return true; - } - // If there is no scheme |condition_type| found, return false. - return false; -} - -void AddPreferredApp(const std::string& app_id, - const apps::IntentFilterPtr& intent_filter, - apps::IntentPtr intent, - arc::ArcServiceManager* arc_service_manager, - ArcAppListPrefs* prefs) { - arc::mojom::IntentHelperInstance* instance = nullptr; - if (arc_service_manager) { - instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), - AddPreferredApp); - } - if (!instance) { - return; - } - std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(app_id); - - // If |app_info| doesn't exist, we are trying to set preferences for a - // non-ARC app. Set the preferred app as the ARC intent helper package. - const std::string& package_name = - app_info ? app_info->package_name : arc::kArcIntentHelperPackageName; - - instance->AddPreferredApp( - package_name, - apps_util::ConvertAppServiceToArcIntentFilter(package_name, - intent_filter), - apps_util::ConvertAppServiceToArcIntent(std::move(intent))); -} - -void ResetVerifiedLinks( - const apps::ReplacedAppPreferences& replaced_app_preferences, - arc::ArcServiceManager* arc_service_manager, - ArcAppListPrefs* prefs) { - if (!arc_service_manager) { - return; - } - std::vector<std::string> package_names; - - // Find the apps that needs to reset verified link domain status in ARC. - for (auto& entry : replaced_app_preferences) { - auto app_info = prefs->GetApp(entry.first); - if (!app_info) { - continue; - } - for (auto& intent_filter : entry.second) { - if (IsHttpOrHttpsIntentFilter(intent_filter)) { - package_names.push_back(app_info->package_name); - break; - } - } - } - - auto* instance = ARC_GET_INSTANCE_FOR_METHOD( - arc_service_manager->arc_bridge_service()->intent_helper(), - SetVerifiedLinks); - if (instance) { - instance->SetVerifiedLinks(package_names, /*always_open=*/false); - } -} - bool ShouldShow(const ArcAppListPrefs::AppInfo& app_info) { return app_info.show_in_launcher; } @@ -1007,22 +928,6 @@ std::move(callback)); } -void ArcApps::OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) { - auto* arc_service_manager = arc::ArcServiceManager::Get(); - - ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); - if (!prefs) { - return; - } - AddPreferredApp(app_id, intent_filter, std::move(intent), arc_service_manager, - prefs); - ResetVerifiedLinks(replaced_app_preferences, arc_service_manager, prefs); -} - void ArcApps::SetResizeLocked(const std::string& app_id, bool locked) { ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); if (!prefs) {
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.h b/chrome/browser/apps/app_service/publishers/arc_apps.h index 1412f6b..04a564a 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.h +++ b/chrome/browser/apps/app_service/publishers/arc_apps.h
@@ -129,11 +129,6 @@ MenuType menu_type, int64_t display_id, base::OnceCallback<void(MenuItems)> callback) override; - void OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) override; void SetResizeLocked(const std::string& app_id, bool locked) override; void PauseApp(const std::string& app_id) override;
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index aa738f6..391efcad 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -594,6 +594,8 @@ "arc/video/gpu_arc_video_service_host.h", "arc/vmm/arc_vmm_manager.cc", "arc/vmm/arc_vmm_manager.h", + "arc/vmm/arc_vmm_swap_scheduler.cc", + "arc/vmm/arc_vmm_swap_scheduler.h", "arc/wallpaper/arc_wallpaper_service.cc", "arc/wallpaper/arc_wallpaper_service.h", "arc/window_predictor/arc_predictor_app_launch_handler.cc", @@ -4952,6 +4954,7 @@ "arc/tracing/arc_value_event_unittest.cc", "arc/tts/arc_tts_service_unittest.cc", "arc/user_session/arc_user_session_service_unittest.cc", + "arc/vmm/arc_vmm_swap_scheduler_unittest.cc", "arc/wallpaper/arc_wallpaper_service_unittest.cc", "assistant/assistant_util_unittest.cc", "attestation/attestation_ca_client_unittest.cc",
diff --git a/chrome/browser/ash/app_list/OWNERS b/chrome/browser/ash/app_list/OWNERS index 4be8fd7..d290e5b 100644 --- a/chrome/browser/ash/app_list/OWNERS +++ b/chrome/browser/ash/app_list/OWNERS
@@ -7,8 +7,7 @@ # Mainly for launcher search and ranking purposes. amandadeacon@chromium.org +chenjih@google.com tby@chromium.org thanhdng@chromium.org wrong@chromium.org - -per-file app_launch_event_logger*=charleszhao@chromium.org
diff --git a/chrome/browser/ash/app_list/search/help_app_provider.cc b/chrome/browser/ash/app_list/search/help_app_provider.cc index 10e47f9..41899ae 100644 --- a/chrome/browser/ash/app_list/search/help_app_provider.cc +++ b/chrome/browser/ash/app_list/search/help_app_provider.cc
@@ -101,6 +101,10 @@ app_service_proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile_); Observe(&app_service_proxy_->AppRegistryCache()); LoadIcon(); + + // TODO(b/261867385): We manually load the icon from the local codebase as + // the icon load from proxy is flaky. When the flakiness if solved, we can + // safely remove this. icon_ = gfx::CreateVectorIcon(app_list::kHelpAppIcon, kAppIconDimension, SK_ColorTRANSPARENT);
diff --git a/chrome/browser/ash/app_list/search/os_settings_provider.cc b/chrome/browser/ash/app_list/search/os_settings_provider.cc index 3b74c35..afcf178 100644 --- a/chrome/browser/ash/app_list/search/os_settings_provider.cc +++ b/chrome/browser/ash/app_list/search/os_settings_provider.cc
@@ -217,20 +217,19 @@ search_handler_->Observe( search_results_observer_receiver_.BindNewPipeAndPassRemote()); + // TODO(b/261867385): We manually load the icon from the local codebase as + // the icon load from proxy is flaky. When the flakiness if solved, we can + // safely remove this. icon_ = gfx::CreateVectorIcon(app_list::kOsSettingsIcon, kAppIconDimension, SK_ColorTRANSPARENT); if (app_service_proxy_) { Observe(&app_service_proxy_->AppRegistryCache()); - app_service_proxy_->LoadIcon( - app_service_proxy_->AppRegistryCache().GetAppType( - web_app::kOsSettingsAppId), - web_app::kOsSettingsAppId, apps::IconType::kStandard, kAppIconDimension, - /*allow_placeholder_icon=*/false, - base::BindOnce(&OsSettingsProvider::OnLoadIcon, - weak_factory_.GetWeakPtr(), - /*is_from_constructor=*/true)); + // TODO(b/261867385): `LoadIcon()` from constructor is removed as it never + // succeeds and the icon is only updated from "OnAppUpdate()" according to + // the UMA metrics. We can either remove this comments if this issue is + // confirmed, or revert the remove if this issue is solved. LogIconLoadStatus(IconLoadStatus::kBindOnLoadIconFromConstructor); } else { LogStatus(Status::kNoAppServiceProxy);
diff --git a/chrome/browser/ash/app_list/search/system_info/system_info_card_provider.cc b/chrome/browser/ash/app_list/search/system_info/system_info_card_provider.cc index e958567..c135cb34 100644 --- a/chrome/browser/ash/app_list/search/system_info/system_info_card_provider.cc +++ b/chrome/browser/ash/app_list/search/system_info/system_info_card_provider.cc
@@ -80,6 +80,9 @@ StartObservingCalculators(); chromeos::PowerManagerClient::Get()->AddObserver(this); + // TODO(b/261867385): We manually load the icon from the local codebase as + // the icon load from proxy is flaky. When the flakiness if solved, we can + // safely remove this and add the logic to load icons from proxy. os_settings_icon_ = gfx::CreateVectorIcon( app_list::kOsSettingsIcon, kAppIconDimension, SK_ColorTRANSPARENT); diagnostics_icon_ = gfx::CreateVectorIcon(
diff --git a/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.cc b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.cc new file mode 100644 index 0000000..c8125bb --- /dev/null +++ b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.cc
@@ -0,0 +1,62 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h" + +#include "ash/components/arc/arc_prefs.h" +#include "chrome/browser/ash/arc/vmm/arc_vmm_manager.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "components/prefs/pref_service.h" + +namespace arc { + +namespace { + +PrefService* local_state() { + return g_browser_process->local_state(); +} +} // namespace + +ArcVmmSwapScheduler::ArcVmmSwapScheduler( + base::TimeDelta minimum_swap_gap, + base::TimeDelta checking_period, + base::RepeatingCallback<bool()> swappable_checking_call, + base::RepeatingCallback<void(bool)> swap_call) + : minimum_swap_gap_(minimum_swap_gap), + checking_period_(checking_period), + swappable_checking_callback_(std::move(swappable_checking_call)), + swap_callback_(std::move(swap_call)) {} + +ArcVmmSwapScheduler::~ArcVmmSwapScheduler() = default; + +void ArcVmmSwapScheduler::Start() { + if (!timer_.IsRunning()) { + timer_.Start(FROM_HERE, checking_period_, + base::BindRepeating(&ArcVmmSwapScheduler::AttemptSwap, + weak_ptr_factory_.GetWeakPtr())); + } +} + +void ArcVmmSwapScheduler::AttemptSwap() { + const base::Time last_swap_out_time = + local_state()->GetTime(prefs::kArcVmmSwapOutTime); + + if (!last_swap_out_time.is_null()) { + auto past = base::Time::Now() - last_swap_out_time; + if (past < minimum_swap_gap_) { + return; + } + } + + if (!swappable_checking_callback_.is_null() && + swappable_checking_callback_.Run()) { + swap_callback_.Run(true); + + // TODO(sstan): Should be set by swap out notify. + local_state()->SetTime(prefs::kArcVmmSwapOutTime, base::Time::Now()); + } +} + +} // namespace arc
diff --git a/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h new file mode 100644 index 0000000..40f0e75 --- /dev/null +++ b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h
@@ -0,0 +1,45 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_ +#define CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_ + +#include "base/functional/callback.h" +#include "base/timer/timer.h" + +namespace arc { + +// ArcVmmSwapScheduler periodically tries to swap out if it's suitable to enable +// VMM swap for ARCVM. It won't request to swap out within the given interval +// from the last swap out operation. +class ArcVmmSwapScheduler { + public: + ArcVmmSwapScheduler(base::TimeDelta minimum_swap_gap, + base::TimeDelta checking_period, + base::RepeatingCallback<bool()> swappable_checking_call, + base::RepeatingCallback<void(bool)> swap_call); + ArcVmmSwapScheduler(const ArcVmmSwapScheduler&) = delete; + ArcVmmSwapScheduler& operator=(const ArcVmmSwapScheduler&) = delete; + ~ArcVmmSwapScheduler(); + + void Start(); + + private: + void AttemptSwap(); + + base::TimeDelta minimum_swap_gap_; + base::TimeDelta checking_period_; + + base::RepeatingTimer timer_; + + // Callback returns true if the current ARCVM state is swappable. + base::RepeatingCallback<bool()> swappable_checking_callback_; + + // Callback sends swap status to vmm manager. + base::RepeatingCallback<void(bool)> swap_callback_; + + base::WeakPtrFactory<ArcVmmSwapScheduler> weak_ptr_factory_{this}; +}; +} // namespace arc +#endif // CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_
diff --git a/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc new file mode 100644 index 0000000..59ca238 --- /dev/null +++ b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc
@@ -0,0 +1,87 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h" + +#include "ash/components/arc/arc_prefs.h" +#include "ash/components/arc/session/arc_service_manager.h" +#include "base/test/bind.h" +#include "chrome/browser/ash/arc/vmm/arc_vmm_manager.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { + +namespace { +constexpr auto kSwapGap = base::Minutes(60); +constexpr auto kCheckingPreiod = base::Minutes(5); +} // namespace + +class ArcVmmSwapSchedulerTest : public testing::Test { + public: + ArcVmmSwapSchedulerTest() : local_state_(TestingBrowserProcess::GetGlobal()) { + ash::ConciergeClient::InitializeFake(); + } + + ArcVmmSwapSchedulerTest(const ArcVmmSwapSchedulerTest&) = delete; + ArcVmmSwapSchedulerTest& operator=(const ArcVmmSwapSchedulerTest&) = delete; + + ~ArcVmmSwapSchedulerTest() override { ash::ConciergeClient::Shutdown(); } + + void InitScheduler(base::RepeatingCallback<bool()> swappable_checking_call, + base::RepeatingCallback<void(bool)> swap_call) { + scheduler_ = std::make_unique<ArcVmmSwapScheduler>( + kSwapGap, kCheckingPreiod, swappable_checking_call, swap_call); + } + + void SetSwapOutTime(base::Time time) { + local_state_.Get()->SetTime(prefs::kArcVmmSwapOutTime, base::Time()); + } + + base::test::TaskEnvironment* task_environment() { return &task_environment_; } + + ArcVmmSwapScheduler* scheduler() { return scheduler_.get(); } + + protected: + content::BrowserTaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + private: + std::unique_ptr<ArcVmmSwapScheduler> scheduler_; + + ScopedTestingLocalState local_state_; +}; + +TEST_F(ArcVmmSwapSchedulerTest, FirstSwap) { + // Pref value will be the base::Time() if it's empty. + SetSwapOutTime(base::Time()); + + int checking_count = 0, swap_count = 0; + InitScheduler(base::BindLambdaForTesting([&]() { + checking_count++; + return true; + }), + base::BindLambdaForTesting([&](bool enabled) { + if (enabled) { + swap_count++; + } + })); + + scheduler()->Start(); + base::RunLoop().RunUntilIdle(); + + // Checking should wait for the first period. + EXPECT_EQ(checking_count, 0); + + // Check and swapped. + task_environment_.FastForwardBy(base::Minutes(20)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(checking_count, 1); + EXPECT_EQ(swap_count, 1); +} +} // namespace arc
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc index 78f990a5..ff35b74 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator.cc +++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -254,15 +254,11 @@ return false; } - // Currently we turn on profile migration only for Googlers. To test profile - // migration without @google.com account, enable feature - // `kLacrosProfileMigrationForAnyUser` defined in browser_util. - // TODO(crbug.com/1266669): Remove this check once profile migration is - // enabled for all users. - if (!crosapi::browser_util::IsProfileMigrationEnabled(account_id)) { + if (base::FeatureList::IsEnabled( + ash::features::kLacrosProfileMigrationForceOff)) { // TODO(crbug.com/1277848): Once `BrowserDataMigrator` stabilises, remove // this log message. - LOG(WARNING) << "Profile migration is disabled."; + LOG(WARNING) << "Profile migration is disabled by a flag."; return false; }
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.h b/chrome/browser/ash/crosapi/browser_data_migrator.h index aa6514af..f10ee844 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator.h +++ b/chrome/browser/ash/crosapi/browser_data_migrator.h
@@ -209,10 +209,6 @@ MaybeRestartToMigrateWithMigrationStep); FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorRestartTest, MaybeRestartToMigrateMoveAfterCopy); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorRestartTest, - LacrosProfileMigrationForAnyUserDisabled); - FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorRestartTest, - LacrosProfileMigrationForAnyUserDisabledForGoogler); // The common implementation of `MaybeRestartToMigrate` and // `MaybeRestartToMigrateWithDiskCheck`.
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc index 44b37f6..4d659aa9 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc
@@ -526,58 +526,4 @@ } } -TEST_F(BrowserDataMigratorRestartTest, - LacrosProfileMigrationForAnyUserDisabled) { - AddRegularUser("user@gmail.com"); - const user_manager::User* const user = - ash::ProfileHelper::Get()->GetUserByProfile(testing_profile()); - - crosapi::browser_util::RecordDataVer( - local_state(), user->username_hash(), - base::Version( - base::StringPiece(crosapi::browser_util::kRequiredDataVersion))); - { - // If Lacros is enabled, migration should run. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures({ash::features::kLacrosSupport}, {}); - EXPECT_TRUE(BrowserDataMigratorImpl::MaybeRestartToMigrateInternal( - user->GetAccountId(), user->username_hash(), - crosapi::browser_util::PolicyInitState::kAfterInit)); - } - - { - // If Lacros is enabled but `kLacrosProfileMigrationForAnyUser` is disabled, - // migration should not run. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {}, {ash::features::kLacrosProfileMigrationForAnyUser}); - EXPECT_FALSE(BrowserDataMigratorImpl::MaybeRestartToMigrateInternal( - user->GetAccountId(), user->username_hash(), - crosapi::browser_util::PolicyInitState::kAfterInit)); - } -} - -TEST_F(BrowserDataMigratorRestartTest, - LacrosProfileMigrationForAnyUserDisabledForGoogler) { - AddRegularUser("user@google.com"); - const user_manager::User* const user = - ash::ProfileHelper::Get()->GetUserByProfile(testing_profile()); - - crosapi::browser_util::RecordDataVer( - local_state(), user->username_hash(), - base::Version( - base::StringPiece(crosapi::browser_util::kRequiredDataVersion))); - { - // If Lacros is enabled, migration should run even if - // `kLacrosProfileMigrationForAnyUser` is disabled for Googlers. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {ash::features::kLacrosSupport}, - {ash::features::kLacrosProfileMigrationForAnyUser}); - EXPECT_TRUE(BrowserDataMigratorImpl::MaybeRestartToMigrateInternal( - user->GetAccountId(), user->username_hash(), - crosapi::browser_util::PolicyInitState::kAfterInit)); - } -} - } // namespace ash
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator_util.h b/chrome/browser/ash/crosapi/browser_data_migrator_util.h index 296160e..1e8528a4 100644 --- a/chrome/browser/ash/crosapi/browser_data_migrator_util.h +++ b/chrome/browser/ash/crosapi/browser_data_migrator_util.h
@@ -282,12 +282,13 @@ // Preferences's keys that have to be split between Ash and Lacros // based on extension id. constexpr const char* kSplitPreferencesKeys[] = { - "app_list.local_state", "extensions.pinned_extensions", - "extensions.settings", "extensions.toolbar", - "updateclientdata.apps", "web_apps.web_app_ids", + "extensions.pinned_extensions", "extensions.settings", + "extensions.toolbar", "updateclientdata.apps", + "web_apps.web_app_ids", }; // Preferences's keys that should not be migrated to Lacros. constexpr const char* kAshOnlyPreferencesKeys[] = { + "app_list.local_state", "fcm.invalidation.client_id_cache", "invalidation.active_registration_token", "invalidation.per_sender_active_registration_tokens",
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 5ed0947..1971636 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -354,10 +354,10 @@ if (!IsLacrosAllowedToBeEnabled()) return false; - // If profile migration is enabled for the user, then make profile migration a - // requirement to enable lacros. - if (IsProfileMigrationEnabled( - UserManager::Get()->GetPrimaryUser()->GetAccountId())) { + // Unless profile migration is disabled, completion of profile migration is + // required for Lacros to be enabled. + if (!base::FeatureList::IsEnabled( + ash::features::kLacrosProfileMigrationForceOff)) { PrefService* local_state = g_browser_process->local_state(); // Note that local_state can be nullptr in tests. if (local_state && @@ -383,27 +383,6 @@ return base::FeatureList::IsEnabled(ash::features::kLacrosSupport); } -bool IsProfileMigrationEnabled(const AccountId& account_id) { - // Emergency switch to turn off profile migration. Turn this on via Finch in - // case profile migration needs to be turned off after launch. - if (base::FeatureList::IsEnabled( - ash::features::kLacrosProfileMigrationForceOff)) { - return false; - } - - // Now `kLacrosProfileMigrationForAnyUser` is enabled by default thus the - // following condition is false only when the account is not an internal - // google account (@google.com account) and the user has disabled - // `kLacrosProfileMigrationForAnyUser`. - if (gaia::IsGoogleInternalAccountEmail(account_id.GetUserEmail()) || - base::FeatureList::IsEnabled( - ash::features::kLacrosProfileMigrationForAnyUser)) { - return true; - } - - return false; -} - bool IsLacrosEnabledForMigration(const User* user, PolicyInitState policy_init_state) { if (g_lacros_enabled_for_test) @@ -441,14 +420,18 @@ } bool IsProfileMigrationAvailable() { + if (base::FeatureList::IsEnabled( + ash::features::kLacrosProfileMigrationForceOff)) { + return false; + } + UserManager* user_manager = UserManager::Get(); const user_manager::User* user = user_manager->GetPrimaryUser(); // |user| may be nullptr on unittests. - if (!user || !IsProfileMigrationEnabled(user->GetAccountId())) + if (!user || + !IsLacrosEnabledForMigration(user, PolicyInitState::kAfterInit)) { return false; - - if (!IsLacrosEnabledForMigration(user, PolicyInitState::kAfterInit)) - return false; + } // If migration is already completed, it is not necessary to run again. if (IsCopyOrMoveProfileMigrationCompletedForUser(
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index 14cc0a8b..fef6bd6 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -13,7 +13,6 @@ #include "chromeos/ash/components/standalone_browser/lacros_availability.h" #include "third_party/abseil-cpp/absl/types/optional.h" -class AccountId; class PrefRegistrySimple; class PrefService; @@ -399,7 +398,7 @@ // Clears the cached value for LacrosSelection policy. void ClearLacrosSelectionCacheForTest(); -bool IsProfileMigrationEnabled(const AccountId& account_id); +bool IsProfileMigrationEnabled(); // Returns true if the profile migration can run, but not yet completed. bool IsProfileMigrationAvailable();
diff --git a/chrome/browser/ash/crosapi/input_method_test_interface_ash.cc b/chrome/browser/ash/crosapi/input_method_test_interface_ash.cc index 7e63920..68c602c9 100644 --- a/chrome/browser/ash/crosapi/input_method_test_interface_ash.cc +++ b/chrome/browser/ash/crosapi/input_method_test_interface_ash.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/strings/utf_offset_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/ime/ash/ime_bridge.h" #include "ui/base/ime/ash/input_method_ash.h" @@ -65,6 +66,25 @@ std::move(callback)); } +void FakeTextInputMethod::SetSurroundingText(const std::u16string& text, + const gfx::Range selection_range, + uint32_t offset_pos) { + // TODO(b/238838841): Handle `offset_pos`. + // Don't send surrounding text changed event if the surrounding text hasn't + // changed. + if (previous_surrounding_text_ == text && + previous_selection_range_ == selection_range) { + return; + } + + previous_surrounding_text_ = text; + previous_selection_range_ = selection_range; + + for (auto& observer : observers_) { + observer.OnSurroundingTextChanged(text, selection_range); + } +} + void FakeTextInputMethod::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -149,8 +169,46 @@ std::move(callback).Run(); } +void InputMethodTestInterfaceAsh::WaitForNextSurroundingTextChange( + WaitForNextSurroundingTextChangeCallback callback) { + // If there are no queued surrounding text changes, then save the callback to + // be called by the next surrounding text change. Otherwise, pop the first + // pending surrounding text and pass it to the callback. + if (surrounding_text_changes_.empty()) { + DCHECK(surrounding_text_change_callback_.is_null()); + // `callback` is assumed to outlive this class. + surrounding_text_change_callback_ = std::move(callback); + return; + } + const auto& [text, selection_range] = surrounding_text_changes_.front(); + surrounding_text_changes_.pop(); + std::move(callback).Run(text, selection_range); +} + void InputMethodTestInterfaceAsh::OnFocus() { focus_callbacks_.Notify(); } +void InputMethodTestInterfaceAsh::OnSurroundingTextChanged( + const std::u16string& text, + const gfx::Range& selection_range) { + std::vector<size_t> offsets = {selection_range.start(), + selection_range.end()}; + const std::string text_utf8 = + base::UTF16ToUTF8AndAdjustOffsets(text, &offsets); + const gfx::Range selection_range_utf8(offsets[0], offsets[1]); + + // If there is no pending WaitForNextSurroundingTextChange callback, queue the + // surrounding text change to be returned by the next + // WaitForNextSurroundingTextChange call. Otherwise, resolve the pending + // callback with the current surrounding text change. + if (surrounding_text_change_callback_.is_null()) { + surrounding_text_changes_.push({text_utf8, selection_range_utf8}); + return; + } + + std::move(surrounding_text_change_callback_) + .Run(text_utf8, selection_range_utf8); +} + } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/input_method_test_interface_ash.h b/chrome/browser/ash/crosapi/input_method_test_interface_ash.h index f72a392e..8b2010d 100644 --- a/chrome/browser/ash/crosapi/input_method_test_interface_ash.h +++ b/chrome/browser/ash/crosapi/input_method_test_interface_ash.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_ASH_CROSAPI_INPUT_METHOD_TEST_INTERFACE_ASH_H_ #define CHROME_BROWSER_ASH_CROSAPI_INPUT_METHOD_TEST_INTERFACE_ASH_H_ +#include <queue> #include <string> #include "base/callback_list.h" @@ -20,6 +21,9 @@ class Observer { public: virtual void OnFocus() = 0; + virtual void OnSurroundingTextChanged( + const std::u16string& text, + const gfx::Range& selection_range) = 0; }; FakeTextInputMethod(); @@ -35,7 +39,7 @@ KeyEventDoneCallback callback) override; void SetSurroundingText(const std::u16string& text, const gfx::Range selection_range, - uint32_t offset_pos) override {} + uint32_t offset_pos) override; void SetCaretBounds(const gfx::Rect& caret_bounds) override {} ui::VirtualKeyboardController* GetVirtualKeyboardController() const override; void PropertyActivate(const std::string& property_name) override {} @@ -55,6 +59,10 @@ private: uint64_t current_key_event_id_ = 0; std::map<uint64_t, KeyEventDoneCallback> pending_key_event_callbacks_; + + std::u16string previous_surrounding_text_; + gfx::Range previous_selection_range_; + base::ObserverList<Observer>::Unchecked observers_; }; @@ -79,16 +87,26 @@ void KeyEventHandled(uint64_t key_event_id, bool handled, KeyEventHandledCallback callback) override; + void WaitForNextSurroundingTextChange( + WaitForNextSurroundingTextChangeCallback callback) override; // FakeTextInputMethod::Observer: void OnFocus() override; + void OnSurroundingTextChanged(const std::u16string& text, + const gfx::Range& selection_range) override; private: + struct SurroundingText { + std::string text; + gfx::Range selection_range; + }; ash::InputMethodAsh* text_input_target_; FakeTextInputMethod fake_text_input_method_; base::ScopedObservation<FakeTextInputMethod, FakeTextInputMethod::Observer> text_input_method_observation_{this}; base::OnceClosureList focus_callbacks_; + std::queue<SurroundingText> surrounding_text_changes_; + WaitForNextSurroundingTextChangeCallback surrounding_text_change_callback_; }; } // namespace crosapi
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc index aca44186..4dcd4387 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -2338,7 +2338,8 @@ .Offline(), TestCase("openOfficeWordFromDriveOffline") .EnableUploadOfficeToCloud() - .Offline())); + .Offline(), + TestCase("officeShowNudgeGoogleDrive"))); WRAPPED_INSTANTIATE_TEST_SUITE_P( GuestOs, /* guest_os.js */
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc index 0dee999..2e53f231 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -2947,6 +2947,14 @@ return; } + if (name == "setPrefOfficeFileMovedToGoogleDrive") { + absl::optional<int64_t> timestamp = value.FindDouble("timestamp"); + ASSERT_TRUE(timestamp.has_value()); + profile()->GetPrefs()->SetTime(prefs::kOfficeFileMovedToGoogleDrive, + base::Time::FromJsTime(timestamp.value())); + return; + } + if (name == "setCrostiniEnabled") { absl::optional<bool> enabled = value.FindBool("enabled"); ASSERT_TRUE(enabled.has_value());
diff --git a/chrome/browser/ash/file_manager/io_task_controller.cc b/chrome/browser/ash/file_manager/io_task_controller.cc index a4d0f87..d6072cf 100644 --- a/chrome/browser/ash/file_manager/io_task_controller.cc +++ b/chrome/browser/ash/file_manager/io_task_controller.cc
@@ -6,6 +6,7 @@ #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" +#include "base/time/time.h" #include "content/public/browser/device_service.h" #include "services/device/public/mojom/wake_lock_provider.mojom.h" @@ -13,6 +14,8 @@ namespace io_task { +constexpr auto kThrottleInterval = base::Milliseconds(200); + IOTaskController::IOTaskController() { DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -21,15 +24,27 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } +void IOTaskController::MaybeNotifyIOTaskObservers( + const ProgressStatus& status) { + auto last_update = tasks_last_update_[status.task_id]; + + if (base::Time::Now() - last_update < kThrottleInterval) { + return; + } + + NotifyIOTaskObservers(status); +} + void IOTaskController::NotifyIOTaskObservers(const ProgressStatus& status) { for (IOTaskController::Observer& observer : observers_) { observer.OnIOTaskStatus(status); } + tasks_last_update_[status.task_id] = base::Time::Now(); } void IOTaskController::OnIOTaskProgress(const ProgressStatus& status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NotifyIOTaskObservers(status); + MaybeNotifyIOTaskObservers(status); } void IOTaskController::OnIOTaskComplete(IOTaskId task_id, @@ -59,6 +74,10 @@ // Notify observers that the task has been queued. NotifyIOTaskObservers(task->progress()); + // Make sure the first "in progress" event after "queued" is always sent. + // Some listeners require at least one in progress event. + tasks_last_update_[task_id] -= kThrottleInterval; + // TODO(b/199807189): Queue the task. PutIOTask(task_id, std::move(task)) ->Execute(base::BindRepeating(&IOTaskController::OnIOTaskProgress, @@ -98,9 +117,9 @@ void IOTaskController::ProgressPausedTasks() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(b/255264604): TaskId order is potentially racey when mutliple files - // app windows open. Fix this: develop a concept of the current PAUSED task - // in this code, and always progress that task. + // TODO(b/255264604): TaskId order is potentially racey when multiple + // files app windows open. Fix this: develop a concept of the current + // PAUSED task in this code, and always progress that task. for (auto it = tasks_.begin(); it != tasks_.end(); ++it) { IOTask* task = it->second.get(); if (task->progress().IsPaused()) { @@ -138,6 +157,7 @@ } void IOTaskController::RemoveIOTask(const IOTaskId task_id) { + tasks_last_update_.erase(task_id); tasks_.erase(task_id); // TODO(b/255264604): fix me: PAUSED tasks can hold the wake lock and
diff --git a/chrome/browser/ash/file_manager/io_task_controller.h b/chrome/browser/ash/file_manager/io_task_controller.h index 4eb6a3a..185db0e0 100644 --- a/chrome/browser/ash/file_manager/io_task_controller.h +++ b/chrome/browser/ash/file_manager/io_task_controller.h
@@ -8,11 +8,13 @@ #include <map> #include <memory> +#include "base/containers/flat_map.h" #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/sequence_checker.h" #include "base/task/sequenced_task_runner.h" +#include "base/time/time.h" #include "chrome/browser/ash/file_manager/io_task.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/wake_lock.mojom.h" @@ -62,6 +64,7 @@ } private: + void MaybeNotifyIOTaskObservers(const ProgressStatus& status); void NotifyIOTaskObservers(const ProgressStatus& status); void OnIOTaskProgress(const ProgressStatus& status); void OnIOTaskComplete(IOTaskId task_id, ProgressStatus status); @@ -90,6 +93,9 @@ int wake_lock_counter_for_tests_ = 0; + // A map of when each task has been last notified to its observers. + base::flat_map<IOTaskId, base::Time> tasks_last_update_; + base::WeakPtrFactory<IOTaskController> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ash/file_manager/io_task_controller_unittest.cc b/chrome/browser/ash/file_manager/io_task_controller_unittest.cc index 71756e8..5c680ce4 100644 --- a/chrome/browser/ash/file_manager/io_task_controller_unittest.cc +++ b/chrome/browser/ash/file_manager/io_task_controller_unittest.cc
@@ -82,17 +82,7 @@ std::make_unique<DummyIOTask>(source_urls, dest, OperationType::kCopy)); EXPECT_EQ(1, io_task_controller_.wake_lock_counter_for_tests()); - // Wait for the two callbacks posted to the main sequence to finish. - { - base::RunLoop run_loop; - EXPECT_CALL(observer, - OnIOTaskStatus(AllOf( - Field(&ProgressStatus::state, State::kInProgress), - Field(&ProgressStatus::task_id, task_id), base_matcher))) - .WillOnce(RunClosure(run_loop.QuitClosure())); - run_loop.Run(); - } - + // Wait for the callbacks posted to the main sequence to finish. { base::RunLoop run_loop; EXPECT_CALL(observer, OnIOTaskStatus(AllOf(
diff --git a/chrome/browser/extensions/active_tab_apitest.cc b/chrome/browser/extensions/active_tab_apitest.cc index d1e1a20..f82474d 100644 --- a/chrome/browser/extensions/active_tab_apitest.cc +++ b/chrome/browser/extensions/active_tab_apitest.cc
@@ -48,13 +48,8 @@ } }; -#if BUILDFLAG(IS_MAC) -// TODO(crbug.com/1380627): Flaky on Mac. -#define MAYBE_ActiveTab DISABLED_ActiveTab -#else -#define MAYBE_ActiveTab ActiveTab -#endif -IN_PROC_BROWSER_TEST_F(ExtensionActiveTabTest, MAYBE_ActiveTab) { +// TODO(crbug.com/1380627): Flaky on all platforms. +IN_PROC_BROWSER_TEST_F(ExtensionActiveTabTest, DISABLED_ActiveTab) { ASSERT_TRUE(StartEmbeddedTestServer()); ExtensionTestMessageListener background_page_ready("ready");
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc index ddcabc5..41a17658 100644 --- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc +++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_unittest.cc
@@ -10,7 +10,6 @@ #include "base/base_paths.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" -#include "base/json/json_reader.h" #include "base/json/values_util.h" #include "base/strings/strcat.h" #include "base/test/bind.h" @@ -19,6 +18,7 @@ #include "base/test/simple_test_clock.h" #include "base/test/test_file_util.h" #include "base/test/test_future.h" +#include "base/test/values_test_util.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -577,9 +577,9 @@ auto* prefs = profile()->GetTestingPrefService(); prefs->SetManagedPref(prefs::kManagedDefaultFileSystemReadGuardSetting, std::make_unique<base::Value>(CONTENT_SETTING_BLOCK)); - prefs->SetManagedPref(prefs::kManagedFileSystemReadAskForUrls, - base::JSONReader::ReadDeprecated( - "[\"" + kTestOrigin.Serialize() + "\"]")); + prefs->SetManagedPref( + prefs::kManagedFileSystemReadAskForUrls, + base::test::ParseJsonList("[\"" + kTestOrigin.Serialize() + "\"]")); EXPECT_TRUE(permission_context()->CanObtainReadPermission(kTestOrigin)); EXPECT_FALSE(permission_context()->CanObtainReadPermission(kTestOrigin2)); @@ -587,9 +587,9 @@ TEST_F(ChromeFileSystemAccessPermissionContextTest, PolicyReadBlockedForUrls) { auto* prefs = profile()->GetTestingPrefService(); - prefs->SetManagedPref(prefs::kManagedFileSystemReadBlockedForUrls, - base::JSONReader::ReadDeprecated( - "[\"" + kTestOrigin.Serialize() + "\"]")); + prefs->SetManagedPref( + prefs::kManagedFileSystemReadBlockedForUrls, + base::test::ParseJsonList("[\"" + kTestOrigin.Serialize() + "\"]")); EXPECT_FALSE(permission_context()->CanObtainReadPermission(kTestOrigin)); EXPECT_TRUE(permission_context()->CanObtainReadPermission(kTestOrigin2)); @@ -600,9 +600,9 @@ auto* prefs = profile()->GetTestingPrefService(); prefs->SetManagedPref(prefs::kManagedDefaultFileSystemWriteGuardSetting, std::make_unique<base::Value>(CONTENT_SETTING_BLOCK)); - prefs->SetManagedPref(prefs::kManagedFileSystemWriteAskForUrls, - base::JSONReader::ReadDeprecated( - "[\"" + kTestOrigin.Serialize() + "\"]")); + prefs->SetManagedPref( + prefs::kManagedFileSystemWriteAskForUrls, + base::test::ParseJsonList("[\"" + kTestOrigin.Serialize() + "\"]")); EXPECT_TRUE(permission_context()->CanObtainWritePermission(kTestOrigin)); EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin2)); @@ -610,9 +610,9 @@ TEST_F(ChromeFileSystemAccessPermissionContextTest, PolicyWriteBlockedForUrls) { auto* prefs = profile()->GetTestingPrefService(); - prefs->SetManagedPref(prefs::kManagedFileSystemWriteBlockedForUrls, - base::JSONReader::ReadDeprecated( - "[\"" + kTestOrigin.Serialize() + "\"]")); + prefs->SetManagedPref( + prefs::kManagedFileSystemWriteBlockedForUrls, + base::test::ParseJsonList("[\"" + kTestOrigin.Serialize() + "\"]")); EXPECT_FALSE(permission_context()->CanObtainWritePermission(kTestOrigin)); EXPECT_TRUE(permission_context()->CanObtainWritePermission(kTestOrigin2));
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index cfc29191..4d206436 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -5653,15 +5653,6 @@ "Enables wayland logging for Lacros. This generates a significant amount " "of logs on disk. Logs are cleared after two restarts."; -const char kLacrosProfileMigrationForAnyUserName[] = - "Lacros profile migration for any user"; -const char kLacrosProfileMigrationForAnyUserDescription[] = - "Enables lacros profile migration that are currently only enabled for " - "certain users. Please enable with CAUTION. Enabling profile migration " - "means that any pre-existing lacros data will be wiped and replaced with " - "data migrated from ash. It also has a side effect that lacros will be " - "disbled until profile migration is completed."; - const char kLacrosMoveProfileMigrationName[] = "Enforce profile move migration"; const char kLacrosMoveProfileMigrationDescription[] = "Enforce Lacros profile move migration which moves files from Ash profile "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d5167dc..619db65 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -3199,9 +3199,6 @@ extern const char kImeTrayHideVoiceButtonName[]; extern const char kImeTrayHideVoiceButtonDescription[]; -extern const char kLacrosProfileMigrationForAnyUserName[]; -extern const char kLacrosProfileMigrationForAnyUserDescription[]; - extern const char kLacrosMoveProfileMigrationName[]; extern const char kLacrosMoveProfileMigrationDescription[];
diff --git a/chrome/browser/lacros/input_method_lacros_browsertest.cc b/chrome/browser/lacros/input_method_lacros_browsertest.cc index 5931cbe..83608614 100644 --- a/chrome/browser/lacros/input_method_lacros_browsertest.cc +++ b/chrome/browser/lacros/input_method_lacros_browsertest.cc
@@ -396,6 +396,32 @@ } IN_PROC_BROWSER_TEST_F(InputMethodLacrosBrowserTest, + CommitTextUpdatesSurroundingText) { + mojo::Remote<InputMethodTestInterface> input_method = + BindInputMethodTestInterface( + {InputMethodTestInterface::MethodMinVersions::kWaitForFocusMinVersion, + InputMethodTestInterface::MethodMinVersions::kCommitTextMinVersion, + InputMethodTestInterface::MethodMinVersions:: + kWaitForNextSurroundingTextChangeMinVersion}); + if (!input_method.is_bound()) { + GTEST_SKIP() << "Unsupported ash version"; + } + const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + InputMethodTestInterfaceAsyncWaiter input_method_async_waiter( + input_method.get()); + input_method_async_waiter.WaitForFocus(); + + input_method_async_waiter.CommitText("abc"); + std::string surrounding_text; + gfx::Range selection_range; + input_method_async_waiter.WaitForNextSurroundingTextChange(&surrounding_text, + &selection_range); + + EXPECT_EQ(surrounding_text, "abc"); + EXPECT_EQ(selection_range, gfx::Range(3)); +} + +IN_PROC_BROWSER_TEST_F(InputMethodLacrosBrowserTest, CommitTextReplacesCompositionText) { mojo::Remote<InputMethodTestInterface> input_method = BindInputMethodTestInterface( @@ -705,6 +731,32 @@ } IN_PROC_BROWSER_TEST_F(InputMethodLacrosBrowserTest, + SetCompositionUpdatesSurroundingText) { + mojo::Remote<InputMethodTestInterface> input_method = + BindInputMethodTestInterface( + {InputMethodTestInterface::MethodMinVersions::kWaitForFocusMinVersion, + InputMethodTestInterface::MethodMinVersions::kCommitTextMinVersion, + InputMethodTestInterface::MethodMinVersions:: + kWaitForNextSurroundingTextChangeMinVersion}); + if (!input_method.is_bound()) { + GTEST_SKIP() << "Unsupported ash version"; + } + const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + InputMethodTestInterfaceAsyncWaiter input_method_async_waiter( + input_method.get()); + input_method_async_waiter.WaitForFocus(); + + input_method_async_waiter.SetComposition("abc", 3); + std::string surrounding_text; + gfx::Range selection_range; + input_method_async_waiter.WaitForNextSurroundingTextChange(&surrounding_text, + &selection_range); + + EXPECT_EQ(surrounding_text, "abc"); + EXPECT_EQ(selection_range, gfx::Range(3)); +} + +IN_PROC_BROWSER_TEST_F(InputMethodLacrosBrowserTest, SendKeyEventNotHandledTypesInEmptyTextField) { mojo::Remote<InputMethodTestInterface> input_method = BindInputMethodTestInterface(
diff --git a/chrome/browser/media/webrtc/test_stats_dictionary_unittest.cc b/chrome/browser/media/webrtc/test_stats_dictionary_unittest.cc index c4e99bf..041cf4d6 100644 --- a/chrome/browser/media/webrtc/test_stats_dictionary_unittest.cc +++ b/chrome/browser/media/webrtc/test_stats_dictionary_unittest.cc
@@ -10,8 +10,8 @@ #include <vector> #include "base/check.h" -#include "base/json/json_reader.h" #include "base/memory/ref_counted.h" +#include "base/test/values_test_util.h" #include "base/values.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,13 +47,8 @@ class TestStatsDictionaryTest : public testing::Test { public: TestStatsDictionaryTest() { - std::unique_ptr<base::Value> value = - base::JSONReader::ReadDeprecated(kTestStatsReportJson); - CHECK(value); - base::Value::Dict* dictionary = value->GetIfDict(); - CHECK(dictionary); - report_ = - base::MakeRefCounted<TestStatsReportDictionary>(std::move(*dictionary)); + base::Value::Dict dict = base::test::ParseJsonDict(kTestStatsReportJson); + report_ = base::MakeRefCounted<TestStatsReportDictionary>(std::move(dict)); } protected:
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc index fbc2acb..064b412 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest_base.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest_base.cc
@@ -569,8 +569,8 @@ WebRtcTestBase::GetStatsReportDictionary(content::WebContents* tab) const { std::string result = ExecuteJavascript("getStatsReportDictionary()", tab); EXPECT_TRUE(base::StartsWith(result, "ok-", base::CompareCase::SENSITIVE)); - std::unique_ptr<base::Value> parsed_json = - base::JSONReader::ReadDeprecated(result.substr(3)); + absl::optional<base::Value> parsed_json = + base::JSONReader::Read(result.substr(3)); CHECK(parsed_json); base::Value::Dict* dictionary = parsed_json->GetIfDict(); CHECK(dictionary);
diff --git a/chrome/browser/resources/settings/autofill_page/address_edit_dialog_components.ts b/chrome/browser/resources/settings/autofill_page/address_edit_dialog_components.ts index 9e2ded70..061b5f81 100644 --- a/chrome/browser/resources/settings/autofill_page/address_edit_dialog_components.ts +++ b/chrome/browser/resources/settings/autofill_page/address_edit_dialog_components.ts
@@ -147,7 +147,7 @@ } protected setValue(value: string|undefined, address: AddressEntry): void { - address[this.property] = isValueNonEmpty(value) ? [value!] : undefined; + address[this.property] = isValueNonEmpty(value) ? [value!] : []; } }
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb index bff9caf..7130380 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -1242,6 +1242,7 @@ <translation id="7682724950699840886">Cuba petua berikut: pastikan ruang pada peranti anda mencukupi, cuba eksport sekali lagi.</translation> <translation id="7686086654630106285">Lagi tentang iklan laman yang dicadangkan</translation> <translation id="768618399695552958">Beberapa halaman yang anda lawati dipramuat. Halaman mungkin dipramuat melalui pelayan Google apabila dipautkan dari laman Google.</translation> +<translation id="7691043218961417207">Terokai kandungan untuk diikuti</translation> <translation id="7698359219371678927">Buat e-mel dalam <ph name="APP_NAME" /></translation> <translation id="7707922173985738739">Gunakan data mudah alih</translation> <translation id="7709094866268987903">Minat yang anda alih keluar akan dipaparkan di sini</translation>
diff --git a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos_browsertest.cc b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos_browsertest.cc index d1adf08a..8b4a9f7 100644 --- a/chrome/browser/ui/views/tabs/tab_scrubber_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/tabs/tab_scrubber_chromeos_browsertest.cc
@@ -22,6 +22,10 @@ #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" +#include "chromeos/crosapi/cpp/crosapi_constants.h" +#include "components/exo/shell_surface_util.h" +#include "components/exo/test/shell_surface_builder.h" +#include "components/exo/wm_helper.h" #include "content/public/browser/notification_service.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test.h" @@ -29,6 +33,7 @@ #include "ui/aura/window.h" #include "ui/events/event_utils.h" #include "ui/events/test/event_generator.h" +#include "ui/wm/core/window_util.h" namespace { @@ -101,9 +106,13 @@ ash::Shell* shell = ash::Shell::Get(); shell->event_transformation_handler()->set_transformation_mode( ash::EventTransformationHandler::TRANSFORM_NONE); + + wm_helper_ = std::make_unique<exo::WMHelper>(); } void TearDownOnMainThread() override { + wm_helper_.reset(); + browser()->tab_strip_model()->RemoveObserver(this); } @@ -269,6 +278,12 @@ activation_order_.push_back(selection.new_model.active().value()); } + std::unique_ptr<ui::test::EventGenerator> CreateEventGenerator( + Browser* browser) { + aura::Window* window = browser->window()->GetNativeWindow(); + aura::Window* root = window->GetRootWindow(); + return std::make_unique<ui::test::EventGenerator>(root, window); + } // History of tab activation. Scrub() resets it. std::vector<size_t> activation_order_; @@ -311,18 +326,12 @@ TabScrubberChromeOS::GetInstance()->FinishScrub(true); } - private: ui::test::EventGenerator* event_generator_; base::TimeTicks time_for_next_event_ = ui::EventTimeForNow(); int last_x_offset_ = 0; }; - std::unique_ptr<ui::test::EventGenerator> CreateEventGenerator( - Browser* browser) { - aura::Window* window = browser->window()->GetNativeWindow(); - aura::Window* root = window->GetRootWindow(); - return std::make_unique<ui::test::EventGenerator>(root, window); - } + std::unique_ptr<exo::WMHelper> wm_helper_; }; // Swipe a single tab in each direction. @@ -588,3 +597,44 @@ EXPECT_THAT(activation_order_, testing::ElementsAre(3, 2, 1, 0)); EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); } + +// Check scroll events other than 3-fingers scroll are not stopped by +// TabScrubber. +IN_PROC_BROWSER_TEST_F(TabScrubberChromeOSTest, + EventPropagationWithLacrosWindow) { + // Create Lacros window and activate. + auto shell_surface = exo::test::ShellSurfaceBuilder({100, 100}) + .BuildClientControlledShellSurface(); + exo::SetShellApplicationId(shell_surface->GetWidget()->GetNativeWindow(), + crosapi::kLacrosAppIdPrefix); + wm::ActivateWindow(shell_surface->GetWidget()->GetNativeWindow()); + ASSERT_TRUE( + wm::IsActiveWindow(shell_surface->GetWidget()->GetNativeWindow())); + + auto event_generator = CreateEventGenerator(browser()); + int kOffset = 100; + + // Stop propagation for 3-fingers scroll event. + ui::ScrollEvent scroll_event_with_3_fingers( + ui::ET_SCROLL, gfx::Point(0, 0), ui::EventTimeForNow(), 0, kOffset, 0, + kOffset, 0, kScrubbingGestureFingerCount); + event_generator->Dispatch(&scroll_event_with_3_fingers); + EXPECT_TRUE(scroll_event_with_3_fingers.stopped_propagation()); + + // Fling scroll event should be passed to Lacros via HandleTabScrubbing, but + // should not be stopped as it may be consumed elsewhere as well. + ui::ScrollEvent fling_scroll_event(ui::ET_SCROLL_FLING_START, + gfx::Point(0, 0), ui::EventTimeForNow(), 0, + kOffset, 0, kOffset, 0, 0); + event_generator->Dispatch(&fling_scroll_event); + EXPECT_FALSE(fling_scroll_event.stopped_propagation()); + + // Other scroll events should be not handled by TabScrubber and should not be + // stopped. + ui::ScrollEvent scroll_event_with_2_fingers(ui::ET_SCROLL, gfx::Point(0, 0), + ui::EventTimeForNow(), 0, kOffset, + 0, kOffset, 0, + /*finger_count=*/2); + event_generator->Dispatch(&scroll_event_with_2_fingers); + EXPECT_FALSE(scroll_event_with_2_fingers.stopped_propagation()); +}
diff --git a/chrome/browser/ui/web_applications/web_app_dark_mode_browsertest.cc b/chrome/browser/ui/web_applications/web_app_dark_mode_browsertest.cc index 0a024a9..f21e533 100644 --- a/chrome/browser/ui/web_applications/web_app_dark_mode_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_dark_mode_browsertest.cc
@@ -191,7 +191,8 @@ } // namespace IN_PROC_BROWSER_TEST_F(WebAppDarkModeOriginTrialBrowserTest, OriginTrial) { - ManifestUpdateManager::BypassWindowCloseWaitingForTesting() = true; + ManifestUpdateManager::ScopedBypassWindowCloseWaitingForTesting + bypass_window_close_waiting; bool serve_token = true; content::URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
diff --git a/chrome/browser/ui/web_applications/web_app_launch_handler_browsertest.cc b/chrome/browser/ui/web_applications/web_app_launch_handler_browsertest.cc index 3c50a2dd..4e7a51f 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_handler_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_handler_browsertest.cc
@@ -574,7 +574,8 @@ } // namespace IN_PROC_BROWSER_TEST_F(WebAppLaunchHandlerOriginTrialBrowserTest, OriginTrial) { - ManifestUpdateManager::BypassWindowCloseWaitingForTesting() = true; + ManifestUpdateManager::ScopedBypassWindowCloseWaitingForTesting + bypass_window_close_waiting; bool serve_token = true; content::URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
diff --git a/chrome/browser/web_applications/manifest_update_manager.cc b/chrome/browser/web_applications/manifest_update_manager.cc index 3ec7752..f5a2888 100644 --- a/chrome/browser/web_applications/manifest_update_manager.cc +++ b/chrome/browser/web_applications/manifest_update_manager.cc
@@ -62,6 +62,16 @@ } // namespace +ManifestUpdateManager::ScopedBypassWindowCloseWaitingForTesting:: + ScopedBypassWindowCloseWaitingForTesting() { + BypassWindowCloseWaitingForTesting() = true; // IN-TEST +} + +ManifestUpdateManager::ScopedBypassWindowCloseWaitingForTesting:: + ~ScopedBypassWindowCloseWaitingForTesting() { + BypassWindowCloseWaitingForTesting() = false; // IN-TEST +} + class ManifestUpdateManager::PreUpdateWebContentsObserver : public content::WebContentsObserver { public:
diff --git a/chrome/browser/web_applications/manifest_update_manager.h b/chrome/browser/web_applications/manifest_update_manager.h index 3eacc09..df4eba8 100644 --- a/chrome/browser/web_applications/manifest_update_manager.h +++ b/chrome/browser/web_applications/manifest_update_manager.h
@@ -54,6 +54,16 @@ // of being triggered by page loads. class ManifestUpdateManager final : public WebAppInstallManagerObserver { public: + class ScopedBypassWindowCloseWaitingForTesting { + public: + ScopedBypassWindowCloseWaitingForTesting(); + ScopedBypassWindowCloseWaitingForTesting( + const ScopedBypassWindowCloseWaitingForTesting&) = delete; + ScopedBypassWindowCloseWaitingForTesting& operator=( + const ScopedBypassWindowCloseWaitingForTesting&) = delete; + ~ScopedBypassWindowCloseWaitingForTesting(); + }; + using UpdatePendingCallback = base::OnceCallback<void(const GURL& url)>; // Sets a |callback| for testing code to get notified when a manifest update // is needed and there is a PWA window preventing the update from proceeding. @@ -65,8 +75,6 @@ base::OnceCallback<void(const GURL& url, ManifestUpdateResult result)>; static void SetResultCallbackForTesting(ResultCallback callback); - static bool& BypassWindowCloseWaitingForTesting(); - ManifestUpdateManager(); ~ManifestUpdateManager() override; @@ -175,6 +183,8 @@ const absl::optional<AppId>& app_id, ManifestUpdateResult result); + static bool& BypassWindowCloseWaitingForTesting(); + raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr; raw_ptr<WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr; #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc index aa57c4a..6e05845 100644 --- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc +++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -4671,7 +4671,8 @@ } )"; - ManifestUpdateManager::BypassWindowCloseWaitingForTesting() = true; + ManifestUpdateManager::ScopedBypassWindowCloseWaitingForTesting + bypass_window_close_waiting; testing::TestParamInfo< std::tuple<AppIdTestParam, AppIdTestParam, AppIdTestParam>> @@ -4974,8 +4975,6 @@ EXPECT_EQ(ExpectTitleUpdate() ? "Different app name" : "Test app name", GetProvider().registrar_unsafe().GetAppShortName(app_id)); - - ManifestUpdateManager::BypassWindowCloseWaitingForTesting() = false; } INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 92a6979..2a49998 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1676764274-89e7cd69a3c233e9436e207fa0d34deb05d8c223.profdata +chrome-mac-arm-main-1676850737-cf05384d4dd0a82f02206a88ab39798586a0aee8.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index b99b5d4..c0db6be 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1676764274-cda5544408048f6a3d63f7536782ceca78cbb6d3.profdata +chrome-mac-main-1676850737-2f65e102ccf6597581256e4836afa725b70810d5.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 957303c..1453eef 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1676764274-5b529975f2445ff9ef1500e28bfa1723e386f0a3.profdata +chrome-win32-main-1676850737-e568e6f32363b1512688b64dcab99bc913427796.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 94571596..9a6cc4d 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1676764274-cdafd1264b975758bef64097d5ef3ae1fab3543b.profdata +chrome-win64-main-1676850737-55e96e551a7601c07a5374f7b376ad4a763a729a.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 114b8e2..9623766d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4403,6 +4403,7 @@ "//chromeos/components/onc:test_support", "//chromeos/components/quick_answers/public/cpp:cpp", "//chromeos/components/remote_apps/mojom:mojom", + "//chromeos/crosapi/cpp:crosapi_constants", "//chromeos/dbus/dlp", "//chromeos/dbus/missive:test_support", "//chromeos/process_proxy",
diff --git a/chrome/test/data/webui/settings/autofill_section_test.ts b/chrome/test/data/webui/settings/autofill_section_test.ts index 4d8edda..4f94d05 100644 --- a/chrome/test/data/webui/settings/autofill_section_test.ts +++ b/chrome/test/data/webui/settings/autofill_section_test.ts
@@ -8,7 +8,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AutofillManagerImpl, CountryDetailManagerImpl, CrInputElement, CrTextareaElement} from 'chrome://settings/lazy_load.js'; -import {assertEquals, assertFalse, assertGT, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertArrayEquals, assertEquals, assertFalse, assertGT, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {eventToPromise, whenAttributeIs, isVisible} from 'chrome://webui-test/test_util.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -440,8 +440,8 @@ return expectEvent(dialog, 'save-address', function() { dialog.$.saveButton.click(); }).then(function() { - assertEquals(undefined, address.phoneNumbers); - assertEquals(undefined, address.emailAddresses); + assertArrayEquals([], address.phoneNumbers!); + assertArrayEquals([], address.emailAddresses!); }); }); });
diff --git a/chromeos/ash/components/drivefs/sync_status_tracker.cc b/chromeos/ash/components/drivefs/sync_status_tracker.cc index 6ccb588..2260a32 100644 --- a/chromeos/ash/components/drivefs/sync_status_tracker.cc +++ b/chromeos/ash/components/drivefs/sync_status_tracker.cc
@@ -178,7 +178,7 @@ path.empty() ? GetNodePath(node) : std::move(path)}; } -void SyncStatusTracker::SetNodeState(Node* node, +void SyncStatusTracker::SetNodeState(Node* const node, const SyncStatus status, const int64_t transferred = 0, const int64_t total = 0) { @@ -215,8 +215,8 @@ SyncStatusTracker::NodeState SyncStatusTracker::NodeState::Set( const SyncStatus status, - int32_t transferred, - int32_t total) { + int64_t transferred, + int64_t total) { NodeState delta; // If the node's status has changed, mark as dirty (both the node and the
diff --git a/chromeos/ash/components/drivefs/sync_status_tracker.h b/chromeos/ash/components/drivefs/sync_status_tracker.h index 8acddcc..40a41e94 100644 --- a/chromeos/ash/components/drivefs/sync_status_tracker.h +++ b/chromeos/ash/components/drivefs/sync_status_tracker.h
@@ -78,11 +78,13 @@ SetSyncState(id, path, SyncStatus::kCompleted); } } + void SetQueued(const int64_t id, const base::FilePath& path, const int64_t total) { SetSyncState(id, path, SyncStatus::kQueued, 0, total); } + void SetInProgress(const int64_t id, const base::FilePath& path, const int64_t transferred, @@ -93,6 +95,7 @@ } SetSyncState(id, path, SyncStatus::kInProgress, transferred, total); } + void SetError(const int64_t id, const base::FilePath& path) { SetSyncState(id, path, SyncStatus::kError); } @@ -130,8 +133,8 @@ // ancestors until the root. void SetNodeState(Node* node, const SyncStatus status, - const int64_t transferred, - const int64_t total); + int64_t transferred, + int64_t total); const SyncState GetNodeState( const Node* node, @@ -148,9 +151,7 @@ // Sets the state with the provided new values and returns a "delta" NodeState // representing what changes were applied. If delta is pristine, no changes // were applied. - NodeState Set(const SyncStatus new_status, - const int32_t transferred, - const int32_t total); + NodeState Set(SyncStatus new_status, int64_t transferred, int64_t total); void ApplyDelta(const NodeState& status); @@ -160,7 +161,9 @@ inline bool IsPristine() const { return !is_dirty_; } float GetProgress() const { - return total_ ? (float)transferred_ / (float)total_ : 0; + return total_ + ? static_cast<double>(transferred_) / static_cast<double>(total_) + : 0; } SyncStatus GetStatus() const;
diff --git a/chromeos/crosapi/mojom/test_controller.mojom b/chromeos/crosapi/mojom/test_controller.mojom index 95bf6cec..96a9745 100644 --- a/chromeos/crosapi/mojom/test_controller.mojom +++ b/chromeos/crosapi/mojom/test_controller.mojom
@@ -9,6 +9,7 @@ import "chromeos/crosapi/mojom/tts.mojom"; import "mojo/public/mojom/base/values.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; +import "ui/gfx/range/mojom/range.mojom"; // The enum of possible states for a shelf item. // Each value must be a power of 2. @@ -158,8 +159,8 @@ // This interface is implemented by Ash-Chrome. // It enables tests in Lacros-Chrome to send commands as an input method. -// Next version: 4 -// Next method id: 5 +// Next version: 5 +// Next method id: 6 [Stable, Uuid="c214f4f5-c583-44d1-9547-bb2456d9e70b"] interface InputMethodTestInterface { // Calls the callback when the input method has focused on some input field. @@ -196,6 +197,21 @@ // Handle the pending key event with ID `key_event_id` with result of // `handled`. [MinVersion=3] KeyEventHandled@4(uint64 key_event_id, bool handled) => (); + + // Waits for the next surrounding text change since the last + // WaitForNextSurroundingTextChange call (or since InputMethodTestInterface + // was instantiated if there are no previous calls to + // WaitForNextSurroundingTextChange). + // + // In other words, starting from when InputMethodTestInterface is created, any + // surrounding text changes are queued. WaitForNextSurroundingTextChange + // pops the front of the queue, or waits for a new surrounding text change if + // the queue is empty. + // + // This avoids timing issues so that calling WaitForNextSurroundingTextChange + // always returns the same set of values for the same set of operations. + [MinVersion=4] WaitForNextSurroundingTextChange@5() => + (string surrounding_text, gfx.mojom.Range selection_range); }; // This interface is implemented by Ash-Chrome.
diff --git a/chromeos/strings/chromeos_strings_bs.xtb b/chromeos/strings/chromeos_strings_bs.xtb index 7bbf29f..231b7f8 100644 --- a/chromeos/strings/chromeos_strings_bs.xtb +++ b/chromeos/strings/chromeos_strings_bs.xtb
@@ -520,6 +520,7 @@ <translation id="576835345334454681">Pojačavanje osvjetljenja ekrana</translation> <translation id="57838592816432529">Isključi zvuk</translation> <translation id="5784136236926853061">Visoka HTTP latentnost</translation> +<translation id="5826644637650799838">O umjetnosti</translation> <translation id="5832805196449965646">Dodaj osobu</translation> <translation id="583281660410589416">Nepoznato</translation> <translation id="5843706793424741864">Farenhajt</translation>
diff --git a/chromeos/strings/chromeos_strings_uz.xtb b/chromeos/strings/chromeos_strings_uz.xtb index c87ce48f..c4774cec 100644 --- a/chromeos/strings/chromeos_strings_uz.xtb +++ b/chromeos/strings/chromeos_strings_uz.xtb
@@ -520,6 +520,7 @@ <translation id="576835345334454681">Displey yorqinligini oshirish</translation> <translation id="57838592816432529">Ovozni o‘chirib qo‘yish</translation> <translation id="5784136236926853061">HTTP kechikishi yuqori</translation> +<translation id="5826644637650799838">Asar haqida</translation> <translation id="5832805196449965646">Foydalanuvchi qo‘shish</translation> <translation id="583281660410589416">Noma’lum</translation> <translation id="5843706793424741864">Farengeyt</translation>
diff --git a/components/arc/test/fake_intent_helper_instance.cc b/components/arc/test/fake_intent_helper_instance.cc index 8a32568..979a61d8e 100644 --- a/components/arc/test/fake_intent_helper_instance.cc +++ b/components/arc/test/fake_intent_helper_instance.cc
@@ -55,10 +55,6 @@ void FakeIntentHelperInstance::AddPreferredPackage( const std::string& package_name) {} -void FakeIntentHelperInstance::AddPreferredApp(const std::string& package_name, - IntentFilter intent_filter, - mojom::IntentInfoPtr intent) {} - void FakeIntentHelperInstance::SetVerifiedLinks( const std::vector<std::string>& package_names, bool always_open) {
diff --git a/components/arc/test/fake_intent_helper_instance.h b/components/arc/test/fake_intent_helper_instance.h index 0a07e03c..1b5db50 100644 --- a/components/arc/test/fake_intent_helper_instance.h +++ b/components/arc/test/fake_intent_helper_instance.h
@@ -75,10 +75,6 @@ void AddPreferredPackage(const std::string& package_name) override; - void AddPreferredApp(const std::string& package_name, - IntentFilter intent_filter, - mojom::IntentInfoPtr intent) override; - void SetVerifiedLinks(const std::vector<std::string>& package_names, bool always_open) override;
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 503ab66..28e973e 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "19.15", - "log_list_timestamp": "2023-02-18T12:54:28Z", + "version": "19.16", + "log_list_timestamp": "2023-02-19T12:54:54Z", "operators": [ { "name": "Google",
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index 2927c6d..5132cd3 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -51,6 +51,8 @@ "extended_drag_source.h", "frame_sink_resource_manager.cc", "frame_sink_resource_manager.h", + "frame_timing_history.cc", + "frame_timing_history.h", "gamepad.cc", "gamepad.h", "gamepad_observer.h", @@ -216,6 +218,8 @@ "test/mock_security_delegate.h", "test/shell_surface_builder.cc", "test/shell_surface_builder.h", + "test/surface_tree_host_test_util.cc", + "test/surface_tree_host_test_util.h", "test/test_security_delegate.cc", "test/test_security_delegate.h", ]
diff --git a/components/exo/buffer_unittest.cc b/components/exo/buffer_unittest.cc index 3c44f68..e03994b 100644 --- a/components/exo/buffer_unittest.cc +++ b/components/exo/buffer_unittest.cc
@@ -256,7 +256,7 @@ frame.metadata.begin_frame_ack.frame_id.sequence_number = viz::BeginFrameArgs::kStartingFrameNumber; frame.metadata.begin_frame_ack.has_damage = true; - frame.metadata.frame_token = 1; + frame.metadata.frame_token = surface_tree_host->GenerateNextFrameToken(); frame.metadata.device_scale_factor = 1; auto pass = viz::CompositorRenderPass::Create(); pass->SetNew(viz::CompositorRenderPassId{1}, gfx::Rect(buffer_size), @@ -264,7 +264,7 @@ frame.render_pass_list.push_back(std::move(pass)); frame.resource_list.push_back(resource); VerifySyncTokensInCompositorFrame(&frame); - frame_sink_holder->SubmitCompositorFrame(std::move(frame)); + surface_tree_host->SubmitCompositorFrameForTesting(std::move(frame)); } buffer->OnDetach(); @@ -313,7 +313,7 @@ viz::BeginFrameId(viz::BeginFrameArgs::kManualSourceId, viz::BeginFrameArgs::kStartingFrameNumber); frame.metadata.begin_frame_ack.has_damage = true; - frame.metadata.frame_token = 1; + frame.metadata.frame_token = surface_tree_host->GenerateNextFrameToken(); frame.metadata.device_scale_factor = 1; auto pass = viz::CompositorRenderPass::Create(); pass->SetNew(viz::CompositorRenderPassId{1}, gfx::Rect(buffer_size), @@ -321,7 +321,7 @@ frame.render_pass_list.push_back(std::move(pass)); frame.resource_list.push_back(resource); VerifySyncTokensInCompositorFrame(&frame); - frame_sink_holder->SubmitCompositorFrame(std::move(frame)); + surface_tree_host->SubmitCompositorFrameForTesting(std::move(frame)); // Try to release buffer in last frame. This can happen during a resize // when frame sink id changes. @@ -346,13 +346,13 @@ viz::BeginFrameId(viz::BeginFrameArgs::kManualSourceId, viz::BeginFrameArgs::kStartingFrameNumber); frame.metadata.begin_frame_ack.has_damage = true; - frame.metadata.frame_token = 1; + frame.metadata.frame_token = surface_tree_host->GenerateNextFrameToken(); frame.metadata.device_scale_factor = 1; auto pass = viz::CompositorRenderPass::Create(); pass->SetNew(viz::CompositorRenderPassId{1}, gfx::Rect(buffer_size), gfx::Rect(buffer_size), gfx::Transform()); frame.render_pass_list.push_back(std::move(pass)); - frame_sink_holder->SubmitCompositorFrame(std::move(frame)); + surface_tree_host->SubmitCompositorFrameForTesting(std::move(frame)); } base::RunLoop().RunUntilIdle();
diff --git a/components/exo/frame_timing_history.cc b/components/exo/frame_timing_history.cc new file mode 100644 index 0000000..8a5092dd --- /dev/null +++ b/components/exo/frame_timing_history.cc
@@ -0,0 +1,140 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/frame_timing_history.h" + +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" + +namespace exo { +namespace { + +constexpr size_t kRollingHistorySize = 60u; +constexpr double kFrameArrivalIntervalEstimationPercentile = 90.0; +constexpr double kFrameTransferDurationEstimationPercentile = 90.0; + +// Reports metrics when the number of data points reaches this threshold. +constexpr int32_t kReportMetricsThreshold = 100; + +} // namespace + +FrameTimingHistory::FrameTimingHistory() + : frame_arrival_interval_history_(kRollingHistorySize), + frame_transfer_duration_history_(kRollingHistorySize) {} + +FrameTimingHistory::~FrameTimingHistory() = default; + +base::TimeDelta FrameTimingHistory::GetFrameTransferDurationEstimate() const { + return frame_transfer_duration_history_.Percentile( + kFrameTransferDurationEstimationPercentile); +} + +base::TimeTicks FrameTimingHistory::GetNextFrameArrivalTimeEstimate() const { + return last_frame_arrival_time_ + GetFrameArrivalIntervalEstimate(); +} + +void FrameTimingHistory::FrameArrived(base::TimeTicks arrival_time) { + DCHECK_GE(arrival_time, last_frame_arrival_time_); + + if (!last_frame_arrival_time_.is_null()) { + frame_arrival_interval_history_.InsertSample(arrival_time - + last_frame_arrival_time_); + } + + last_frame_arrival_time_ = arrival_time; +} + +void FrameTimingHistory::FrameSubmitted(uint32_t frame_token, + base::TimeTicks submitted_time) { + DCHECK(pending_submitted_time_.find(frame_token) == + pending_submitted_time_.end()); + + pending_submitted_time_[frame_token] = submitted_time; + + RecordFrameResponseToRemote(/*did_not_produce=*/false); + RecordFrameHandled(/*discarded=*/false); +} + +void FrameTimingHistory::FrameDidNotProduce() { + RecordFrameResponseToRemote(/*did_not_produce=*/true); +} + +void FrameTimingHistory::FrameReceivedAtRemoteSide( + uint32_t frame_token, + base::TimeTicks received_time) { + auto iter = pending_submitted_time_.find(frame_token); + + DCHECK(iter != pending_submitted_time_.end()) + << "Frame submitted time information is missing. Frame Token: " + << frame_token; + + DCHECK_GE(received_time, iter->second); + frame_transfer_duration_history_.InsertSample(received_time - iter->second); + pending_submitted_time_.erase(iter); + + // FrameSubmitted() / FrameReceivedAtRemoteSide() are supposed to match, so + // that the map won't grow indefinitely. + DCHECK_LE(pending_submitted_time_.size(), 60u); +} + +void FrameTimingHistory::FrameDiscarded() { + RecordFrameHandled(/*discarded=*/true); +} + +void FrameTimingHistory::MayRecordDidNotProduceToFrameArrvial(bool valid) { + if (last_did_not_produce_time_.is_null()) { + return; + } + + base::TimeDelta duration = + valid ? (base::TimeTicks::Now() - last_did_not_produce_time_) + : base::TimeDelta(); + + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Graphics.Exo.Smoothness.DidNotProduceToFrameArrival", duration, + base::Microseconds(1), base::Milliseconds(50), 50); + + last_did_not_produce_time_ = {}; +} + +void FrameTimingHistory::RecordFrameResponseToRemote(bool did_not_produce) { + last_did_not_produce_time_ = + did_not_produce ? base::TimeTicks::Now() : base::TimeTicks(); + last_frame_did_not_produce_ = did_not_produce; + + frame_response_count_++; + if (did_not_produce) { + frame_response_did_not_produce_++; + } + + if (frame_response_count_ >= kReportMetricsThreshold) { + UMA_HISTOGRAM_PERCENTAGE( + "Graphics.Exo.Smoothness.PercentDidNotProduceFrame", + frame_response_did_not_produce_ * 100 / frame_response_count_); + frame_response_count_ = 0; + frame_response_did_not_produce_ = 0; + } +} + +void FrameTimingHistory::RecordFrameHandled(bool discarded) { + frame_handling_count_++; + if (discarded) { + frame_handling_discarded_++; + } + + if (frame_handling_count_ >= kReportMetricsThreshold) { + UMA_HISTOGRAM_PERCENTAGE( + "Graphics.Exo.Smoothness.PercentFrameDiscarded", + frame_handling_discarded_ * 100 / frame_handling_count_); + frame_handling_count_ = 0; + frame_handling_discarded_ = 0; + } +} + +base::TimeDelta FrameTimingHistory::GetFrameArrivalIntervalEstimate() const { + return frame_arrival_interval_history_.Percentile( + kFrameArrivalIntervalEstimationPercentile); +} + +} // namespace exo
diff --git a/components/exo/frame_timing_history.h b/components/exo/frame_timing_history.h new file mode 100644 index 0000000..43bec32 --- /dev/null +++ b/components/exo/frame_timing_history.h
@@ -0,0 +1,89 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_FRAME_TIMING_HISTORY_H_ +#define COMPONENTS_EXO_FRAME_TIMING_HISTORY_H_ + +#include "base/containers/flat_map.h" +#include "base/time/time.h" +#include "cc/base/rolling_time_delta_history.h" + +namespace exo { + +// Records timing history of compositor frames and reports related metrics. Used +// by LayerTreeFrameSinkHolder to determine when to respond to BeginFrame +// requests. +class FrameTimingHistory { + public: + FrameTimingHistory(); + + FrameTimingHistory(const FrameTimingHistory&) = delete; + FrameTimingHistory& operator=(const FrameTimingHistory&) = delete; + + ~FrameTimingHistory(); + + // Estimates the duration from LayerTreeFrameSinkHolder submitting a frame to + // the remote side receiving it. + base::TimeDelta GetFrameTransferDurationEstimate() const; + // Estimates the time when the next frame arrives at LayerTreeFrameSinkHolder. + base::TimeTicks GetNextFrameArrivalTimeEstimate() const; + + // Notifies that a frame arrives at LayerTreeFrameSinkHolder. + void FrameArrived(base::TimeTicks arrival_time); + + // Notifies that a frame is submitted to the remote side. + void FrameSubmitted(uint32_t frame_token, base::TimeTicks submitted_time); + // Notifies that a frame request is responded with DidNotProduceFrame. + void FrameDidNotProduce(); + // Notifies that a frame is received at the remote side. + void FrameReceivedAtRemoteSide(uint32_t frame_token, + base::TimeTicks received_time); + // Notifies that a frame is discarded locally. + void FrameDiscarded(); + + // Records a value for DidNotProduceToFrameArrival histogram if applicable. + // For each DidNotProduceFrame response, the first call to this method + // reports one value; the subsequent calls (if any) are ignored. + // - `valid` set to false indicates that either (1) DidNotProduceFrame is + // issued when there are already queued BeginFrame requests; or (2) a new + // BeginFrame request arrives before the next frame. In this case the + // value reported is 0. + // - `valid` set to true: called at the next frame arrival time, reporting + // the duration between sending the DidNotProduceFrame response and the + // next frame arrival. + void MayRecordDidNotProduceToFrameArrvial(bool valid); + + bool last_frame_did_not_produce() const { + return last_frame_did_not_produce_; + } + + private: + void RecordFrameResponseToRemote(bool did_not_produce); + void RecordFrameHandled(bool discarded); + + base::TimeDelta GetFrameArrivalIntervalEstimate() const; + + base::TimeTicks last_frame_arrival_time_; + + base::flat_map<uint32_t, base::TimeTicks> pending_submitted_time_; + + cc::RollingTimeDeltaHistory frame_arrival_interval_history_; + cc::RollingTimeDeltaHistory frame_transfer_duration_history_; + + // True if the last response to the remote side is DidNotProduceFrame. + bool last_frame_did_not_produce_ = false; + // Records the time of sending the last DidNotProduceFrame response. It is + // used to report DidNotProduceToFrameArrival metric and then reset. + base::TimeTicks last_did_not_produce_time_; + + // Counters used to report metrics. + int32_t frame_response_count_ = 0; + int32_t frame_response_did_not_produce_ = 0; + int32_t frame_handling_count_ = 0; + int32_t frame_handling_discarded_ = 0; +}; + +} // namespace exo + +#endif // COMPONENTS_EXO_FRAME_TIMING_HISTORY_H_
diff --git a/components/exo/layer_tree_frame_sink_holder.cc b/components/exo/layer_tree_frame_sink_holder.cc index fc281ea..5d5fc21 100644 --- a/components/exo/layer_tree_frame_sink_holder.cc +++ b/components/exo/layer_tree_frame_sink_holder.cc
@@ -14,6 +14,10 @@ namespace exo { +BASE_FEATURE(kExoReactiveFrameSubmission, + "ExoReactiveFrameSubmission", + base::FEATURE_DISABLED_BY_DEFAULT); + //////////////////////////////////////////////////////////////////////////////// // LayerTreeFrameSinkHolder, public: @@ -21,11 +25,19 @@ SurfaceTreeHost* surface_tree_host, std::unique_ptr<cc::LayerTreeFrameSink> frame_sink) : surface_tree_host_(surface_tree_host), - frame_sink_(std::move(frame_sink)) { + frame_sink_(std::move(frame_sink)), + reactive_frame_submission_( + base::FeatureList::IsEnabled(kExoReactiveFrameSubmission)) { + if (reactive_frame_submission_) { + frame_timing_history_.emplace(); + } + frame_sink_->BindToClient(this); } LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() { + DiscardCachedFrame(); + if (frame_sink_) frame_sink_->DetachFromClient(); @@ -36,6 +48,9 @@ // static void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed( std::unique_ptr<LayerTreeFrameSinkHolder> holder) { + // Ensure that no cached frame is submitted in the future. + holder->StopProcessingPendingFrames(); + // Delete immediately if LayerTreeFrameSink was already lost. if (holder->is_lost_) return; @@ -47,22 +62,20 @@ } // Submit an empty frame to ensure that pending release callbacks will be - // processed in a finite amount of time. + // processed in a finite amount of time. This frame is submitted directly, + // disregarding BeginFrame request. viz::CompositorFrame frame; - frame.metadata.begin_frame_ack.frame_id = - viz::BeginFrameId(viz::BeginFrameArgs::kManualSourceId, - viz::BeginFrameArgs::kStartingFrameNumber); - frame.metadata.begin_frame_ack.has_damage = true; - frame.metadata.frame_token = ++holder->next_frame_token_; + frame.metadata.begin_frame_ack = + viz::BeginFrameAck::CreateManualAckWithDamage(); + frame.metadata.frame_token = + holder->surface_tree_host_->GenerateNextFrameToken(); frame.metadata.device_scale_factor = holder->last_frame_device_scale_factor_; auto pass = viz::CompositorRenderPass::Create(); pass->SetNew(viz::CompositorRenderPassId{1}, gfx::Rect(holder->last_frame_size_in_pixels_), gfx::Rect(holder->last_frame_size_in_pixels_), gfx::Transform()); frame.render_pass_list.push_back(std::move(pass)); - holder->last_frame_resources_.clear(); - holder->frame_sink_->SubmitCompositorFrame(std::move(frame), - /*hit_test_data_changed=*/true); + holder->SubmitCompositorFrameToRemote(&frame); // Delete sink holder immediately if not waiting for resources to be // reclaimed. @@ -83,26 +96,46 @@ void LayerTreeFrameSinkHolder::SubmitCompositorFrame( viz::CompositorFrame frame) { - DCHECK(!is_lost_); + if (!reactive_frame_submission_) { + SubmitCompositorFrameToRemote(&frame); + return; + } - last_frame_size_in_pixels_ = frame.size_in_pixels(); - last_frame_device_scale_factor_ = frame.metadata.device_scale_factor; - last_frame_resources_.clear(); - for (auto& resource : frame.resource_list) - last_frame_resources_.push_back(resource.id); - frame_sink_->SubmitCompositorFrame(std::move(frame), - /*hit_test_data_changed=*/true); -} + frame_timing_history_->FrameArrived(base::TimeTicks::Now()); + frame_timing_history_->MayRecordDidNotProduceToFrameArrvial(/*valid=*/true); -void LayerTreeFrameSinkHolder::DidNotProduceFrame( - const viz::BeginFrameAck& ack) { - DCHECK(!is_lost_); - frame_sink_->DidNotProduceFrame(ack, cc::FrameSkippedReason::kNoDamage); + DiscardCachedFrame(); + + if (!ShouldSubmitFrameNow()) { + cached_frame_ = std::move(frame); + return; + } + + ProcessFirstPendingBeginFrame(&frame); + SubmitCompositorFrameToRemote(&frame); + UpdateSubmitFrameTimer(); } //////////////////////////////////////////////////////////////////////////////// // cc::LayerTreeFrameSinkClient overrides: +void LayerTreeFrameSinkHolder::SetBeginFrameSource( + viz::BeginFrameSource* source) { + if (!reactive_frame_submission_) { + return; + } + + if (begin_frame_source_) { + begin_frame_source_->RemoveObserver(this); + } + + begin_frame_source_ = source; + + if (begin_frame_source_) { + begin_frame_source_->AddObserver(this); + } +} + absl::optional<viz::HitTestRegionList> LayerTreeFrameSinkHolder::BuildHitTestData() { return {}; @@ -124,13 +157,40 @@ } void LayerTreeFrameSinkHolder::DidReceiveCompositorFrameAck() { + pending_submit_frames_--; + DCHECK_GE(pending_submit_frames_, 0); + if (surface_tree_host_) surface_tree_host_->DidReceiveCompositorFrameAck(); + + if (!reactive_frame_submission_) { + return; + } + + if (pending_submit_frames_ == 0) { + while (!pending_discarded_frame_notifications_.empty()) { + SendDiscardedFrameNotifications( + pending_discarded_frame_notifications_.front()); + pending_discarded_frame_notifications_.pop(); + } + } + + if (cached_frame_ && ShouldSubmitFrameNow()) { + ProcessFirstPendingBeginFrame(&cached_frame_.value()); + SubmitCompositorFrameToRemote(&cached_frame_.value()); + cached_frame_.reset(); + UpdateSubmitFrameTimer(); + } } void LayerTreeFrameSinkHolder::DidPresentCompositorFrame( uint32_t frame_token, const viz::FrameTimingDetails& details) { + if (frame_timing_history_) { + frame_timing_history_->FrameReceivedAtRemoteSide( + frame_token, details.received_compositor_frame_timestamp); + } + if (surface_tree_host_) { surface_tree_host_->DidPresentCompositorFrame( frame_token, details.presentation_feedback); @@ -138,6 +198,8 @@ } void LayerTreeFrameSinkHolder::DidLoseLayerTreeFrameSink() { + StopProcessingPendingFrames(); + last_frame_resources_.clear(); resource_manager_.ClearAllCallbacks(); is_lost_ = true; @@ -167,4 +229,177 @@ ScheduleDelete(); } +bool LayerTreeFrameSinkHolder::OnBeginFrameDerivedImpl( + const viz::BeginFrameArgs& args) { + DCHECK(reactive_frame_submission_); + + frame_timing_history_->MayRecordDidNotProduceToFrameArrvial(/*valid=*/false); + + pending_begin_frames_.emplace(); + pending_begin_frames_.back().begin_frame_ack = + viz::BeginFrameAck(args, /*has_damage=*/true); + pending_begin_frames_.back().send_deadline_estimate = + args.deadline - + viz::BeginFrameArgs::DefaultEstimatedDisplayDrawTime(args.interval) - + frame_timing_history_->GetFrameTransferDurationEstimate(); + + if (pending_begin_frames_.size() > 1) { + return true; + } + + if (cached_frame_ && ShouldSubmitFrameNow()) { + ProcessFirstPendingBeginFrame(&cached_frame_.value()); + SubmitCompositorFrameToRemote(&cached_frame_.value()); + cached_frame_.reset(); + + DCHECK(!submit_frame_timer_.IsRunning()); + } else { + UpdateSubmitFrameTimer(); + } + + return true; +} + +void LayerTreeFrameSinkHolder::OnBeginFrameSourcePausedChanged(bool paused) {} + +void LayerTreeFrameSinkHolder::SubmitCompositorFrameToRemote( + viz::CompositorFrame* frame) { + DCHECK(!is_lost_); + + if (frame_timing_history_) { + frame_timing_history_->FrameSubmitted(frame->metadata.frame_token, + base::TimeTicks::Now()); + } + + last_frame_size_in_pixels_ = frame->size_in_pixels(); + last_frame_device_scale_factor_ = frame->metadata.device_scale_factor; + last_frame_resources_.clear(); + for (auto& resource : frame->resource_list) { + last_frame_resources_.push_back(resource.id); + } + frame_sink_->SubmitCompositorFrame(std::move(*frame), + /*hit_test_data_changed=*/true); + + pending_submit_frames_++; +} + +void LayerTreeFrameSinkHolder::DiscardCachedFrame() { + if (!cached_frame_) { + return; + } + + DCHECK(reactive_frame_submission_); + + for (const auto& resource : cached_frame_->resource_list) { + resource_manager_.ReclaimResource(resource.ToReturnedResource()); + } + + if (pending_submit_frames_ == 0) { + SendDiscardedFrameNotifications(cached_frame_->metadata.frame_token); + } else { + // If a frame (frame_1) sent to the remote side hasn't received ack, we + // should hold off sending back ack to `surface_tree_host_` for the + // discarded frame (frame_2). The reason is that acks are not associated + // with frame tokens. Sending back an ack here for frame_2 will be + // indistinguishable from an ack for frame_1. + pending_discarded_frame_notifications_.push( + cached_frame_->metadata.frame_token); + } + + cached_frame_.reset(); + + frame_timing_history_->FrameDiscarded(); +} + +void LayerTreeFrameSinkHolder::SendDiscardedFrameNotifications( + uint32_t frame_token) { + if (!surface_tree_host_) { + return; + } + + surface_tree_host_->DidReceiveCompositorFrameAck(); + surface_tree_host_->DidPresentCompositorFrame( + frame_token, gfx::PresentationFeedback::Failure()); +} + +void LayerTreeFrameSinkHolder::StopProcessingPendingFrames() { + DiscardCachedFrame(); + pending_begin_frames_ = {}; + UpdateSubmitFrameTimer(); +} + +void LayerTreeFrameSinkHolder::OnSendDeadlineExpired(bool update_timer) { + DCHECK(!is_lost_ && reactive_frame_submission_); + + if (pending_begin_frames_.empty()) { + return; + } + + if (cached_frame_) { + ProcessFirstPendingBeginFrame(&cached_frame_.value()); + SubmitCompositorFrameToRemote(&cached_frame_.value()); + cached_frame_.reset(); + } else { + auto& pending_begin_frame = pending_begin_frames_.front(); + pending_begin_frame.begin_frame_ack.has_damage = false; + frame_sink_->DidNotProduceFrame(pending_begin_frame.begin_frame_ack, + cc::FrameSkippedReason::kNoDamage); + + pending_begin_frames_.pop(); + + frame_timing_history_->FrameDidNotProduce(); + if (!pending_begin_frames_.empty()) { + frame_timing_history_->MayRecordDidNotProduceToFrameArrvial( + /*valid=*/false); + } + } + + if (update_timer) { + UpdateSubmitFrameTimer(); + } +} + +void LayerTreeFrameSinkHolder::UpdateSubmitFrameTimer() { + while (!pending_begin_frames_.empty() && + base::TimeTicks::Now() >= + pending_begin_frames_.front().send_deadline_estimate) { + OnSendDeadlineExpired(/*update_timer=*/false); + }; + + if (!pending_begin_frames_.empty()) { + submit_frame_timer_.Start( + FROM_HERE, pending_begin_frames_.front().send_deadline_estimate, + base::BindOnce(&LayerTreeFrameSinkHolder::OnSendDeadlineExpired, + base::Unretained(this), true)); + } else { + submit_frame_timer_.Stop(); + } +} + +void LayerTreeFrameSinkHolder::ProcessFirstPendingBeginFrame( + viz::CompositorFrame* frame) { + DCHECK(!pending_begin_frames_.empty()); + + frame->metadata.begin_frame_ack = + pending_begin_frames_.front().begin_frame_ack; + pending_begin_frames_.pop(); +} + +bool LayerTreeFrameSinkHolder::ShouldSubmitFrameNow() const { + DCHECK(reactive_frame_submission_); + + if (pending_begin_frames_.empty() || pending_submit_frames_ >= 1) { + return false; + } + + // Two cases when we don't want to wait any longer: + // - if `last_frame_did_notproduce_` is true (i.e., the previous response to + // BeginFrame is DidNotProduceFrame); or + // - if we expect there won't be more frames arriving before reaching the + // deadline. + return frame_timing_history_->last_frame_did_not_produce() || + frame_timing_history_->GetNextFrameArrivalTimeEstimate() >= + pending_begin_frames_.front().send_deadline_estimate; +} + } // namespace exo
diff --git a/components/exo/layer_tree_frame_sink_holder.h b/components/exo/layer_tree_frame_sink_holder.h index 5c3b1640..2981442 100644 --- a/components/exo/layer_tree_frame_sink_holder.h +++ b/components/exo/layer_tree_frame_sink_holder.h
@@ -7,11 +7,16 @@ #include <memory> +#include "base/containers/queue.h" +#include "base/feature_list.h" +#include "base/timer/timer.h" #include "cc/trees/layer_tree_frame_sink_client.h" #include "components/exo/frame_sink_resource_manager.h" +#include "components/exo/frame_timing_history.h" #include "components/exo/wm_helper.h" +#include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/quads/compositor_frame.h" -#include "components/viz/common/resources/release_callback.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace viz { struct FrameTimingDetails; @@ -25,10 +30,19 @@ class SurfaceTreeHost; +// When this feature is disabled (by default at the moment), frames are +// submitted to the remote side as soon as they arrive, disregarding BeginFrame +// requests. +// +// TODO(yzshen): Remove this flag and always submit according to BeginFrame +// requests. crbug.com/1408614 +BASE_DECLARE_FEATURE(kExoReactiveFrameSubmission); + // This class talks to CompositorFrameSink and keeps track of references to // the contents of Buffers. class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient, - public WMHelper::LifetimeManager::Observer { + public WMHelper::LifetimeManager::Observer, + public viz::BeginFrameObserverBase { public: LayerTreeFrameSinkHolder(SurfaceTreeHost* surface_tree_host, std::unique_ptr<cc::LayerTreeFrameSink> frame_sink); @@ -46,7 +60,6 @@ std::unique_ptr<LayerTreeFrameSinkHolder> holder); void SubmitCompositorFrame(viz::CompositorFrame frame); - void DidNotProduceFrame(const viz::BeginFrameAck& ack); // Returns true if owned LayerTreeFrameSink has been lost. bool is_lost() const { return is_lost_; } @@ -54,7 +67,7 @@ FrameSinkResourceManager* resource_manager() { return &resource_manager_; } // Overridden from cc::LayerTreeFrameSinkClient: - void SetBeginFrameSource(viz::BeginFrameSource* source) override {} + void SetBeginFrameSource(viz::BeginFrameSource* source) override; absl::optional<viz::HitTestRegionList> BuildHitTestData() override; void ReclaimResources(std::vector<viz::ReturnedResource> resources) override; void SetTreeActivationCallback(base::RepeatingClosure callback) override {} @@ -73,11 +86,39 @@ const gfx::Transform& transform) override {} private: + struct PendingBeginFrame { + viz::BeginFrameAck begin_frame_ack; + base::TimeTicks send_deadline_estimate; + }; + void ScheduleDelete(); // WMHelper::LifetimeManager::Observer: void OnDestroyed() override; + // viz::BeginFrameObserverBase: + bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override; + void OnBeginFrameSourcePausedChanged(bool paused) override; + + void SubmitCompositorFrameToRemote(viz::CompositorFrame* frame); + + // Discards `cached_frame_`, reclaims resources and returns failure + // presentation feedback. + void DiscardCachedFrame(); + void SendDiscardedFrameNotifications(uint32_t frame_token); + + void StopProcessingPendingFrames(); + + void OnSendDeadlineExpired(bool update_timer); + + // Starts timer based on estimated deadline of the first pending BeginFrame + // request; or stops timer if there is no pending BeginFrame request. + void UpdateSubmitFrameTimer(); + + void ProcessFirstPendingBeginFrame(viz::CompositorFrame* frame); + + bool ShouldSubmitFrameNow() const; + SurfaceTreeHost* surface_tree_host_; std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_; @@ -86,12 +127,32 @@ gfx::Size last_frame_size_in_pixels_; float last_frame_device_scale_factor_ = 1.0f; std::vector<viz::ResourceId> last_frame_resources_; - viz::FrameTokenGenerator next_frame_token_; + + absl::optional<viz::CompositorFrame> cached_frame_; bool is_lost_ = false; bool delete_pending_ = false; WMHelper::LifetimeManager* lifetime_manager_ = nullptr; + + viz::BeginFrameSource* begin_frame_source_ = nullptr; + + base::queue<PendingBeginFrame> pending_begin_frames_; + + // The number of frames submitted to the remote side for which acks haven't + // been received. + int pending_submit_frames_ = 0; + + // A queue of discarded frame tokens for which acks and presentation feedbacks + // haven't been sent to `surface_tree_host_`. + base::queue<uint32_t> pending_discarded_frame_notifications_; + + base::DeadlineTimer submit_frame_timer_; + + const bool reactive_frame_submission_ = false; + + // Set if `reactive_frame_submission_` is enabled. + absl::optional<FrameTimingHistory> frame_timing_history_; }; } // namespace exo
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc index 97f1ff14..6c5ae16 100644 --- a/components/exo/pointer_unittest.cc +++ b/components/exo/pointer_unittest.cc
@@ -32,6 +32,7 @@ #include "components/exo/test/exo_test_helper.h" #include "components/exo/test/mock_security_delegate.h" #include "components/exo/test/shell_surface_builder.h" +#include "components/exo/test/surface_tree_host_test_util.h" #include "components/exo/wm_helper.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/service/surfaces/surface.h" @@ -256,7 +257,7 @@ // Set pointer surface. pointer->SetCursor(pointer_surface.get(), gfx::Point(5, 5)); - base::RunLoop().RunUntilIdle(); + test::WaitForLastFramePresentation(pointer.get()); const viz::CompositorRenderPass* last_render_pass; { @@ -272,7 +273,7 @@ // Adjust hotspot. pointer->SetCursor(pointer_surface.get(), gfx::Point()); - base::RunLoop().RunUntilIdle(); + test::WaitForLastFramePresentation(pointer.get()); // Verify that adjustment to hotspot resulted in new frame. { @@ -426,7 +427,7 @@ // Set pointer surface. pointer->SetCursor(pointer_surface.get(), gfx::Point()); EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size()); - base::RunLoop().RunUntilIdle(); + test::WaitForLastFramePresentation(pointer.get()); { viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId(); @@ -447,15 +448,7 @@ // Set the same pointer surface again. pointer->SetCursor(pointer_surface.get(), gfx::Point()); EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size()); - auto& list = - pointer->GetActivePresentationCallbacksForTesting().begin()->second; - base::RunLoop runloop; - list.push_back(base::BindRepeating( - [](base::RepeatingClosure callback, const gfx::PresentationFeedback&) { - callback.Run(); - }, - runloop.QuitClosure())); - runloop.Run(); + test::WaitForLastFramePresentation(pointer.get()); { viz::SurfaceId surface_id = pointer->host_window()->GetSurfaceId();
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 564cd17e..213c410 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -1142,9 +1142,6 @@ AppendContentsToFrame(origin, device_scale_factor, client_submits_in_pixel_coords, frame); - - DCHECK(!current_resource_.id || - resource_manager->HasReleaseCallbackForResource(current_resource_.id)); } bool Surface::IsSynchronized() const {
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index 916e63e..d671907 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -125,6 +125,8 @@ SetRootSurface(nullptr); LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed( std::move(layer_tree_frame_sink_holder_)); + + CleanUpCallbacks(); } void SurfaceTreeHost::SetRootSurface(Surface* root_surface) { @@ -145,22 +147,6 @@ // Force recreating resources when the surface is added to a tree again. root_surface_->SurfaceHierarchyResourcesLost(); root_surface_ = nullptr; - - // Call all frame callbacks with a null frame time to indicate that they - // have been cancelled. - while (!frame_callbacks_.empty()) { - frame_callbacks_.front().Run(base::TimeTicks()); - frame_callbacks_.pop_front(); - } - - DCHECK(presentation_callbacks_.empty()); - for (auto entry : active_presentation_callbacks_) { - while (!entry.second.empty()) { - entry.second.front().Run(gfx::PresentationFeedback()); - entry.second.pop_front(); - } - } - active_presentation_callbacks_.clear(); } if (root_surface) { @@ -182,10 +168,11 @@ } void SurfaceTreeHost::DidReceiveCompositorFrameAck() { - while (!frame_callbacks_.empty()) { - frame_callbacks_.front().Run(base::TimeTicks::Now()); - frame_callbacks_.pop_front(); + const base::TimeTicks now = base::TimeTicks::Now(); + for (auto& callback : frame_callbacks_.front()) { + callback.Run(now); } + frame_callbacks_.pop(); } void SurfaceTreeHost::DidPresentCompositorFrame( @@ -208,6 +195,16 @@ security_delegate_ = security_delegate; } +void SurfaceTreeHost::SubmitCompositorFrameForTesting( + viz::CompositorFrame frame) { + // Make sure that every submission has an entry pushed into + // `frame_callbacks_`, which will be pop when ack is received. + frame_callbacks_.emplace(); + active_presentation_callbacks_[frame.metadata.frame_token] = + PresentationCallbacks(); + layer_tree_frame_sink_holder_->SubmitCompositorFrame(std::move(frame)); +} + //////////////////////////////////////////////////////////////////////////////// // SurfaceDelegate overrides: @@ -298,14 +295,19 @@ << ", StartupId=" << (startup_id ? *startup_id : "''"); } - root_surface_->AppendSurfaceHierarchyCallbacks(&frame_callbacks_, + std::list<Surface::FrameCallback> current_frame_callbacks; + root_surface_->AppendSurfaceHierarchyCallbacks(¤t_frame_callbacks, &presentation_callbacks_); + + frame_callbacks_.push(std::move(current_frame_callbacks)); + + const uint32_t frame_token = frame.metadata.frame_token; if (!presentation_callbacks_.empty()) { - DCHECK_EQ(active_presentation_callbacks_.count(*next_token_), 0u); - active_presentation_callbacks_[*next_token_] = + DCHECK_EQ(active_presentation_callbacks_.count(frame_token), 0u); + active_presentation_callbacks_[frame_token] = std::move(presentation_callbacks_); } else { - active_presentation_callbacks_[*next_token_] = PresentationCallbacks(); + active_presentation_callbacks_[frame_token] = PresentationCallbacks(); } root_surface_->AppendSurfaceHierarchyContentsToFrame( @@ -364,7 +366,13 @@ viz::SolidColorDrawQuad* solid_quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); solid_quad->SetNew(quad_state, quad_rect, quad_rect, SkColors::kBlack, - /*force_anti_aliasing_off=*/false); + /*anti_aliasing_off=*/false); + + // Make sure that every submission has an entry pushed into + // `frame_callbacks_`, which will be pop when ack is received. + frame_callbacks_.emplace(); + active_presentation_callbacks_[frame.metadata.frame_token] = + PresentationCallbacks(); layer_tree_frame_sink_holder_->SubmitCompositorFrame(std::move(frame)); } @@ -412,12 +420,13 @@ // it's resources are lost anyways. layer_tree_frame_sink_holder_ = std::make_unique<LayerTreeFrameSinkHolder>( this, host_window_->CreateLayerTreeFrameSink()); + CleanUpCallbacks(); } viz::CompositorFrame frame; frame.metadata.begin_frame_ack = viz::BeginFrameAck::CreateManualAckWithDamage(); - frame.metadata.frame_token = ++next_token_; + frame.metadata.frame_token = GenerateNextFrameToken(); frame.render_pass_list.push_back(viz::CompositorRenderPass::Create()); const std::unique_ptr<viz::CompositorRenderPass>& render_pass = frame.render_pass_list.back(); @@ -484,4 +493,24 @@ return host_window_->layer()->device_scale_factor(); } +void SurfaceTreeHost::CleanUpCallbacks() { + // Call all frame callbacks with a null frame time to indicate that they + // have been cancelled. + while (!frame_callbacks_.empty()) { + for (auto& callback : frame_callbacks_.front()) { + callback.Run(base::TimeTicks()); + } + frame_callbacks_.pop(); + } + + DCHECK(presentation_callbacks_.empty()); + for (auto entry : active_presentation_callbacks_) { + while (!entry.second.empty()) { + entry.second.front().Run(gfx::PresentationFeedback()); + entry.second.pop_front(); + } + } + active_presentation_callbacks_.clear(); +} + } // namespace exo
diff --git a/components/exo/surface_tree_host.h b/components/exo/surface_tree_host.h index ee8bbb2..88dbe00 100644 --- a/components/exo/surface_tree_host.h +++ b/components/exo/surface_tree_host.h
@@ -8,6 +8,7 @@ #include <memory> #include <set> +#include "base/containers/queue.h" #include "base/memory/weak_ptr.h" #include "components/exo/layer_tree_frame_sink_holder.h" #include "components/exo/surface.h" @@ -89,6 +90,8 @@ return active_presentation_callbacks_; } + uint32_t GenerateNextFrameToken() { return ++next_token_; } + // SurfaceDelegate: void OnSurfaceCommit() override; bool IsSurfaceSynchronized() const override; @@ -136,6 +139,8 @@ void SetSecurityDelegate(SecurityDelegate* security_delegate); + void SubmitCompositorFrameForTesting(viz::CompositorFrame frame); + protected: void UpdateDisplayOnTree(); @@ -168,6 +173,8 @@ // the host window's layer's scale factor. float GetScaleFactor(); + void CleanUpCallbacks(); + Surface* root_surface_ = nullptr; // Position of root surface relative to topmost, leftmost sub-surface. The @@ -177,11 +184,14 @@ std::unique_ptr<aura::Window> host_window_; std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_; - // This list contains the callbacks to notify the client when it is a good - // time to start producing a new frame. These callbacks move to - // |frame_callbacks_| when Commit() is called. They fire when the effect - // of the Commit() is scheduled to be drawn. - std::list<Surface::FrameCallback> frame_callbacks_; + // This queue contains lists the callbacks to notify the client when it is a + // good time to start producing a new frame. Each list corresponds to a + // compositor frame, in the order of submission to + // `layer_tree_frame_sink_holder_`. + // + // These callbacks move to |frame_callbacks_| when Commit() is called. They + // fire when the effect of the Commit() is scheduled to be drawn. + base::queue<std::list<Surface::FrameCallback>> frame_callbacks_; // These lists contains the callbacks to notify the client when surface // contents have been presented.
diff --git a/components/exo/test/surface_tree_host_test_util.cc b/components/exo/test/surface_tree_host_test_util.cc new file mode 100644 index 0000000..949df74 --- /dev/null +++ b/components/exo/test/surface_tree_host_test_util.cc
@@ -0,0 +1,28 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/exo/test/surface_tree_host_test_util.h" + +#include "base/check.h" +#include "base/functional/bind.h" +#include "base/run_loop.h" + +namespace exo::test { + +void WaitForLastFramePresentation(SurfaceTreeHost* surface_tree_host) { + CHECK(!surface_tree_host->GetActivePresentationCallbacksForTesting().empty()); + + auto& list = surface_tree_host->GetActivePresentationCallbacksForTesting() + .rbegin() + ->second; + base::RunLoop runloop; + list.push_back(base::BindRepeating( + [](base::RepeatingClosure callback, const gfx::PresentationFeedback&) { + callback.Run(); + }, + runloop.QuitClosure())); + runloop.Run(); +} + +} // namespace exo::test
diff --git a/components/exo/test/surface_tree_host_test_util.h b/components/exo/test/surface_tree_host_test_util.h new file mode 100644 index 0000000..265dc94e --- /dev/null +++ b/components/exo/test/surface_tree_host_test_util.h
@@ -0,0 +1,18 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_EXO_TEST_SURFACE_TREE_HOST_TEST_UTIL_H_ +#define COMPONENTS_EXO_TEST_SURFACE_TREE_HOST_TEST_UTIL_H_ + +#include "components/exo/surface_tree_host.h" + +namespace exo::test { + +// Waits for the last compositor frame submitted by `surface_tree_host` to be +// presented. +void WaitForLastFramePresentation(SurfaceTreeHost* surface_tree_host); + +} // namespace exo::test + +#endif // COMPONENTS_EXO_TEST_SURFACE_TREE_HOST_TEST_UTIL_H_
diff --git a/components/services/app_service/public/cpp/preferred_apps_impl.cc b/components/services/app_service/public/cpp/preferred_apps_impl.cc index ed578e84..2b988b3 100644 --- a/components/services/app_service/public/cpp/preferred_apps_impl.cc +++ b/components/services/app_service/public/cpp/preferred_apps_impl.cc
@@ -96,17 +96,6 @@ PreferredAppsImpl::~PreferredAppsImpl() = default; -void PreferredAppsImpl::AddPreferredApp(AppType app_type, - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - bool from_publisher) { - RunAfterPreferredAppsReady(base::BindOnce( - &PreferredAppsImpl::AddPreferredAppImpl, weak_ptr_factory_.GetWeakPtr(), - app_type, app_id, std::move(intent_filter), std::move(intent), - from_publisher)); -} - void PreferredAppsImpl::RemovePreferredApp(const std::string& app_id) { RunAfterPreferredAppsReady( base::BindOnce(&PreferredAppsImpl::RemovePreferredAppImpl, @@ -239,37 +228,6 @@ } } -void PreferredAppsImpl::AddPreferredAppImpl(AppType app_type, - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - bool from_publisher) { - DCHECK(!app_id.empty()); - - auto replaced_apps = - preferred_apps_list_.AddPreferredApp(app_id, intent_filter); - - WriteToJSON(profile_dir_, preferred_apps_list_); - - auto changes = std::make_unique<PreferredAppChanges>(); - changes->added_filters[app_id].push_back(intent_filter->Clone()); - changes->removed_filters = CloneIntentFiltersMap(replaced_apps); - host_->OnPreferredAppsChanged(std::move(changes)); - - if (from_publisher || !intent) { - return; - } - - // Sync the change to publishers. Because |replaced_app_preference| can - // be any app type, we should run this for all publishers. Currently - // only implemented in ARC publisher. - // TODO(crbug.com/1322000): The |replaced_app_preference| can be really big, - // update this logic to only call the relevant publisher for each app after - // updating the storage structure. - host_->OnPreferredAppSet(app_id, std::move(intent_filter), std::move(intent), - std::move(replaced_apps)); -} - void PreferredAppsImpl::RemovePreferredAppImpl(const std::string& app_id) { IntentFilters removed_filters = preferred_apps_list_.DeleteAppId(app_id); if (!removed_filters.empty()) {
diff --git a/components/services/app_service/public/cpp/preferred_apps_impl.h b/components/services/app_service/public/cpp/preferred_apps_impl.h index 8cbe52cd..5ac1d65 100644 --- a/components/services/app_service/public/cpp/preferred_apps_impl.h +++ b/components/services/app_service/public/cpp/preferred_apps_impl.h
@@ -48,12 +48,6 @@ // PreferredAppsList. virtual void OnPreferredAppsChanged(PreferredAppChangesPtr changes) {} - virtual void OnPreferredAppSet( - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - ReplacedAppPreferences replaced_app_preferences) = 0; - // Notifies the host that the supported links preference for a particular // `app_id` was enabled/disabled. Used by the host to notify the app // publisher (if any) of the change. @@ -72,11 +66,6 @@ ~PreferredAppsImpl(); - void AddPreferredApp(AppType app_type, - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - bool from_publisher); void RemovePreferredApp(const std::string& app_id); void SetSupportedLinksPreference(const std::string& app_id, IntentFilters all_link_filters); @@ -107,11 +96,6 @@ // be run immediately if preferred apps are already initialized. void RunAfterPreferredAppsReady(base::OnceClosure task); - void AddPreferredAppImpl(AppType app_type, - const std::string& app_id, - IntentFilterPtr intent_filter, - IntentPtr intent, - bool from_publisher); void RemovePreferredAppImpl(const std::string& app_id); void SetSupportedLinksPreferenceImpl(const std::string& app_id, IntentFilters all_link_filters);
diff --git a/components/services/screen_ai/BUILD.gn b/components/services/screen_ai/BUILD.gn index 26e8ea2..6b71d67 100644 --- a/components/services/screen_ai/BUILD.gn +++ b/components/services/screen_ai/BUILD.gn
@@ -8,6 +8,8 @@ sources = [ "screen_ai_ax_tree_serializer.cc", "screen_ai_ax_tree_serializer.h", + "screen_ai_library_wrapper.cc", + "screen_ai_library_wrapper.h", "screen_ai_service_impl.cc", "screen_ai_service_impl.h", ] @@ -21,6 +23,7 @@ "//mojo/public/cpp/bindings", "//sandbox/policy", "//services/metrics/public/cpp:ukm_builders", + "//skia", "//ui/accessibility:accessibility", ] }
diff --git a/components/services/screen_ai/DEPS b/components/services/screen_ai/DEPS index 3ab8fba..7a9f974 100644 --- a/components/services/screen_ai/DEPS +++ b/components/services/screen_ai/DEPS
@@ -4,6 +4,7 @@ "+content/public/browser", "+sandbox/policy", "+services/metrics/public/cpp", + "+third_party/skia/include/core/SkBitmap.h", "+ui/accessibility/accessibility_features.h", "+ui/accessibility/ax_enum_util.h", "+ui/accessibility/ax_enums.mojom.h",
diff --git a/components/services/screen_ai/public/cpp/screen_ai_service_router.cc b/components/services/screen_ai/public/cpp/screen_ai_service_router.cc index ba5b6ff..8be2206 100644 --- a/components/services/screen_ai/public/cpp/screen_ai_service_router.cc +++ b/components/services/screen_ai/public/cpp/screen_ai_service_router.cc
@@ -109,7 +109,7 @@ std::unique_ptr<ComponentModelFiles> model_files) { if (!service_router) return; - service_router->screen_ai_service_->LoadLibrary( + service_router->screen_ai_service_->LoadAndInitializeLibrary( std::move(model_files->screen2x_model_config_), std::move(model_files->screen2x_model_), model_files->library_binary_path_);
diff --git a/components/services/screen_ai/public/cpp/utilities.cc b/components/services/screen_ai/public/cpp/utilities.cc index 8d44c34..1891b0f 100644 --- a/components/services/screen_ai/public/cpp/utilities.cc +++ b/components/services/screen_ai/public/cpp/utilities.cc
@@ -44,10 +44,11 @@ base::FilePath GetComponentDir() { base::FilePath components_dir; - base::PathService::Get(component_updater::DIR_COMPONENT_USER, - &components_dir); - if (components_dir.empty()) + if (!base::PathService::Get(component_updater::DIR_COMPONENT_USER, + &components_dir) || + components_dir.empty()) { return base::FilePath(); + } return components_dir.Append(kScreenAISubDirName); } @@ -72,6 +73,10 @@ } #endif + if (latest_version_dir.empty()) { + return base::FilePath(); + } + base::FilePath component_path = latest_version_dir.Append(kScreenAIComponentBinaryName); if (!base::PathExists(component_path))
diff --git a/components/services/screen_ai/public/mojom/screen_ai_service.mojom b/components/services/screen_ai/public/mojom/screen_ai_service.mojom index c6f1191..13faf9f7 100644 --- a/components/services/screen_ai/public/mojom/screen_ai_service.mojom +++ b/components/services/screen_ai/public/mojom/screen_ai_service.mojom
@@ -69,7 +69,7 @@ // read from |library_path| folder. // This should be called from the browser process. // TODO(https://crbug.com/1278249): Read all model files from file handles. - LoadLibrary( + LoadAndInitializeLibrary( mojo_base.mojom.ReadOnlyFile screen2x_model_config, mojo_base.mojom.ReadOnlyFile screen2x_model, mojo_base.mojom.FilePath library_path);
diff --git a/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc b/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc index 4e86912..ab94c65 100644 --- a/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc +++ b/components/services/screen_ai/sandbox/screen_ai_sandbox_hook_linux.cc
@@ -20,15 +20,7 @@ NO_SANITIZE("cfi-icall") void CallPresandboxInitFunction(void* presandbox_init_function) { - // TODO(crbug.com/1278249): Replace this with DCHECK after library is updated - // to 112.0. OCR function will not work without presandbox init but main - // content extraction does not require it. - if (!presandbox_init_function) { - VLOG(0) << "Screen AI library is outdated. Current version does not " - "support OCR."; - return; - } - + DCHECK(presandbox_init_function); typedef void (*PresandboxInitFn)(); (*reinterpret_cast<PresandboxInitFn>(presandbox_init_function))(); } @@ -38,19 +30,26 @@ bool ScreenAIPreSandboxHook(sandbox::policy::SandboxLinux::Options options) { base::FilePath library_path = screen_ai::GetLatestComponentBinaryPath(); if (library_path.empty()) { - VLOG(1) << "Screen AI component binary not found."; + VLOG(0) << "Screen AI component binary not found."; } else { void* screen_ai_library = dlopen(library_path.value().c_str(), RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); - // The library is delivered by the component updater. If it is not available - // we cannot do anything about it here. The requests to the service will - // fail later as the library does not exist. - if (!screen_ai_library) { - VLOG(1) << dlerror(); + // The library is delivered by the component updater or DLC. If it is not + // available or has loading or syntax problems, we cannot do anything about + // them here. The requests to the service will fail later as the library + // does not exist or does not initialize. + if (screen_ai_library == nullptr) { + VLOG(0) << dlerror(); library_path.clear(); } else { - VLOG(2) << "Screen AI library loaded pre-sandboxing:" << library_path; - CallPresandboxInitFunction(dlsym(screen_ai_library, "PresandboxInit")); + void* presandbox_init = dlsym(screen_ai_library, "PresandboxInit"); + if (presandbox_init == nullptr) { + VLOG(0) << "PresandboxInit function of Screen AI library not found."; + library_path.clear(); + } else { + VLOG(2) << "Screen AI library loaded pre-sandboxing: " << library_path; + CallPresandboxInitFunction(presandbox_init); + } } }
diff --git a/components/services/screen_ai/screen_ai_library_wrapper.cc b/components/services/screen_ai/screen_ai_library_wrapper.cc new file mode 100644 index 0000000..0501b7b5 --- /dev/null +++ b/components/services/screen_ai/screen_ai_library_wrapper.cc
@@ -0,0 +1,231 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/services/screen_ai/screen_ai_library_wrapper.h" + +#include "ui/accessibility/accessibility_features.h" + +namespace screen_ai { + +namespace { + +#if BUILDFLAG(IS_CHROMEOS_ASH) +void HandleLibraryLogging(int severity, const char* message) { + switch (severity) { + case logging::LOG_VERBOSE: + case logging::LOG_INFO: + VLOG(2) << message; + break; + case logging::LOG_WARNING: + VLOG(1) << message; + break; + case logging::LOG_ERROR: + case logging::LOG_FATAL: + VLOG(0) << message; + break; + } +} +#endif + +std::vector<char> LoadModelFile(base::File& model_file) { + std::vector<char> buffer; + int64_t length = model_file.GetLength(); + if (length < 0) { + VLOG(0) << "Could not query Screen AI model file's length."; + return buffer; + } + + buffer.resize(length); + if (model_file.Read(0, buffer.data(), length) != length) { + buffer.clear(); + VLOG(0) << "Could not read Screen AI model file's content."; + } + + return buffer; +} + +// TODO(crbug.com/1413983): Remove this function when the bug is fixed. +// This function is added only to get a better stack trace in the crash dump. +void CheckLibraryIsLoaded(base::ScopedNativeLibrary& library) { + CHECK_NE(library.GetError(), nullptr); +#if BUILDFLAG(IS_WIN) + CHECK_EQ(library.GetError()->code, 0u); +#else + CHECK(library.GetError()->message.empty()); +#endif +} + +} // namespace + +ScreenAILibraryWrapper::ScreenAILibraryWrapper() = default; + +bool ScreenAILibraryWrapper::Init(const base::FilePath& library_path) { + library_ = base::ScopedNativeLibrary(library_path); + CheckLibraryIsLoaded(library_); + + if (library_.GetError() == nullptr) { + VLOG(0) << "Library load state cannot be read."; + return false; + } +#if BUILDFLAG(IS_WIN) + if (library_.GetError()->code != 0u) { + VLOG(0) << "Library load error: " << library_.GetError()->code; + return false; + } +#else + if (!library_.GetError()->message.empty()) { + VLOG(0) << "Library load error: " << library_.GetError()->message; + return false; + } +#endif + +// Loads a library function with name N, type T, and puts it in variable V. +// If the function is not loaded, returns false. +#define LOAD_FUNCTION(V, T, N) \ + V = reinterpret_cast<T>(library_.GetFunctionPointer(N)); \ + if (V == nullptr) { \ + VLOG(0) << "Could not load function: " << N; \ + return false; \ + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + set_logger_ = + reinterpret_cast<SetLoggerFn>(library_.GetFunctionPointer("SetLogger")); + DCHECK(set_logger_); +#endif + + // General functions. + LOAD_FUNCTION(get_library_version_, GetLibraryVersionFn, "GetLibraryVersion"); + LOAD_FUNCTION(enable_debug_mode_, EnableDebugModeFn, "EnableDebugMode"); + LOAD_FUNCTION(read_buffered_int32_array_, ReadBufferedInt32ArrayFn, + "ReadBufferedInt32Array"); + LOAD_FUNCTION(read_buffered_char_array_, ReadBufferedCharArrayFn, + "ReadBufferedCharArray"); + + // Layout Extraction functions. + if (features::IsLayoutExtractionEnabled()) { + LOAD_FUNCTION(init_layout_extraction_, InitLayoutExtractionFn, + "InitLayoutExtraction"); + LOAD_FUNCTION(extract_layout_, ExtractLayoutFn, "ExtractLayout"); + } + + // OCR functions. + if (features::IsPdfOcrEnabled()) { + LOAD_FUNCTION(init_ocr_, InitOCRFn, "InitOCR"); + LOAD_FUNCTION(perform_ocr_, PerformOcrFn, "PerformOCR"); + } + + // Main Content Extraction functions. + if (features::IsReadAnythingWithScreen2xEnabled()) { + LOAD_FUNCTION(init_main_content_extraction_, InitMainContentExtractionFn, + "InitMainContentExtraction"); + LOAD_FUNCTION(extract_main_content_, ExtractMainContentFn, + "ExtractMainContent"); + } + + return true; +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +NO_SANITIZE("cfi-icall") +void ScreenAILibraryWrapper::ScreenAILibraryWrapper::SetLogger() { + DCHECK(set_logger_); + set_logger_(&HandleLibraryLogging); +} +#endif + +NO_SANITIZE("cfi-icall") +void ScreenAILibraryWrapper::GetLibraryVersion(uint32_t& major, + uint32_t& minor) { + DCHECK(get_library_version_); + get_library_version_(major, minor); +} + +NO_SANITIZE("cfi-icall") +void ScreenAILibraryWrapper::EnableDebugMode() { + DCHECK(enable_debug_mode_); + enable_debug_mode_(); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::InitLayoutExtraction() { + DCHECK(init_layout_extraction_); + return init_layout_extraction_(); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::InitOCR(const base::FilePath& models_folder) { + DCHECK(init_ocr_); + return init_ocr_(models_folder.MaybeAsASCII().c_str()); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::InitMainContentExtraction( + base::File& model_config_file, + base::File& model_tflite_file) { + DCHECK(init_main_content_extraction_); + + std::vector<char> model_config = LoadModelFile(model_config_file); + std::vector<char> model_tflite = LoadModelFile(model_tflite_file); + if (model_config.empty() || model_tflite.empty()) { + return false; + } + + return init_main_content_extraction_(model_config.data(), model_config.size(), + model_tflite.data(), + model_tflite.size()); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::PerformOcr(const SkBitmap& image, + std::string& annotation_proto) { + DCHECK(perform_ocr_); + DCHECK(read_buffered_char_array_); + + uint32_t annotation_proto_length; + if (!perform_ocr_(image, annotation_proto_length)) { + return false; + } + + annotation_proto.resize(annotation_proto_length); + return read_buffered_char_array_(annotation_proto.data(), + annotation_proto_length); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::ExtractLayout(const SkBitmap& image, + std::string& annotation_proto) { + DCHECK(extract_layout_); + DCHECK(read_buffered_char_array_); + uint32_t annotation_proto_length; + if (!extract_layout_(image, annotation_proto_length)) { + return false; + } + + annotation_proto.resize(annotation_proto_length); + return read_buffered_char_array_(annotation_proto.data(), + annotation_proto_length); +} + +NO_SANITIZE("cfi-icall") +bool ScreenAILibraryWrapper::ExtractMainContent( + const std::string& serialized_view_hierarchy, + std::vector<int32_t>& node_ids) { + DCHECK(extract_main_content_); + DCHECK(read_buffered_int32_array_); + + uint32_t nodes_count; + if (!extract_main_content_(serialized_view_hierarchy.data(), + serialized_view_hierarchy.length(), nodes_count)) { + return false; + } + node_ids.resize(nodes_count); + if (nodes_count == 0) { + return true; + } + + return read_buffered_int32_array_(node_ids.data(), nodes_count); +} + +} // namespace screen_ai
diff --git a/components/services/screen_ai/screen_ai_library_wrapper.h b/components/services/screen_ai/screen_ai_library_wrapper.h new file mode 100644 index 0000000..de46756 --- /dev/null +++ b/components/services/screen_ai/screen_ai_library_wrapper.h
@@ -0,0 +1,144 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SERVICES_SCREEN_AI_SCREEN_AI_LIBRARY_WRAPPER_H_ +#define COMPONENTS_SERVICES_SCREEN_AI_SCREEN_AI_LIBRARY_WRAPPER_H_ + +#include <stdint.h> + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/scoped_native_library.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace screen_ai { + +// Wrapper class for Chrome Screen AI library. +class ScreenAILibraryWrapper { + public: + ScreenAILibraryWrapper(); + ScreenAILibraryWrapper(const ScreenAILibraryWrapper&) = delete; + ScreenAILibraryWrapper& operator=(const ScreenAILibraryWrapper&) = delete; + ~ScreenAILibraryWrapper() = default; + + bool Init(const base::FilePath& library_path); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + void SetLogger(); +#endif + + void GetLibraryVersion(uint32_t& major, uint32_t& minor); + void EnableDebugMode(); + bool InitLayoutExtraction(); + bool InitOCR(const base::FilePath& models_folder); + bool InitMainContentExtraction(base::File& model_config_file, + base::File& model_tflite_file); + bool ExtractLayout(const SkBitmap& image, std::string& annotation_proto); + bool PerformOcr(const SkBitmap& image, std::string& annotation_proto); + bool ExtractMainContent(const std::string& serialized_view_hierarchy, + std::vector<int32_t>& node_ids); + + private: +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Sets a function to receive library logs and add them to Chrome logs. + typedef void (*SetLoggerFn)(void (*logger_func)(int /*severity*/, + const char* /*message*/)); + SetLoggerFn set_logger_ = nullptr; +#endif + + // Gets the library version number. + typedef void (*GetLibraryVersionFn)(uint32_t& major, uint32_t& minor); + GetLibraryVersionFn get_library_version_ = nullptr; + + // Enables the debug mode which stores all i/o protos in the temp folder. + typedef void (*EnableDebugModeFn)(); + EnableDebugModeFn enable_debug_mode_ = nullptr; + + // Initializes the pipeline for layout extraction. + typedef bool (*InitLayoutExtractionFn)(); + InitLayoutExtractionFn init_layout_extraction_ = nullptr; + + // Initializes the pipeline for OCR. + // |models_folder| is a null terminated string pointing to the + // folder that includes model files for OCR. + // TODO(http://crbug.com/1278249): Replace |models_folder| with file + // handle(s). + typedef bool (*InitOCRFn)(const char* /*models_folder*/); + InitOCRFn init_ocr_ = nullptr; + + // Initializes the pipeline for main content extraction. + // |model_config| and |model_tflite| pass content of the required files to + // initialize Screen2x engine. + typedef bool (*InitMainContentExtractionFn)(const char* model_config, + uint32_t model_config_length, + const char* model_tflite, + uint32_t model_tflite_length); + InitMainContentExtractionFn init_main_content_extraction_ = nullptr; + + // Sends the given bitmap to layout extraction pipeline and returns visual + // annotations. The annotations will be returned as a serialized + // VisualAnnotation proto. + // `serialized_visual_annotation_length` will return the size of required + // buffer to read the output serialized proto. The buffered results are + // guaranteed to be kept until the next call to any function of the library. + // The caller should then allocate the required buffer and call + // `ReadBufferedCharArray` to get the results. Note that the results can be + // read only once. + typedef bool (*ExtractLayoutFn)( + const SkBitmap& /*bitmap*/, + uint32_t& /*serialized_visual_annotation_length*/); + ExtractLayoutFn extract_layout_ = nullptr; + + // Sends the given bitmap to the OCR pipeline and returns visual + // annotations. The annotations will be returned as a serialized + // VisualAnnotation proto. + // `serialized_visual_annotation_length` will return the size of required + // buffer to read the output serialized proto. The buffered results are + // guaranteed to be kept until the next call to any function of the library. + // The caller should then allocate the required buffer and call + // `ReadBufferedCharArray` to get the results. Note that the results can be + // read only once. + typedef bool (*PerformOcrFn)( + const SkBitmap& /*bitmap*/, + uint32_t& /*serialized_visual_annotation_length*/); + PerformOcrFn perform_ocr_ = nullptr; + + // Passes the given accessibility tree proto to Screen2x pipeline and returns + // the main content ids. The input is in form of a serialized ViewHierarchy + // proto. + // `content_node_ids_length` returns the size of required buffer to read the + // output content node ids. The buffered results are guaranteed to be kept + // until the next call to any function of the library. + // The caller should then allocate the required buffer and call + // `ReadBufferedInt32Array` to get the results. Note that the results can be + // read only once. + typedef bool (*ExtractMainContentFn)( + const char* /*serialized_view_hierarchy*/, + uint32_t /*serialized_view_hierarchy_length*/, + uint32_t& /*content_node_ids_length*/); + ExtractMainContentFn extract_main_content_ = nullptr; + + // Reads buffered int32 array. This function is used to read the int32* + // results that are computed by other functions and kept in library's memory. + // The read operation can be done only once and the results are cleared after + // reading. + typedef bool (*ReadBufferedInt32ArrayFn)(int32_t* results, + uint32_t max_count); + ReadBufferedInt32ArrayFn read_buffered_int32_array_; + + // Reads buffered char array. This function is used to read the char* + // results that are computed by other functions and kept in library's memory. + // The read operation can be done only once and the results are cleared after + // reading. + typedef bool (*ReadBufferedCharArrayFn)(char* results, uint32_t max_count); + ReadBufferedCharArrayFn read_buffered_char_array_; + + base::ScopedNativeLibrary library_; +}; + +} // namespace screen_ai + +#endif // COMPONENTS_SERVICES_SCREEN_AI_SCREEN_AI_LIBRARY_WRAPPER_H_
diff --git a/components/services/screen_ai/screen_ai_service_impl.cc b/components/services/screen_ai/screen_ai_service_impl.cc index b93a676..c404d73 100644 --- a/components/services/screen_ai/screen_ai_service_impl.cc +++ b/components/services/screen_ai/screen_ai_service_impl.cc
@@ -9,18 +9,13 @@ #include <vector> #include "base/check.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/location.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" -#include "base/notreached.h" #include "base/process/process.h" -#include "base/scoped_native_library.h" #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool.h" -#include "build/build_config.h" #include "components/services/screen_ai/proto/main_content_extractor_proto_convertor.h" #include "components/services/screen_ai/proto/visual_annotator_proto_convertor.h" #include "components/services/screen_ai/public/cpp/utilities.h" @@ -47,121 +42,34 @@ kMaxValue = kOcrFailed, }; -#if BUILDFLAG(IS_CHROMEOS_ASH) -void HandleLibraryLogging(int severity, const char* message) { - switch (severity) { - case logging::LOG_VERBOSE: - case logging::LOG_INFO: - VLOG(2) << message; - break; - case logging::LOG_WARNING: - VLOG(1) << message; - break; - case logging::LOG_ERROR: - case logging::LOG_FATAL: - VLOG(0) << message; - break; - } -} -#endif - -std::vector<char> LoadModelFile(base::File& model_file) { - std::vector<char> buffer; - int64_t length = model_file.GetLength(); - if (length < 0) { - VLOG(0) << "Could not query Screen AI model file's length."; - return buffer; - } - - buffer.resize(length); - if (model_file.Read(0, buffer.data(), length) != length) { - buffer.clear(); - VLOG(0) << "Could not read Screen AI model file's content."; - } - - return buffer; -} - -NO_SANITIZE("cfi-icall") -void CallGetLibraryVersionFunction(LibraryFunctions* library_functions, - uint32_t& major, - uint32_t& minor) { - DCHECK(library_functions); - DCHECK(library_functions->get_library_version_); - - library_functions->get_library_version_(major, minor); -} - -#if BUILDFLAG(IS_CHROMEOS_ASH) -NO_SANITIZE("cfi-icall") -void CallSetLoggerFunction(LibraryFunctions* library_functions) { - DCHECK(library_functions); - DCHECK(library_functions->set_logger_); - library_functions->set_logger_(&HandleLibraryLogging); -} -#endif - -NO_SANITIZE("cfi-icall") -bool CallInitLayoutExtractionFunction(LibraryFunctions* library_functions) { - DCHECK(library_functions); - DCHECK(library_functions->init_layout_extraction_); - return library_functions->init_layout_extraction_(); -} - -NO_SANITIZE("cfi-icall") -bool CallInitOCRFunction(LibraryFunctions* library_functions, - const base::FilePath& models_folder) { - DCHECK(library_functions); - DCHECK(library_functions->init_ocr_); - return library_functions->init_ocr_(models_folder.MaybeAsASCII().c_str()); -} - -NO_SANITIZE("cfi-icall") -bool CallInitMainContentExtractionFunction(LibraryFunctions* library_functions, - base::File& model_config_file, - base::File& model_tflite_file) { - DCHECK(library_functions); - DCHECK(library_functions->init_main_content_extraction_); - std::vector<char> model_config = LoadModelFile(model_config_file); - std::vector<char> model_tflite = LoadModelFile(model_tflite_file); - if (model_config.empty() || model_tflite.empty()) - return false; - - return library_functions->init_main_content_extraction_( - model_config.data(), model_config.size(), model_tflite.data(), - model_tflite.size()); -} - -NO_SANITIZE("cfi-icall") -void CallEnableDebugMode(LibraryFunctions* library_functions) { - library_functions->enable_debug_mode_(); -} - -std::unique_ptr<LibraryFunctions> LoadAndInitializeLibrary( +std::unique_ptr<ScreenAILibraryWrapper> LoadAndInitializeLibraryInternal( base::File model_config, base::File model_tflite, const base::FilePath& library_path) { DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - std::unique_ptr<LibraryFunctions> library_functions = - std::make_unique<LibraryFunctions>(library_path); + std::unique_ptr<ScreenAILibraryWrapper> library = + std::make_unique<ScreenAILibraryWrapper>(); + + // TODO(crbug.com/1413983): Replace CHECK with an UMA and a process + // termination similar to below cases when the bug is fixed. + CHECK(library->Init(library_path)); uint32_t version_major; uint32_t version_minor; - CallGetLibraryVersionFunction(library_functions.get(), version_major, - version_minor); + library->GetLibraryVersion(version_major, version_minor); VLOG(2) << "Screen AI library version: " << version_major << "." << version_minor; #if BUILDFLAG(IS_CHROMEOS_ASH) - CallSetLoggerFunction(library_functions.get()); + library->SetLogger(); #endif if (features::IsScreenAIDebugModeEnabled()) - CallEnableDebugMode(library_functions.get()); + library->EnableDebugMode(); bool init_ok = true; if (features::IsPdfOcrEnabled()) { - if (!CallInitOCRFunction(library_functions.get(), library_path.DirName())) { + if (!library->InitOCR(library_path.DirName())) { init_ok = false; base::UmaHistogramEnumeration("Accessibility.ScreenAI.LoadLibraryResult", ScreenAILoadLibraryResult::kOcrFailed); @@ -169,7 +77,7 @@ } if (init_ok && features::IsLayoutExtractionEnabled()) { - if (!CallInitLayoutExtractionFunction(library_functions.get())) { + if (!library->InitLayoutExtraction()) { init_ok = false; base::UmaHistogramEnumeration( "Accessibility.ScreenAI.LoadLibraryResult", @@ -178,8 +86,7 @@ } if (init_ok && features::IsReadAnythingWithScreen2xEnabled()) { - if (!CallInitMainContentExtractionFunction(library_functions.get(), - model_config, model_tflite)) { + if (!library->InitMainContentExtraction(model_config, model_tflite)) { init_ok = false; base::UmaHistogramEnumeration( "Accessibility.ScreenAI.LoadLibraryResult", @@ -195,7 +102,7 @@ base::UmaHistogramEnumeration("Accessibility.ScreenAI.LoadLibraryResult", ScreenAILoadLibraryResult::kAllOk); - return library_functions; + return library; } } // namespace @@ -208,84 +115,22 @@ ScreenAIService::~ScreenAIService() = default; -LibraryFunctions::LibraryFunctions(const base::FilePath& library_path) { - library_ = base::ScopedNativeLibrary(library_path); - DCHECK(library_.GetError()); -#if BUILDFLAG(IS_WIN) - DCHECK_EQ(0u, library_.GetError()->code) - << "Library load error: " << library_.GetError()->code; -#else - DCHECK(library_.GetError()->message.empty()) - << "Library load error: " << library_.GetError()->message; -#endif - - // General functions. - get_library_version_ = reinterpret_cast<GetLibraryVersionFn>( - library_.GetFunctionPointer("GetLibraryVersion")); - DCHECK(get_library_version_); - enable_debug_mode_ = reinterpret_cast<EnableDebugModeFn>( - library_.GetFunctionPointer("EnableDebugMode")); - DCHECK(enable_debug_mode_); - read_buffered_int32_array_ = reinterpret_cast<ReadBufferedInt32ArrayFn>( - library_.GetFunctionPointer("ReadBufferedInt32Array")); - DCHECK(read_buffered_int32_array_); - read_buffered_char_array_ = reinterpret_cast<ReadBufferedCharArrayFn>( - library_.GetFunctionPointer("ReadBufferedCharArray")); - DCHECK(read_buffered_char_array_); - -#if BUILDFLAG(IS_CHROMEOS_ASH) - set_logger_ = - reinterpret_cast<SetLoggerFn>(library_.GetFunctionPointer("SetLogger")); - DCHECK(set_logger_); -#endif - - // Main Content Extraction functions. - if (features::IsReadAnythingWithScreen2xEnabled()) { - init_main_content_extraction_ = - reinterpret_cast<InitMainContentExtractionFn>( - library_.GetFunctionPointer("InitMainContentExtraction")); - DCHECK(init_main_content_extraction_); - extract_main_content_ = reinterpret_cast<ExtractMainContentFn>( - library_.GetFunctionPointer("ExtractMainContent")); - DCHECK(extract_main_content_); - } - - // Layout Extraction. - if (features::IsLayoutExtractionEnabled()) { - init_layout_extraction_ = reinterpret_cast<InitLayoutExtractionFn>( - library_.GetFunctionPointer("InitLayoutExtraction")); - DCHECK(init_layout_extraction_); - extract_layout_ = reinterpret_cast<ExtractLayoutFn>( - library_.GetFunctionPointer("ExtractLayout")); - DCHECK(extract_layout_); - } - - // OCR. - if (features::IsPdfOcrEnabled()) { - init_ocr_ = - reinterpret_cast<InitOCRFn>(library_.GetFunctionPointer("InitOCR")); - DCHECK(init_ocr_); - perform_ocr_ = reinterpret_cast<PerformOcrFn>( - library_.GetFunctionPointer("PerformOCR")); - DCHECK(perform_ocr_); - } -} - -void ScreenAIService::LoadLibrary(base::File model_config, - base::File model_tflite, - const base::FilePath& library_path) { +void ScreenAIService::LoadAndInitializeLibrary( + base::File model_config, + base::File model_tflite, + const base::FilePath& library_path) { base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&LoadAndInitializeLibrary, std::move(model_config), + base::BindOnce(&LoadAndInitializeLibraryInternal, std::move(model_config), std::move(model_tflite), library_path), - base::BindOnce(&ScreenAIService::SetLibraryFunctions, + base::BindOnce(&ScreenAIService::SetLibraryAndStartTaskRunner, weak_ptr_factory_.GetWeakPtr())); } -void ScreenAIService::SetLibraryFunctions( - std::unique_ptr<LibraryFunctions> library_functions) { - library_functions_ = std::move(library_functions); +void ScreenAIService::SetLibraryAndStartTaskRunner( + std::unique_ptr<ScreenAILibraryWrapper> library) { + library_ = std::move(library); task_runner_->Start(); } @@ -376,9 +221,9 @@ // verifies the data integrity and source. bool result = false; if (run_ocr) { - result = CallLibraryOcrFunction(image, proto_as_string); + result = library_->PerformOcr(image, proto_as_string); } else /* if (run_layout_extraction) */ { - result = CallLibraryLayoutExtractionFunction(image, proto_as_string); + result = library_->ExtractLayout(image, proto_as_string); } if (!result || proto_as_string.empty()) { DCHECK_EQ(annotation->tree_data.tree_id, ui::AXTreeIDUnknown()); @@ -400,33 +245,6 @@ << annotation->ToString(); } -NO_SANITIZE("cfi-icall") -bool ScreenAIService::CallLibraryOcrFunction(const SkBitmap& image, - std::string& annotation_proto) { - uint32_t annotation_proto_length; - if (!library_functions_->perform_ocr_(image, annotation_proto_length)) { - return false; - } - - annotation_proto.resize(annotation_proto_length); - return library_functions_->read_buffered_char_array_(annotation_proto.data(), - annotation_proto_length); -} - -NO_SANITIZE("cfi-icall") -bool ScreenAIService::CallLibraryLayoutExtractionFunction( - const SkBitmap& image, - std::string& annotation_proto) { - uint32_t annotation_proto_length; - if (!library_functions_->extract_layout_(image, annotation_proto_length)) { - return false; - } - - annotation_proto.resize(annotation_proto_length); - return library_functions_->read_buffered_char_array_(annotation_proto.data(), - annotation_proto_length); -} - void ScreenAIService::ExtractMainContent(const ui::AXTreeUpdate& snapshot, ukm::SourceId ukm_source_id, ContentExtractionCallback callback) { @@ -464,8 +282,8 @@ std::string serialized_snapshot = SnapshotToViewHierarchy(snapshot); base::TimeTicks start_time = base::TimeTicks::Now(); - bool success = CallLibraryExtractMainContentFunction(serialized_snapshot, - *content_node_ids); + bool success = + library_->ExtractMainContent(serialized_snapshot, *content_node_ids); base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time; if (!success) { VLOG(1) << "Screen2x did not return main content."; @@ -505,23 +323,4 @@ } } -NO_SANITIZE("cfi-icall") -bool ScreenAIService::CallLibraryExtractMainContentFunction( - const std::string& serialized_view_hierarchy, - std::vector<int32_t>& node_ids) { - uint32_t nodes_count; - if (!library_functions_->extract_main_content_( - serialized_view_hierarchy.data(), serialized_view_hierarchy.length(), - nodes_count)) { - return false; - } - node_ids.resize(nodes_count); - if (nodes_count == 0) { - return true; - } - - return library_functions_->read_buffered_int32_array_(node_ids.data(), - nodes_count); -} - } // namespace screen_ai
diff --git a/components/services/screen_ai/screen_ai_service_impl.h b/components/services/screen_ai/screen_ai_service_impl.h index 3a37a48..25abdaff 100644 --- a/components/services/screen_ai/screen_ai_service_impl.h +++ b/components/services/screen_ai/screen_ai_service_impl.h
@@ -10,10 +10,11 @@ #include "base/functional/callback.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" -#include "base/scoped_native_library.h" #include "base/task/deferred_sequenced_task_runner.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/services/screen_ai/public/mojom/screen_ai_service.mojom.h" +#include "components/services/screen_ai/screen_ai_library_wrapper.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -30,110 +31,6 @@ using ContentExtractionCallback = base::OnceCallback<void(const std::vector<int32_t>&)>; -// Defines and keeps pointers to ScreenAI library functions. -class LibraryFunctions { - public: - explicit LibraryFunctions(const base::FilePath& library_path); - LibraryFunctions(const LibraryFunctions&) = delete; - LibraryFunctions& operator=(const LibraryFunctions&) = delete; - ~LibraryFunctions() = default; - - // Initializes the pipeline for layout extraction. - typedef bool (*InitLayoutExtractionFn)(); - InitLayoutExtractionFn init_layout_extraction_ = nullptr; - - // Sends the given bitmap to layout extraction pipeline and returns visual - // annotations. The annotations will be returned as a serialized - // VisualAnnotation proto. - // `serialized_visual_annotation_length` will return the size of required - // buffer to read the output serialized proto. The buffered results are - // guaranteed to be kept until the next call to any function of the library. - // The caller should then allocate the required buffer and call - // `ReadBufferedCharArray` to get the results. Note that the results can be - // read only once. - typedef bool (*ExtractLayoutFn)( - const SkBitmap& /*bitmap*/, - uint32_t& /*serialized_visual_annotation_length*/); - ExtractLayoutFn extract_layout_ = nullptr; - - // Initializes the pipeline for OCR. - // |models_folder| is a null terminated string pointing to the - // folder that includes model files for OCR. - // TODO(http://crbug.com/1278249): Replace |models_folder| with file - // handle(s). - typedef bool (*InitOCRFn)(const char* /*models_folder*/); - InitOCRFn init_ocr_ = nullptr; - - // Sends the given bitmap to the OCR pipeline and returns visual - // annotations. The annotations will be returned as a serialized - // VisualAnnotation proto. - // `serialized_visual_annotation_length` will return the size of required - // buffer to read the output serialized proto. The buffered results are - // guaranteed to be kept until the next call to any function of the library. - // The caller should then allocate the required buffer and call - // `ReadBufferedCharArray` to get the results. Note that the results can be - // read only once. - typedef bool (*PerformOcrFn)( - const SkBitmap& /*bitmap*/, - uint32_t& /*serialized_visual_annotation_length*/); - PerformOcrFn perform_ocr_ = nullptr; - - // Initializes the pipeline for main content extraction. - // |model_config| and |model_tflite| pass content of the required files to - // initialize Screen2x engine. - typedef bool (*InitMainContentExtractionFn)(const char* model_config, - uint32_t model_config_length, - const char* model_tflite, - uint32_t model_tflite_length); - InitMainContentExtractionFn init_main_content_extraction_ = nullptr; - - // Passes the given accessibility tree proto to Screen2x pipeline and returns - // the main content ids. The input is in form of a serialized ViewHierarchy - // proto. - // `content_node_ids_length` returns the size of required buffer to read the - // output content node ids. The buffered results are guaranteed to be kept - // until the next call to any function of the library. - // The caller should then allocate the required buffer and call - // `ReadBufferedInt32Array` to get the results. Note that the results can be - // read only once. - typedef bool (*ExtractMainContentFn)( - const char* /*serialized_view_hierarchy*/, - uint32_t /*serialized_view_hierarchy_length*/, - uint32_t& /*content_node_ids_length*/); - ExtractMainContentFn extract_main_content_ = nullptr; - - // Enables the debug mode which stores all i/o protos in the temp folder. - typedef void (*EnableDebugModeFn)(); - EnableDebugModeFn enable_debug_mode_ = nullptr; - - // Sets a function to receive library logs and add them to Chrome logs. - typedef void (*SetLoggerFn)(void (*logger_func)(int /*severity*/, - const char* /*message*/)); - SetLoggerFn set_logger_ = nullptr; - - // Gets the library version number. - typedef void (*GetLibraryVersionFn)(uint32_t& major, uint32_t& minor); - GetLibraryVersionFn get_library_version_ = nullptr; - - // Reads buffered int32 array. This function is used to read the int32* - // results that are computed by other functions and kept in library's memory. - // The read operation can be done only once and the results are cleared after - // reading. - typedef bool (*ReadBufferedInt32ArrayFn)(int32_t* results, - uint32_t max_count); - ReadBufferedInt32ArrayFn read_buffered_int32_array_; - - // Reads buffered char array. This function is used to read the char* - // results that are computed by other functions and kept in library's memory. - // The read operation can be done only once and the results are cleared after - // reading. - typedef bool (*ReadBufferedCharArrayFn)(char* results, uint32_t max_count); - ReadBufferedCharArrayFn read_buffered_char_array_; - - private: - base::ScopedNativeLibrary library_; -}; - // Uses a local machine intelligence library to augment the accessibility // tree. Functionalities include extracting layout and running OCR on passed // snapshots and extracting the main content of a page. @@ -149,7 +46,8 @@ ScreenAIService& operator=(const ScreenAIService&) = delete; ~ScreenAIService() override; - void SetLibraryFunctions(std::unique_ptr<LibraryFunctions> library_functions); + void SetLibraryAndStartTaskRunner( + std::unique_ptr<ScreenAILibraryWrapper> library); static void RecordMetrics(ukm::SourceId ukm_source_id, ukm::UkmRecorder* ukm_recorder, @@ -157,7 +55,7 @@ bool success); private: - std::unique_ptr<LibraryFunctions> library_functions_; + std::unique_ptr<ScreenAILibraryWrapper> library_; // mojom::ScreenAIAnnotator: void ExtractSemanticLayout(const SkBitmap& image, @@ -175,9 +73,9 @@ ContentExtractionCallback callback) override; // mojom::ScreenAIService: - void LoadLibrary(base::File model_config, - base::File model_tflite, - const base::FilePath& library_path) override; + void LoadAndInitializeLibrary(base::File model_config, + base::File model_tflite, + const base::FilePath& library_path) override; // mojom::ScreenAIService: void BindAnnotator( @@ -209,15 +107,6 @@ const ukm::SourceId& ukm_source_id, std::vector<int32_t>* content_node_ids); - // Library function calls are isolated to have specific compiler directives. - bool CallLibraryLayoutExtractionFunction(const SkBitmap& image, - std::string& annotation_proto); - bool CallLibraryOcrFunction(const SkBitmap& image, - std::string& annotation_proto); - bool CallLibraryExtractMainContentFunction( - const std::string& serialized_view_hierarchy, - std::vector<int32_t>& node_ids); - // Internal task scheduler that starts after library load is completed. scoped_refptr<base::DeferredSequencedTaskRunner> task_runner_;
diff --git a/components/strings/components_strings_uz.xtb b/components/strings/components_strings_uz.xtb index e850d87f..8081c46 100644 --- a/components/strings/components_strings_uz.xtb +++ b/components/strings/components_strings_uz.xtb
@@ -84,6 +84,7 @@ <translation id="1178821169867863726">12 x 16 in</translation> <translation id="1181037720776840403">Olib tashlash</translation> <translation id="1186201132766001848">Parollarni tekshiring</translation> +<translation id="1195073053842921378">Bu qurilmadan mazkur manzil oʻchirib tashlanadi</translation> <translation id="1195558154361252544">Bildirishnoamalar siz ruxsat bergan saytlardan tashqari barcha saytlar uchun taqiqlanadi</translation> <translation id="1197088940767939838">Apelsinrang</translation> <translation id="1201402288615127009">Keyingisi</translation>
diff --git a/components/viz/common/frame_sinks/begin_frame_args.h b/components/viz/common/frame_sinks/begin_frame_args.h index 788940c..00f85ded 100644 --- a/components/viz/common/frame_sinks/begin_frame_args.h +++ b/components/viz/common/frame_sinks/begin_frame_args.h
@@ -259,6 +259,9 @@ bool has_damage, int64_t trace_id = -1); + BeginFrameAck(const BeginFrameAck& other) = default; + BeginFrameAck& operator=(const BeginFrameAck& other) = default; + // Creates a BeginFrameAck for a manual BeginFrame. Used when clients produce // a CompositorFrame without prior BeginFrame, e.g. for synchronous drawing. static BeginFrameAck CreateManualAckWithDamage();
diff --git a/content/browser/aggregation_service/public_key_parsing_utils.cc b/content/browser/aggregation_service/public_key_parsing_utils.cc index cda7e11..3ed920a 100644 --- a/content/browser/aggregation_service/public_key_parsing_utils.cc +++ b/content/browser/aggregation_service/public_key_parsing_utils.cc
@@ -25,26 +25,30 @@ if (!value.is_dict()) return absl::nullopt; - absl::optional<base::Value> id = value.ExtractKey("id"); - if (!id || !id.value().is_string()) + base::Value::Dict& dict = value.GetDict(); + std::string* key_id = dict.FindString("id"); + if (!key_id) { return absl::nullopt; + } - std::string key_id = id->GetString(); - if (key_id.size() > PublicKey::kMaxIdSize) + if (key_id->size() > PublicKey::kMaxIdSize) { return absl::nullopt; + } - absl::optional<base::Value> key = value.ExtractKey("key"); - if (!key || !key.value().is_string()) + std::string* key = dict.FindString("key"); + if (!key) { return absl::nullopt; + } - std::string key_string = key->GetString(); - if (!base::Base64Decode(key_string, &key_string)) + std::string key_string; + if (!base::Base64Decode(*key, &key_string)) { return absl::nullopt; + } if (key_string.size() != PublicKey::kKeyByteLength) return absl::nullopt; - return PublicKey(std::move(key_id), + return PublicKey(std::move(*key_id), std::vector<uint8_t>(key_string.begin(), key_string.end())); } @@ -56,14 +60,15 @@ if (!value.is_dict()) return {}; - absl::optional<base::Value> keys_json = value.ExtractKey("keys"); - if (!keys_json.has_value() || !keys_json.value().is_list()) + base::Value::List* keys_json = value.GetDict().FindList("keys"); + if (!keys_json) { return {}; + } std::vector<PublicKey> public_keys; base::flat_set<std::string> key_ids_set; - for (auto& key_json : keys_json.value().GetList()) { + for (auto& key_json : *keys_json) { // Return error (i.e. empty vector) if more keys than expected are // specified. if (public_keys.size() == PublicKeyset::kMaxNumberKeys)
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index 0111f54..6569aae 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -444,6 +444,19 @@ initiating_frame_id, prefetch_url, status); } +void DidUpdatePrerenderStatus(int initiator_frame_tree_node_id, + const GURL& prerender_url, + PreloadingTriggeringOutcome status) { + auto* ftn = FrameTreeNode::GloballyFindByID(initiator_frame_tree_node_id); + // ftn will be null if this is browser-initiated, which has no initiator. + if (ftn) { + std::string initiating_frame_id = + ftn->current_frame_host()->devtools_frame_token().ToString(); + DispatchToAgents(ftn, &protocol::PageHandler::DidUpdatePrerenderStatus, + initiating_frame_id, prerender_url, status); + } +} + namespace { protocol::String BuildBlockedByResponseReason(
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h index d5e1b3b5..ba37a4f 100644 --- a/content/browser/devtools/devtools_instrumentation.h +++ b/content/browser/devtools/devtools_instrumentation.h
@@ -204,6 +204,10 @@ const GURL& prefetch_url, PreloadingTriggeringOutcome status); +void DidUpdatePrerenderStatus(int initiator_frame_tree_node_id, + const GURL& prerender_url, + PreloadingTriggeringOutcome status); + void OnSignedExchangeReceived( FrameTreeNode* frame_tree_node, absl::optional<const base::UnguessableToken> devtools_navigation_token,
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index 4b933db3..b39900b 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1606,34 +1606,63 @@ } } -Page::PrefetchStatus PreloadingTriggeringOutcomeToProtocol( +Page::PreloadingStatus PreloadingTriggeringOutcomeToProtocol( PreloadingTriggeringOutcome feature) { switch (feature) { case PreloadingTriggeringOutcome::kRunning: - return Page::PrefetchStatusEnum::Running; + return Page::PreloadingStatusEnum::Running; case PreloadingTriggeringOutcome::kReady: - return Page::PrefetchStatusEnum::Ready; + return Page::PreloadingStatusEnum::Ready; case PreloadingTriggeringOutcome::kSuccess: - return Page::PrefetchStatusEnum::Success; + return Page::PreloadingStatusEnum::Success; case PreloadingTriggeringOutcome::kFailure: - return Page::PrefetchStatusEnum::Failure; + return Page::PreloadingStatusEnum::Failure; + case PreloadingTriggeringOutcome::kTriggeredButPending: + return Page::PreloadingStatusEnum::Pending; case PreloadingTriggeringOutcome::kUnspecified: case PreloadingTriggeringOutcome::kDuplicate: case PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown: case PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender: - case PreloadingTriggeringOutcome::kTriggeredButPending: - return Page::PrefetchStatusEnum::NotSupported; + return Page::PreloadingStatusEnum::NotSupported; } } -bool PreloadingTriggeringOutcomeSupported(PreloadingTriggeringOutcome feature) { +bool PreloadingTriggeringOutcomeSupportedByPrefetch( + PreloadingTriggeringOutcome feature) { + // TODO(crbug/1384419): revisit the unsupported cases call sites to make sure + // that either they are covered by other CDPs or they are included by the + // current CDPs in the future. switch (feature) { case PreloadingTriggeringOutcome::kRunning: case PreloadingTriggeringOutcome::kReady: case PreloadingTriggeringOutcome::kSuccess: case PreloadingTriggeringOutcome::kFailure: return true; - default: + case PreloadingTriggeringOutcome::kTriggeredButPending: + case PreloadingTriggeringOutcome::kUnspecified: + case PreloadingTriggeringOutcome::kDuplicate: + case PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown: + case PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender: + return false; + } +} + +bool PreloadingTriggeringOutcomeSupportedByPrerender( + PreloadingTriggeringOutcome feature) { + // TODO(crbug/1384419): revisit the unsupported cases call sites to make sure + // that either they are covered by other CDPs or they are included by the + // current CDPs in the future. + switch (feature) { + case PreloadingTriggeringOutcome::kRunning: + case PreloadingTriggeringOutcome::kReady: + case PreloadingTriggeringOutcome::kSuccess: + case PreloadingTriggeringOutcome::kFailure: + case PreloadingTriggeringOutcome::kTriggeredButPending: + return true; + case PreloadingTriggeringOutcome::kUnspecified: + case PreloadingTriggeringOutcome::kDuplicate: + case PreloadingTriggeringOutcome::kTriggeredButOutcomeUnknown: + case PreloadingTriggeringOutcome::kTriggeredButUpgradedToPrerender: return false; } } @@ -2132,10 +2161,25 @@ return; } - auto statusEnum = PreloadingTriggeringOutcomeToProtocol(status); - if (statusEnum != Page::PrefetchStatusEnum::NotSupported) { - frontend_->PrefetchStatusUpdated(initiating_frame_id, prefetch_url.spec(), - statusEnum); + if (PreloadingTriggeringOutcomeSupportedByPrefetch(status)) { + frontend_->PrefetchStatusUpdated( + initiating_frame_id, prefetch_url.spec(), + PreloadingTriggeringOutcomeToProtocol(status)); + } +} + +void PageHandler::DidUpdatePrerenderStatus( + const std::string& initiating_frame_id, + const GURL& prerender_url, + PreloadingTriggeringOutcome status) { + if (!enabled_) { + return; + } + + if (PreloadingTriggeringOutcomeSupportedByPrerender(status)) { + frontend_->PrerenderStatusUpdated( + initiating_frame_id, prerender_url.spec(), + PreloadingTriggeringOutcomeToProtocol(status)); } }
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h index 2debaf5..b3632d8 100644 --- a/content/browser/devtools/protocol/page_handler.h +++ b/content/browser/devtools/protocol/page_handler.h
@@ -120,6 +120,10 @@ const GURL& prefetch_url, PreloadingTriggeringOutcome status); + void DidUpdatePrerenderStatus(const std::string& initiating_frame_id, + const GURL& prerender_url, + PreloadingTriggeringOutcome status); + Response Enable() override; Response Disable() override;
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json index 3687b73..ae38c0c 100644 --- a/content/browser/devtools/protocol_config.json +++ b/content/browser/devtools/protocol_config.json
@@ -71,7 +71,7 @@ "include": ["enable", "disable", "reload", "navigate", "stopLoading", "getNavigationHistory", "navigateToHistoryEntry", "resetNavigationHistory", "captureScreenshot", "startScreencast", "stopScreencast", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled", "bringToFront", "setDownloadBehavior", "getAppManifest", "crash", "close", "setWebLifecycleState", "captureSnapshot", "getInstallabilityErrors", "getManifestIcons", "setBypassCSP", "getAppId", "addCompilationCache"], - "include_events": ["frameDetached", "colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "downloadWillBegin", "downloadProgress", "screencastVisibilityChanged", "screencastFrame", "backForwardCacheNotUsed", "prerenderAttemptCompleted", "prefetchStatusUpdated"], + "include_events": ["frameDetached", "colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "downloadWillBegin", "downloadProgress", "screencastVisibilityChanged", "screencastFrame", "backForwardCacheNotUsed", "prerenderAttemptCompleted", "prefetchStatusUpdated", "prerenderStatusUpdated"], "async": ["captureScreenshot", "navigate", "getAppManifest", "reload", "captureSnapshot", "getInstallabilityErrors", "getManifestIcons", "getAppId"] }, {
diff --git a/content/browser/preloading/prerender/prerender_host.cc b/content/browser/preloading/prerender/prerender_host.cc index 6fddc84..6f7c3772 100644 --- a/content/browser/preloading/prerender/prerender_host.cc +++ b/content/browser/preloading/prerender/prerender_host.cc
@@ -168,10 +168,8 @@ // host can be pending until the host starts or is cancelled. So the outcome // is set here to track the pending status. if (base::FeatureList::IsEnabled( - blink::features::kPrerender2SequentialPrerendering) && - attempt_) { - attempt_->SetTriggeringOutcome( - PreloadingTriggeringOutcome::kTriggeredButPending); + blink::features::kPrerender2SequentialPrerendering)) { + SetTriggeringOutcome(PreloadingTriggeringOutcome::kTriggeredButPending); } scoped_refptr<SiteInstanceImpl> site_instance = @@ -922,6 +920,9 @@ } void PrerenderHost::SetTriggeringOutcome(PreloadingTriggeringOutcome outcome) { + devtools_instrumentation::DidUpdatePrerenderStatus( + initiator_frame_tree_node_id(), prerendering_url(), outcome); + if (!attempt_) return; @@ -936,9 +937,6 @@ } void PrerenderHost::SetFailureReason(PrerenderFinalStatus status) { - if (!attempt_) - return; - switch (status) { // When adding a new failure reason, consider whether it should be // propagated to `attempt_`. Most values should be propagated, but we @@ -1003,11 +1001,18 @@ case PrerenderFinalStatus::kBatterySaverEnabled: case PrerenderFinalStatus::kActivatedDuringMainFrameNavigation: case PrerenderFinalStatus::kPreloadingUnsupportedByWebContents: - attempt_->SetFailureReason(ToPreloadingFailureReason(status)); - // We reset the attempt to ensure we don't update once we have reported it - // as failure or accidentally use it for any other prerender attempts as - // PrerenderHost deletion is async. - attempt_.reset(); + // SetFailureReason() will call SetTriggeringOutcome() with kFailure. + devtools_instrumentation::DidUpdatePrerenderStatus( + initiator_frame_tree_node_id(), prerendering_url(), + PreloadingTriggeringOutcome::kFailure); + + if (attempt_) { + attempt_->SetFailureReason(ToPreloadingFailureReason(status)); + // We reset the attempt to ensure we don't update once we have reported + // it as failure or accidentally use it for any other prerender attempts + // as PrerenderHost deletion is async. + attempt_.reset(); + } return; case PrerenderFinalStatus::kActivated: // The activation path does not call this method, so it should never reach
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 6a59fc6..a1e721b 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1439,6 +1439,10 @@ FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest, PointerLockInnerContentsCrashes); FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest, PointerLockOopifCrashes); + FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, + PopupWindowBrowserNavResumeLoad); + FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, + SuppressedPopupWindowBrowserNavResumeLoad); // So |find_request_manager_| can be accessed for testing. friend class FindRequestManagerTest;
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 2433969..05e603e5 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -3656,11 +3656,53 @@ } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + SuppressedPopupWindowBrowserNavResumeLoad) { + // This test verifies a suppressed pop up that requires navigation from + // browser side works with a delegate that delays navigations of pop ups. + base::FilePath test_data_dir; + CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); + base::FilePath simple_links_path = + test_data_dir.Append(GetTestDataFilePath()) + .Append(FILE_PATH_LITERAL("simple_links.html")); + GURL url("file://" + simple_links_path.AsUTF8Unsafe()); + + shell()->set_delay_popup_contents_delegate_for_testing(true); + EXPECT_TRUE(NavigateToURL(shell(), url)); + + Shell* new_shell = nullptr; + WebContents* new_contents = nullptr; + { + ShellAddedObserver new_shell_observer; + bool success = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool( + shell(), + "window.domAutomationController.send(clickLinkToSelfNoOpener());", + &success)); + new_shell = new_shell_observer.GetShell(); + new_contents = new_shell->web_contents(); + // Delaying popup holds the initial load of |url|. + EXPECT_TRUE(WaitForLoadStop(new_contents)); + EXPECT_TRUE(new_contents->GetController() + .GetLastCommittedEntry() + ->IsInitialEntry()); + EXPECT_NE(url, new_contents->GetLastCommittedURL()); + } + + EXPECT_FALSE(new_contents->GetDelegate()); + new_contents->SetDelegate(new_shell); + EXPECT_TRUE( + static_cast<WebContentsImpl*>(new_contents)->delayed_load_url_params_); + new_contents->ResumeLoadingCreatedWebContents(); + EXPECT_TRUE(WaitForLoadStop(new_contents)); + EXPECT_EQ(url, new_contents->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, PopupWindowBrowserNavResumeLoad) { // This test verifies a pop up that requires navigation from browser side // works with a delegate that delays navigations of pop ups. - // Create a file: scheme pop up from a file: scheme page, which requires - // requires an OpenURL IPC to the browser process. + // Create a file: scheme non-suppressed pop up from a file: scheme page will + // be blocked and wait for the renderer to signal. base::FilePath test_data_dir; CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); base::FilePath simple_links_path = @@ -3691,6 +3733,11 @@ EXPECT_FALSE(new_contents->GetDelegate()); new_contents->SetDelegate(new_shell); + EXPECT_FALSE( + static_cast<WebContentsImpl*>(new_contents)->delayed_load_url_params_); + EXPECT_FALSE( + static_cast<WebContentsImpl*>(new_contents)->delayed_open_url_params_); + EXPECT_TRUE(static_cast<WebContentsImpl*>(new_contents)->is_resume_pending_); new_contents->ResumeLoadingCreatedWebContents(); EXPECT_TRUE(WaitForLoadStop(new_contents)); EXPECT_EQ(url, new_contents->GetLastCommittedURL());
diff --git a/content/test/data/simple_links.html b/content/test/data/simple_links.html index 30fc53e..9045dcd 100644 --- a/content/test/data/simple_links.html +++ b/content/test/data/simple_links.html
@@ -56,7 +56,11 @@ } function clickLinkToSelf() { - return simulateClick(document.getElementById("linkToSelf")); + return simulateClick(document.getElementById("link_to_self_opener")); + } + + function clickLinkToSelfNoOpener() { + return simulateClick(document.getElementById("link_to_self_no_opener")); } function clickGoogleChromeLink() { @@ -73,9 +77,11 @@ <a href="title2.html" id="same_site_new_window_with_opener_link" rel="opener" target="_blank">same-site new window with opener</a> <a href="http://foo.com/title2.html" id="cross_site_new_window_link" rel="opener" target="_blank">cross-site new window</a> <a href="http://foo.com/title2.html" id="cross_site_new_window_no_opener_link" rel="noopener" target="_blank">cross-site new window no opener</a> -<a href="" id="linkToSelf" rel="opener" target="_blank">self new window</a> +<a href="" id="link_to_self_opener" rel="opener" target="_blank">self new window_opener</a> +<a href="" id="link_to_self_no_opener" rel="noopener" target="_blank">self new window_noopener</a> <script> - document.getElementById("linkToSelf").href = window.location.toString(); + document.getElementById("link_to_self_opener").href = window.location.toString(); + document.getElementById("link_to_self_no_opener").href = window.location.toString(); </script> <a href="googlechrome://" id="google_chrome_link">googlechrome:</a></br> </html>
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 6caad19..f874e70 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -26262,10 +26262,6 @@ value: 100 } experiments { - key: "luci.buildbucket.omit_python2" - value: 0 - } - experiments { key: "luci.recipes.use_python3" value: 100 }
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.star b/infra/config/subprojects/chromium/ci/chromium.android.star index 468c904..b8d1318 100644 --- a/infra/config/subprojects/chromium/ci/chromium.android.star +++ b/infra/config/subprojects/chromium/ci/chromium.android.star
@@ -857,9 +857,6 @@ short_name = "m", ), notifies = ["cronet"], - - # TODO(crbug.com/1362440): remove this. - omit_python2 = False, reclient_jobs = reclient.jobs.DEFAULT, )
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb index a3e3c8fb..58a8f95 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb
@@ -4,6 +4,7 @@ <translation id="1047130070405668746">Odaberite Chromium</translation> <translation id="1091252999271033193">Ovo znači da će Chromium svaki put zatražiti web lokaciju za mobilni uređaj.</translation> <translation id="1185134272377778587">O programu Chromium</translation> +<translation id="1256849392437386613">Da uključite funkciju "Prati cijenu" dozvolite obavještenja Chromiuma u postavkama uređaja</translation> <translation id="1257458525759135959">Da sačuvate slike, dodirnite Postavke da omogućite Chromiumu dodavanje u vaše fotografije</translation> <translation id="1289216811211435351">Pređite na Chromium</translation> <translation id="1361748954329991663">Chromium je zastario. Ako ažuriranje nije dostupno u <ph name="BEGIN_LINK" />App Storeu<ph name="END_LINK" />, moguće je da vaš uređaj više ne podržava nove verzije Chromiuma.</translation> @@ -71,6 +72,7 @@ <translation id="5573014823074921752">Savjet za Chromium. Za više opcija za kartice dodirnite i zadržite dugme Prikaži kartice na alatnoj traci, na dnu ili na vrhu ekrana.</translation> <translation id="5700709190537129682">Chromium ne može provjeriti vaše lozinke</translation> <translation id="5777187867430702742">Stranica Chromiuma</translation> +<translation id="5918064849477363478">Obavještenja Chromiuma su isključena u postavkama uređaja. Najprije ćete morati dozvoliti obavještenja.</translation> <translation id="5945387852661427312">Prijavljujete se s računom kojim upravlja domena <ph name="DOMAIN" /> i dajete njenom administratoru kontrolu nad svojim podacima iz Chromiuma. Vaši podaci će se trajno povezati s ovim računom. Odjavom iz Chromiuma će se izbrisati vaši podaci s ovog uređaja, ali će ostati pohranjeni na vašem Google računu.</translation> <translation id="5983312940147103417">Poboljšajte Chromium</translation> <translation id="6062449165341879460">Vaša organizacija <ph name="DOMAIN" /> će imati pristup podacima Chromiuma, oznakama, historiji, lozinkama i drugim postavkama koje pohranjujete na ovom računu Kada se odjavite, vaši podaci će biti obrisani s ovog uređaja. Međutim, vaši podaci će ostati pohranjeni na vašem upravljanom Google računu i bit će dostupni vašoj organizaciji. Vaša organizacija također može postaviti pravila za korisnike koja su specifična za taj račun koja mogu promijeniti ponašanje Chromiuma.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_iw.xtb index 9fb2785..ff85ddcc1 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_iw.xtb
@@ -65,6 +65,7 @@ <translation id="5224391634244552924">אין סיסמאות שמורות. Chromium יכול לבדוק את הסיסמאות שלך רק אם שמרת אותן.</translation> <translation id="5308226104666789935">Chromium לא יכול לחפש עדכונים</translation> <translation id="5396916991083608703">להגדיר את Chromium כדפדפן ברירת המחדל?</translation> +<translation id="5453478652154926037">Chromium לא יכול לבדוק את הסיסמאות שלך.</translation> <translation id="5521125884468363740">כדי לראות את הכרטיסיות שלך מכל מקום שבו פתחת את Chromium יש להיכנס לחשבון ולהפעיל את הסנכרון</translation> <translation id="5522297504975449419">חלק מהתכונות של Chromium לא יהיו זמינות יותר.</translation> <translation id="5573014823074921752">טיפ למשתמשי Chromium: כדי לקבל אפשרויות נוספות של כרטיסיות, יש ללחוץ לחיצה ארוכה על הלחצן 'הצגת כרטיסיות' בסרגל הכלים, שנמצא בחלק התחתון או העליון של המסך.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb index afa53c2..e5c9c6b7 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
@@ -4,6 +4,7 @@ <translation id="1047130070405668746">Chromium brauzerini tanlang</translation> <translation id="1091252999271033193">Bunda Chromium har safar saytning mobil versiyasini talab qiladi.</translation> <translation id="1185134272377778587">Chromium haqida</translation> +<translation id="1256849392437386613">“Narxni kuzatish” uchun Qurilma sozlamalari orqali Chromium bildirishnomalariga ruxsat bering</translation> <translation id="1257458525759135959">Rasmlarni saqlash uchun Sozlamalar ustiga bosib, Chromiumga rasmlarni ochishga ruxsat bering.</translation> <translation id="1289216811211435351">Chromiumga almashish</translation> <translation id="1361748954329991663">Chromium versiyasi eskirdi. Agar <ph name="BEGIN_LINK" />App Store<ph name="END_LINK" /> orqali chiqmasa, demak qurilmangizda yangi versiyadagi Chromium nashrlari ishlamasligi mumkin.</translation> @@ -70,6 +71,7 @@ <translation id="5573014823074921752">Chromium maslahati. Ko‘proq varaqlarni tanlash uchun ekranning quyi yoki yuqorisida joylashgan asboblar panelidan Varaqlarni ko‘rsatish tugmasi ustiga bosib turing.</translation> <translation id="5700709190537129682">Chromium parollaringizni tekshira olmadi</translation> <translation id="5777187867430702742">Chromium sahifasi</translation> +<translation id="5918064849477363478">Chromium bildirishnomalari qurilma sozlamalaridan faolsizlantirilgan. Ularga ruxsat bering.</translation> <translation id="5945387852661427312"><ph name="DOMAIN" /> domenida boshqariladigan hisobga kirish bilan siz administratorga Chromium ma’lumotlaringizni boshqarishiga rozilik bildirasiz. Barcha Chromium ma’lumotlaringiz bu hisobga butunlay bog‘langan. Agar hisobdan chiqadigan bo‘lsangiz, bu qurilmadagi barcha ma’lumotlaringiz o‘chib ketadi, lekin Google hisobingizda saqlanib qoladi.</translation> <translation id="5983312940147103417">Chromiumni yaxshilash</translation> <translation id="6062449165341879460">Tashkilotingiz (<ph name="DOMAIN" />) hisobingizdagi Chromium maʼlumotlari, bukmarklar, tarix, parollar va boshqa sozlamalaringizni koʻra oladi. Hisobdan chiqsangiz, bu qurilmadagi maʼlumotlaringiz tozalanadi. Lekin, boshqaruvdagi Google hisobi maʼlumotlari joyida qoladi va tashkilotingiz ularni koʻra oladi. Tashkilotingiz Chromium funksiyasini oʻzgartirish mumkin boʻlgan oʻsha hisobga tegishli foydalanuvchi siyosatlarini oʻrnatishi ham mumkin.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb index b79df44..cf9fbc3 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb
@@ -113,6 +113,7 @@ <translation id="7780154209050837198">Da iskoristite sve prednosti Chromea, prijavite se na Chrome pomoću Google računa.</translation> <translation id="7855730255114109580">Google Chrome je ažuriran</translation> <translation id="7939179037291298976">U postavkama iPhone uređaja otvorite Opcije lozinke i odaberite Chrome</translation> +<translation id="7975131781538454817">Obavještenja Chromea su isključena u postavkama uređaja. Najprije ćete morati dozvoliti obavještenja.</translation> <translation id="8022947259858476807">Koristite Chrome prema zadanim postavkama da otvarate linkove, pretražujete iz vidžeta i automatski popunjavate lozinke u drugim aplikacijama</translation> <translation id="81358522153858150">Chrome sada podržava korisnička pravila za vaš upravljani račun</translation> <translation id="8160472928944011082">Nije moguće ažurirati Chrome</translation> @@ -140,6 +141,7 @@ <ph name="BEGIN_INDENT" /> • Informacije o vašem korištenju Chromea se šalju Googleu, ali se ne povezuju s vama. • Ako dođe do pada Chromea, detalji o padu mogu uključivati neke lične informacije. • Ako uključite sinhronizaciju, pokazatelji također mogu uključivati informacije o URL-ovima koje posjetite.<ph name="END_INDENT" /></translation> +<translation id="9101160735177453133">Da uključite funkciju "Prati cijenu" dozvolite obavještenja Chromea u postavkama uređaja</translation> <translation id="9103442491611662960">Za ovaj Chrome profil dobijate standardnu sigurnosnu zaštitu</translation> <translation id="9112744793181547300">Postaviti Chrome kao zadani preglednik?</translation> <translation id="9122931302567044771">Ovo znači da će Chrome svaki put zatražiti web lokaciju za računar.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_iw.xtb index 9f8cc7f9..43c59410 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_iw.xtb
@@ -67,6 +67,7 @@ <translation id="5162467219239570114">Chrome אינו מעודכן. אם אין עדכון זמין ב-<ph name="BEGIN_LINK" />App Store<ph name="END_LINK" />, ייתכן שהמכשיר שלך אינו תומך עוד בגרסאות חדשות של Chrome.</translation> <translation id="5389212809648216794">Google Chrome לא יכול להשתמש במצלמה כי אפליקציה אחרת משתמשת בה</translation> <translation id="5460571915754665838">4. בוחרים באפשרות Chrome</translation> +<translation id="5492504007368565877">למנהל הסיסמאות של Google אין אפשרות לבדוק את הסיסמאות.</translation> <translation id="5552137475244467770">מערכת Chrome בודקת מדי פעם את הסיסמאות שלך ומשווה אותן לרשימות שהתפרסמו באינטרנט. כשהפעולה הזו מבוצעת, הסיסמאות ושמות המשתמש מוצפנים, כך שאיש לא יוכל לקרוא אותם, כולל Google.</translation> <translation id="5639704535586432836">יש לעבור אל 'הגדרות' > 'פרטיות' > 'מצלמה' > Google Chrome ולהפעיל את המצלמה.</translation> <translation id="5642200033778930880">Google Chrome לא יכול להשתמש במצלמה במצב תצוגה מפוצלת</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb index 660623f..8a5788f 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
@@ -113,6 +113,7 @@ <translation id="7780154209050837198">Chrome imkoniyatlaridan maksimal foydalanish uchun Chromega Google hisobingiz bilan kiring.</translation> <translation id="7855730255114109580">Google Chrome versiyasi yangi</translation> <translation id="7939179037291298976">iPhone sozlamalari orqali “Parol variantlari” sahifasini oching va “Chrome” ilovasini tanlang</translation> +<translation id="7975131781538454817">Chrome bildirishnomalari qurilma sozlamalaridan faolsizlantirilgan. Ularga ruxsat bering.</translation> <translation id="8022947259858476807">Havolalarni ochish, vidjetlar orqali qidiruv, boshqa ilovalarda parollar avtomatik kitilishda Chrome birlamchi ilova sifatida ishlatilsin</translation> <translation id="81358522153858150">Chrome endi boshqariladigan hisobingiz uchun foydalanuvchi siyosatlarini qoʻllab-quvvatlaydi</translation> <translation id="8160472928944011082">Chrome yangilanmadi</translation> @@ -142,6 +143,7 @@ • Chromeda nosozlik yuz bersa, u haqidagi maʼlumotlar, shuningdek, ayrim shaxsiy axborotlar ham yuboriladi • Sinxronizatsiya yoqilsa, koʻrsatkichlarga siz kiritgan URL manzillar ham biriktiriladi<ph name="END_INDENT" /></translation> +<translation id="9101160735177453133">“Narxni kuzatish” uchun Qurilma sozlamalari orqali Chrome bildirishnomalariga ruxsat bering</translation> <translation id="9103442491611662960">Bu Chrome profili standart xavfsizlik tizimi bilan himoyalangan</translation> <translation id="9112744793181547300">Chrome asosiy brauzer sifatida tanlansinmi?</translation> <translation id="9122931302567044771">Bunda Chrome har safar saytning kompyuter versiyasini talab qiladi.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_strings_bs.xtb index 40224bc..d4565a2 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bs.xtb
@@ -561,6 +561,7 @@ <translation id="5118713593561876160">Interesovanja</translation> <translation id="5118764316110575523">Isključeno</translation> <translation id="5119391094379141756">Odaberite Chrome</translation> +<translation id="5121618895923301719">Već pratite ovaj proizvod. Ova stranica je sačuvana u <ph name="BEGIN_LINK" />Mobilnim oznakama<ph name="END_LINK" />.</translation> <translation id="5132942445612118989">Sinhronizacija lozinki, historije i ostalog na svim uređajima</translation> <translation id="5142890110117755815">{COUNT,plural, =1{{COUNT} slaba lozinka}one{{COUNT} slaba lozinka}few{{COUNT} slabe lozinke}other{{COUNT} slabih lozinki}}</translation> <translation id="5149188072385105201">Dodaj lozinku...</translation> @@ -591,6 +592,7 @@ <translation id="5386314158584363703">Web lokacije koje pratite ćete pronaći ovdje</translation> <translation id="5388358297987318779">Otvori sliku</translation> <translation id="5407969256130905701">Odbaci promjene</translation> +<translation id="5414763847370083940">Dobit ćete obavještenje ako cijena padne na bilo kojoj web lokaciji.</translation> <translation id="5416022985862681400">Posljednjih 7 dana</translation> <translation id="5423269318075950257">Praćenje cijena</translation> <translation id="543338862236136125">Uredite lozinku</translation> @@ -1133,6 +1135,7 @@ <translation id="952704832371081537">Otkaži</translation> <translation id="953008885340860025">Chrome je odjavljen</translation> <translation id="959066944189734975">Pratite kanal <ph name="CHANNEL_NAME" /></translation> +<translation id="973493300226275298">Pratite cijenu proizvoda u online trgovinama. Dobit ćete upozorenja kada padnu cijene.</translation> <translation id="980712131080209571">N</translation> <translation id="981498610235328462">Vaša organizacija vam dozvoljava da se prijavite samo s određenim računima. Računi koji nisu dozvoljeni su skriveni.</translation> <translation id="984509647832111802">Sinhronizacija ne funkcionira.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_strings_iw.xtb index b8bb2ddb..0467d70 100644 --- a/ios/chrome/app/strings/resources/ios_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_iw.xtb
@@ -101,6 +101,7 @@ <translation id="1608337082864370066">חיפוש תמונה שהועתקה</translation> <translation id="1612730193129642006">הצגת רשת כרטיסיות</translation> <translation id="1620510694547887537">מצלמה</translation> +<translation id="1626771852476987600">יש <ph name="COUNT" /> סיסמאות בשימוש חוזר</translation> <translation id="1641113438599504367">גלישה בטוחה</translation> <translation id="1644574205037202324">היסטוריה</translation> <translation id="1650222530560417226">אפשר להקיש על הלחצן "התחלת הרישום ביומן" כדי לאסוף רשומות יומן ושגיאות של לוח JavaScript מכל הכרטיסיות. רשומות היומן ייאספו (ויישמרו רק בזיכרון) עד לסגירת הדף הזה, או להקשה על "הפסקת הרישום ביומן".</translation> @@ -193,6 +194,7 @@ <translation id="2411749908844615428">{count,plural, =1{כתובת שמורה אחת ({count}) זמינה מעל המקלדת.}one{{count} כתובות שמורות זמינות מעל המקלדת.}two{{count} כתובות שמורות זמינות מעל המקלדת.}other{{count} כתובות שמורות זמינות מעל המקלדת.}}</translation> <translation id="2421004566762153674">חסימת קובצי Cookie של צד שלישי</translation> <translation id="2421044535038393232">המשך העריכה</translation> +<translation id="2430198251915534025">{COUNT,plural, =1{סיסמה אחת ({COUNT}) שנחשפה}one{{COUNT} סיסמאות שנחשפו}two{{COUNT} סיסמאות שנחשפו}other{{COUNT} סיסמאות שנחשפו}}</translation> <translation id="2434405374328098816">כבר שמרת סיסמה עבור המשתמש "<ph name="USERNAME" />" לאתר <ph name="WEBSITE" /></translation> <translation id="2435457462613246316">הצגת סיסמה</translation> <translation id="2451654228769116489">הצמדת הכרטיסייה</translation> @@ -336,6 +338,7 @@ <translation id="345565170154308620">ניהול סיסמאות…</translation> <translation id="3469166899695866866">לעצור את ההורדה?</translation> <translation id="3470502288861289375">ההעתקה מתבצעת...</translation> +<translation id="3474048842645761983">{COUNT,plural, =1{לאתר אחד או לאפליקציה אחת ({COUNT})}one{ל-{COUNT} אתרים ואפליקציות}two{ל-{COUNT} אתרים ואפליקציות}other{ל-{COUNT} אתרים ואפליקציות}}</translation> <translation id="3474624961160222204">המשך כ-<ph name="NAME" /></translation> <translation id="3478058380795961209">חודש פקיעת התוקף</translation> <translation id="3482959374254649722">מתבצע סנכרון של הכרטיסיות שלך...</translation> @@ -382,6 +385,7 @@ <translation id="3818293389945649617">חיפוש המחרוזת הבאה</translation> <translation id="3819183753496523827">אין לך חיבור לאינטרנט. צריך לבדוק את החיבור לאינטרנט ולנסות שוב.</translation> <translation id="3835964409414434850">מעבר לכרטיסייה הבאה</translation> +<translation id="3838691874161539578">כדאי לבדוק את הסיסמאות השמורות כדי להגביר את האבטחה ולשמור על הבטיחות באינטרנט</translation> <translation id="385051799172605136">חזרה</translation> <translation id="3851938967634752633">הסיסמאות של <ph name="WEBSITE" />, של <ph name="SECOND_WEBSITE" /> ושל <ph name="NUMBER_OF_ACCOUNTS" /> אתרים נוספים יימחקו. החשבונות שלך לא יימחקו.</translation> <translation id="3858860766373142691">שם</translation> @@ -437,6 +441,7 @@ <translation id="4249955472157341256">מיון לפי 'האחרון'</translation> <translation id="4253168017788158739">הערה</translation> <translation id="4263576668337963058">הצגה של פעולות זמינות בדף</translation> +<translation id="4267586310863245665">{COUNT,plural, =1{סגרת אזהרה אחת ({COUNT})}one{סגרת {COUNT} אזהרות}two{סגרת {COUNT} אזהרות}other{סגרת {COUNT} אזהרות}}</translation> <translation id="4272631900155121838">כדי לסרוק את קוד ה-QR, יש להפעיל את המצלמה דרך ההגדרות</translation> <translation id="4277990410970811858">גלישה בטוחה</translation> <translation id="4281844954008187215">תנאי שירות</translation> @@ -483,6 +488,7 @@ <translation id="4630540211544979320">תרגום דפים</translation> <translation id="4634124774493850572">שימוש בסיסמה</translation> <translation id="4636930964841734540">מידע</translation> +<translation id="4642472735733036929">המעקב אחר מחירים הופסק</translation> <translation id="4650125387981512669">המשך בשם <ph name="FIRST_RUN_ACCOUNT_NAME" /></translation> <translation id="4659126640776004816">התכונה הזו מופעלת בעת הכניסה לחשבון Google.</translation> <translation id="4659667755519643272">כניסה אל Tab Switcher</translation> @@ -556,6 +562,7 @@ <translation id="5118764316110575523">כבויה</translation> <translation id="5119391094379141756">בוחרים באפשרות Chrome</translation> <translation id="5132942445612118989">סנכרון הסיסמאות, ההיסטוריה ונתונים נוספים בכל המכשירים</translation> +<translation id="5142890110117755815">{COUNT,plural, =1{סיסמה חלשה אחת ({COUNT})}one{{COUNT} סיסמאות חלשות}two{{COUNT} סיסמאות חלשות}other{{COUNT} סיסמאות חלשות}}</translation> <translation id="5149188072385105201">הוספת סיסמאות…</translation> <translation id="5150492518600715772">שליחה למכשיר שלך</translation> <translation id="5168414296986405587">מותאם ל-iPadOS</translation> @@ -639,6 +646,7 @@ <translation id="5804241973901381774">הרשאות</translation> <translation id="5812974770859303494">הוספה אל…</translation> <translation id="581659025233126501">הפעלת הסנכרון</translation> +<translation id="5817176759448082654">בדיקת סיסמאות</translation> <translation id="5819208479324046259">מנוהל על ידי <ph name="MANAGER" />. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="5833643789537100742">אפשר לשמור סיסמאות, אמצעי תשלום וכתובות ש-Chrome יוכל למלא באופן אוטומטי מאוחר יותר.</translation> <translation id="5834415013958049700">תמונת Lens שהעתקת</translation> @@ -839,6 +847,7 @@ <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="7004499039102548441">כרטיסיות אחרונות</translation> <translation id="7006788746334555276">הגדרות תוכן</translation> +<translation id="7014087399239955356">הסיסמאות נבדקות…</translation> <translation id="7029809446516969842">סיסמאות</translation> <translation id="7053983685419859001">חסימה</translation> <translation id="7062545763355031412">אישור והחלפת חשבונות</translation> @@ -894,6 +903,7 @@ <translation id="7514365320538308">הורדה</translation> <translation id="7531345132340165516">האתר הנוכחי</translation> <translation id="7537586195939242955">מצטערים, לא ניתן להתקין את ה-Pass שלך ב-Passbook בשלב הזה.</translation> +<translation id="754655535278952384">הבדיקה האחרונה: <ph name="TIME" /></translation> <translation id="7553234618121028547">כדי להשבית את המילוי האוטומטי, פותחים את ה<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" /> ועוברים אל 'אפשרויות של סיסמאות'.</translation> <translation id="7554645225856321710">סגירת הכול</translation> <translation id="7554791636758816595">כרטיסייה חדשה</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_strings_uz.xtb index 247e403..c9575a5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_uz.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
@@ -314,6 +314,7 @@ <translation id="3227137524299004712">Mikrofon</translation> <translation id="3240426699337459095">Nusxalandi</translation> <translation id="3244271242291266297">OO</translation> +<translation id="3245744387817103524">Oʻzgarish saqlanmadi.</translation> <translation id="3252394070589632019"><ph name="VALUE" />, <ph name="ADDITIONAL_INFO" />, <ph name="INDEX" /> / <ph name="NUM_SUGGESTIONS" /></translation> <translation id="3268451620468152448">Ochiq ichki oynalar</translation> <translation id="3272527697863656322">Bekor qilish</translation> @@ -336,6 +337,7 @@ <translation id="3445288400492335833"><ph name="MINUTES" /> daq</translation> <translation id="3448016392200048164">Split View</translation> <translation id="345565170154308620">Parollarni boshqarish...</translation> +<translation id="3464194322481586217">Narxni kuzatish imkonsiz.</translation> <translation id="3469166899695866866">Yuklab olish to‘xtatilsinmi?</translation> <translation id="3470502288861289375">Nusxa olinmoqda...</translation> <translation id="3474048842645761983">{COUNT,plural, =1{{COUNT} ta sayt yoki ilova uchun}other{{COUNT} ta sayt yoki ilova uchun}}</translation> @@ -561,6 +563,7 @@ <translation id="5118713593561876160">Qiziqishlar</translation> <translation id="5118764316110575523">Yoqilmagan</translation> <translation id="5119391094379141756">Chrome brauzerini tanlang</translation> +<translation id="5121618895923301719">Siz bu mahsulotni kuzatyapsiz. Bu sahifa <ph name="BEGIN_LINK" />Mobil bukmarklarga<ph name="END_LINK" /> saqlandi.</translation> <translation id="5132942445612118989">Parollar, tarix va boshqa sozlamalaringizni barcha qurilmalaringizda sinxronlang</translation> <translation id="5142890110117755815">{COUNT,plural, =1{{COUNT} ta kuchsiz parol aniqlandi}other{{COUNT} ta kuchsiz parol aniqlandi}}</translation> <translation id="5149188072385105201">Parol kiritish...</translation> @@ -591,6 +594,7 @@ <translation id="5386314158584363703">Kuzatuvdagi saytlar shu yerda chiqadi</translation> <translation id="5388358297987318779">Tasvirni ochish</translation> <translation id="5407969256130905701">Bekor qilish</translation> +<translation id="5414763847370083940">Istalgan saytda narx tushganda ogohlantirish olasiz.</translation> <translation id="5416022985862681400">Oxirgi 7 kun</translation> <translation id="5423269318075950257">Narxni kuzatish</translation> <translation id="543338862236136125">Parolni almashtirish</translation> @@ -761,6 +765,7 @@ <translation id="6464397691496239022">Saytlar sahifalarni kezishingizni yaxshilash, jumladan, kirish axborotingiz yoki xarid qutingizni eslab qolish uchun cookie fayllardan foydalanishi mumkin. Saytlar reklamalarni sizga moslashtirish uchun brauzerdagi faoliyatingizni kuzata olmaydi.</translation> +<translation id="6476253015009698798">Bu saytdagi narxlarni kuzatish imkonsiz.</translation> <translation id="6476800141292307438">Sahifa <ph name="LANGUAGE" /> tiliga tarjima qilinmoqda. Parametrlar ekranning pastiga yaqin joyda joylashgan.</translation> <translation id="648164694371393720">Autentifikatsiya xatosi</translation> <translation id="6482629121755362506"><ph name="NUMBER_OF_SELECTED_BOOKMARKS" /> ta xatcho‘p o‘chirildi</translation> @@ -812,6 +817,7 @@ <translation id="6780034285637185932">Pochta indeksi</translation> <translation id="6781260999953472352">Sinxronizatsiya yoqilsinmi?</translation> <translation id="6785453220513215166">Ishdan chiqish hisoboti yuborilmoqda...</translation> +<translation id="6790502149545262384">Tez orada yangi varaq ochilganda <ph name="CHANNEL_NAME" /> hikoyalari chiqadi.</translation> <translation id="6797885426782475225">Ovozli qidiruv</translation> <translation id="6801927553864092214">Yashirin kezish uchun inkognito rejimida varaq oching</translation> <translation id="6807889908376551050">Hammasini ochish...</translation> @@ -1121,6 +1127,7 @@ <translation id="9137526406337347448">Google xizmatlari</translation> <translation id="9148126808321036104">Qaytadan kiring</translation> <translation id="9157836665414082580">Muloqot oynalarini bloklash</translation> +<translation id="9162432979321511934">Parollar avtomatik kiritilishini yoqish</translation> <translation id="9177438225260810839">Ochiq varaqlar ichidan qidirish</translation> <translation id="9188680907066685419">Boshqariladigan hisobdan chiqish</translation> <translation id="9193147658040604536">Varaqni mahkamlash uchun tashlang</translation> @@ -1133,6 +1140,7 @@ <translation id="952704832371081537">Bekor qilish</translation> <translation id="953008885340860025">Chrome hisobidan chiqarildi</translation> <translation id="959066944189734975"><ph name="CHANNEL_NAME" /> tasmasiga obuna boʻlgansiz</translation> +<translation id="973493300226275298">Onlayn doʻkonlarda mahsulot narxini kuzating. Narx tushganda ogohlantirish olasiz.</translation> <translation id="980712131080209571">Y</translation> <translation id="981498610235328462">Tashkilotingiz faqat ayrim hisoblardan kirishga ruxsat beradi. Ruxsat etilmagan hisoblar yashirilgan.</translation> <translation id="984509647832111802">Sinxronizatsiya ishlamayapti.</translation>
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index cc547b8..2ffd6df7 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -f18656a2c20ff68874f714b3a9a6609fcef426a1 \ No newline at end of file +9dcdbbac87f001bdcbee15617385a065d7c226b5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 9a1fad9..a0844e2 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -d85eb5f15d3af48e03bdc6e7f0b74eb236711e4c \ No newline at end of file +0606833ba64614b281440f58b5c2201ce5f04676 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 07a35b59..6cbae9a 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -f022594a9f5f9504253c63cac20395ae8ef59b89 \ No newline at end of file +e317aca07b871af8323f025a505482173154e500 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 6efb06c7..2e1a03a 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b9909db3bbfaa567f21ef3b3f32e863a1bb5028e \ No newline at end of file +cafa786f55935b4107f36cc1355a14c03271f051 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index d8d33126..0dabeb5 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -bd6a5e69143a2c6f478bcfd784822b82410821d1 \ No newline at end of file +a7c76bb67650cfa921297953df67d6f4c15bf157 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 64fd925..f903af2 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -21e8c063a882f3d98d128d45bf87fd84fd442248 \ No newline at end of file +d5c895d5abeba93d870bef9ebc9c6342429dd0ce \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index 5ae45178..476ca33 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e59c1111f3557325f9dc4317d0a37624edb588e8 \ No newline at end of file +7850eb1008ec1c19ec9bdc2af6b3e994af046d00 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index cc99d53..6508fca 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -85abb58123b95b5a0413e4e66f0cd581f3920d5d \ No newline at end of file +c61c03f1148eb14bd6281aaa1582c4d528be38f9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 4ba4036a..8814ef2 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -eb505f6512441affc91433a7273a726eaa1c16b5 \ No newline at end of file +541dbab7d5545214f3d0181f71a267dc3eebdfd0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 3fd8266f..febf4c0 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8eacbc759d22fa18ca356cef9d04d683ddd2e124 \ No newline at end of file +10c01194501a085a5cff778f0624c340499e88ea \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index e92f42f..e20c38b 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -93e1a8df3de8ffabc8d6684b568b6329ad9d8f42 \ No newline at end of file +79e0d2afc7e0dd5235b77d9fdd0827392bae640c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 0d839fd..3d39e25 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -dda34ef5072ab0bdcf3b9630d43aca1d5296b9e7 \ No newline at end of file +ca6ca29e35c2e356487dea8bb07aca875f2554a1 \ No newline at end of file
diff --git a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc index 571894a..0511b8d 100644 --- a/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_jpeg_encode_accelerator.cc
@@ -1585,6 +1585,10 @@ std::move(output_gmb_handle), output_gmb_buffer_size, gfx::BufferFormat::R_8, gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, base::DoNothing()); + if (!output_gmb_buffer) { + VLOGF(1) << "Failed to import gmb buffer"; + return 0; + } bool isMapped = output_gmb_buffer->Map(); if (!isMapped) {
diff --git a/mojo/core/ipcz_driver/data_pipe.cc b/mojo/core/ipcz_driver/data_pipe.cc index 2abbf4c..ec1c053 100644 --- a/mojo/core/ipcz_driver/data_pipe.cc +++ b/mojo/core/ipcz_driver/data_pipe.cc
@@ -40,6 +40,7 @@ RingBuffer::SerializedState ring_buffer_state; }; +static_assert(sizeof(DataPipeHeader) == 24, "Invalid DataPipeHeader size"); // Attempts to put a single (32-bit) integer into the given `portal`. Returns // true if successful, or false to indicate that the peer portal is closed. @@ -521,7 +522,7 @@ const auto& header = *reinterpret_cast<const DataPipeHeader*>(data.data()); const size_t header_size = header.size; - if (header_size < sizeof(header)) { + if (header_size < sizeof(header) || header_size % 8 != 0) { return nullptr; }
diff --git a/mojo/core/ipcz_driver/ring_buffer.h b/mojo/core/ipcz_driver/ring_buffer.h index 0c6348e..bc3981f 100644 --- a/mojo/core/ipcz_driver/ring_buffer.h +++ b/mojo/core/ipcz_driver/ring_buffer.h
@@ -152,6 +152,7 @@ uint32_t offset = 0; uint32_t size = 0; }; + static_assert(sizeof(SerializedState) == 8, "Invalid SerializedState size"); void Serialize(SerializedState& state); bool Deserialize(const SerializedState& state);
diff --git a/mojo/core/ipcz_driver/shared_buffer.cc b/mojo/core/ipcz_driver/shared_buffer.cc index 1515564..510a7f20 100644 --- a/mojo/core/ipcz_driver/shared_buffer.cc +++ b/mojo/core/ipcz_driver/shared_buffer.cc
@@ -36,11 +36,15 @@ // Access mode for the region. BufferMode mode; + // Explicit padding for the next field to be 8-byte-aligned. + uint32_t padding; + // The low and high components of the 128-bit GUID used to identify this // buffer. uint64_t guid_low; uint64_t guid_high; }; +static_assert(sizeof(BufferHeader) == 32, "Invalid BufferHeader size"); // Produces a ScopedPlatformSharedMemoryHandle from a set of PlatformHandles and // an access mode. @@ -190,7 +194,9 @@ DCHECK_GE(data.size(), sizeof(BufferHeader)); BufferHeader& header = *reinterpret_cast<BufferHeader*>(data.data()); - header.size = static_cast<uint32_t>(region_.GetSize()); + header.size = sizeof(header); + header.buffer_size = static_cast<uint32_t>(region_.GetSize()); + header.padding = 0; switch (region_.GetMode()) { case base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly: header.mode = BufferMode::kReadOnly; @@ -235,6 +241,11 @@ const BufferHeader& header = *reinterpret_cast<const BufferHeader*>(data.data()); + const size_t header_size = header.size; + if (header_size < sizeof(BufferHeader) || header_size % 8 != 0) { + return nullptr; + } + base::subtle::PlatformSharedMemoryRegion::Mode mode; switch (header.mode) { case BufferMode::kReadOnly: @@ -258,7 +269,7 @@ auto handle = CreateRegionHandleFromPlatformHandles(handles, mode); auto region = base::subtle::PlatformSharedMemoryRegion::Take( - std::move(handle), mode, header.size, guid.value()); + std::move(handle), mode, header.buffer_size, guid.value()); if (!region.IsValid()) { return nullptr; }
diff --git a/mojo/core/ipcz_driver/wrapped_platform_handle.cc b/mojo/core/ipcz_driver/wrapped_platform_handle.cc index fb499d8..65c5b33 100644 --- a/mojo/core/ipcz_driver/wrapped_platform_handle.cc +++ b/mojo/core/ipcz_driver/wrapped_platform_handle.cc
@@ -60,6 +60,8 @@ // Indicates what specific type of handle is wrapped. WrapperType type; }; +static_assert(sizeof(WrappedPlatformHandleHeader) == 8, + "Invalid WrappedPlatformHandleHeader size"); #if BUILDFLAG(IS_FUCHSIA) PlatformHandle MakeFDTransmissible(base::ScopedFD fd) { @@ -169,7 +171,8 @@ const auto& header = *reinterpret_cast<const WrappedPlatformHandleHeader*>(data.data()); - if (header.size < sizeof(header)) { + const size_t header_size = header.size; + if (header_size < sizeof(header) || header_size % 8 != 0) { return nullptr; }
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index ca0ea70..a894974 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2023-02-18 12:54 UTC +# Last updated: 2023-02-19 12:54 UTC PinsListTimestamp -1676724868 +1676811294 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/services/image_annotation/annotator_unittest.cc b/services/image_annotation/annotator_unittest.cc index 5d760af..db74d48 100644 --- a/services/image_annotation/annotator_unittest.cc +++ b/services/image_annotation/annotator_unittest.cc
@@ -363,8 +363,7 @@ // Returns a "canonically" formatted version of a JSON string by parsing and // then rewriting it. std::string ReformatJson(const std::string& in) { - const std::unique_ptr<base::Value> json = - base::JSONReader::ReadDeprecated(in); + const absl::optional<base::Value> json = base::JSONReader::Read(in); CHECK(json); std::string out;
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 4f7d3357..b29d65d 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5818,9 +5818,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -5832,8 +5832,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -5989,9 +5989,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -6003,8 +6003,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -6141,9 +6141,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -6155,8 +6155,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 2556795..c011e49 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -20507,9 +20507,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20521,8 +20521,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -20678,9 +20678,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20692,8 +20692,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -20830,9 +20830,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -20844,8 +20844,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 81627b9..84063e2 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -57176,9 +57176,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -57189,8 +57189,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -57347,9 +57347,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -57360,8 +57360,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -57499,9 +57499,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -57512,8 +57512,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -59037,9 +59037,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -59050,8 +59050,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -59208,9 +59208,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -59221,8 +59221,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -59360,9 +59360,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -59373,8 +59373,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -60146,9 +60146,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -60159,8 +60159,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 8421a58..e93b4bd 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -18533,12 +18533,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18550,8 +18550,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -18724,12 +18724,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18741,8 +18741,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [ @@ -18891,12 +18891,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 112.0.5604.0", + "description": "Run with ash-chrome version 112.0.5606.0", "isolate_profile_data": true, "merge": { "args": [], @@ -18908,8 +18908,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v112.0.5604.0", - "revision": "version:112.0.5604.0" + "location": "lacros_version_skew_tests_v112.0.5606.0", + "revision": "version:112.0.5606.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 36df6b5..43c655a4 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5604.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v112.0.5606.0/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 112.0.5604.0', + 'description': 'Run with ash-chrome version 112.0.5606.0', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v112.0.5604.0', - 'revision': 'version:112.0.5604.0', + 'location': 'lacros_version_skew_tests_v112.0.5606.0', + 'revision': 'version:112.0.5606.0', }, ], },
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 1b147ad..4aa93004 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1509,7 +1509,7 @@ BASE_FEATURE(kSerializeAccessibilityPostLifecycle, "SerializeAccessibilityPostLifeycle", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kThreadedPreloadScanner, "ThreadedPreloadScanner",
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index e75884a..2373e81ed 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -8555,14 +8555,16 @@ # that is incompatible with prerender and has caused the cancellation of the attempt optional string disallowedApiMethod - # List of Prefetch status, which refers to PreloadingTriggeringOutcome. - type PrefetchStatus extends string + # Preloading status values, see also PreloadingTriggeringOutcome. This + # status is shared by prefetchStatusUpdated and prerenderStatusUpdated. + type PreloadingStatus extends string enum + Pending Running Ready Success Failure - # PreloadingTriggeringOutcome which not used by prefetch. + # PreloadingTriggeringOutcome which not used by prefetch nor prerender. NotSupported # TODO(crbug/1384419): Create a dedicated domain for preloading. @@ -8572,7 +8574,16 @@ # The frame id of the frame initiating prefetch. FrameId initiatingFrameId string prefetchUrl - PrefetchStatus status + PreloadingStatus status + + # TODO(crbug/1384419): Create a dedicated domain for preloading. + # Fired when a prerender attempt is updated. + experimental event prerenderStatusUpdated + parameters + # The frame id of the frame initiating prerender. + FrameId initiatingFrameId + string prerenderingUrl + PreloadingStatus status event loadEventFired parameters
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 26ad8ba..6aece9d 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -101,7 +101,6 @@ crbug.com/24182 [ Release ] fast/dom/timer-throttling-background-page-near-alignment-interval.html [ Slow ] crbug.com/24182 http/tests/perf/large-inlined-script.html [ Slow ] crbug.com/24182 [ Debug Linux ] fast/css/should-not-insert-stylesheet-into-detached-document.html [ Slow ] -crbug.com/24182 [ Debug Mac12 ] fast/css/should-not-insert-stylesheet-into-detached-document.html [ Slow ] crbug.com/24182 [ Release ] fast/css/should-not-insert-stylesheet-into-detached-document.html [ Slow ] crbug.com/24182 fast/encoding/char-encoding.html [ Slow ] crbug.com/24182 fast/frames/sandboxed-iframe-navigation-targetlink.html [ Slow ] @@ -413,7 +412,6 @@ ### Some timeout tests in xmlhttprequest/timeout/ are slow crbug.com/869800 [ Debug Mac12 ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-aborted.html [ Slow ] crbug.com/869800 [ Release ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-aborted.html [ Slow ] -crbug.com/869800 [ Debug Mac12 ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-simple.html [ Slow ] crbug.com/869800 [ Release ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-simple.html [ Slow ] crbug.com/869800 [ Debug Mac12 ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-synconworker.html [ Slow ] crbug.com/869800 [ Release ] http/tests/xmlhttprequest/timeout/xmlhttprequest-timeout-worker-synconworker.html [ Slow ] @@ -557,7 +555,6 @@ crbug.com/874695 fast/scrolling/autoscroll-iframe-no-scrolling.html [ Slow ] crbug.com/874695 [ Debug Mac12 ] fast/table/multiple-captions-crash3.html [ Slow ] crbug.com/874695 [ Release ] fast/table/multiple-captions-crash3.html [ Slow ] -crbug.com/874695 [ Debug Linux ] fast/table/multiple-captions-crash4.html [ Slow ] crbug.com/874695 [ Debug Mac12 ] fast/table/multiple-captions-crash4.html [ Slow ] crbug.com/874695 [ Release ] fast/table/multiple-captions-crash4.html [ Slow ] crbug.com/874695 [ Linux ] fast/webgl/canvas-toDataURL-crash.html [ Slow ] @@ -587,7 +584,6 @@ crbug.com/874695 [ Debug Linux ] http/tests/fetch/serviceworker/body-mixin.html [ Slow ] crbug.com/874695 [ Release ] http/tests/fetch/serviceworker/body-mixin.html [ Slow ] crbug.com/874695 [ Debug Linux ] http/tests/fetch/serviceworker/stream-reader-base-https-other-https.html [ Slow ] -crbug.com/874695 [ Debug Mac12 ] http/tests/fetch/serviceworker/stream-reader-base-https-other-https.html [ Slow ] crbug.com/874695 [ Release ] http/tests/fetch/serviceworker/stream-reader-base-https-other-https.html [ Slow ] crbug.com/874695 [ Debug Mac12 ] http/tests/fetch/serviceworker/stream-reader.html [ Slow ] crbug.com/874695 [ Release ] http/tests/fetch/serviceworker/stream-reader.html [ Slow ] @@ -616,7 +612,6 @@ crbug.com/874695 http/tests/fetch/workers/thorough/* [ Slow ] crbug.com/874695 [ Release ] http/tests/images/png-progressive-load.html [ Slow ] crbug.com/874695 [ Linux Release ] http/tests/images/webp-progressive-load.html [ Slow ] -crbug.com/874695 [ Debug Mac12 ] http/tests/images/webp-progressive-load.html [ Slow ] crbug.com/874695 [ Mac Release ] http/tests/images/webp-progressive-load.html [ Slow ] crbug.com/874695 [ Release Win ] http/tests/images/webp-progressive-load.html [ Slow ] crbug.com/874695 [ Debug Mac12 ] http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Slow ] @@ -698,7 +693,6 @@ crbug.com/874695 [ Debug Linux ] media/video-controls-hide-after-touch-on-control.html [ Slow ] crbug.com/874695 [ Release ] media/video-controls-hide-after-touch-on-control.html [ Slow ] crbug.com/874695 [ Debug Linux ] media/video-controls-hide-on-move-outside-controls.html [ Slow ] -crbug.com/874695 [ Debug Mac12 ] media/video-controls-hide-on-move-outside-controls.html [ Slow ] crbug.com/874695 [ Release ] media/video-controls-hide-on-move-outside-controls.html [ Slow ] crbug.com/874695 [ Debug Mac12 ] media/video-controls-show-on-focus.html [ Slow ] crbug.com/874695 [ Release ] media/video-controls-show-on-focus.html [ Slow ] @@ -807,7 +801,6 @@ crbug.com/983642 fast/canvas/canvas-composite-text-alpha.html [ Slow ] crbug.com/626703 [ Debug Linux ] external/wpt/html/cross-origin-embedder-policy/multi-globals/workers-coep-report.https.html [ Slow ] -crbug.com/626703 [ Debug Mac12 ] external/wpt/html/cross-origin-embedder-policy/multi-globals/workers-coep-report.https.html [ Slow ] crbug.com/626703 [ Release ] external/wpt/html/cross-origin-embedder-policy/multi-globals/workers-coep-report.https.html [ Slow ] # Slow when using Vulkan.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c36bdc9d..b4bede17 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1672,7 +1672,6 @@ crbug.com/1035708 wpt_internal/css/css-pseudo/grammar-error-color-dynamic-004.html [ Failure ] crbug.com/1147859 external/wpt/css/css-pseudo/target-text-004.html [ Failure ] crbug.com/1035708 external/wpt/css/css-pseudo/target-text-dynamic-001.html [ Failure ] -crbug.com/1035708 external/wpt/css/css-pseudo/target-text-dynamic-002.html [ Failure ] crbug.com/1035708 external/wpt/css/css-pseudo/target-text-dynamic-003.html [ Failure ] crbug.com/1035708 external/wpt/css/css-pseudo/target-text-dynamic-004.html [ Failure ] crbug.com/1353352 fast/css3-text/css3-text-decoration/text-decoration-line-grammar-error.html [ Failure ] @@ -2776,7 +2775,6 @@ crbug.com/654666 external/wpt/css/motion/offset-path-url.html [ Failure ] # Various css-values WPT failures -crbug.com/1053965 external/wpt/css/css-values/ex-unit-004.html [ Failure ] crbug.com/759914 external/wpt/css/css-values/ch-unit-011.html [ Failure ] crbug.com/965366 external/wpt/css/css-values/ch-unit-017.html [ Failure ] crbug.com/1350027 [ Mac ] external/wpt/css/css-values/ic-unit-002.html [ Failure ] @@ -2855,7 +2853,6 @@ crbug.com/1024156 external/wpt/css/css-pseudo/cascade-highlight-004.html [ Failure ] crbug.com/1024156 external/wpt/css/css-pseudo/cascade-highlight-005.html [ Failure ] -crbug.com/1024156 external/wpt/css/css-pseudo/highlight-cascade-001.html [ Failure ] crbug.com/1024156 external/wpt/css/css-pseudo/highlight-cascade-002.html [ Failure ] crbug.com/1024156 external/wpt/css/css-pseudo/highlight-cascade-007.html [ Failure ] crbug.com/1024156 external/wpt/css/css-pseudo/highlight-paired-cascade-003.html [ Failure ] @@ -4051,7 +4048,7 @@ crbug.com/922951 http/tests/history/back-to-post.html [ Crash Failure Pass Timeout ] crbug.com/922951 http/tests/security/cookies/basic.html [ Crash Failure Pass Timeout ] crbug.com/922951 http/tests/webaudio/autoplay-crossorigin.html [ Crash Failure Pass Timeout ] -crbug.com/922951 media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Crash Failure Pass Timeout ] +crbug.com/922951 [ Release Win ] media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Crash Failure Pass Timeout ] crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/frame-model-instrumentation.js [ Crash Failure Pass Timeout ] crbug.com/922951 [ Release Win ] virtual/threaded/http/tests/devtools/tracing/timeline-misc/timeline-record-reload.js [ Crash Failure Pass Timeout ] crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-layout/timeline-layout-with-invalidations.js [ Crash Failure Pass Timeout ] @@ -5165,7 +5162,8 @@ crbug.com/1231699 [ Linux ] fast/reflections/opacity-reflection-transform.html [ Failure Pass ] # Other devtools flaky tests outside of http/tests/inspector-protocol/network. -crbug.com/1228261 http/tests/inspector-protocol/browser-grant-permissions.js [ Failure Pass Timeout ] +crbug.com/1228261 [ Debug Mac12 ] http/tests/inspector-protocol/browser-grant-permissions.js [ Failure Pass Timeout ] +crbug.com/1228261 [ Release Win ] http/tests/inspector-protocol/browser-grant-permissions.js [ Failure Pass Timeout ] # Flakes that might be caused or aggravated by PlzServiceWorker crbug.com/996511 external/wpt/service-workers/service-worker/getregistrations.https.html [ Crash Failure Pass Timeout ] @@ -5942,7 +5940,6 @@ crbug.com/1319320 rootscroller/root-scroller-apply-filter-to-parent.html [ Failure Pass ] # Sheriff 2022-04-26 -crbug.com/1320140 [ Win ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/disallowed-navigations.https.html [ Pass Timeout ] crbug.com/1320140 [ Win ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/opaque-ad-sizes.https.html [ Pass Timeout ] crbug.com/1288741 external/wpt/scroll-to-text-fragment/find-range-from-text-directive.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 969751a..ef319df 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -197458,6 +197458,19 @@ {} ] ], + "preserve3d-pseudo-element.html": [ + "f3a4441e991ad57fb1459c1ebb0a9b3a810620a1", + [ + null, + [ + [ + "/css/css-transforms/preserve3d-pseudo-element-ref.html", + "==" + ] + ], + {} + ] + ], "rotate": { "svg-rotate-3args-002.html": [ "5906a2f4041319143b926f75af321b714f66d39b", @@ -264619,16 +264632,6 @@ } }, "support": { - ".cache": { - "gitignore2.json": [ - "1e2869ce4b97b1e5a0139fdf79e3c8150833d7e6", - [] - ], - "mtime.json": [ - "562cf180f36828e10467618c079de90c392ef9c6", - [] - ] - }, ".gitignore": [ "d93e645d547894b50149d3726de2654957b6e06f", [] @@ -317089,6 +317092,10 @@ "df0bfc417df08d4e23eaa0107f4ed298abd72f0f", [] ], + "preserve3d-pseudo-element-ref.html": [ + "8b3c3b08af40ee08869366e5465adafb45d98bcc", + [] + ], "reference": { "backface-visibility-hidden-ref.html": [ "6a3e305e5c0c7fca6c8d53574b7a09eb21afb6cc",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element-ref.html new file mode 100644 index 0000000..8b3c3b08af --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element-ref.html
@@ -0,0 +1,12 @@ +<!doctype html> +<title>CSS Test: preserve-3d on pseudo elements</title> +<link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com"> +<style> +div { + width: 200px; + height: 200px; + background-color: green; +} +</style> +<div></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element.html new file mode 100644 index 0000000..f3a4441 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-pseudo-element.html
@@ -0,0 +1,24 @@ +<!doctype html> +<title>CSS Test: preserve-3d on pseudo elements</title> +<link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com"> +<link rel="help" href="https://drafts.csswg.org/css-transforms-2/"> +<link rel="match" href="preserve3d-pseudo-element-ref.html"> +<style> +div { + width: 200px; + height: 200px; + transform: rotateX(90deg); + transform-style: preserve-3d; +} + +div::before { + display: inline-block; + width: 200px; + height: 200px; + transform: rotateX(90deg); + content: ''; + background-color: green; +} +</style> +<div></div> +</div>
diff --git a/third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html b/third_party/blink/web_tests/external/wpt/idle-detection/page-visibility.https.html similarity index 65% rename from third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html rename to third_party/blink/web_tests/external/wpt/idle-detection/page-visibility.https.html index 2f2ad63..550683f 100644 --- a/third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html +++ b/third_party/blink/web_tests/external/wpt/idle-detection/page-visibility.https.html
@@ -1,33 +1,18 @@ <!DOCTYPE html> <link rel="help" href="https://github.com/samuelgoto/idle-detection"> <title>Tests the Idle Detection API</title> -<script src="/resources/test-only-api.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="/idle-detection/resources/idle-detection-helper.js"></script> +<script src="/resources/test-only-api.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/page-visibility/resources/window_state_context.js"></script> +<script src="resources/idle-detection-helper.js"></script> <script> 'use strict'; -// setMainWindowHidden is duplicated from resources/visibility.js. -// This is necessary to have the test in wpt_internal. -function setMainWindowHidden(hidden) { - return new Promise((resolve, reject) => { - if (!window.testRunner) { - reject("no window.testRunner present"); - return; - } - if (document.visibilityState == (hidden ? "hidden" : "visible")) { - reject("setMainWindowHidden(" + hidden + ") called but already " + hidden); - return; - } - document.addEventListener("visibilitychange", resolve, {once:true}); - testRunner.setMainWindowHidden(hidden); - }); -} - promise_setup(async t => { - await internals.setPermission({name: 'notifications'}, 'granted', - location.origin, location.origin); + await test_driver.set_permission({ name: 'idle-detection' }, 'granted'); if (isChromiumBased) { await loadChromiumResources(); } @@ -48,6 +33,9 @@ }); const controller = new AbortController(); + t.add_cleanup(() => { + controller.abort(); + }); const detector = new IdleDetector(); const watcher = new EventWatcher(t, detector, ["change"]); const initial_state = watcher.wait_for("change"); @@ -56,9 +44,11 @@ await initial_state; assert_equals(detector.userState, "active"); + assert_false(document.hidden); - setMainWindowHidden(true); + const {minimize, restore} = window_state_context(t); + await minimize(); monitor.update( { idleTime: { milliseconds: 0 }, @@ -70,9 +60,9 @@ // Assert that the detector works while the page is not visible. await watcher.wait_for("change"); assert_equals(detector.userState, "idle"); + assert_true(document.hidden); - setMainWindowHidden(false); - + await restore(); monitor.update( { idleTime: null, @@ -83,8 +73,7 @@ await watcher.wait_for("change"); assert_equals(detector.userState, "active"); - - controller.abort(); + assert_false(document.hidden); }, 'Page visibility.'); </script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update-expected.txt new file mode 100644 index 0000000..2fea330c --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update-expected.txt
@@ -0,0 +1,29 @@ +Test that prerender navigations receives the failure status updates +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/echo?status=204 + status : Pending + } + sessionId : <string> +} +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/echo?status=204 + status : Running + } + sessionId : <string> +} +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/echo?status=204 + status : Failure + } + sessionId : <string> +} +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update.js b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update.js new file mode 100644 index 0000000..f9dcb75 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-failure-status-update.js
@@ -0,0 +1,15 @@ + (async function(testRunner) { + const {page, session, dp} = await testRunner.startBlank( + `Test that prerender navigations receives the failure status updates`); + await dp.Page.enable(); + + // Navigate to speculation rules Prerender Page. + page.navigate('resources/bad-http-prerender.html'); + let statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update-expected.txt new file mode 100644 index 0000000..c986773 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update-expected.txt
@@ -0,0 +1,38 @@ +Test that prerender navigations receives the status updates +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/inspector-protocol/prerender/resources/empty.html + status : Pending + } + sessionId : <string> +} +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/inspector-protocol/prerender/resources/empty.html + status : Running + } + sessionId : <string> +} +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/inspector-protocol/prerender/resources/empty.html + status : Ready + } + sessionId : <string> +} +{ + method : Page.prerenderStatusUpdated + params : { + initiatingFrameId : <string> + prerenderingUrl : http://127.0.0.1:8000/inspector-protocol/prerender/resources/empty.html + status : Success + } + sessionId : <string> +} +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update.js b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update.js new file mode 100644 index 0000000..ec51443 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/prerender-status-update.js
@@ -0,0 +1,21 @@ +(async function(testRunner) { + const {page, session, dp} = await testRunner.startBlank( + `Test that prerender navigations receives the status updates`); + await dp.Page.enable(); + + // Navigate to speculation rules Prerender Page. + page.navigate('resources/simple-prerender.html'); + + let statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + + session.evaluate(`document.getElementById('link').click()`); + statusReport = await dp.Page.oncePrerenderStatusUpdated(); + testRunner.log(statusReport, '', ['initiatingFrameId', 'sessionId']); + + testRunner.completeTest(); +});
diff --git a/third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html.ini b/third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html.ini deleted file mode 100644 index 536e46f..0000000 --- a/third_party/blink/web_tests/wpt_internal/idle-detection/page-visibility.https.html.ini +++ /dev/null
@@ -1,4 +0,0 @@ -[page-visibility.https.html] - expected: ERROR - [Page visibility.] - expected: NOTRUN
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn index 94177b5e..f77c735e 100644 --- a/third_party/ipcz/src/BUILD.gn +++ b/third_party/ipcz/src/BUILD.gn
@@ -261,7 +261,6 @@ "ipcz/driver_object.cc", "ipcz/driver_transport.cc", "ipcz/fragment.cc", - "ipcz/fragment_descriptor.cc", "ipcz/fragment_ref.cc", "ipcz/handle_type.h", "ipcz/link_side.cc", @@ -291,7 +290,6 @@ "ipcz/remote_router_link.cc", "ipcz/route_edge.cc", "ipcz/router.cc", - "ipcz/router_descriptor.cc", "ipcz/router_descriptor.h", "ipcz/router_link_state.cc", "ipcz/test_messages.cc",
diff --git a/third_party/ipcz/src/ipcz/fragment_descriptor.cc b/third_party/ipcz/src/ipcz/fragment_descriptor.cc deleted file mode 100644 index 6ef132c..0000000 --- a/third_party/ipcz/src/ipcz/fragment_descriptor.cc +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ipcz/fragment_descriptor.h" - -namespace ipcz { - -FragmentDescriptor::FragmentDescriptor(const FragmentDescriptor&) = default; - -FragmentDescriptor& FragmentDescriptor::operator=(const FragmentDescriptor&) = - default; - -} // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/fragment_descriptor.h b/third_party/ipcz/src/ipcz/fragment_descriptor.h index b247215..ed5229a 100644 --- a/third_party/ipcz/src/ipcz/fragment_descriptor.h +++ b/third_party/ipcz/src/ipcz/fragment_descriptor.h
@@ -23,9 +23,6 @@ // fragments. constexpr FragmentDescriptor() = default; - FragmentDescriptor(const FragmentDescriptor&); - FragmentDescriptor& operator=(const FragmentDescriptor&); - // Constructs a descriptor for a span of memory `size` bytes long, starting // at byte `offset` within the buffer identified by `buffer_id` within some // BufferPool. @@ -53,6 +50,8 @@ // The size of this fragment in bytes. uint32_t size_ = 0; }; +static_assert(std::is_trivially_copyable_v<FragmentDescriptor>, + "FragmentDescriptor must be trivially copyable"); } // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/message.cc b/third_party/ipcz/src/ipcz/message.cc index cb0351e..5d856ab 100644 --- a/third_party/ipcz/src/ipcz/message.cc +++ b/third_party/ipcz/src/ipcz/message.cc
@@ -13,6 +13,7 @@ #include "ipcz/driver_object.h" #include "ipcz/driver_transport.h" #include "ipcz/ipcz.h" +#include "third_party/abseil-cpp/absl/base/macros.h" #include "third_party/abseil-cpp/absl/container/inlined_vector.h" #include "third_party/abseil-cpp/absl/types/span.h" #include "util/safe_math.h" @@ -133,6 +134,10 @@ object_data.num_driver_handles)); } +bool IsAligned(size_t n) { + return n % 8 == 0; +} + } // namespace Message::ReceivedDataBuffer::ReceivedDataBuffer() = default; @@ -164,6 +169,8 @@ h.version = 0; h.message_id = message_id; h.driver_object_data_array = 0; + + ABSL_ASSERT(IsAligned(inlined_data_->size())); } Message::~Message() = default; @@ -335,8 +342,8 @@ } // The header's stated size (and thus the start of the parameter payload) - // must not run over the edge of the message. - if (header.size > data_.size()) { + // must not run over the edge of the message and must be 8-byte-aligned. + if (header.size > data_.size() || !IsAligned(header.size)) { return false; } @@ -366,6 +373,11 @@ return false; } + // Parameter struct sizes must be 8-byte-aligned. + if (!IsAligned(params_header.size)) { + return false; + } + // NOTE: In Chromium, a vast majority of IPC messages have 0, 1, or 2 OS // handles attached. Since these objects are small, we inline some storage on // the stack to avoid some heap allocation in the most common cases.
diff --git a/third_party/ipcz/src/ipcz/message_macros/message_declaration_macros.h b/third_party/ipcz/src/ipcz/message_macros/message_declaration_macros.h index 9ec18751..3f2b2c5e 100644 --- a/third_party/ipcz/src/ipcz/message_macros/message_declaration_macros.h +++ b/third_party/ipcz/src/ipcz/message_macros/message_declaration_macros.h
@@ -14,6 +14,7 @@ class name : public MessageWithParams<name##_Params> { \ public: \ using ParamsType = name##_Params; \ + static_assert(sizeof(ParamsType) % 8 == 0, "Invalid size"); \ id_decl; \ version_decl; \ name(); \
diff --git a/third_party/ipcz/src/ipcz/node.cc b/third_party/ipcz/src/ipcz/node.cc index 9d266da0..e5979e6f 100644 --- a/third_party/ipcz/src/ipcz/node.cc +++ b/third_party/ipcz/src/ipcz/node.cc
@@ -451,6 +451,7 @@ msg::AcceptRelayedMessage accept; accept.params().source = from_node; accept.params().data = accept.AllocateArray<uint8_t>(data.size()); + accept.params().padding = 0; memcpy(accept.GetArrayData(accept.params().data), data.data(), data.size()); accept.params().driver_objects = accept.AppendDriverObjects(relay.driver_objects());
diff --git a/third_party/ipcz/src/ipcz/node_connector.cc b/third_party/ipcz/src/ipcz/node_connector.cc index 88386343..f30d239 100644 --- a/third_party/ipcz/src/ipcz/node_connector.cc +++ b/third_party/ipcz/src/ipcz/node_connector.cc
@@ -62,6 +62,7 @@ checked_cast<uint32_t>(num_portals()); connect.params().buffer = connect.AppendDriverObject( link_memory_allocation_.memory.TakeDriverObject()); + connect.params().padding = 0; return IPCZ_RESULT_OK == transport_->Transmit(connect); } @@ -430,6 +431,7 @@ checked_cast<uint32_t>(num_portals()); connect.params().buffer = connect.AppendDriverObject( link_memory_allocation_.memory.TakeDriverObject()); + connect.params().padding = 0; return IPCZ_RESULT_OK == transport_->Transmit(connect); }
diff --git a/third_party/ipcz/src/ipcz/node_link.cc b/third_party/ipcz/src/ipcz/node_link.cc index 194eb62..a1ede6f 100644 --- a/third_party/ipcz/src/ipcz/node_link.cc +++ b/third_party/ipcz/src/ipcz/node_link.cc
@@ -42,7 +42,8 @@ template <typename T> FragmentRef<T> MaybeAdoptFragmentRef(NodeLinkMemory& memory, const FragmentDescriptor& descriptor) { - if (descriptor.is_null() || descriptor.size() < sizeof(T)) { + if (descriptor.is_null() || descriptor.size() < sizeof(T) || + descriptor.offset() % 8 != 0) { return {}; } @@ -203,6 +204,7 @@ accept.params().name = name; accept.params().link_side = side; accept.params().remote_node_type = remote_node_type; + accept.params().padding = 0; accept.params().remote_protocol_version = remote_protocol_version; accept.params().transport = accept.AppendDriverObject(transport->TakeDriverObject()); @@ -270,6 +272,7 @@ msg::RequestMemory request; request.params().size = size32; + request.params().padding = 0; Transmit(request); } @@ -280,6 +283,7 @@ relay.params().destination = to_node; relay.params().data = relay.AllocateArray<uint8_t>(message.data_view().size()); + relay.params().padding = 0; memcpy(relay.GetArrayData(relay.params().data), message.data_view().data(), message.data_view().size()); relay.params().driver_objects =
diff --git a/third_party/ipcz/src/ipcz/node_messages_generator.h b/third_party/ipcz/src/ipcz/node_messages_generator.h index e2b41a5..7079525 100644 --- a/third_party/ipcz/src/ipcz/node_messages_generator.h +++ b/third_party/ipcz/src/ipcz/node_messages_generator.h
@@ -36,6 +36,9 @@ // A driver memory object to serve as the new NodeLink's primary shared // buffer. That is, BufferId 0 within its NodeLinkMemory's BufferPool. IPCZ_MSG_PARAM_DRIVER_OBJECT(buffer) + + // Explicit padding to preserve 8-byte size alignemnt. + IPCZ_MSG_PARAM(uint32_t, padding) IPCZ_MSG_END() // Initial greeting sent by a non-broker node when ConnectNode() is invoked with @@ -204,6 +207,9 @@ // determined by whichever broker's name is the lesser of the two when // compared numerically. IPCZ_MSG_PARAM_DRIVER_OBJECT(buffer) + + // Explicit padding to preserve 8-byte size alignment. + IPCZ_MSG_PARAM(uint32_t, padding) IPCZ_MSG_END() // Sent to a broker to ask for an introduction to one of the non-broker nodes in @@ -234,6 +240,9 @@ // Indicates the type of the remote node being introduced. IPCZ_MSG_PARAM(NodeType, remote_node_type) + // Explicit padding to preserve 4-byte alignment of the following field. + IPCZ_MSG_PARAM(uint16_t, padding) + // Indicates the highest ipcz protocol version which the remote side of // `transport` able and willing to use according to the broker. IPCZ_MSG_PARAM(uint32_t, remote_protocol_version) @@ -310,15 +319,15 @@ // its main containing Parcel. IPCZ_MSG_PARAM(uint32_t, num_subparcels) - // Free-form array of application-provided data bytes for this parcel. This - // field is only meaningful if `parcel_fragment` is null. - IPCZ_MSG_PARAM_ARRAY(uint8_t, parcel_data) - // An optional shared memory fragment containing this parcel's data. If this // is null, the parcel data is instead inlined via the `parcel_data` array // above. IPCZ_MSG_PARAM(FragmentDescriptor, parcel_fragment) + // Free-form array of application-provided data bytes for this parcel. This + // field is only meaningful if `parcel_fragment` is null. + IPCZ_MSG_PARAM_ARRAY(uint8_t, parcel_data) + // Array of handle types, with each corresponding to a single IpczHandle // attached to the parcel. IPCZ_MSG_PARAM_ARRAY(HandleType, handle_types) @@ -328,6 +337,9 @@ // to extend the transmitted portal's route there. IPCZ_MSG_PARAM_ARRAY(RouterDescriptor, new_routers) + // Explicit padding to preserve 8-byte alignment. + IPCZ_MSG_PARAM(uint32_t, padding) + // Every DriverObject boxed and attached to this parcel has an entry in this // array. IPCZ_MSG_PARAM_DRIVER_OBJECT_ARRAY(driver_objects) @@ -570,6 +582,7 @@ // providing the IPCZ_CONNECT_NODE_TO_ALLOCATION_DELEGATE flag to ConnectNode(). IPCZ_MSG_BEGIN(RequestMemory, IPCZ_MSG_ID(64), IPCZ_MSG_VERSION(0)) IPCZ_MSG_PARAM(uint32_t, size) + IPCZ_MSG_PARAM(uint32_t, padding) IPCZ_MSG_END() // Provides a new shared buffer to the receiver, owned exclusively by the @@ -590,6 +603,9 @@ // The actual serialized message to be relayed, including its own header. IPCZ_MSG_PARAM_ARRAY(uint8_t, data) + // Padding to preserve 8-byte alignment of the `driver_objects` field below. + IPCZ_MSG_PARAM(uint32_t, padding) + // The set of driver objects to be relayed along with `data`. IPCZ_MSG_PARAM_DRIVER_OBJECT_ARRAY(driver_objects) IPCZ_MSG_END() @@ -603,6 +619,9 @@ // The full serialized data of the relayed message. IPCZ_MSG_PARAM_ARRAY(uint8_t, data) + // Padding to preserve 8-byte alignment of the `driver_objects` field below. + IPCZ_MSG_PARAM(uint32_t, padding) + // The set of driver objects relayed along with `data`. IPCZ_MSG_PARAM_DRIVER_OBJECT_ARRAY(driver_objects) IPCZ_MSG_END()
diff --git a/third_party/ipcz/src/ipcz/parcel.cc b/third_party/ipcz/src/ipcz/parcel.cc index 474cc0a..6acb7f9 100644 --- a/third_party/ipcz/src/ipcz/parcel.cc +++ b/third_party/ipcz/src/ipcz/parcel.cc
@@ -87,7 +87,8 @@ bool Parcel::AdoptDataFragment(Ref<NodeLinkMemory> memory, const Fragment& fragment) { - if (!fragment.is_addressable() || fragment.size() <= sizeof(FragmentHeader)) { + if (!fragment.is_addressable() || fragment.size() <= sizeof(FragmentHeader) || + fragment.offset() % 8 != 0) { return false; }
diff --git a/third_party/ipcz/src/ipcz/portal.cc b/third_party/ipcz/src/ipcz/portal.cc index 14357e7..b669803 100644 --- a/third_party/ipcz/src/ipcz/portal.cc +++ b/third_party/ipcz/src/ipcz/portal.cc
@@ -99,7 +99,9 @@ return allocate_result; } - memcpy(parcel.data_view().data(), data.data(), data.size()); + if (!data.empty()) { + memcpy(parcel.data_view().data(), data.data(), data.size()); + } parcel.CommitData(data.size()); parcel.SetObjects(std::move(objects)); const IpczResult result = router_->SendOutboundParcel(parcel);
diff --git a/third_party/ipcz/src/ipcz/remote_router_link.cc b/third_party/ipcz/src/ipcz/remote_router_link.cc index 0aa2373..3907cf5 100644 --- a/third_party/ipcz/src/ipcz/remote_router_link.cc +++ b/third_party/ipcz/src/ipcz/remote_router_link.cc
@@ -146,6 +146,7 @@ msg::AcceptParcel accept; accept.params().sublink = sublink_; accept.params().sequence_number = parcel.sequence_number(); + accept.params().padding = 0; size_t num_portals = 0; absl::InlinedVector<DriverObject, 2> driver_objects; @@ -332,8 +333,10 @@ // Copy all the serialized router descriptors into the message. Our local // copy will supply inputs for BeginProxyingToNewRouter() calls below. - memcpy(new_routers.data(), descriptors.data(), - new_routers.size() * sizeof(new_routers[0])); + if (!descriptors.empty()) { + memcpy(new_routers.data(), descriptors.data(), + new_routers.size() * sizeof(new_routers[0])); + } if (must_split_parcel) { msg::AcceptParcelDriverObjects accept_objects;
diff --git a/third_party/ipcz/src/ipcz/router.cc b/third_party/ipcz/src/ipcz/router.cc index d286a0c..cdeb509 100644 --- a/third_party/ipcz/src/ipcz/router.cc +++ b/third_party/ipcz/src/ipcz/router.cc
@@ -429,7 +429,9 @@ const bool ok = inbound_parcels_.Pop(consumed_parcel); ABSL_ASSERT(ok); } else { - memcpy(data, p.data_view().data(), data_size); + if (data_size > 0) { + memcpy(data, p.data_view().data(), data_size); + } if (consuming_whole_parcel) { const bool ok = inbound_parcels_.Pop(consumed_parcel); ABSL_ASSERT(ok);
diff --git a/third_party/ipcz/src/ipcz/router_descriptor.cc b/third_party/ipcz/src/ipcz/router_descriptor.cc deleted file mode 100644 index 4dbfbe3..0000000 --- a/third_party/ipcz/src/ipcz/router_descriptor.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ipcz/router_descriptor.h" - -namespace ipcz { - -RouterDescriptor::RouterDescriptor() = default; - -RouterDescriptor::RouterDescriptor(const RouterDescriptor&) = default; - -RouterDescriptor& RouterDescriptor::operator=(const RouterDescriptor&) = - default; - -RouterDescriptor::~RouterDescriptor() = default; - -} // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/router_descriptor.h b/third_party/ipcz/src/ipcz/router_descriptor.h index 9cb539b0..40126b9 100644 --- a/third_party/ipcz/src/ipcz/router_descriptor.h +++ b/third_party/ipcz/src/ipcz/router_descriptor.h
@@ -5,6 +5,8 @@ #ifndef IPCZ_SRC_IPCZ_ROUTER_DESCRIPTOR_H_ #define IPCZ_SRC_IPCZ_ROUTER_DESCRIPTOR_H_ +#include <type_traits> + #include "ipcz/fragment_descriptor.h" #include "ipcz/ipcz.h" #include "ipcz/node_name.h" @@ -21,11 +23,6 @@ // NOTE: This is a wire structure and must remain backwards-compatible across // changes. struct IPCZ_ALIGN(8) RouterDescriptor { - RouterDescriptor(); - RouterDescriptor(const RouterDescriptor&); - RouterDescriptor& operator=(const RouterDescriptor&); - ~RouterDescriptor(); - // If the other end of the route is already known to be closed when this // router is serialized, this is the total number of parcels sent from that // end. @@ -100,6 +97,9 @@ SublinkId proxy_peer_sublink; }; +static_assert(std::is_trivially_copyable_v<RouterDescriptor>, + "RouterDescriptor must be trivially copyable"); + } // namespace ipcz #endif // IPCZ_SRC_IPCZ_ROUTER_DESCRIPTOR_H_
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 6acb2a48..bf80a9b 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -928,6 +928,54 @@ </token> </histogram> +<histogram name="Graphics.Exo.Smoothness.DidNotProduceToFrameArrival" + units="microseconds" expires_after="2023-12-31"> + <owner>jonross@chromium.org</owner> + <owner>yzshen@chromium.org</owner> + <owner>graphics-dev@chromium.org</owner> + <summary> + Measures the time duration between Exo sending a DidNotProduceFrame response + and the next frame arrival, if the next frame arrives before a new + BeginFrame request. Reported for clients with high-resolution clocks. + + This metric is used to measure whether the deadline Exo uses to wait for + frames is reasonable. Please note that a value is reported for each + DidNotProduceFrame. If (1) DidNotProduceFrame is issued when there are + already queued BeginFrame requests; or (2) a new BeginFrame request arrives + before the next frame, then the value reported is 0. + </summary> +</histogram> + +<histogram name="Graphics.Exo.Smoothness.PercentDidNotProduceFrame" units="%" + expires_after="2023-12-31"> + <owner>jonross@chromium.org</owner> + <owner>yzshen@chromium.org</owner> + <owner>graphics-dev@chromium.org</owner> + <summary> + Tracks the percent of BeginFrame requests that Exo receives and responds + with DidNotProduceFrame. + + A new value is reported for every 100 BeginFrame requests that a shell + surface receives. Note that this metric is reported only when there are + sufficient number of BeginFrame requests (>= 100). + </summary> +</histogram> + +<histogram name="Graphics.Exo.Smoothness.PercentFrameDiscarded" units="%" + expires_after="2023-12-31"> + <owner>jonross@chromium.org</owner> + <owner>yzshen@chromium.org</owner> + <owner>graphics-dev@chromium.org</owner> + <summary> + Tracks the percent of compositor frames that are submitted from Exo clients + and directly discarded without being sent to the GPU process. + + A new value is reported for every 100 frames that a shell surface submits. + Note that this metric is reported only when there are sufficient number of + frames (>= 100). + </summary> +</histogram> + <histogram name="Graphics.Smoothness.95pctPercentDroppedFrames_1sWindow" units="%" expires_after="2023-07-02"> <owner>jonross@chromium.org</owner>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb index 4ab594cd..be1ce19 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb
@@ -27,6 +27,7 @@ <translation id="1201402288615127009">Naprijed</translation> <translation id="1209796539517632982">Serveri s automatskim nazivima</translation> <translation id="1210831758834677569">laoški</translation> +<translation id="1221555006497674479">Malo je prostora za pohranu. Preostalo je <ph name="REMAINING_PERCENTAGE" />% od <ph name="TOTAL_SPACE" /> dijeljene pohrane na disku.</translation> <translation id="1243314992276662751">Otpremi</translation> <translation id="1249250836236328755">Žanr</translation> <translation id="1254593899333212300">Direktna internetska veza</translation> @@ -73,6 +74,7 @@ <translation id="1641780993263690097">kineski pinyin</translation> <translation id="1646019627374511909">Postavljanje dostupnosti van mreže za fajlove (njih <ph name="NUMBER_OF_ITEMS" />)</translation> <translation id="164969095109328410">Chrome uređaj</translation> +<translation id="1661207570040737402">Iskoristili ste svu svoju pohranu Dijeljenog diska Google Workspacea.</translation> <translation id="1661867754829461514">PIN nedostaje</translation> <translation id="166439687370499867">Nije dozvoljena promjena konfiguracije dijeljene mreže</translation> <translation id="1665611772925418501">Izmjena ovog fajla nije uspjela.</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_uz.xtb b/ui/chromeos/translations/ui_chromeos_strings_uz.xtb index dcbc883..02c8754 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_uz.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_uz.xtb
@@ -27,6 +27,7 @@ <translation id="1201402288615127009">Keyingisi</translation> <translation id="1209796539517632982">Avtomatik nom serverlari</translation> <translation id="1210831758834677569">Lao</translation> +<translation id="1221555006497674479">Xotirada joy kam, umumiy diskda <ph name="REMAINING_PERCENTAGE" />% / <ph name="TOTAL_SPACE" /> qoldi.</translation> <translation id="1243314992276662751">Yuklash</translation> <translation id="1249250836236328755">Janri</translation> <translation id="1254593899333212300">Internetga to‘g‘ridan-to‘g‘ri ulanish</translation> @@ -73,6 +74,7 @@ <translation id="1641780993263690097">Xitoy (Pinyin)</translation> <translation id="1646019627374511909"><ph name="NUMBER_OF_ITEMS" /> ta fayl oflaynga nusxalanmoqda</translation> <translation id="164969095109328410">Chrome qurilmasi</translation> +<translation id="1661207570040737402">Umumiy disk va Google Workspace xotirasida joy qolmadi.</translation> <translation id="1661867754829461514">PIN-kod kiritilmagan</translation> <translation id="166439687370499867">Umumiy tarmoq sozlamalarini o‘zgartirib bo‘lmaydi</translation> <translation id="1665611772925418501">Faylni o‘zgartirib bo‘lmadi.</translation> @@ -354,6 +356,7 @@ <translation id="3971140002794351170">Mobil profil, tarmoq <ph name="NETWORK_INDEX" /><ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, <ph name="NETWORK_PROVIDER_NAME" /> kabilarni yuklab olish</translation> <translation id="3973925058222872294">Ingliz (Buyuk Britaniya)</translation> <translation id="3975895378829046965">Bangla (Fonetik)</translation> +<translation id="3999574733850440202">Yaqinda ochilgan OneDrive omboriga olingan Microsoft fayllari</translation> <translation id="4002066346123236978">Nomi</translation> <translation id="4017788180641807848">Ingliz (AQSH) va Workman klaviaturasi</translation> <translation id="4019998208269143058">Tezkor fayllarga mahkamlash</translation> @@ -904,6 +907,7 @@ <translation id="8300849813060516376">OTASP amalga oshmadi</translation> <translation id="8312871300878166382">Jild ichiga qo‘shib qo‘yish</translation> <translation id="8329978297633540474">Oddiy matn</translation> +<translation id="8332007959299458842">Yaqinda ochilgan Google Drive omboriga olingan Microsoft fayllari</translation> <translation id="8335587457941836791">Javondan olib tashlash</translation> <translation id="8335837413233998004">Belarus</translation> <translation id="8336153091935557858">Kecha <ph name="YESTERDAY_DAYTIME" /></translation>
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index eec810cc..18cfba6 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {startColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js'; import {assert, assertInstanceof} from 'chrome://resources/ash/common/assert.js'; import {NativeEventTarget as EventTarget} from 'chrome://resources/ash/common/event_target.js'; import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; +import {startColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js'; import {getDialogCaller, getDlpBlockedComponents, getPreferences} from '../../common/js/api.js'; import {ArrayDataModel} from '../../common/js/array_data_model.js'; @@ -19,6 +19,7 @@ import {TrashRootEntry} from '../../common/js/trash.js'; import {str, util} from '../../common/js/util.js'; import {AllowedPaths, VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; +import {NudgeType} from '../../containers/nudge_container.js'; import {Crostini} from '../../externs/background/crostini.js'; import {FileManagerBaseInterface} from '../../externs/background/file_manager_base.js'; import {FileOperationManager} from '../../externs/background/file_operation_manager.js'; @@ -1689,6 +1690,16 @@ redraw = true; } + // These prefs starts with value 0. We only want to display when they're + // non-zero and show the most recent (larger value). + if (prefs.officeFileMovedOneDrive > prefs.officeFileMovedGoogleDrive) { + this.ui_.nudgeContainer.showNudge( + NudgeType['ONE_DRIVE_MOVED_FILE_NUDGE']); + } else if ( + prefs.officeFileMovedOneDrive < prefs.officeFileMovedGoogleDrive) { + this.ui_.nudgeContainer.showNudge(NudgeType['DRIVE_MOVED_FILE_NUDGE']); + } + if (redraw) { this.directoryTree.redraw(false); }
diff --git a/ui/file_manager/integration_tests/file_manager/office.js b/ui/file_manager/integration_tests/file_manager/office.js index e206a32..0dfeb6a 100644 --- a/ui/file_manager/integration_tests/file_manager/office.js +++ b/ui/file_manager/integration_tests/file_manager/office.js
@@ -391,3 +391,20 @@ 'removeAllForegroundFakes', appId, []); chrome.test.assertEq(1, removedCount); }; + +/** Tests that the educational nudge is displayed when the preference is set. */ +testcase.officeShowNudgeGoogleDrive = async () => { + // Set the pref emulating that the user has moved a file. + await sendTestMessage({ + name: 'setPrefOfficeFileMovedToGoogleDrive', + timestamp: Date.now(), + }); + + // Open the Files app. + const appId = await setupAndWaitUntilReady( + RootPath.DRIVE, [], [ENTRIES.smallDocxPinned]); + + // Check that the nudge and its text is visible. + await remoteCall.waitNudge( + appId, 'Recently opened Microsoft files have moved to Google Drive'); +};
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js index 1ea7f3d..052c8e97 100644 --- a/ui/file_manager/integration_tests/remote_call.js +++ b/ui/file_manager/integration_tests/remote_call.js
@@ -1012,4 +1012,29 @@ path, }); } + + /** + * Wait for the nudge with the given text to be visible. + * + * @param {string} appId app window ID. + * @param {string} expectedText Text that should be displayed in the Nudge. + * @return {!Promise<boolean>} + */ + async waitNudge(appId, expectedText) { + const caller = getCaller(); + return repeatUntil(async () => { + const nudgeDot = await this.waitForElementStyles( + appId, ['xf-nudge', '#dot'], ['left']); + if (nudgeDot.renderedLeft < 0) { + return pending(caller, 'Wait nudge to appear'); + } + + const actualText = + await this.waitForElement(appId, ['xf-nudge', '#text']); + console.log(actualText); + chrome.test.assertEq(actualText.text, expectedText); + + return true; + }); + } }
diff --git a/ui/gfx/range/mojom/range.mojom b/ui/gfx/range/mojom/range.mojom index d46e42b..01869e7d 100644 --- a/ui/gfx/range/mojom/range.mojom +++ b/ui/gfx/range/mojom/range.mojom
@@ -4,11 +4,13 @@ module gfx.mojom; +[Stable] struct Range { uint32 start; uint32 end; }; +[Stable] struct RangeF { float start; float end;