diff --git a/.gitmodules b/.gitmodules index 5091812..d199205 100644 --- a/.gitmodules +++ b/.gitmodules
@@ -1,438 +1,438 @@ [submodule "third_party/clang-format/script"] path = third_party/clang-format/script - url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git + url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format [submodule "chrome/browser/resources/preinstalled_web_apps/internal"] path = chrome/browser/resources/preinstalled_web_apps/internal - url = https://chrome-internal.googlesource.com/chrome/components/default_apps.git + url = https://chrome-internal.googlesource.com/chrome/components/default_apps gclient-condition = checkout_src_internal [submodule "chrome/installer/mac/third_party/xz/xz"] path = chrome/installer/mac/third_party/xz/xz - url = https://chromium.googlesource.com/chromium/deps/xz.git + url = https://chromium.googlesource.com/chromium/deps/xz gclient-condition = checkout_mac [submodule "third_party/libc++/src"] path = third_party/libc++/src - url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git + url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx [submodule "third_party/libc++abi/src"] path = third_party/libc++abi/src - url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git + url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi [submodule "third_party/libunwind/src"] path = third_party/libunwind/src - url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git + url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind [submodule "chrome/test/data/autofill/captured_sites/artifacts"] path = chrome/test/data/autofill/captured_sites/artifacts - url = https://chrome-internal.googlesource.com/chrome/test/captured_sites/autofill.git + url = https://chrome-internal.googlesource.com/chrome/test/captured_sites/autofill gclient-condition = checkout_chromium_autofill_test_dependencies [submodule "chrome/test/data/password/captured_sites/artifacts"] path = chrome/test/data/password/captured_sites/artifacts - url = https://chrome-internal.googlesource.com/chrome/test/captured_sites/password.git + url = https://chrome-internal.googlesource.com/chrome/test/captured_sites/password gclient-condition = checkout_chromium_password_manager_test_dependencies [submodule "chrome/test/data/perf/canvas_bench"] path = chrome/test/data/perf/canvas_bench - url = https://chromium.googlesource.com/chromium/canvas_bench.git + url = https://chromium.googlesource.com/chromium/canvas_bench [submodule "chrome/test/data/perf/frame_rate/content"] path = chrome/test/data/perf/frame_rate/content - url = https://chromium.googlesource.com/chromium/frame_rate/content.git + url = https://chromium.googlesource.com/chromium/frame_rate/content [submodule "chrome/test/data/xr/webvr_info"] path = chrome/test/data/xr/webvr_info - url = https://chromium.googlesource.com/external/github.com/toji/webvr.info.git + url = https://chromium.googlesource.com/external/github.com/toji/webvr.info [submodule "clank"] path = clank - url = https://chrome-internal.googlesource.com/clank/internal/apps.git + url = https://chrome-internal.googlesource.com/clank/internal/apps gclient-condition = checkout_android and checkout_src_internal [submodule "docs/website"] path = docs/website - url = https://chromium.googlesource.com/website.git + url = https://chromium.googlesource.com/website [submodule "ios/third_party/earl_grey2/src"] path = ios/third_party/earl_grey2/src - url = https://chromium.googlesource.com/external/github.com/google/EarlGrey.git + url = https://chromium.googlesource.com/external/github.com/google/EarlGrey gclient-condition = checkout_ios [submodule "ios/third_party/edo/src"] path = ios/third_party/edo/src - url = https://chromium.googlesource.com/external/github.com/google/eDistantObject.git + url = https://chromium.googlesource.com/external/github.com/google/eDistantObject gclient-condition = checkout_ios [submodule "ios/third_party/gtx/src"] path = ios/third_party/gtx/src - url = https://chromium.googlesource.com/external/github.com/google/GTXiLib.git + url = https://chromium.googlesource.com/external/github.com/google/GTXiLib gclient-condition = checkout_ios [submodule "ios/third_party/lottie/src"] path = ios/third_party/lottie/src - url = https://chromium.googlesource.com/external/github.com/airbnb/lottie-ios.git + url = https://chromium.googlesource.com/external/github.com/airbnb/lottie-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_components_ios/src"] path = ios/third_party/material_components_ios/src - url = https://chromium.googlesource.com/external/github.com/material-components/material-components-ios.git + url = https://chromium.googlesource.com/external/github.com/material-components/material-components-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_font_disk_loader_ios/src"] path = ios/third_party/material_font_disk_loader_ios/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-font-disk-loader-ios.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-font-disk-loader-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_internationalization_ios/src"] path = ios/third_party/material_internationalization_ios/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-internationalization-ios.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-internationalization-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_roboto_font_loader_ios/src"] path = ios/third_party/material_roboto_font_loader_ios/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-roboto-font-loader-ios.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-roboto-font-loader-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_sprited_animation_view_ios/src"] path = ios/third_party/material_sprited_animation_view_ios/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-sprited-animation-view-ios.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-sprited-animation-view-ios gclient-condition = checkout_ios [submodule "ios/third_party/material_text_accessibility_ios/src"] path = ios/third_party/material_text_accessibility_ios/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-text-accessibility-ios.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-text-accessibility-ios gclient-condition = checkout_ios [submodule "ios/third_party/motion_interchange_objc/src"] path = ios/third_party/motion_interchange_objc/src - url = https://chromium.googlesource.com/external/github.com/material-motion/motion-interchange-objc.git + url = https://chromium.googlesource.com/external/github.com/material-motion/motion-interchange-objc gclient-condition = checkout_ios [submodule "ios/third_party/motion_animator_objc/src"] path = ios/third_party/motion_animator_objc/src - url = https://chromium.googlesource.com/external/github.com/material-motion/motion-animator-objc.git + url = https://chromium.googlesource.com/external/github.com/material-motion/motion-animator-objc gclient-condition = checkout_ios [submodule "ios/third_party/motion_transitioning_objc/src"] path = ios/third_party/motion_transitioning_objc/src - url = https://chromium.googlesource.com/external/github.com/material-motion/motion-transitioning-objc.git + url = https://chromium.googlesource.com/external/github.com/material-motion/motion-transitioning-objc gclient-condition = checkout_ios [submodule "ios/third_party/ochamcrest/src"] path = ios/third_party/ochamcrest/src - url = https://chromium.googlesource.com/external/github.com/hamcrest/OCHamcrest.git + url = https://chromium.googlesource.com/external/github.com/hamcrest/OCHamcrest gclient-condition = checkout_ios [submodule "ios/third_party/webkit/src"] path = ios/third_party/webkit/src - url = https://chromium.googlesource.com/external/github.com/WebKit/webkit.git + url = https://chromium.googlesource.com/external/github.com/WebKit/webkit gclient-condition = checkout_ios and checkout_ios_webkit [submodule "media/cdm/api"] path = media/cdm/api - url = https://chromium.googlesource.com/chromium/cdm.git + url = https://chromium.googlesource.com/chromium/cdm [submodule "native_client"] path = native_client - url = https://chromium.googlesource.com/native_client/src/native_client.git + url = https://chromium.googlesource.com/native_client/src/native_client gclient-condition = checkout_nacl [submodule "net/third_party/quiche/src"] path = net/third_party/quiche/src - url = https://quiche.googlesource.com/quiche.git + url = https://quiche.googlesource.com/quiche [submodule "third_party/android_protobuf/src"] path = third_party/android_protobuf/src - url = https://android.googlesource.com/platform/external/protobuf.git + url = https://android.googlesource.com/platform/external/protobuf gclient-condition = checkout_android [submodule "third_party/androidx_javascriptengine/src"] path = third_party/androidx_javascriptengine/src - url = https://chromium.googlesource.com/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src.git + url = https://chromium.googlesource.com/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src gclient-condition = checkout_android [submodule "third_party/angle"] path = third_party/angle - url = https://chromium.googlesource.com/angle/angle.git + url = https://chromium.googlesource.com/angle/angle [submodule "third_party/anonymous_tokens/src"] path = third_party/anonymous_tokens/src - url = https://chromium.googlesource.com/external/github.com/google/anonymous-tokens.git + url = https://chromium.googlesource.com/external/github.com/google/anonymous-tokens [submodule "third_party/content_analysis_sdk/src"] path = third_party/content_analysis_sdk/src - url = https://chromium.googlesource.com/external/github.com/chromium/content_analysis_sdk.git + url = https://chromium.googlesource.com/external/github.com/chromium/content_analysis_sdk [submodule "third_party/dav1d/libdav1d"] path = third_party/dav1d/libdav1d - url = https://chromium.googlesource.com/external/github.com/videolan/dav1d.git + url = https://chromium.googlesource.com/external/github.com/videolan/dav1d [submodule "third_party/dawn"] path = third_party/dawn - url = https://dawn.googlesource.com/dawn.git + url = https://dawn.googlesource.com/dawn [submodule "third_party/highway/src"] path = third_party/highway/src - url = https://chromium.googlesource.com/external/github.com/google/highway.git + url = https://chromium.googlesource.com/external/github.com/google/highway [submodule "third_party/apache-portable-runtime/src"] path = third_party/apache-portable-runtime/src - url = https://chromium.googlesource.com/external/apache-portable-runtime.git + url = https://chromium.googlesource.com/external/apache-portable-runtime gclient-condition = checkout_android [submodule "third_party/barhopper"] path = third_party/barhopper - url = https://chrome-internal.googlesource.com/chrome/deps/barhopper.git + url = https://chrome-internal.googlesource.com/chrome/deps/barhopper gclient-condition = checkout_src_internal and checkout_chromeos [submodule "third_party/google_benchmark/src"] path = third_party/google_benchmark/src - url = https://chromium.googlesource.com/external/github.com/google/benchmark.git + url = https://chromium.googlesource.com/external/github.com/google/benchmark [submodule "third_party/boringssl/src"] path = third_party/boringssl/src - url = https://boringssl.googlesource.com/boringssl.git + url = https://boringssl.googlesource.com/boringssl [submodule "third_party/breakpad/breakpad"] path = third_party/breakpad/breakpad - url = https://chromium.googlesource.com/breakpad/breakpad.git + url = https://chromium.googlesource.com/breakpad/breakpad [submodule "third_party/cast_core/public/src"] path = third_party/cast_core/public/src url = https://chromium.googlesource.com/cast_core/public [submodule "third_party/catapult"] path = third_party/catapult - url = https://chromium.googlesource.com/catapult.git + url = https://chromium.googlesource.com/catapult [submodule "third_party/ced/src"] path = third_party/ced/src - url = https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git + url = https://chromium.googlesource.com/external/github.com/google/compact_enc_det [submodule "third_party/chromium-variations"] path = third_party/chromium-variations - url = https://chromium.googlesource.com/chromium-variations.git + url = https://chromium.googlesource.com/chromium-variations [submodule "third_party/chromevox/third_party/sre/src"] path = third_party/chromevox/third_party/sre/src - url = https://chromium.googlesource.com/external/github.com/zorkow/speech-rule-engine.git + url = https://chromium.googlesource.com/external/github.com/zorkow/speech-rule-engine gclient-condition = checkout_chromeos [submodule "third_party/chromite"] path = third_party/chromite - url = https://chromium.googlesource.com/chromiumos/chromite.git + url = https://chromium.googlesource.com/chromiumos/chromite gclient-condition = checkout_chromeos [submodule "third_party/cld_3/src"] path = third_party/cld_3/src - url = https://chromium.googlesource.com/external/github.com/google/cld_3.git + url = https://chromium.googlesource.com/external/github.com/google/cld_3 [submodule "third_party/colorama/src"] path = third_party/colorama/src - url = https://chromium.googlesource.com/external/colorama.git + url = https://chromium.googlesource.com/external/colorama [submodule "third_party/cpu_features/src"] path = third_party/cpu_features/src - url = https://chromium.googlesource.com/external/github.com/google/cpu_features.git + url = https://chromium.googlesource.com/external/github.com/google/cpu_features [submodule "third_party/cpuinfo/src"] path = third_party/cpuinfo/src - url = https://chromium.googlesource.com/external/github.com/pytorch/cpuinfo.git + url = https://chromium.googlesource.com/external/github.com/pytorch/cpuinfo [submodule "third_party/crc32c/src"] path = third_party/crc32c/src - url = https://chromium.googlesource.com/external/github.com/google/crc32c.git + url = https://chromium.googlesource.com/external/github.com/google/crc32c [submodule "third_party/cros_system_api"] path = third_party/cros_system_api - url = https://chromium.googlesource.com/chromiumos/platform2/system_api.git + url = https://chromium.googlesource.com/chromiumos/platform2/system_api gclient-condition = checkout_linux [submodule "third_party/crossbench"] path = third_party/crossbench - url = https://chromium.googlesource.com/crossbench.git + url = https://chromium.googlesource.com/crossbench [submodule "third_party/crubit/src"] path = third_party/crubit/src - url = https://chromium.googlesource.com/external/github.com/google/crubit.git + url = https://chromium.googlesource.com/external/github.com/google/crubit gclient-condition = checkout_crubit [submodule "third_party/depot_tools"] path = third_party/depot_tools - url = https://chromium.googlesource.com/chromium/tools/depot_tools.git + url = https://chromium.googlesource.com/chromium/tools/depot_tools [submodule "third_party/devtools-frontend/src"] path = third_party/devtools-frontend/src url = https://chromium.googlesource.com/devtools/devtools-frontend [submodule "third_party/devtools-frontend-internal"] path = third_party/devtools-frontend-internal - url = https://chrome-internal.googlesource.com/devtools/devtools-internal.git + url = https://chrome-internal.googlesource.com/devtools/devtools-internal gclient-condition = checkout_src_internal [submodule "third_party/dom_distiller_js/dist"] path = third_party/dom_distiller_js/dist - url = https://chromium.googlesource.com/chromium/dom-distiller/dist.git + url = https://chromium.googlesource.com/chromium/dom-distiller/dist [submodule "third_party/eigen3/src"] path = third_party/eigen3/src - url = https://chromium.googlesource.com/external/gitlab.com/libeigen/eigen.git + url = https://chromium.googlesource.com/external/gitlab.com/libeigen/eigen [submodule "third_party/emoji-metadata/src"] path = third_party/emoji-metadata/src url = https://chromium.googlesource.com/external/github.com/googlefonts/emoji-metadata gclient-condition = checkout_chromeos [submodule "third_party/farmhash/src"] path = third_party/farmhash/src - url = https://chromium.googlesource.com/external/github.com/google/farmhash.git + url = https://chromium.googlesource.com/external/github.com/google/farmhash [submodule "third_party/ffmpeg"] path = third_party/ffmpeg - url = https://chromium.googlesource.com/chromium/third_party/ffmpeg.git + url = https://chromium.googlesource.com/chromium/third_party/ffmpeg [submodule "third_party/flac"] path = third_party/flac - url = https://chromium.googlesource.com/chromium/deps/flac.git + url = https://chromium.googlesource.com/chromium/deps/flac [submodule "third_party/flatbuffers/src"] path = third_party/flatbuffers/src - url = https://chromium.googlesource.com/external/github.com/google/flatbuffers.git + url = https://chromium.googlesource.com/external/github.com/google/flatbuffers [submodule "third_party/fontconfig/src"] path = third_party/fontconfig/src - url = https://chromium.googlesource.com/external/fontconfig.git + url = https://chromium.googlesource.com/external/fontconfig gclient-condition = checkout_linux [submodule "third_party/fp16/src"] path = third_party/fp16/src - url = https://chromium.googlesource.com/external/github.com/Maratyszcza/FP16.git + url = https://chromium.googlesource.com/external/github.com/Maratyszcza/FP16 [submodule "third_party/gemmlowp/src"] path = third_party/gemmlowp/src - url = https://chromium.googlesource.com/external/github.com/google/gemmlowp.git + url = https://chromium.googlesource.com/external/github.com/google/gemmlowp [submodule "third_party/grpc/src"] path = third_party/grpc/src - url = https://chromium.googlesource.com/external/github.com/grpc/grpc.git + url = https://chromium.googlesource.com/external/github.com/grpc/grpc [submodule "third_party/freetype/src"] path = third_party/freetype/src - url = https://chromium.googlesource.com/chromium/src/third_party/freetype2.git + url = https://chromium.googlesource.com/chromium/src/third_party/freetype2 [submodule "third_party/freetype-testing/src"] path = third_party/freetype-testing/src - url = https://chromium.googlesource.com/external/github.com/freetype/freetype2-testing.git + url = https://chromium.googlesource.com/external/github.com/freetype/freetype2-testing [submodule "third_party/fxdiv/src"] path = third_party/fxdiv/src - url = https://chromium.googlesource.com/external/github.com/Maratyszcza/FXdiv.git + url = https://chromium.googlesource.com/external/github.com/Maratyszcza/FXdiv [submodule "third_party/harfbuzz-ng/src"] path = third_party/harfbuzz-ng/src - url = https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git + url = https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz [submodule "third_party/jszip/src"] path = third_party/jszip/src - url = https://chromium.googlesource.com/external/github.com/Stuk/jszip.git + url = https://chromium.googlesource.com/external/github.com/Stuk/jszip gclient-condition = checkout_ios [submodule "third_party/emoji-segmenter/src"] path = third_party/emoji-segmenter/src - url = https://chromium.googlesource.com/external/github.com/google/emoji-segmenter.git + url = https://chromium.googlesource.com/external/github.com/google/emoji-segmenter [submodule "third_party/ots/src"] path = third_party/ots/src - url = https://chromium.googlesource.com/external/github.com/khaledhosny/ots.git + url = https://chromium.googlesource.com/external/github.com/khaledhosny/ots [submodule "third_party/libgav1/src"] path = third_party/libgav1/src - url = https://chromium.googlesource.com/codecs/libgav1.git + url = https://chromium.googlesource.com/codecs/libgav1 [submodule "third_party/google_toolbox_for_mac/src"] path = third_party/google_toolbox_for_mac/src - url = https://chromium.googlesource.com/external/github.com/google/google-toolbox-for-mac.git + url = https://chromium.googlesource.com/external/github.com/google/google-toolbox-for-mac gclient-condition = checkout_ios or checkout_mac [submodule "third_party/google-truth/src"] path = third_party/google-truth/src - url = https://chromium.googlesource.com/external/github.com/google/truth.git + url = https://chromium.googlesource.com/external/github.com/google/truth gclient-condition = checkout_android [submodule "third_party/googletest/src"] path = third_party/googletest/src - url = https://chromium.googlesource.com/external/github.com/google/googletest.git + url = https://chromium.googlesource.com/external/github.com/google/googletest [submodule "third_party/gperf"] path = third_party/gperf - url = https://chromium.googlesource.com/chromium/deps/gperf.git + url = https://chromium.googlesource.com/chromium/deps/gperf gclient-condition = checkout_win [submodule "third_party/gvr-android-sdk/src"] path = third_party/gvr-android-sdk/src - url = https://chromium.googlesource.com/external/github.com/googlevr/gvr-android-sdk.git + url = https://chromium.googlesource.com/external/github.com/googlevr/gvr-android-sdk gclient-condition = checkout_android [submodule "third_party/cardboard/src"] path = third_party/cardboard/src - url = https://chromium.googlesource.com/external/github.com/googlevr/cardboard/ + url = https://chromium.googlesource.com/external/github.com/googlevr/cardboard gclient-condition = checkout_android [submodule "third_party/arcore-android-sdk/src"] path = third_party/arcore-android-sdk/src - url = https://chromium.googlesource.com/external/github.com/google-ar/arcore-android-sdk.git + url = https://chromium.googlesource.com/external/github.com/google-ar/arcore-android-sdk gclient-condition = checkout_android [submodule "third_party/hunspell_dictionaries"] path = third_party/hunspell_dictionaries - url = https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries.git + url = https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries [submodule "third_party/icu"] path = third_party/icu - url = https://chromium.googlesource.com/chromium/deps/icu.git + url = https://chromium.googlesource.com/chromium/deps/icu [submodule "third_party/javalang/src"] path = third_party/javalang/src - url = https://chromium.googlesource.com/external/github.com/c2nes/javalang.git + url = https://chromium.googlesource.com/external/github.com/c2nes/javalang gclient-condition = checkout_android [submodule "third_party/jsoncpp/source"] path = third_party/jsoncpp/source - url = https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp.git + url = https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp [submodule "third_party/junit/src"] path = third_party/junit/src - url = https://chromium.googlesource.com/external/junit.git + url = https://chromium.googlesource.com/external/junit gclient-condition = checkout_android [submodule "third_party/leveldatabase/src"] path = third_party/leveldatabase/src - url = https://chromium.googlesource.com/external/leveldb.git + url = https://chromium.googlesource.com/external/leveldb [submodule "third_party/libFuzzer/src"] path = third_party/libFuzzer/src - url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/compiler-rt/lib/fuzzer.git + url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/compiler-rt/lib/fuzzer [submodule "third_party/fuzztest/src"] path = third_party/fuzztest/src - url = https://chromium.googlesource.com/external/github.com/google/fuzztest.git + url = https://chromium.googlesource.com/external/github.com/google/fuzztest [submodule "third_party/libaddressinput/src"] path = third_party/libaddressinput/src - url = https://chromium.googlesource.com/external/libaddressinput.git + url = https://chromium.googlesource.com/external/libaddressinput [submodule "third_party/libaom/source/libaom"] path = third_party/libaom/source/libaom - url = https://aomedia.googlesource.com/aom.git + url = https://aomedia.googlesource.com/aom [submodule "third_party/libavif/src"] path = third_party/libavif/src - url = https://chromium.googlesource.com/external/github.com/AOMediaCodec/libavif.git + url = https://chromium.googlesource.com/external/github.com/AOMediaCodec/libavif [submodule "third_party/libavifinfo/src"] path = third_party/libavifinfo/src - url = https://aomedia.googlesource.com/libavifinfo.git + url = https://aomedia.googlesource.com/libavifinfo [submodule "third_party/nearby/src"] path = third_party/nearby/src - url = https://chromium.googlesource.com/external/github.com/google/nearby-connections.git + url = https://chromium.googlesource.com/external/github.com/google/nearby-connections [submodule "third_party/beto-core/src"] path = third_party/beto-core/src - url = https://beto-core.googlesource.com/beto-core.git + url = https://beto-core.googlesource.com/beto-core [submodule "third_party/securemessage/src"] path = third_party/securemessage/src - url = https://chromium.googlesource.com/external/github.com/google/securemessage.git + url = https://chromium.googlesource.com/external/github.com/google/securemessage [submodule "third_party/speedometer/v3.0"] path = third_party/speedometer/v3.0 - url = https://chromium.googlesource.com/external/github.com/WebKit/Speedometer.git + url = https://chromium.googlesource.com/external/github.com/WebKit/Speedometer [submodule "third_party/ukey2/src"] path = third_party/ukey2/src - url = https://chromium.googlesource.com/external/github.com/google/ukey2.git + url = https://chromium.googlesource.com/external/github.com/google/ukey2 [submodule "third_party/cros-components/src"] path = third_party/cros-components/src - url = https://chromium.googlesource.com/external/google3/cros_components.git + url = https://chromium.googlesource.com/external/google3/cros_components [submodule "third_party/libdrm/src"] path = third_party/libdrm/src - url = https://chromium.googlesource.com/chromiumos/third_party/libdrm.git + url = https://chromium.googlesource.com/chromiumos/third_party/libdrm gclient-condition = checkout_linux [submodule "third_party/expat/src"] path = third_party/expat/src - url = https://chromium.googlesource.com/external/github.com/libexpat/libexpat.git + url = https://chromium.googlesource.com/external/github.com/libexpat/libexpat [submodule "third_party/libipp/libipp"] path = third_party/libipp/libipp - url = https://chromium.googlesource.com/chromiumos/platform2/libipp.git + url = https://chromium.googlesource.com/chromiumos/platform2/libipp gclient-condition = checkout_linux [submodule "third_party/libjpeg_turbo"] path = third_party/libjpeg_turbo - url = https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git + url = https://chromium.googlesource.com/chromium/deps/libjpeg_turbo [submodule "third_party/liblouis/src"] path = third_party/liblouis/src - url = https://chromium.googlesource.com/external/liblouis-github.git + url = https://chromium.googlesource.com/external/liblouis-github gclient-condition = checkout_linux [submodule "third_party/libphonenumber/dist"] path = third_party/libphonenumber/dist - url = https://chromium.googlesource.com/external/libphonenumber.git + url = https://chromium.googlesource.com/external/libphonenumber [submodule "third_party/libprotobuf-mutator/src"] path = third_party/libprotobuf-mutator/src - url = https://chromium.googlesource.com/external/github.com/google/libprotobuf-mutator.git + url = https://chromium.googlesource.com/external/github.com/google/libprotobuf-mutator [submodule "third_party/libsrtp"] path = third_party/libsrtp - url = https://chromium.googlesource.com/chromium/deps/libsrtp.git + url = https://chromium.googlesource.com/chromium/deps/libsrtp [submodule "third_party/libsync/src"] path = third_party/libsync/src - url = https://chromium.googlesource.com/aosp/platform/system/core/libsync.git + url = https://chromium.googlesource.com/aosp/platform/system/core/libsync gclient-condition = checkout_linux [submodule "third_party/libunwindstack"] path = third_party/libunwindstack - url = https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git + url = https://chromium.googlesource.com/chromium/src/third_party/libunwindstack gclient-condition = checkout_android [submodule "third_party/libvpx/source/libvpx"] path = third_party/libvpx/source/libvpx - url = https://chromium.googlesource.com/webm/libvpx.git + url = https://chromium.googlesource.com/webm/libvpx [submodule "third_party/libwebm/source"] path = third_party/libwebm/source - url = https://chromium.googlesource.com/webm/libwebm.git + url = https://chromium.googlesource.com/webm/libwebm [submodule "third_party/libwebp/src"] path = third_party/libwebp/src - url = https://chromium.googlesource.com/webm/libwebp.git + url = https://chromium.googlesource.com/webm/libwebp [submodule "third_party/libyuv"] path = third_party/libyuv - url = https://chromium.googlesource.com/libyuv/libyuv.git + url = https://chromium.googlesource.com/libyuv/libyuv [submodule "third_party/lighttpd"] path = third_party/lighttpd - url = https://chromium.googlesource.com/chromium/deps/lighttpd.git + url = https://chromium.googlesource.com/chromium/deps/lighttpd gclient-condition = checkout_mac or checkout_win [submodule "third_party/lss"] path = third_party/lss - url = https://chromium.googlesource.com/linux-syscall-support.git + url = https://chromium.googlesource.com/linux-syscall-support gclient-condition = checkout_android or checkout_linux [submodule "third_party/material_color_utilities/src"] path = third_party/material_color_utilities/src - url = https://chromium.googlesource.com/external/github.com/material-foundation/material-color-utilities.git + url = https://chromium.googlesource.com/external/github.com/material-foundation/material-color-utilities [submodule "third_party/material_design_icons/src"] path = third_party/material_design_icons/src - url = https://chromium.googlesource.com/external/github.com/google/material-design-icons.git + url = https://chromium.googlesource.com/external/github.com/google/material-design-icons gclient-condition = checkout_ios [submodule "third_party/minigbm/src"] path = third_party/minigbm/src - url = https://chromium.googlesource.com/chromiumos/platform/minigbm.git + url = https://chromium.googlesource.com/chromiumos/platform/minigbm gclient-condition = checkout_linux [submodule "third_party/nasm"] path = third_party/nasm - url = https://chromium.googlesource.com/chromium/deps/nasm.git + url = https://chromium.googlesource.com/chromium/deps/nasm [submodule "third_party/neon_2_sse/src"] path = third_party/neon_2_sse/src - url = https://chromium.googlesource.com/external/github.com/intel/ARM_NEON_2_x86_SSE.git + url = https://chromium.googlesource.com/external/github.com/intel/ARM_NEON_2_x86_SSE [submodule "third_party/netty-tcnative/src"] path = third_party/netty-tcnative/src - url = https://chromium.googlesource.com/external/netty-tcnative.git + url = https://chromium.googlesource.com/external/netty-tcnative gclient-condition = checkout_android [submodule "third_party/netty4/src"] path = third_party/netty4/src - url = https://chromium.googlesource.com/external/netty4.git + url = https://chromium.googlesource.com/external/netty4 gclient-condition = checkout_android [submodule "third_party/openh264/src"] path = third_party/openh264/src @@ -446,380 +446,380 @@ gclient-condition = checkout_openxr [submodule "third_party/pdfium"] path = third_party/pdfium - url = https://pdfium.googlesource.com/pdfium.git + url = https://pdfium.googlesource.com/pdfium [submodule "third_party/perfetto"] path = third_party/perfetto - url = https://android.googlesource.com/platform/external/perfetto.git + url = https://android.googlesource.com/platform/external/perfetto [submodule "third_party/perl"] path = third_party/perl - url = https://chromium.googlesource.com/chromium/deps/perl.git + url = https://chromium.googlesource.com/chromium/deps/perl gclient-condition = checkout_win [submodule "third_party/pthreadpool/src"] path = third_party/pthreadpool/src - url = https://chromium.googlesource.com/external/github.com/Maratyszcza/pthreadpool.git + url = https://chromium.googlesource.com/external/github.com/Maratyszcza/pthreadpool [submodule "third_party/pyelftools"] path = third_party/pyelftools - url = https://chromium.googlesource.com/chromiumos/third_party/pyelftools.git + url = https://chromium.googlesource.com/chromiumos/third_party/pyelftools gclient-condition = checkout_linux [submodule "third_party/quic_trace/src"] path = third_party/quic_trace/src - url = https://chromium.googlesource.com/external/github.com/google/quic-trace.git + url = https://chromium.googlesource.com/external/github.com/google/quic-trace [submodule "third_party/pywebsocket3/src"] path = third_party/pywebsocket3/src - url = https://chromium.googlesource.com/external/github.com/GoogleChromeLabs/pywebsocket3.git + url = https://chromium.googlesource.com/external/github.com/GoogleChromeLabs/pywebsocket3 [submodule "third_party/re2/src"] path = third_party/re2/src - url = https://chromium.googlesource.com/external/github.com/google/re2.git + url = https://chromium.googlesource.com/external/github.com/google/re2 [submodule "third_party/requests/src"] path = third_party/requests/src - url = https://chromium.googlesource.com/external/github.com/kennethreitz/requests.git + url = https://chromium.googlesource.com/external/github.com/kennethreitz/requests gclient-condition = checkout_android [submodule "third_party/ruy/src"] path = third_party/ruy/src - url = https://chromium.googlesource.com/external/github.com/google/ruy.git + url = https://chromium.googlesource.com/external/github.com/google/ruy [submodule "third_party/skia"] path = third_party/skia - url = https://skia.googlesource.com/skia.git + url = https://skia.googlesource.com/skia [submodule "third_party/smhasher/src"] path = third_party/smhasher/src - url = https://chromium.googlesource.com/external/smhasher.git + url = https://chromium.googlesource.com/external/smhasher [submodule "third_party/snappy/src"] path = third_party/snappy/src - url = https://chromium.googlesource.com/external/github.com/google/snappy.git + url = https://chromium.googlesource.com/external/github.com/google/snappy [submodule "third_party/sqlite/src"] path = third_party/sqlite/src - url = https://chromium.googlesource.com/chromium/deps/sqlite.git + url = https://chromium.googlesource.com/chromium/deps/sqlite [submodule "third_party/swiftshader"] path = third_party/swiftshader - url = https://swiftshader.googlesource.com/SwiftShader.git + url = https://swiftshader.googlesource.com/SwiftShader [submodule "third_party/text-fragments-polyfill/src"] path = third_party/text-fragments-polyfill/src - url = https://chromium.googlesource.com/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git + url = https://chromium.googlesource.com/external/github.com/GoogleChromeLabs/text-fragments-polyfill [submodule "third_party/tflite/src"] path = third_party/tflite/src - url = https://chromium.googlesource.com/external/github.com/tensorflow/tensorflow.git + url = https://chromium.googlesource.com/external/github.com/tensorflow/tensorflow [submodule "third_party/vulkan-deps"] path = third_party/vulkan-deps url = https://chromium.googlesource.com/vulkan-deps [submodule "third_party/vulkan_memory_allocator"] path = third_party/vulkan_memory_allocator - url = https://chromium.googlesource.com/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git + url = https://chromium.googlesource.com/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator [submodule "third_party/wayland/src"] path = third_party/wayland/src - url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/wayland.git + url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/wayland gclient-condition = checkout_linux [submodule "third_party/wayland-protocols/src"] path = third_party/wayland-protocols/src - url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/wayland-protocols.git + url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/wayland-protocols gclient-condition = checkout_linux [submodule "third_party/wayland-protocols/kde"] path = third_party/wayland-protocols/kde - url = https://chromium.googlesource.com/external/github.com/KDE/plasma-wayland-protocols.git + url = https://chromium.googlesource.com/external/github.com/KDE/plasma-wayland-protocols gclient-condition = checkout_linux [submodule "third_party/wayland-protocols/gtk"] path = third_party/wayland-protocols/gtk - url = https://chromium.googlesource.com/external/github.com/GNOME/gtk.git + url = https://chromium.googlesource.com/external/github.com/GNOME/gtk gclient-condition = checkout_linux [submodule "third_party/webdriver/pylib"] path = third_party/webdriver/pylib - url = https://chromium.googlesource.com/external/github.com/SeleniumHQ/selenium/py.git + url = https://chromium.googlesource.com/external/github.com/SeleniumHQ/selenium/py [submodule "third_party/webgl/src"] path = third_party/webgl/src - url = https://chromium.googlesource.com/external/khronosgroup/webgl.git + url = https://chromium.googlesource.com/external/khronosgroup/webgl [submodule "third_party/webgpu-cts/src"] path = third_party/webgpu-cts/src - url = https://chromium.googlesource.com/external/github.com/gpuweb/cts.git + url = https://chromium.googlesource.com/external/github.com/gpuweb/cts [submodule "third_party/webrtc"] path = third_party/webrtc - url = https://webrtc.googlesource.com/src.git + url = https://webrtc.googlesource.com/src [submodule "third_party/wuffs/src"] path = third_party/wuffs/src - url = https://skia.googlesource.com/external/github.com/google/wuffs-mirror-release-c.git + url = https://skia.googlesource.com/external/github.com/google/wuffs-mirror-release-c [submodule "third_party/weston/src"] path = third_party/weston/src - url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/weston.git + url = https://chromium.googlesource.com/external/anongit.freedesktop.org/git/wayland/weston gclient-condition = checkout_linux [submodule "third_party/wlcs/src"] path = third_party/wlcs/src - url = https://chromium.googlesource.com/external/github.com/MirServer/wlcs.git + url = https://chromium.googlesource.com/external/github.com/MirServer/wlcs gclient-condition = checkout_chromeos [submodule "third_party/xdg-utils"] path = third_party/xdg-utils - url = https://chromium.googlesource.com/chromium/deps/xdg-utils.git + url = https://chromium.googlesource.com/chromium/deps/xdg-utils gclient-condition = checkout_linux [submodule "third_party/xnnpack/src"] path = third_party/xnnpack/src - url = https://chromium.googlesource.com/external/github.com/google/XNNPACK.git + url = https://chromium.googlesource.com/external/github.com/google/XNNPACK [submodule "tools/page_cycler/acid3"] path = tools/page_cycler/acid3 - url = https://chromium.googlesource.com/chromium/deps/acid3.git + url = https://chromium.googlesource.com/chromium/deps/acid3 [submodule "third_party/zstd/src"] path = third_party/zstd/src - url = https://chromium.googlesource.com/external/github.com/facebook/zstd.git + url = https://chromium.googlesource.com/external/github.com/facebook/zstd [submodule "v8"] path = v8 - url = https://chromium.googlesource.com/v8/v8.git + url = https://chromium.googlesource.com/v8/v8 [submodule "internal"] path = internal - url = https://chrome-internal.googlesource.com/chrome/src-internal.git + url = https://chrome-internal.googlesource.com/chrome/src-internal gclient-condition = checkout_src_internal [submodule "third_party/android_prebuilts/build_tools"] path = third_party/android_prebuilts/build_tools - url = https://android.googlesource.com/platform/prebuilts/build-tools.git + url = https://android.googlesource.com/platform/prebuilts/build-tools gclient-condition = checkout_android_prebuilts_build_tools [submodule "chromeos/assistant/internal"] path = chromeos/assistant/internal - url = https://chrome-internal.googlesource.com/chrome/assistant.git + url = https://chrome-internal.googlesource.com/chrome/assistant gclient-condition = checkout_src_internal and checkout_chromeos [submodule "build/fuchsia/internal"] path = build/fuchsia/internal - url = https://chrome-internal.googlesource.com/fuchsia/build.git + url = https://chrome-internal.googlesource.com/fuchsia/build gclient-condition = checkout_fuchsia_internal and checkout_src_internal [submodule "chrome/app/theme/default_100_percent/google_chrome"] path = chrome/app/theme/default_100_percent/google_chrome - url = https://chrome-internal.googlesource.com/chrome/theme/default_100_percent/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/theme/default_100_percent/google_chrome gclient-condition = checkout_src_internal [submodule "chrome/app/theme/default_200_percent/google_chrome"] path = chrome/app/theme/default_200_percent/google_chrome - url = https://chrome-internal.googlesource.com/chrome/theme/default_200_percent/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/theme/default_200_percent/google_chrome gclient-condition = checkout_src_internal [submodule "chrome/app/theme/google_chrome"] path = chrome/app/theme/google_chrome - url = https://chrome-internal.googlesource.com/chrome/theme/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/theme/google_chrome gclient-condition = checkout_src_internal [submodule "chrome/browser/enterprise/connectors/internal"] path = chrome/browser/enterprise/connectors/internal - url = https://chrome-internal.googlesource.com/chrome/browser/enterprise/connectors/internal.git + url = https://chrome-internal.googlesource.com/chrome/browser/enterprise/connectors/internal gclient-condition = checkout_src_internal [submodule "chrome/browser/google/linkdoctor_internal"] path = chrome/browser/google/linkdoctor_internal - url = https://chrome-internal.googlesource.com/chrome/linkdoctor.git + url = https://chrome-internal.googlesource.com/chrome/linkdoctor gclient-condition = checkout_src_internal [submodule "chrome/browser/internal"] path = chrome/browser/internal - url = https://chrome-internal.googlesource.com/chrome/browser_internal.git + url = https://chrome-internal.googlesource.com/chrome/browser_internal gclient-condition = checkout_src_internal [submodule "chrome/browser/media/engagement_internal"] path = chrome/browser/media/engagement_internal - url = https://chrome-internal.googlesource.com/chrome/browser/media/engagement_internal.git + url = https://chrome-internal.googlesource.com/chrome/browser/media/engagement_internal gclient-condition = checkout_src_internal [submodule "chrome/browser/nearby_sharing/internal"] path = chrome/browser/nearby_sharing/internal - url = https://chrome-internal.googlesource.com/chrome/browser/nearby_sharing/internal.git + url = https://chrome-internal.googlesource.com/chrome/browser/nearby_sharing/internal gclient-condition = checkout_src_internal [submodule "chrome/browser/resources/chromeos/quickoffice"] path = chrome/browser/resources/chromeos/quickoffice - url = https://chrome-internal.googlesource.com/quickoffice/crx.git + url = https://chrome-internal.googlesource.com/quickoffice/crx gclient-condition = (checkout_chromeos or checkout_linux) and checkout_src_internal [submodule "chrome/browser/resources/settings_internal"] path = chrome/browser/resources/settings_internal - url = https://chrome-internal.googlesource.com/chrome/browser/resources/settings_internal.git + url = https://chrome-internal.googlesource.com/chrome/browser/resources/settings_internal gclient-condition = checkout_src_internal [submodule "chrome/browser/spellchecker/internal"] path = chrome/browser/spellchecker/internal - url = https://chrome-internal.googlesource.com/chrome/spellchecker/internal.git + url = https://chrome-internal.googlesource.com/chrome/spellchecker/internal gclient-condition = checkout_src_internal [submodule "chrome/installer/mac/internal"] path = chrome/installer/mac/internal - url = https://chrome-internal.googlesource.com/chrome/installer/mac/internal.git + url = https://chrome-internal.googlesource.com/chrome/installer/mac/internal gclient-condition = checkout_src_internal [submodule "chrome/test/data/firefox3_profile/searchplugins"] path = chrome/test/data/firefox3_profile/searchplugins - url = https://chrome-internal.googlesource.com/chrome/data/osdd/firefox3_profile_searchplugins.git + url = https://chrome-internal.googlesource.com/chrome/data/osdd/firefox3_profile_searchplugins gclient-condition = checkout_src_internal [submodule "chrome/test/data/firefox3_searchplugins"] path = chrome/test/data/firefox3_searchplugins - url = https://chrome-internal.googlesource.com/chrome/data/osdd/firefox3_searchplugins.git + url = https://chrome-internal.googlesource.com/chrome/data/osdd/firefox3_searchplugins gclient-condition = checkout_src_internal [submodule "chrome/test/data/gpu/vt"] path = chrome/test/data/gpu/vt - url = https://chrome-internal.googlesource.com/chrome/data/vectortown_endurance/vectortownstatic-20121022.git + url = https://chrome-internal.googlesource.com/chrome/data/vectortown_endurance/vectortownstatic-20121022 gclient-condition = checkout_src_internal [submodule "chrome/test/data/perf/frame_rate/private"] path = chrome/test/data/perf/frame_rate/private - url = https://chrome-internal.googlesource.com/chrome/data/frame_rate_tests.git + url = https://chrome-internal.googlesource.com/chrome/data/frame_rate_tests gclient-condition = checkout_src_internal [submodule "chrome/test/data/perf/private"] path = chrome/test/data/perf/private - url = https://chrome-internal.googlesource.com/chrome/data/perf_tests.git + url = https://chrome-internal.googlesource.com/chrome/data/perf_tests gclient-condition = checkout_src_internal [submodule "chrome/test/data/pdf_private"] path = chrome/test/data/pdf_private - url = https://chrome-internal.googlesource.com/chrome/data/pdf_private.git + url = https://chrome-internal.googlesource.com/chrome/data/pdf_private gclient-condition = checkout_src_internal [submodule "chrome/test/media_router/internal"] path = chrome/test/media_router/internal - url = https://chrome-internal.googlesource.com/chrome/test/media_router/internal.git + url = https://chrome-internal.googlesource.com/chrome/test/media_router/internal gclient-condition = checkout_src_internal [submodule "chrome/test/python_tests"] path = chrome/test/python_tests - url = https://chrome-internal.googlesource.com/chrome/test/python_tests.git + url = https://chrome-internal.googlesource.com/chrome/test/python_tests gclient-condition = checkout_src_internal [submodule "chrome/tools/memory"] path = chrome/tools/memory - url = https://chrome-internal.googlesource.com/chrome/tools/memory.git + url = https://chrome-internal.googlesource.com/chrome/tools/memory gclient-condition = checkout_win and checkout_src_internal [submodule "chrome/services/speech/internal"] path = chrome/services/speech/internal - url = https://chrome-internal.googlesource.com/chromeos/speech.git + url = https://chrome-internal.googlesource.com/chromeos/speech gclient-condition = checkout_chromeos and checkout_src_internal [submodule "components/autofill/core/browser/form_parsing/internal_resources"] path = components/autofill/core/browser/form_parsing/internal_resources - url = https://chrome-internal.googlesource.com/chrome/components/autofill_regex_patterns.git + url = https://chrome-internal.googlesource.com/chrome/components/autofill_regex_patterns gclient-condition = checkout_src_internal [submodule "components/crash/core/app/internal"] path = components/crash/core/app/internal - url = https://chrome-internal.googlesource.com/chrome/components/crash.git + url = https://chrome-internal.googlesource.com/chrome/components/crash gclient-condition = checkout_src_internal [submodule "components/metrics/internal"] path = components/metrics/internal - url = https://chrome-internal.googlesource.com/chrome/components/metrics/internal.git + url = https://chrome-internal.googlesource.com/chrome/components/metrics/internal gclient-condition = checkout_src_internal [submodule "components/ntp_tiles/resources/internal"] path = components/ntp_tiles/resources/internal - url = https://chrome-internal.googlesource.com/chrome/components/ntp_tiles/resources.git + url = https://chrome-internal.googlesource.com/chrome/components/ntp_tiles/resources gclient-condition = checkout_src_internal [submodule "components/optimization_guide/internal"] path = components/optimization_guide/internal - url = https://chrome-internal.googlesource.com/chrome/components/optimization_guide.git + url = https://chrome-internal.googlesource.com/chrome/components/optimization_guide gclient-condition = checkout_src_internal [submodule "components/resources/default_100_percent/google_chrome"] path = components/resources/default_100_percent/google_chrome - url = https://chrome-internal.googlesource.com/chrome/components/default_100_percent/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/components/default_100_percent/google_chrome gclient-condition = checkout_src_internal [submodule "components/resources/default_200_percent/google_chrome"] path = components/resources/default_200_percent/google_chrome - url = https://chrome-internal.googlesource.com/chrome/components/default_200_percent/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/components/default_200_percent/google_chrome gclient-condition = checkout_src_internal [submodule "components/resources/default_300_percent/google_chrome"] path = components/resources/default_300_percent/google_chrome - url = https://chrome-internal.googlesource.com/chrome/components/default_300_percent/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/components/default_300_percent/google_chrome gclient-condition = checkout_src_internal [submodule "components/site_isolation/internal"] path = components/site_isolation/internal - url = https://chrome-internal.googlesource.com/chrome/components/site_isolation.git + url = https://chrome-internal.googlesource.com/chrome/components/site_isolation gclient-condition = checkout_src_internal [submodule "components/test/data/autofill/heuristics-json/internal"] path = components/test/data/autofill/heuristics-json/internal - url = https://chrome-internal.googlesource.com/chrome/test/autofill/structured_forms.git + url = https://chrome-internal.googlesource.com/chrome/test/autofill/structured_forms gclient-condition = checkout_chromium_autofill_test_dependencies [submodule "components/vector_icons/google_chrome"] path = components/vector_icons/google_chrome - url = https://chrome-internal.googlesource.com/chrome/vector_icons/google_chrome.git + url = https://chrome-internal.googlesource.com/chrome/vector_icons/google_chrome gclient-condition = checkout_src_internal [submodule "content/test/data/plugin"] path = content/test/data/plugin - url = https://chrome-internal.googlesource.com/chrome/data/chrome_plugin_tests.git + url = https://chrome-internal.googlesource.com/chrome/data/chrome_plugin_tests gclient-condition = checkout_src_internal [submodule "google_apis/internal"] path = google_apis/internal - url = https://chrome-internal.googlesource.com/chrome/google_apis/internal.git + url = https://chrome-internal.googlesource.com/chrome/google_apis/internal gclient-condition = checkout_src_internal [submodule "ios_internal"] path = ios_internal - url = https://chrome-internal.googlesource.com/chrome/ios_internal.git + url = https://chrome-internal.googlesource.com/chrome/ios_internal gclient-condition = checkout_ios and checkout_src_internal [submodule "remoting/android/internal"] path = remoting/android/internal - url = https://chrome-internal.googlesource.com/chrome/remoting/android/internal.git + url = https://chrome-internal.googlesource.com/chrome/remoting/android/internal gclient-condition = checkout_android and checkout_src_internal [submodule "remoting/host/installer/linux/internal"] path = remoting/host/installer/linux/internal - url = https://chrome-internal.googlesource.com/chrome/remoting/host/installer/linux/internal.git + url = https://chrome-internal.googlesource.com/chrome/remoting/host/installer/linux/internal gclient-condition = checkout_linux and checkout_src_internal [submodule "remoting/internal"] path = remoting/internal - url = https://chrome-internal.googlesource.com/chrome/remoting/internal.git + url = https://chrome-internal.googlesource.com/chrome/remoting/internal gclient-condition = checkout_src_internal [submodule "remoting/test/internal"] path = remoting/test/internal - url = https://chrome-internal.googlesource.com/chrome/remoting/test/internal.git + url = https://chrome-internal.googlesource.com/chrome/remoting/test/internal gclient-condition = checkout_src_internal [submodule "remoting/tools/internal"] path = remoting/tools/internal - url = https://chrome-internal.googlesource.com/chrome/remoting/tools/internal.git + url = https://chrome-internal.googlesource.com/chrome/remoting/tools/internal gclient-condition = checkout_src_internal [submodule "signing_keys"] path = signing_keys - url = https://chrome-internal.googlesource.com/clank/apptestkey.git + url = https://chrome-internal.googlesource.com/clank/apptestkey gclient-condition = checkout_android and checkout_google_internal and checkout_src_internal [submodule "skia/tools/clusterfuzz-data"] path = skia/tools/clusterfuzz-data - url = https://chrome-internal.googlesource.com/chrome/tools/clusterfuzz-data.git + url = https://chrome-internal.googlesource.com/chrome/tools/clusterfuzz-data gclient-condition = checkout_clusterfuzz_data and checkout_src_internal [submodule "third_party/amd"] path = third_party/amd - url = https://chrome-internal.googlesource.com/chrome/deps/amd.git + url = https://chrome-internal.googlesource.com/chrome/deps/amd gclient-condition = checkout_win and checkout_src_internal [submodule "third_party/android_tools_internal"] path = third_party/android_tools_internal - url = https://chrome-internal.googlesource.com/clank/third_party/android_tools.git + url = https://chrome-internal.googlesource.com/clank/third_party/android_tools gclient-condition = checkout_android and checkout_src_internal [submodule "third_party/gles2_conform"] path = third_party/gles2_conform - url = https://chrome-internal.googlesource.com/chrome/deps/gles2_conform.git + url = https://chrome-internal.googlesource.com/chrome/deps/gles2_conform gclient-condition = checkout_src_internal [submodule "third_party/googlemac"] path = third_party/googlemac - url = https://chrome-internal.googlesource.com/chrome/deps/googlemac.git + url = https://chrome-internal.googlesource.com/chrome/deps/googlemac gclient-condition = checkout_mac and checkout_src_internal [submodule "third_party/khronos_glcts"] path = third_party/khronos_glcts - url = https://chrome-internal.googlesource.com/chrome/deps/khronos_glcts.git + url = https://chrome-internal.googlesource.com/chrome/deps/khronos_glcts gclient-condition = checkout_src_internal [submodule "third_party/ml"] path = third_party/ml - url = https://chrome-internal.googlesource.com/chrome/third_party/ml.git + url = https://chrome-internal.googlesource.com/chrome/third_party/ml gclient-condition = checkout_third_party_ml [submodule "third_party/widevine/cdm/chromeos"] path = third_party/widevine/cdm/chromeos - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/chromeos.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/chromeos gclient-condition = (checkout_chromeos or checkout_linux) and checkout_src_internal [submodule "third_party/widevine/cdm/linux"] path = third_party/widevine/cdm/linux - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/linux.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/linux gclient-condition = checkout_linux and checkout_src_internal [submodule "third_party/widevine/cdm/mac"] path = third_party/widevine/cdm/mac - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/mac.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/mac gclient-condition = checkout_mac and checkout_src_internal [submodule "third_party/widevine/cdm/win"] path = third_party/widevine/cdm/win - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/win.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/cdm/win gclient-condition = checkout_win and checkout_src_internal [submodule "third_party/widevine/scripts"] path = third_party/widevine/scripts - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/scripts.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/scripts gclient-condition = checkout_src_internal [submodule "third_party/widevine/test/license_server"] path = third_party/widevine/test/license_server - url = https://chrome-internal.googlesource.com/chrome/deps/widevine/test/license_server.git + url = https://chrome-internal.googlesource.com/chrome/deps/widevine/test/license_server gclient-condition = checkout_linux and checkout_src_internal [submodule "third_party/wix"] path = third_party/wix - url = https://chrome-internal.googlesource.com/chrome/deps/wix/v3_5_2519.git + url = https://chrome-internal.googlesource.com/chrome/deps/wix/v3_5_2519 gclient-condition = checkout_win and checkout_src_internal [submodule "tools/perf/data"] path = tools/perf/data - url = https://chrome-internal.googlesource.com/chrome/tools/perf/data.git + url = https://chrome-internal.googlesource.com/chrome/tools/perf/data gclient-condition = checkout_src_internal [submodule "ui/file_manager/internal"] path = ui/file_manager/internal - url = https://chrome-internal.googlesource.com/chrome/file_manager.git + url = https://chrome-internal.googlesource.com/chrome/file_manager gclient-condition = (checkout_chromeos or checkout_linux) and checkout_src_internal [submodule "ui/webui/internal"] path = ui/webui/internal - url = https://chrome-internal.googlesource.com/chrome/ui-webui-internal.git + url = https://chrome-internal.googlesource.com/chrome/ui-webui-internal gclient-condition = checkout_chromeos and checkout_src_internal [submodule "webkit/data/bmp_decoder"] path = webkit/data/bmp_decoder - url = https://chrome-internal.googlesource.com/chrome/data/bmp_decoder.git + url = https://chrome-internal.googlesource.com/chrome/data/bmp_decoder gclient-condition = checkout_src_internal [submodule "webkit/data/ico_decoder"] path = webkit/data/ico_decoder - url = https://chrome-internal.googlesource.com/chrome/data/ico_decoder.git + url = https://chrome-internal.googlesource.com/chrome/data/ico_decoder gclient-condition = checkout_src_internal [submodule "webkit/data/test_shell/plugins"] path = webkit/data/test_shell/plugins - url = https://chrome-internal.googlesource.com/chrome/data/webkit_plugin_tests.git + url = https://chrome-internal.googlesource.com/chrome/data/webkit_plugin_tests gclient-condition = checkout_src_internal
diff --git a/BUILD.gn b/BUILD.gn index 4131b9c..7ee617b 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1352,6 +1352,7 @@ "//third_party/blink/web_tests/permissionclient/", "//third_party/blink/web_tests/plugins/", "//third_party/blink/web_tests/pointer-lock/", + "//third_party/blink/web_tests/ppapi/", "//third_party/blink/web_tests/print_testharness/", "//third_party/blink/web_tests/printing/", "//third_party/blink/web_tests/register-protocol-handler/",
diff --git a/DEPS b/DEPS index 14045c71..0b5099f 100644 --- a/DEPS +++ b/DEPS
@@ -305,7 +305,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'a745a52bdcff739fdbd370e7fb7da57c8111786e', + 'src_internal_revision': '57f20f590e37501b247262add777c9ec78fd696b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -313,11 +313,11 @@ # 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': 'f2a4a2beba1d4056f6d1e66a16c15d70470c1051', + 'v8_revision': '4aa8206baa4a6bc46447e8249466e324112d6a8d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'c8a544dddbae3d1f495e05a36d5c2f4427b4994b', + 'angle_revision': 'cb28076f897ba219a3db42e1755b44076dfebc37', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -400,7 +400,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': 'e6bdd501b906e79f863decb8ca89598d4b1f317c', + 'devtools_frontend_revision': 'bcaddf6069764b73f39192ffe4828e6fd0507c5c', # 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. @@ -424,11 +424,11 @@ # 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': 'ff937f71a801fe382ac1c902f830b56719f4e1da', + 'dawn_revision': 'f56616d501a644383b7abe9848a905aece2a26da', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'e894f322dcd82ef0642834ea2e5ab432d22ec43b', + 'quiche_revision': '45374cbe5557a6d3da7aa1a43c969314f7b1894e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -500,7 +500,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': 'a96e76348a51cb38e2120a7333c49884e5737768', + 'libcxx_revision': '434a8efe28c23fda34464701cd4c7640b1f4c1c8', # GN CIPD package version. 'gn_version': 'git_revision:c7b223bfb225ce87a72a244d016ffdfcf227fa5e', @@ -824,7 +824,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '68949fa36ab0fb6ad6d4f07bfed5139ecc426c3b', + 'f5a65a354e79fc3652b1f2ef7a54e15317abb85a', 'condition': 'checkout_android and checkout_src_internal', }, @@ -986,7 +986,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'iIOjnHoOGIGndTMSfxlARsOPYyR9OOsTud-7duKGuFkC', + 'version': 'GF69C5UiWzJZSV25qmnNbh-6Z9_bze8krd7eDpjAEVsC', }, ], 'condition': 'checkout_android', @@ -1224,7 +1224,7 @@ Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '4b78cf0e89fdbdb7f917beab13a7ad62af3f05ef', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '625b3e2ff82d85646c862dd0457fc86f207a374f', 'condition': 'checkout_src_internal', }, @@ -1689,7 +1689,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '510b65fa04d733f3bfa9e4c6ea7ff98e0c449637', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '2ee1fe9e10b545724f6237028142f87bb98073dd', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1834,7 +1834,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@63bb05a5e0adc21e2436613b6452a7b5cc61ae54', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@ac8158a19e0b76b4efa92989fb08bf00275db213', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -1874,7 +1874,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '300768e70537a52889f9e283465b1fbf8679ebfb', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'f0907c6f5bcdacf2e180acf4f15c4700f72d6982', + Var('webrtc_git') + '/src.git' + '@' + 'a9d497b52dc21497fdfd0e8c03ab2f8559e02d15', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1997,7 +1997,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'Nlaon0avuWo3iySHPjsF1qnYPZMTWqDjkKHMgRnNQ6MC', + 'version': 'GGx-iAvFMRR0ppKm5KggSI2kfsuLXJMAV5GUTKIgg_4C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2008,7 +2008,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '-Sl0qrqXWKSz-0vAUifCPxmok67CpTeecSM7BtQqm6IC', + 'version': 'jFR-rwskNkhWdhJ52SOur67EoEQg2fLIsNWFNGUZgiAC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2041,7 +2041,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'ENdl4n5RLbvdjA0T0scu8P_TDJyKPC0Qe-eVIIIRvWYC', + 'version': 'S3nvhey-ePzmM1g9xMiyfQwnMHFWHUcGLR-DL_hem00C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3977,7 +3977,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - 'f4ab40f18a91c5c4ff2ac0149c4c4914bd00e661', + '192f7a242f1e6348842c261e22dd50852cde0885', 'condition': 'checkout_src_internal', }, @@ -4025,13 +4025,13 @@ 'src/google_apis/internal': { 'url': Var('chrome_git') + '/chrome/google_apis/internal.git' + '@' + - '5e58468fff99dbb1482cb9a211e30bd7ca71fb03', + '8c0bf6a2b3aa247b0fbb15ab114e0ac78fbcbf0f', 'condition': 'checkout_src_internal', }, 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '12205cac93d6adfbfad832d5c9401fbd1c19fa35', + '59495100bd8b3729c012f890af55c96c9abb3e27', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/DEPS b/android_webview/DEPS index 60daec48..49b364c 100644 --- a/android_webview/DEPS +++ b/android_webview/DEPS
@@ -44,7 +44,4 @@ "+ui/android", "+ui/base", "+ui/gfx", - - # Used for Vulkan interop path. - "+third_party/vulkan/include", ]
diff --git a/android_webview/browser/gfx/BUILD.gn b/android_webview/browser/gfx/BUILD.gn index 81a15c3..fc1fa888 100644 --- a/android_webview/browser/gfx/BUILD.gn +++ b/android_webview/browser/gfx/BUILD.gn
@@ -64,8 +64,6 @@ "task_queue_webview.h", "viz_compositor_thread_runner_webview.cc", "viz_compositor_thread_runner_webview.h", - "vulkan_gl_interop.cc", - "vulkan_gl_interop.h", ] deps = [
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc index 9731992f..a6327be 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.cc +++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -14,10 +14,9 @@ #include "base/trace_event/trace_event.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "gpu/config/gpu_finch_features.h" -#include "gpu/config/gpu_switches.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/vk/GrVkTypes.h" #include "third_party/skia/include/private/chromium/GrVkSecondaryCBDrawContext.h" #include "ui/gfx/color_space.h" @@ -198,8 +197,7 @@ } AwDrawFnImpl::AwDrawFnImpl() - : is_interop_mode_(!features::IsUsingVulkan()), - render_thread_manager_(content::GetUIThreadTaskRunner({})) { + : render_thread_manager_(content::GetUIThreadTaskRunner({})) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(g_draw_fn_function_table); @@ -270,9 +268,6 @@ } } - if (interop_) - interop_->MakeGLContextCurrentIgnoreFailure(); - { RenderThreadManager::InsideHardwareReleaseReset release_reset( &render_thread_manager_); @@ -280,7 +275,6 @@ false /* save_restore */, false /* abandon_context */); } - interop_.reset(); vulkan_context_provider_.reset(); } @@ -310,12 +304,8 @@ vulkan_context_provider_ = AwVulkanContextProvider::Create(params); DCHECK(vulkan_context_provider_); - if (is_interop_mode_) { - interop_.emplace(&render_thread_manager_, vulkan_context_provider_.get()); - } else { - render_thread_manager_.SetVulkanContextProviderOnRT( - vulkan_context_provider_.get()); - } + render_thread_manager_.SetVulkanContextProviderOnRT( + vulkan_context_provider_.get()); } void AwDrawFnImpl::DrawVk(AwDrawFn_DrawVkParams* params) { @@ -345,38 +335,6 @@ CreateHRDrawParams(params, color_space.get()); OverlaysParams overlays_params = CreateOverlaysParams(params); - if (is_interop_mode_) { - DCHECK(interop_); - interop_->DrawVk(std::move(draw_context), std::move(color_space), hr_params, - overlays_params); - - } else { - DrawVkDirect(std::move(draw_context), std::move(color_space), hr_params, - overlays_params); - } -} - -void AwDrawFnImpl::PostDrawVk(AwDrawFn_PostDrawVkParams* params) { - if (!vulkan_context_provider_) - return; - - if (skip_next_post_draw_vk_) { - skip_next_post_draw_vk_ = false; - return; - } - - if (is_interop_mode_) { - DCHECK(interop_); - interop_->PostDrawVk(); - } else { - PostDrawVkDirect(params); - } -} - -void AwDrawFnImpl::DrawVkDirect(sk_sp<GrVkSecondaryCBDrawContext> draw_context, - sk_sp<SkColorSpace> color_space, - const HardwareRendererDrawParams& hr_params, - const OverlaysParams& overlays_params) { DCHECK(!scoped_secondary_cb_draw_); // Set the draw contexct in |vulkan_context_provider_|, so the SkiaRenderer @@ -387,10 +345,15 @@ overlays_params); } -void AwDrawFnImpl::PostDrawVkDirect(AwDrawFn_PostDrawVkParams* params) { +void AwDrawFnImpl::PostDrawVk(AwDrawFn_PostDrawVkParams* params) { if (!vulkan_context_provider_) return; + if (skip_next_post_draw_vk_) { + skip_next_post_draw_vk_ = false; + return; + } + DCHECK(scoped_secondary_cb_draw_); scoped_secondary_cb_draw_.reset(); }
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.h b/android_webview/browser/gfx/aw_draw_fn_impl.h index 41df418..5fb458c 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.h +++ b/android_webview/browser/gfx/aw_draw_fn_impl.h
@@ -9,7 +9,6 @@ #include "android_webview/browser/gfx/aw_vulkan_context_provider.h" #include "android_webview/browser/gfx/compositor_frame_consumer.h" #include "android_webview/browser/gfx/render_thread_manager.h" -#include "android_webview/browser/gfx/vulkan_gl_interop.h" #include "android_webview/public/browser/draw_fn.h" #include "base/android/scoped_java_ref.h" #include "base/threading/platform_thread.h" @@ -48,19 +47,10 @@ void RemoveOverlays(AwDrawFn_RemoveOverlaysParams* params); private: - // With direct mode, we will render frames with Vulkan API directly. - void DrawVkDirect(sk_sp<GrVkSecondaryCBDrawContext> draw_context, - sk_sp<SkColorSpace> color_space, - const HardwareRendererDrawParams& params, - const OverlaysParams& overlays_params); - void PostDrawVkDirect(AwDrawFn_PostDrawVkParams* params); - CompositorFrameConsumer* GetCompositorFrameConsumer() { return &render_thread_manager_; } - const bool is_interop_mode_; - int functor_handle_; RenderThreadManager render_thread_manager_; @@ -71,8 +61,6 @@ std::optional<AwVulkanContextProvider::ScopedSecondaryCBDraw> scoped_secondary_cb_draw_; - std::optional<VulkanGLInterop> interop_; - // Latched on first DrawGL / InitVk call. std::optional<base::PlatformThreadId> render_thread_id_;
diff --git a/android_webview/browser/gfx/vulkan_gl_interop.cc b/android_webview/browser/gfx/vulkan_gl_interop.cc deleted file mode 100644 index 8c7a14f..0000000 --- a/android_webview/browser/gfx/vulkan_gl_interop.cc +++ /dev/null
@@ -1,440 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/gfx/vulkan_gl_interop.h" - -#include <utility> - -#include "android_webview/browser/gfx/render_thread_manager.h" -#include "base/android/android_hardware_buffer_compat.h" -#include "base/android/scoped_hardware_buffer_fence_sync.h" -#include "gpu/command_buffer/service/ahardwarebuffer_utils.h" -#include "gpu/command_buffer/service/skia_utils.h" -#include "gpu/vulkan/vulkan_fence_helper.h" -#include "gpu/vulkan/vulkan_function_pointers.h" -#include "gpu/vulkan/vulkan_image.h" -#include "gpu/vulkan/vulkan_implementation.h" -#include "third_party/skia/include/core/SkAlphaType.h" -#include "third_party/skia/include/core/SkBlendMode.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorSpace.h" -#include "third_party/skia/include/core/SkColorType.h" -#include "third_party/skia/include/core/SkImage.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkSamplingOptions.h" -#include "third_party/skia/include/gpu/GrBackendSemaphore.h" -#include "third_party/skia/include/gpu/GrBackendSurface.h" -#include "third_party/skia/include/gpu/GrTypes.h" -#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" -#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h" -#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h" -#include "third_party/skia/include/gpu/vk/GrVkExtensions.h" -#include "third_party/skia/include/private/chromium/GrVkSecondaryCBDrawContext.h" -#include "ui/gfx/gpu_memory_buffer.h" -#include "ui/gl/android/egl_fence_utils.h" -#include "ui/gl/gl_bindings.h" -#include "ui/gl/gl_context_egl.h" -#include "ui/gl/gl_surface_egl.h" -#include "ui/gl/init/gl_factory.h" - -namespace android_webview { - -namespace { - -void CleanupInFlightDraw(sk_sp<GrVkSecondaryCBDrawContext> draw_context, - VkSemaphore post_draw_semaphore, - gpu::VulkanDeviceQueue* device_queue, - bool /* context_lost */) { - VkDevice device = device_queue->GetVulkanDevice(); - // We do the same thing whether or not context is lost. - draw_context->releaseResources(); - draw_context.reset(); - if (post_draw_semaphore != VK_NULL_HANDLE) - vkDestroySemaphore(device, post_draw_semaphore, nullptr); -} -} // namespace - -// static -VulkanGLInterop::GLNonOwnedCompatibilityContext* VulkanGLInterop::g_gl_context = - nullptr; - -class VulkanGLInterop::GLNonOwnedCompatibilityContext - : public gl::GLContextEGL { - public: - GLNonOwnedCompatibilityContext() : gl::GLContextEGL(nullptr) { - gl::GLContextAttribs attribs; - // No need to store the surface as the gl::GLContext will have it saved. - auto surface = base::MakeRefCounted<gl::PbufferGLSurfaceEGL>( - gl::GLSurfaceEGL::GetGLDisplayEGL(), gfx::Size(1, 1)); - Initialize(surface.get(), attribs); - DCHECK(default_surface()); - - DCHECK(!g_gl_context); - g_gl_context = this; - } - - GLNonOwnedCompatibilityContext(const GLNonOwnedCompatibilityContext&) = - delete; - GLNonOwnedCompatibilityContext& operator=( - const GLNonOwnedCompatibilityContext&) = delete; - - bool MakeCurrentImpl(gl::GLSurface* surface) override { - // A GLNonOwnedCompatibilityContext may have set the GetRealCurrent() - // pointer to itself, while re-using our EGL context. In these cases just - // call SetCurrent to restore expected GetRealContext(). - if (GetHandle() == eglGetCurrentContext()) { - if (surface) { - // No one should change the current EGL surface without also changing - // the context. - DCHECK(eglGetCurrentSurface(EGL_DRAW) == surface->GetHandle()); - } - - SetCurrent(surface); - return true; - } - - return gl::GLContextEGL::MakeCurrentImpl(surface); - } - - bool MakeCurrent() { return gl::GLContext::MakeCurrentDefault(); } - - static scoped_refptr<GLNonOwnedCompatibilityContext> GetOrCreateInstance() { - if (g_gl_context) - return base::WrapRefCounted(g_gl_context); - return base::WrapRefCounted(new GLNonOwnedCompatibilityContext); - } - - private: - ~GLNonOwnedCompatibilityContext() override { - DCHECK_EQ(g_gl_context, this); - g_gl_context = nullptr; - } -}; - -VulkanGLInterop::InFlightInteropDraw::InFlightInteropDraw( - AwVulkanContextProvider* vk_context_provider) - : vk_context_provider(vk_context_provider) {} - -VulkanGLInterop::InFlightInteropDraw::~InFlightInteropDraw() { - // If |draw_context| is valid, we encountered an error during Vk drawing and - // should call vkQueueWaitIdle to ensure safe shutdown. - bool encountered_error = !!draw_context; - if (encountered_error) { - // Clean up one-off objects which may have been left alive due to an error. - - // Clean up |ahb_skimage| first, as doing so generates Vk commands we need - // to flush before the vkQueueWaitIdle below. - if (ahb_skimage) { - ahb_skimage.reset(); - vk_context_provider->GetGrContext()->flushAndSubmit(); - } - // We encountered an error and are not sure when our Vk objects are safe to - // delete. VkQueueWaitIdle to ensure safety. - vkQueueWaitIdle(vk_context_provider->queue()); - if (draw_context) { - draw_context->releaseResources(); - draw_context.reset(); - } - if (post_draw_semaphore != VK_NULL_HANDLE) { - vkDestroySemaphore(vk_context_provider->device(), post_draw_semaphore, - nullptr); - post_draw_semaphore = VK_NULL_HANDLE; - } - } - DCHECK(!draw_context); - DCHECK(!ahb_skimage); - DCHECK(post_draw_semaphore == VK_NULL_HANDLE); - - // Clean up re-usable components that are expected to still be alive. - if (texture_id) - glDeleteTextures(1, &texture_id); - if (framebuffer_id) - glDeleteFramebuffersEXT(1, &framebuffer_id); - if (vulkan_image) { - vk_context_provider->GetDeviceQueue() - ->GetFenceHelper() - ->EnqueueVulkanObjectCleanupForSubmittedWork(std::move(vulkan_image)); - } -} - -VulkanGLInterop::VulkanGLInterop( - RenderThreadManager* render_thread_manager, - AwVulkanContextProvider* vulkan_context_provider) - : render_thread_manager_(render_thread_manager), - vulkan_context_provider_(vulkan_context_provider), - gl_context_(GLNonOwnedCompatibilityContext::GetOrCreateInstance()) { - DCHECK(render_thread_manager_); - DCHECK(vulkan_context_provider_); -} - -VulkanGLInterop::~VulkanGLInterop() { - // Clear the queue. - { auto queue = std::move(in_flight_interop_draws_); } - - gl_context_.reset(); -} - -void VulkanGLInterop::DrawVk(sk_sp<GrVkSecondaryCBDrawContext> draw_context, - sk_sp<SkColorSpace> color_space, - const HardwareRendererDrawParams& params, - const OverlaysParams& overlays_params) { - if (!gl_context_) - return; - - if (!gl_context_->MakeCurrent()) { - LOG(ERROR) << "Failed to make GL context current for drawing."; - return; - } - - // If |pending_draw_| is non-null, we called DrawVk twice without PostDrawVk. - DCHECK(!pending_draw_); - - // Use a temporary to automatically clean up if we hit a failure case. - std::unique_ptr<InFlightInteropDraw> pending_draw; - - // If we've exhausted our buffers, re-use an existing one. - // TODO(ericrk): Benchmark using more than 1 buffer. - if (in_flight_interop_draws_.size() >= 1 /* single buffering */) { - pending_draw = std::move(in_flight_interop_draws_.front()); - in_flight_interop_draws_.pop(); - } - - // If prev buffer is wrong size, just re-allocate. - if (pending_draw && - pending_draw->image_size != gfx::Size(params.width, params.height)) { - pending_draw.reset(); - } - - // If we weren't able to re-use a previous draw, create one. - if (!pending_draw) { - pending_draw = - std::make_unique<InFlightInteropDraw>(vulkan_context_provider_); - - AHardwareBuffer_Desc desc = {}; - desc.width = params.width; - desc.height = params.height; - desc.layers = 1; // number of images - // TODO(ericrk): Handle other formats. - desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; - desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER | - AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER | - AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | - AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; - AHardwareBuffer* buffer = nullptr; - base::AndroidHardwareBufferCompat::GetInstance().Allocate(&desc, &buffer); - if (!buffer) { - LOG(ERROR) << "Failed to allocate AHardwareBuffer for WebView rendering."; - return; - } - pending_draw->scoped_buffer = - base::android::ScopedHardwareBufferHandle::Adopt(buffer); - pending_draw->image_size = gfx::Size(params.width, params.height); - - // Create an EGLImage for the buffer. - pending_draw->egl_image = gpu::CreateEGLImageFromAHardwareBuffer( - pending_draw->scoped_buffer.get()); - if (!pending_draw->egl_image.is_valid()) { - LOG(ERROR) << "Failed to initialize EGLImage for AHardwareBuffer"; - return; - } - - glGenTextures(1, static_cast<GLuint*>(&pending_draw->texture_id)); - GLenum target = GL_TEXTURE_2D; - glBindTexture(target, pending_draw->texture_id); - glEGLImageTargetTexture2DOES(target, pending_draw->egl_image.get()); - glBindTexture(target, 0); - glGenFramebuffersEXT(1, &pending_draw->framebuffer_id); - glBindFramebufferEXT(GL_FRAMEBUFFER, pending_draw->framebuffer_id); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, pending_draw->texture_id, 0); - if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != - GL_FRAMEBUFFER_COMPLETE) { - LOG(ERROR) << "Failed to set up framebuffer for WebView GL drawing."; - return; - } - } - - // Ask GL to wait on any Vk sync_fd before writing. - gl::InsertEglFenceAndWait(std::move(pending_draw->sync_fd)); - - // Bind buffer and render with GL. - base::ScopedFD gl_done_fd; - { - glBindFramebufferEXT(GL_FRAMEBUFFER, pending_draw->framebuffer_id); - glViewport(0, 0, params.width, params.height); - glDisable(GL_STENCIL_TEST); - glDisable(GL_SCISSOR_TEST); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); - render_thread_manager_->DrawOnRT(/*save_restore=*/false, params, - overlays_params); - gl_done_fd = gl::CreateEglFenceAndExportFd(); - } - - pending_draw->draw_context = std::move(draw_context); - - // If we have a |gl_done_fd|, create a Skia GrBackendSemaphore from - // |gl_done_fd| and wait. - if (gl_done_fd.is_valid()) { - VkSemaphore gl_done_semaphore = - vulkan_context_provider_->GetVulkanImplementation() - ->ImportSemaphoreHandle( - vulkan_context_provider_->device(), - gpu::SemaphoreHandle( - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, - std::move(gl_done_fd))); - if (gl_done_semaphore == VK_NULL_HANDLE) { - LOG(ERROR) << "Could not create Vulkan semaphore for GL completion."; - return; - } - GrBackendSemaphore gr_semaphore; - gr_semaphore.initVulkan(gl_done_semaphore); - if (!pending_draw->draw_context->wait(1, &gr_semaphore)) { - // If wait returns false, we must clean up the |gl_done_semaphore|. - vkDestroySemaphore(vulkan_context_provider_->device(), gl_done_semaphore, - nullptr); - LOG(ERROR) << "Could not wait on GL completion semaphore."; - return; - } - } - - // Create a VkImage and import AHB. - if (!pending_draw->vulkan_image) { - auto handle = base::android::ScopedHardwareBufferHandle::Create( - pending_draw->scoped_buffer.get()); - gfx::GpuMemoryBufferHandle gmb_handle(std::move(handle)); - auto* device_queue = vulkan_context_provider_->GetDeviceQueue(); - auto vulkan_image = gpu::VulkanImage::CreateFromGpuMemoryBufferHandle( - device_queue, std::move(gmb_handle), - gfx::Size(params.width, params.height), VK_FORMAT_R8G8B8A8_UNORM, - /*usage=*/0, /*flags=*/0, /*image_tiling=*/VK_IMAGE_TILING_OPTIMAL, - /*queue_family_index=*/VK_QUEUE_FAMILY_EXTERNAL); - if (!vulkan_image) { - LOG(ERROR) << "Could not create VkImage from AHB."; - return; - } - - pending_draw->image_info = gpu::CreateGrVkImageInfo( - vulkan_image.get(), gfx::ColorSpace(*color_space)); - pending_draw->vulkan_image = std::move(vulkan_image); - } - - // Create an SkImage from AHB. - auto backend_texture = GrBackendTextures::MakeVk(params.width, params.height, - pending_draw->image_info); - pending_draw->ahb_skimage = SkImages::BorrowTextureFrom( - vulkan_context_provider_->GetGrContext(), backend_texture, - kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, - color_space); - if (!pending_draw->ahb_skimage) { - LOG(ERROR) << "Could not create SkImage from VkImage."; - return; - } - - // Draw the SkImage. - SkPaint paint; - paint.setBlendMode(SkBlendMode::kSrcOver); - pending_draw->draw_context->getCanvas()->drawImage( - pending_draw->ahb_skimage, 0, 0, SkSamplingOptions(), &paint); - pending_draw->draw_context->flush(); - - // Transfer |pending_draw| to |pending_draw_| for handling in - // PostDrawVkInterop. - pending_draw_ = std::move(pending_draw); -} - -void VulkanGLInterop::PostDrawVk() { - // Use a temporary to automatically clean up if we hit a failure case. - std::unique_ptr<InFlightInteropDraw> pending_draw = std::move(pending_draw_); - - if (!gl_context_ || !pending_draw) - return; - - // Get the final state of the SkImage so that we can pass this back to Skia - // during re-use. - GrBackendTexture backend_texture; - if (!SkImages::GetBackendTextureFromImage( - pending_draw->ahb_skimage, &backend_texture, - true /* flushPendingGrContextIO */)) { - LOG(ERROR) << "Could not get Vk backend texture."; - return; - } - GrVkImageInfo image_info; - if (!GrBackendTextures::GetVkImageInfo(backend_texture, &image_info)) { - LOG(ERROR) << "Could not get Vk image info."; - return; - } - - // Copy image layout to our cached image info. - pending_draw->image_info.fImageLayout = image_info.fImageLayout; - - // Release the SkImage so that Skia transitions it back to - // VK_QUEUE_FAMILY_EXTERNAL. - pending_draw->ahb_skimage.reset(); - - // Create a semaphore to track the image's transition back to external. - VkExportSemaphoreCreateInfo export_info; - export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; - export_info.pNext = nullptr; - export_info.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; - VkSemaphoreCreateInfo sem_info; - sem_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - sem_info.pNext = &export_info; - sem_info.flags = 0; - VkResult result = - vkCreateSemaphore(vulkan_context_provider_->device(), &sem_info, nullptr, - &pending_draw->post_draw_semaphore); - if (result != VK_SUCCESS) { - LOG(ERROR) << "Could not create VkSemaphore."; - return; - } - GrBackendSemaphore gr_post_draw_semaphore; - gr_post_draw_semaphore.initVulkan(pending_draw->post_draw_semaphore); - - // Flush so that we know the image's transition has been submitted and that - // the |post_draw_semaphore| is pending. - GrFlushInfo flushInfo; - flushInfo.fNumSemaphores = 1; - flushInfo.fSignalSemaphores = &gr_post_draw_semaphore; - GrSemaphoresSubmitted submitted = - vulkan_context_provider_->GetGrContext()->flush(flushInfo); - vulkan_context_provider_->GetGrContext()->submit(); - if (submitted != GrSemaphoresSubmitted::kYes) { - LOG(ERROR) << "Skia could not submit GrSemaphore."; - return; - } - gpu::SemaphoreHandle semaphore_handle = - vulkan_context_provider_->GetVulkanImplementation()->GetSemaphoreHandle( - vulkan_context_provider_->device(), - pending_draw->post_draw_semaphore); - if (!semaphore_handle.is_valid()) { - LOG(ERROR) << "Could not retrieve SyncFD from |post_draw_semaphore|."; - return; - } - pending_draw->sync_fd = semaphore_handle.TakeHandle(); - - gpu::VulkanFenceHelper* fence_helper = - vulkan_context_provider_->GetDeviceQueue()->GetFenceHelper(); - - fence_helper->EnqueueCleanupTaskForSubmittedWork(base::BindOnce( - &CleanupInFlightDraw, std::move(pending_draw->draw_context), - pending_draw->post_draw_semaphore)); - pending_draw->post_draw_semaphore = VK_NULL_HANDLE; - - // Add the |pending_draw| to |in_flight_interop_draws_|. - in_flight_interop_draws_.push(std::move(pending_draw)); - - // Process cleanup tasks and generate fences at the end of each PostDrawVk. - // TODO(ericrk): We'd ideally combine this with the flushAndSignalSemaphores - // above. - fence_helper->GenerateCleanupFence(); - fence_helper->ProcessCleanupTasks(); -} - -void VulkanGLInterop::MakeGLContextCurrentIgnoreFailure() { - if (gl_context_) - gl_context_->MakeCurrent(); -} - -} // namespace android_webview
diff --git a/android_webview/browser/gfx/vulkan_gl_interop.h b/android_webview/browser/gfx/vulkan_gl_interop.h deleted file mode 100644 index 37af8295..0000000 --- a/android_webview/browser/gfx/vulkan_gl_interop.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_BROWSER_GFX_VULKAN_GL_INTEROP_H_ -#define ANDROID_WEBVIEW_BROWSER_GFX_VULKAN_GL_INTEROP_H_ - -#include <memory> - -#include "android_webview/browser/gfx/aw_vulkan_context_provider.h" -#include "android_webview/public/browser/draw_fn.h" -#include "base/android/scoped_hardware_buffer_handle.h" -#include "base/containers/queue.h" -#include "base/files/scoped_file.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" -#include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/gpu/vk/GrVkTypes.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gl/scoped_egl_image.h" - -class GrVkSecondaryCBDrawContext; -class SkColorSpace; -class SkImage; - -namespace gpu { -class VulkanImage; -} - -namespace android_webview { - -class RenderThreadManager; -struct HardwareRendererDrawParams; -struct OverlaysParams; - -// With interop mode, we will render frames on AHBs with GL api, and then draw -// AHBs with Vulkan API on the final target. -// -// Lifetime: WebView -class VulkanGLInterop { - public: - VulkanGLInterop(RenderThreadManager* render_thread_manager, - AwVulkanContextProvider* vulkan_context_provider); - ~VulkanGLInterop(); - - void DrawVk(sk_sp<GrVkSecondaryCBDrawContext> draw_context, - sk_sp<SkColorSpace> color_space, - const HardwareRendererDrawParams& params, - const OverlaysParams& overlays_params); - void PostDrawVk(); - - // For clean up. - void MakeGLContextCurrentIgnoreFailure(); - - private: - class GLNonOwnedCompatibilityContext; - static GLNonOwnedCompatibilityContext* g_gl_context; - - // Struct which represents one in-flight draw for the Vk interop path. - struct InFlightInteropDraw { - explicit InFlightInteropDraw(AwVulkanContextProvider* vk_context_provider); - ~InFlightInteropDraw(); - - sk_sp<GrVkSecondaryCBDrawContext> draw_context; - VkFence post_draw_fence = VK_NULL_HANDLE; - VkSemaphore post_draw_semaphore = VK_NULL_HANDLE; - base::ScopedFD sync_fd; - gl::ScopedEGLImage egl_image; - gfx::Size image_size; - base::android::ScopedHardwareBufferHandle scoped_buffer; - sk_sp<SkImage> ahb_skimage; - uint32_t texture_id = 0; - uint32_t framebuffer_id = 0; - std::unique_ptr<gpu::VulkanImage> vulkan_image; - GrVkImageInfo image_info; - - // Used to clean up Vulkan objects. - raw_ptr<AwVulkanContextProvider> vk_context_provider; - }; - - raw_ptr<RenderThreadManager> const render_thread_manager_; - - raw_ptr<AwVulkanContextProvider> const vulkan_context_provider_; - - // GL context used to draw via GL in Vk interop path. - scoped_refptr<GLNonOwnedCompatibilityContext> gl_context_; - - // Queue of draw contexts pending cleanup. - base::queue<std::unique_ptr<InFlightInteropDraw>> in_flight_interop_draws_; - std::unique_ptr<InFlightInteropDraw> pending_draw_; -}; - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_GFX_VULKAN_GL_INTEROP_H_
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 2a76146f..5bb669e 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -149,10 +149,6 @@ Flag.baseFeature( "DefaultPassthroughCommandDecoder", "Use the passthrough GLES2 command decoder."), Flag.baseFeature( - GpuFeatures.WEBVIEW_VULKAN, - "Use Vulkan for composite. Requires Android device and OS support. May crash " - + "if enabled on unsupported device."), - Flag.baseFeature( GpuFeatures.WEBVIEW_SURFACE_CONTROL, "Use SurfaceControl. Requires WebViewThreadSafeMedia and Android device and OS " + "support."),
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index 5d1e8bf..a0271996 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -222,8 +222,8 @@ features.EnableIfNotSet(::features::kPrivacySandboxAdsAPIsOverride); } - // WebView uses kWebViewVulkan to control vulkan. Pre-emptively disable - // kVulkan in case it becomes enabled by default. + // WebView uses kWebViewDrawFunctorUsesVulkan to control vulkan. + // Pre-emptively disable kVulkan in case it becomes enabled by default. features.DisableIfNotSet(::features::kVulkan); features.DisableIfNotSet(::features::kWebPayments);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 05237027..2c9afe1f 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1727,14 +1727,10 @@ "system/network/fake_network_detailed_network_view.h", "system/network/fake_network_detailed_view_delegate.cc", "system/network/fake_network_detailed_view_delegate.h", - "system/network/fake_network_list_mobile_header_view.cc", - "system/network/fake_network_list_mobile_header_view.h", "system/network/fake_network_list_network_header_view_delegate.cc", "system/network/fake_network_list_network_header_view_delegate.h", "system/network/fake_network_list_tether_hosts_header_view.cc", "system/network/fake_network_list_tether_hosts_header_view.h", - "system/network/fake_network_list_wifi_header_view.cc", - "system/network/fake_network_list_wifi_header_view.h", "system/network/managed_sim_lock_notifier.cc", "system/network/managed_sim_lock_notifier.h", "system/network/network_detailed_network_view.cc", @@ -1764,8 +1760,6 @@ "system/network/network_list_item_view.h", "system/network/network_list_mobile_header_view.cc", "system/network/network_list_mobile_header_view.h", - "system/network/network_list_mobile_header_view_impl.cc", - "system/network/network_list_mobile_header_view_impl.h", "system/network/network_list_network_header_view.cc", "system/network/network_list_network_header_view.h", "system/network/network_list_network_item_view.cc", @@ -1778,8 +1772,6 @@ "system/network/network_list_view_controller_impl.h", "system/network/network_list_wifi_header_view.cc", "system/network/network_list_wifi_header_view.h", - "system/network/network_list_wifi_header_view_impl.cc", - "system/network/network_list_wifi_header_view_impl.h", "system/network/network_observer.h", "system/network/network_state_list_detailed_view.cc", "system/network/network_state_list_detailed_view.h",
diff --git a/ash/app_list/views/app_list_view_pixeltest.cc b/ash/app_list/views/app_list_view_pixeltest.cc index d422807..19dc2e8 100644 --- a/ash/app_list/views/app_list_view_pixeltest.cc +++ b/ash/app_list/views/app_list_view_pixeltest.cc
@@ -347,9 +347,9 @@ event_generator->ClickLeftButton(); } - ASSERT_TRUE(search_box_view->iph_view()); + ASSERT_TRUE(search_box_view->GetIphView()); ViewDrawnWaiter view_drawn_waiter; - view_drawn_waiter.Wait(search_box_view->iph_view()); + view_drawn_waiter.Wait(search_box_view->GetIphView()); UseFixedPlaceholderTextAndHideCursor(search_box_view); EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 70c78d9..714c010 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -1000,7 +1000,7 @@ // Horizontal margins are selected to match search box icon's vertical // margins. Space used for iph should be ignored. const int iph_height = - iph_view() ? iph_view()->GetPreferredSize().height() : 0; + GetIphView() ? GetIphView()->GetPreferredSize().height() : 0; const int horizontal_spacing = (target_state_height - iph_height - GetSearchBoxIconSize()) / 2; const int horizontal_right_padding = @@ -1198,6 +1198,12 @@ } void SearchBoxView::AssistantButtonPressed() { + // If Launcher search IPH view is showing, notify it that the Assistant + // button is pressed. + if (GetIphView()) { + GetIphView()->NotifyAssistantButtonPressedEvent(); + } + delegate_->AssistantButtonPressed(); } @@ -1657,7 +1663,7 @@ ->show_assistant_button(); const bool would_trigger_iph = AppListModelProvider::Get()->search_model()->would_trigger_iph(); - const bool is_iph_showing = iph_view() != nullptr; + const bool is_iph_showing = GetIphView() != nullptr; const bool should_show_iph = show_assistant_button && is_iph_allowed_ && !HasValidQuery() &&
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index e9dedac..b331aedd 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -431,8 +431,7 @@ } gfx::Size SearchResultPageView::GetPreferredSearchBoxSize() const { - raw_ptr<const views::View> iph_view = - search_view_->search_box_view()->iph_view(); + auto* iph_view = search_view_->search_box_view()->GetIphView(); const int iph_height = iph_view ? iph_view->GetPreferredSize().height() : 0; return gfx::Size(kWidth, kActiveSearchBoxHeight + iph_height);
diff --git a/ash/assistant/ui/main_stage/launcher_search_iph_view.cc b/ash/assistant/ui/main_stage/launcher_search_iph_view.cc index 5f49282e..55869ac1 100644 --- a/ash/assistant/ui/main_stage/launcher_search_iph_view.cc +++ b/ash/assistant/ui/main_stage/launcher_search_iph_view.cc
@@ -184,6 +184,12 @@ } } +void LauncherSearchIphView::NotifyAssistantButtonPressedEvent() { + if (scoped_iph_session_) { + scoped_iph_session_->NotifyEvent(kIphEventNameAssistantClick); + } +} + std::vector<raw_ptr<ChipView>> LauncherSearchIphView::GetChipsForTesting() { return chips_; } @@ -197,9 +203,7 @@ } void LauncherSearchIphView::OpenAssistantPage() { - if (scoped_iph_session_) { - scoped_iph_session_->NotifyEvent(kIphEventNameAssistantClick); - } + NotifyAssistantButtonPressedEvent(); delegate_->OpenAssistantPage(); }
diff --git a/ash/assistant/ui/main_stage/launcher_search_iph_view.h b/ash/assistant/ui/main_stage/launcher_search_iph_view.h index 2e314e5..43d9604 100644 --- a/ash/assistant/ui/main_stage/launcher_search_iph_view.h +++ b/ash/assistant/ui/main_stage/launcher_search_iph_view.h
@@ -59,6 +59,8 @@ // views::View: void VisibilityChanged(views::View* starting_from, bool is_visible) override; + void NotifyAssistantButtonPressedEvent(); + std::vector<raw_ptr<ChipView>> GetChipsForTesting(); private:
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index edbfdb8d..655ee28 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -594,6 +594,10 @@ const char kFakeDriveFsLauncherSocketPath[] = "fake-drivefs-launcher-socket-path"; +// Indicates that the cryptohome keys are evicted and lock screen should message +// cryptohomed to run full authentication and restore filesystem keys. +const char kRestoreKeyOnLockScreen[] = "restore-key-on-lock-screen"; + // Fingerprint sensor location indicates the physical sensor's location. The // value is a string with possible values: "power-button-top-left", // "keyboard-bottom-left", keyboard-bottom-right", "keyboard-top-right".
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index afc2457f..a999a27 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -201,6 +201,7 @@ extern const char kFakeDriveFsLauncherChrootPath[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFakeDriveFsLauncherSocketPath[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kRestoreKeyOnLockScreen[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFingerprintSensorLocation[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kFirstExecAfterBoot[]; COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h index 4901be0..d406bdfb 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -234,6 +234,14 @@ const SeaPenImage& sea_pen_image, SetWallpaperCallback callback) = 0; + // Sets the recently used Sea Pen wallpaper as system wallpaper for + // user with `account_id`. + // Calls `callback` with boolean success. Can fail if `account_id` is not + // allowed to set wallpaper, or the image failed to decode. + virtual void SetSeaPenWallpaperFromFile(const AccountId& account_id, + const base::FilePath& file_path, + SetWallpaperCallback callback) = 0; + // Confirms the wallpaper being previewed to be set as the actual user // wallpaper. Must be called in preview mode. virtual void ConfirmPreviewWallpaper() = 0;
diff --git a/ash/search_box/BUILD.gn b/ash/search_box/BUILD.gn index a407906..f497dd2 100644 --- a/ash/search_box/BUILD.gn +++ b/ash/search_box/BUILD.gn
@@ -14,6 +14,7 @@ ] deps = [ + "//ash/assistant/ui", "//ash/public/cpp", "//ash/strings", "//ash/style",
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 622cb7c..c1208ea 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "ash/assistant/ui/main_stage/launcher_search_iph_view.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/ash_typography.h" #include "ash/public/cpp/style/color_provider.h" @@ -554,8 +555,9 @@ return search_icon_; } -void SearchBoxViewBase::SetIphView(std::unique_ptr<views::View> view) { - if (iph_view()) { +void SearchBoxViewBase::SetIphView( + std::unique_ptr<LauncherSearchIphView> view) { + if (GetIphView()) { DCHECK(false) << "SetIphView gets called with an IPH view being shown."; DeleteIphView(); @@ -564,8 +566,19 @@ iph_view_tracker_.SetView(main_container_->AddChildView(std::move(view))); } +LauncherSearchIphView* SearchBoxViewBase::GetIphView() { + views::View* view = iph_view_tracker_.view(); + if (!view) { + return nullptr; + } + + CHECK(views::IsViewClass<LauncherSearchIphView>(view)) + << "Only LaunchserSearchIph view is supported now"; + return static_cast<LauncherSearchIphView*>(view); +} + void SearchBoxViewBase::DeleteIphView() { - main_container_->RemoveChildViewT(iph_view()); + main_container_->RemoveChildViewT(GetIphView()); } void SearchBoxViewBase::TriggerSearch() {
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h index 60d956a9..c8bb5560 100644 --- a/ash/search_box/search_box_view_base.h +++ b/ash/search_box/search_box_view_base.h
@@ -35,6 +35,7 @@ namespace ash { +class LauncherSearchIphView; class SearchBoxImageButton; class SearchIconImageView; @@ -93,9 +94,9 @@ views::ImageView* search_icon(); views::Textfield* search_box() { return search_box_; } - void SetIphView(std::unique_ptr<views::View> iph_view); + void SetIphView(std::unique_ptr<LauncherSearchIphView> iph_view); + LauncherSearchIphView* GetIphView(); void DeleteIphView(); - raw_ptr<views::View> iph_view() { return iph_view_tracker_.view(); } // Called when the query in the search box textfield changes. The search box // implementation is expected to handle the new query.
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb index c5887bc..83889cc5 100644 --- a/ash/strings/ash_strings_en-GB.xtb +++ b/ash/strings/ash_strings_en-GB.xtb
@@ -1683,6 +1683,13 @@ <translation id="7893503627044934815">Don't want this file shown</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">You pressed the keyboard shortcut for screen rotation. Do you want to rotate the screen?</translation> +<translation id="7897626842031123113">Status tray, time <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">Swap the windows</translation> <translation id="7901405293566323524">Phone Hub</translation> <translation id="7902625623987030061">Touch the fingerprint sensor</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb index a644bc9..eed7a38 100644 --- a/ash/strings/ash_strings_fil.xtb +++ b/ash/strings/ash_strings_fil.xtb
@@ -650,6 +650,7 @@ <translation id="3659667652322717492">Puwede mong baguhin ang gawi ng mikropono anumang oras sa ibang pagkakataon.</translation> <translation id="3659814201068740063">Mga <ph name="TIME_LEFT" /> ang natitira (<ph name="PERCENTAGE" />%). Isaksak ang iyong device.</translation> +<translation id="3660860940251915011">I-toggle ang mataas na visibility ng <ph name="FEATURE_NAME" /></translation> <translation id="366222428570480733">Pinapamahalaang user na <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3666266999138159418">Mag-swipe para i-hide ang iyong naka-float na window</translation> <translation id="367531336287639526">Piliin ang unang icon sa kaliwa ng address bar</translation> @@ -980,6 +981,7 @@ <ph name="NOTIFICATION_1" />, <ph name="NOTIFICATION_2" />, <ph name="NUM_OTHER_NOTIFICATION" /></translation> +<translation id="4981175556418720939">Binago noong <ph name="DATE_AND_TIME" /></translation> <translation id="4987738733603015246">Desk 16</translation> <translation id="4989163558385430922">Tingnan lahat</translation> <translation id="5003993274120026347">Susunod na pangungusap</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb index 3c70549..4184332 100644 --- a/ash/strings/ash_strings_ja.xtb +++ b/ash/strings/ash_strings_ja.xtb
@@ -1684,6 +1684,13 @@ <translation id="7893503627044934815">このファイルの表示を希望しない</translation> <translation id="7895348134893321514">トート</translation> <translation id="7897375687985782769">画面回転のキーボード ショートカットを押しました。画面を回転しますか?</translation> +<translation id="7897626842031123113">ステータス トレイ、時間 <ph name="TIME" />、 + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />、 + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">ウィンドウを入れ替える</translation> <translation id="7901405293566323524">スマートフォン ハブ</translation> <translation id="7902625623987030061">指紋認証センサーをタッチ</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb index d4c7b45f..2b337f3 100644 --- a/ash/strings/ash_strings_lt.xtb +++ b/ash/strings/ash_strings_lt.xtb
@@ -1683,6 +1683,13 @@ <translation id="7893503627044934815">Nenoriu, kad šis failas būtų rodomas</translation> <translation id="7895348134893321514">Perkelti</translation> <translation id="7897375687985782769">Paspaudėte ekrano pasukimo spartųjį klavišą. Ar norite pasukti ekraną?</translation> +<translation id="7897626842031123113">Būsenos dėklas, laikas <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">Sukeisti langus</translation> <translation id="7901405293566323524">Phone Hub</translation> <translation id="7902625623987030061">Palieskite kontrolinio kodo jutiklį</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb index 59aea1f..f0452ff 100644 --- a/ash/strings/ash_strings_ms.xtb +++ b/ash/strings/ash_strings_ms.xtb
@@ -650,6 +650,7 @@ <translation id="3659667652322717492">Anda boleh mengubah gelagat mikrofon pada bila-bila masa nanti.</translation> <translation id="3659814201068740063">Kira-kira <ph name="TIME_LEFT" /> lagi (<ph name="PERCENTAGE" />%). Sambungkan peranti anda kepada sumber kuasa.</translation> +<translation id="3660860940251915011">Togol keterlihatan tinggi <ph name="FEATURE_NAME" /></translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> Pengguna terurus</translation> <translation id="3666266999138159418">Leret untuk menyembunyikan tetingkap terapung anda</translation> <translation id="367531336287639526">Pilih ikon pertama pada sebelah kiri bar alamat</translation> @@ -980,6 +981,7 @@ <ph name="NOTIFICATION_1" />, <ph name="NOTIFICATION_2" />, <ph name="NUM_OTHER_NOTIFICATION" /></translation> +<translation id="4981175556418720939">Diubah suai <ph name="DATE_AND_TIME" /></translation> <translation id="4987738733603015246">Meja 16</translation> <translation id="4989163558385430922">Lihat semua</translation> <translation id="5003993274120026347">Ayat seterusnya</translation> @@ -1683,6 +1685,13 @@ <translation id="7893503627044934815">Tidak mahu fail ini ditunjukkan</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">Anda menekan pintasan papan kekunci untuk putaran skrin. Adakah anda ingin memutarkan skrin?</translation> +<translation id="7897626842031123113">Dulang status, masa <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">Tukar tetingkap</translation> <translation id="7901405293566323524">Hab Telefon</translation> <translation id="7902625623987030061">Sentuh penderia cap jari</translation>
diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb index 1777e91..6e3925a 100644 --- a/ash/strings/ash_strings_ne.xtb +++ b/ash/strings/ash_strings_ne.xtb
@@ -1683,6 +1683,13 @@ <translation id="7893503627044934815">मलाई यो फाइल नदेखाइयोस्</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">तपाईंले स्क्रिन घुमाउनेसम्बन्धी किबोर्ड सर्टकट थिच्नुभयो। तपाईं स्क्रिन घुमाउन चाहनुहुन्छ?</translation> +<translation id="7897626842031123113">स्ट्याटस ट्रे, समय <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">विन्डोहरू अदलबदल गर्नुहोस्</translation> <translation id="7901405293566323524">फोन हब</translation> <translation id="7902625623987030061">फिंगरप्रिन्ट सेन्सरमा छुनुहोस्</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb index 5195b0fb..65d72089 100644 --- a/ash/strings/ash_strings_th.xtb +++ b/ash/strings/ash_strings_th.xtb
@@ -646,6 +646,7 @@ <translation id="3659667652322717492">คุณเปลี่ยนลักษณะการทำงานของไมค์ได้ทุกเมื่อในภายหลัง</translation> <translation id="3659814201068740063">เหลืออีกประมาณ <ph name="TIME_LEFT" /> (<ph name="PERCENTAGE" />%) เชื่อมต่ออุปกรณ์กับแหล่งจ่ายไฟ</translation> +<translation id="3660860940251915011">เปิด/ปิดระดับการเข้าถึงสูงของ <ph name="FEATURE_NAME" /></translation> <translation id="366222428570480733">ผู้ใช้ที่ได้รับการจัดการ <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3666266999138159418">ปัดเพื่อซ่อนหน้าต่างแบบลอย</translation> <translation id="367531336287639526">เลือกไอคอนแรกทางด้านซ้ายของแถบที่อยู่</translation> @@ -975,6 +976,7 @@ <ph name="NOTIFICATION_1" />, <ph name="NOTIFICATION_2" />, <ph name="NUM_OTHER_NOTIFICATION" /></translation> +<translation id="4981175556418720939">แก้ไขเมื่อ <ph name="DATE_AND_TIME" /></translation> <translation id="4987738733603015246">เดสก์ที่ 16</translation> <translation id="4989163558385430922">ดูทั้งหมด</translation> <translation id="5003993274120026347">ประโยคถัดไป</translation>
diff --git a/ash/strings/ash_strings_zh-HK.xtb b/ash/strings/ash_strings_zh-HK.xtb index 8e9edd4..e194402e 100644 --- a/ash/strings/ash_strings_zh-HK.xtb +++ b/ash/strings/ash_strings_zh-HK.xtb
@@ -1681,6 +1681,13 @@ <translation id="7893503627044934815">不想顯示此檔案</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">您已按下螢幕旋轉的鍵盤快速鍵。確定要旋轉螢幕嗎?</translation> +<translation id="7897626842031123113">狀態匣,時間 <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">切換左右視窗位置</translation> <translation id="7901405293566323524">Phone Hub</translation> <translation id="7902625623987030061">請輕觸指紋感應器</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb index 91c509c..cf9c607 100644 --- a/ash/strings/ash_strings_zh-TW.xtb +++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -1679,6 +1679,13 @@ <translation id="7893503627044934815">不想看到這個檔案</translation> <translation id="7895348134893321514">Tote</translation> <translation id="7897375687985782769">你按下了旋轉螢幕的鍵盤快速鍵。確定要旋轉螢幕嗎?</translation> +<translation id="7897626842031123113">狀態匣,時間 <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="CHANNEL" /> + <ph name="NETWORK" />, + <ph name="MANAGED" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="7901190436359881020">交換視窗</translation> <translation id="7901405293566323524">Phone Hub</translation> <translation id="7902625623987030061">請輕觸指紋感應器</translation>
diff --git a/ash/system/network/fake_network_detailed_network_view.cc b/ash/system/network/fake_network_detailed_network_view.cc index e78831f..e66cf60 100644 --- a/ash/system/network/fake_network_detailed_network_view.cc +++ b/ash/system/network/fake_network_detailed_network_view.cc
@@ -4,15 +4,13 @@ #include "ash/system/network/fake_network_detailed_network_view.h" -#include "ash/system/network/fake_network_list_mobile_header_view.h" #include "ash/system/network/fake_network_list_tether_hosts_header_view.h" -#include "ash/system/network/fake_network_list_wifi_header_view.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_list_item_view.h" -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/network_list_view_controller_impl.h" -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "ui/base/metadata/metadata_impl_macros.h" namespace ash { @@ -52,8 +50,8 @@ NetworkListWifiHeaderView* FakeNetworkDetailedNetworkView::AddWifiSectionHeader() { - std::unique_ptr<FakeNetworkListWifiHeaderView> wifi_header_view = - std::make_unique<FakeNetworkListWifiHeaderView>(/*delegate=*/nullptr); + std::unique_ptr<NetworkListWifiHeaderView> wifi_header_view = + std::make_unique<NetworkListWifiHeaderView>(/*delegate=*/nullptr); wifi_header_view->SetID(static_cast<int>( NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: kWifiSectionHeader)); @@ -68,8 +66,8 @@ NetworkListMobileHeaderView* FakeNetworkDetailedNetworkView::AddMobileSectionHeader() { - std::unique_ptr<FakeNetworkListMobileHeaderView> mobile_header_view = - std::make_unique<FakeNetworkListMobileHeaderView>(/*delegate=*/nullptr); + std::unique_ptr<NetworkListMobileHeaderView> mobile_header_view = + std::make_unique<NetworkListMobileHeaderView>(/*delegate=*/nullptr); mobile_header_view->SetID(static_cast<int>( NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: kMobileSectionHeader));
diff --git a/ash/system/network/fake_network_detailed_network_view.h b/ash/system/network/fake_network_detailed_network_view.h index b99cc89e..7ed1f8a 100644 --- a/ash/system/network/fake_network_detailed_network_view.h +++ b/ash/system/network/fake_network_detailed_network_view.h
@@ -8,9 +8,9 @@ #include "ash/ash_export.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_list_item_view.h" -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_item_view.h" -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "base/memory/raw_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/view.h"
diff --git a/ash/system/network/fake_network_list_mobile_header_view.cc b/ash/system/network/fake_network_list_mobile_header_view.cc deleted file mode 100644 index 9c73acf..0000000 --- a/ash/system/network/fake_network_list_mobile_header_view.cc +++ /dev/null
@@ -1,30 +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 "ash/system/network/fake_network_list_mobile_header_view.h" - -#include "ash/system/network/network_list_mobile_header_view.h" -#include "ash/system/network/network_list_network_header_view.h" -#include "ui/base/metadata/metadata_impl_macros.h" - -namespace ash { - -FakeNetworkListMobileHeaderView::FakeNetworkListMobileHeaderView( - NetworkListNetworkHeaderView::Delegate* delegate) - : NetworkListMobileHeaderView(delegate) {} - -FakeNetworkListMobileHeaderView::~FakeNetworkListMobileHeaderView() = default; - -void FakeNetworkListMobileHeaderView::SetToggleState(bool enabled, - bool is_on, - bool animate_toggle) { - is_toggle_enabled_ = enabled; - is_toggle_on_ = is_on; - set_toggle_state_count_++; -} - -BEGIN_METADATA(FakeNetworkListMobileHeaderView) -END_METADATA - -} // namespace ash
diff --git a/ash/system/network/fake_network_list_mobile_header_view.h b/ash/system/network/fake_network_list_mobile_header_view.h deleted file mode 100644 index 218cc7a..0000000 --- a/ash/system/network/fake_network_list_mobile_header_view.h +++ /dev/null
@@ -1,47 +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. - -#ifndef ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_MOBILE_HEADER_VIEW_H_ -#define ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_MOBILE_HEADER_VIEW_H_ - -#include "ash/ash_export.h" -#include "ash/system/network/network_list_mobile_header_view.h" -#include "ash/system/network/network_list_network_header_view.h" -#include "ui/base/metadata/metadata_header_macros.h" - -namespace ash { - -// Fake implementation of NetworkListMobileHeaderView -class ASH_EXPORT FakeNetworkListMobileHeaderView - : public NetworkListMobileHeaderView { - METADATA_HEADER(FakeNetworkListMobileHeaderView, NetworkListMobileHeaderView) - - public: - explicit FakeNetworkListMobileHeaderView( - NetworkListNetworkHeaderView::Delegate* delegate); - FakeNetworkListMobileHeaderView(const FakeNetworkListMobileHeaderView&) = - delete; - FakeNetworkListMobileHeaderView& operator=( - const FakeNetworkListMobileHeaderView&) = delete; - ~FakeNetworkListMobileHeaderView() override; - - bool is_toggle_enabled() { return is_toggle_enabled_; } - - bool is_toggle_on() { return is_toggle_on_; } - - size_t set_toggle_state_count() { return set_toggle_state_count_; } - - private: - // NetworkListNetworkHeaderView: - void SetToggleState(bool enabled, bool is_on, bool animate_toggle) override; - - - bool is_toggle_enabled_; - bool is_toggle_on_; - size_t set_toggle_state_count_; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_MOBIL_HEADER_VIEW_H_
diff --git a/ash/system/network/fake_network_list_wifi_header_view.cc b/ash/system/network/fake_network_list_wifi_header_view.cc deleted file mode 100644 index da9e0a40..0000000 --- a/ash/system/network/fake_network_list_wifi_header_view.cc +++ /dev/null
@@ -1,30 +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 "ash/system/network/fake_network_list_wifi_header_view.h" - -#include "ash/system/network/network_list_network_header_view.h" -#include "ash/system/network/network_list_wifi_header_view.h" -#include "ui/base/metadata/metadata_impl_macros.h" - -namespace ash { - -FakeNetworkListWifiHeaderView::FakeNetworkListWifiHeaderView( - NetworkListNetworkHeaderView::Delegate* delegate) - : NetworkListWifiHeaderView(delegate) {} - -FakeNetworkListWifiHeaderView::~FakeNetworkListWifiHeaderView() = default; - -void FakeNetworkListWifiHeaderView::SetToggleState(bool enabled, - bool is_on, - bool animate_toggle) { - is_toggle_enabled_ = enabled; - is_toggle_on_ = is_on; - set_toggle_state_count_++; -} - -BEGIN_METADATA(FakeNetworkListWifiHeaderView) -END_METADATA - -} // namespace ash
diff --git a/ash/system/network/fake_network_list_wifi_header_view.h b/ash/system/network/fake_network_list_wifi_header_view.h deleted file mode 100644 index d6c32a7d..0000000 --- a/ash/system/network/fake_network_list_wifi_header_view.h +++ /dev/null
@@ -1,45 +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. - -#ifndef ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_WIFI_HEADER_VIEW_H_ -#define ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_WIFI_HEADER_VIEW_H_ - -#include "ash/ash_export.h" -#include "ash/system/network/network_list_network_header_view.h" -#include "ash/system/network/network_list_wifi_header_view.h" -#include "ui/base/metadata/metadata_header_macros.h" - -namespace ash { - -// Fake implementation of NetworkListWifiHeaderView -class ASH_EXPORT FakeNetworkListWifiHeaderView - : public NetworkListWifiHeaderView { - METADATA_HEADER(FakeNetworkListWifiHeaderView, NetworkListWifiHeaderView) - - public: - explicit FakeNetworkListWifiHeaderView( - NetworkListNetworkHeaderView::Delegate* delegate); - FakeNetworkListWifiHeaderView(const FakeNetworkListWifiHeaderView&) = delete; - FakeNetworkListWifiHeaderView& operator=( - const FakeNetworkListWifiHeaderView&) = delete; - ~FakeNetworkListWifiHeaderView() override; - - bool is_toggle_enabled() { return is_toggle_enabled_; } - - bool is_toggle_on() { return is_toggle_on_; } - - size_t set_toggle_state_count() { return set_toggle_state_count_; } - - private: - // NetworkListNetworkHeaderView: - void SetToggleState(bool enabled, bool visible, bool animate_toggle) override; - - bool is_toggle_enabled_; - bool is_toggle_on_; - size_t set_toggle_state_count_; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_NETWORK_FAKE_NETWORK_LIST_WIFI_HEADER_VIEW_H_
diff --git a/ash/system/network/network_detailed_network_view.h b/ash/system/network/network_detailed_network_view.h index 6e491a3..0dceb7c8 100644 --- a/ash/system/network/network_detailed_network_view.h +++ b/ash/system/network/network_detailed_network_view.h
@@ -7,11 +7,11 @@ #include "ash/ash_export.h" #include "ash/system/network/network_detailed_view.h" -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_header_view.h" #include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/network_list_tether_hosts_header_view.h" -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "ash/system/tray/hover_highlight_view.h" #include "base/memory/raw_ptr.h" #include "ui/views/view.h"
diff --git a/ash/system/network/network_detailed_network_view_impl.cc b/ash/system/network/network_detailed_network_view_impl.cc index faed1302..601f9fa7 100644 --- a/ash/system/network/network_detailed_network_view_impl.cc +++ b/ash/system/network/network_detailed_network_view_impl.cc
@@ -15,10 +15,10 @@ #include "ash/style/typography.h" #include "ash/system/model/system_tray_model.h" #include "ash/system/network/network_detailed_view.h" -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/network_list_tether_hosts_header_view.h" -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "ash/system/network/network_utils.h" #include "ash/system/network/tray_network_state_model.h" #include "ash/system/tray/detailed_view_delegate.h" @@ -162,7 +162,7 @@ kBetweenContainerMargins); } return wifi_top_container_->AddChildView( - std::make_unique<NetworkListWifiHeaderViewImpl>(/*delegate=*/this)); + std::make_unique<NetworkListWifiHeaderView>(/*delegate=*/this)); } NetworkListMobileHeaderView* @@ -174,7 +174,7 @@ mobile_top_container_->SetBorderInsets(kTopContainerBorder); } return mobile_top_container_->AddChildView( - std::make_unique<NetworkListMobileHeaderViewImpl>(/*delegate=*/this)); + std::make_unique<NetworkListMobileHeaderView>(/*delegate=*/this)); } NetworkListTetherHostsHeaderView*
diff --git a/ash/system/network/network_detailed_network_view_impl.h b/ash/system/network/network_detailed_network_view_impl.h index 150aab7..f6bc8b7 100644 --- a/ash/system/network/network_detailed_network_view_impl.h +++ b/ash/system/network/network_detailed_network_view_impl.h
@@ -8,10 +8,10 @@ #include "ash/ash_export.h" #include "ash/style/rounded_container.h" #include "ash/system/network/network_detailed_network_view.h" -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/network_list_tether_hosts_header_view.h" -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "base/memory/raw_ptr.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/views/view.h"
diff --git a/ash/system/network/network_list_mobile_header_view.cc b/ash/system/network/network_list_mobile_header_view.cc index 673206e..db7ef7c 100644 --- a/ash/system/network/network_list_mobile_header_view.cc +++ b/ash/system/network/network_list_mobile_header_view.cc
@@ -3,10 +3,12 @@ // found in the LICENSE file. #include "ash/system/network/network_list_mobile_header_view.h" - #include "ash/resources/vector_icons/vector_icons.h" + #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_list_network_header_view.h" +#include "ash/system/tray/hover_highlight_view.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" namespace ash { @@ -19,7 +21,24 @@ NetworkListMobileHeaderView::~NetworkListMobileHeaderView() = default; -BEGIN_METADATA(NetworkListMobileHeaderView, NetworkListNetworkHeaderView) +void NetworkListMobileHeaderView::SetToggleState(bool enabled, + bool is_on, + bool animate_toggle) { + std::u16string tooltip_text = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_NETWORK_TOGGLE_MOBILE, + l10n_util::GetStringUTF16( + is_on ? IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_ENABLED + : IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLED)); + entry_row()->SetTooltipText(tooltip_text); + toggle()->SetTooltipText(tooltip_text); + NetworkListNetworkHeaderView::SetToggleState(enabled, is_on, animate_toggle); +} + +void NetworkListMobileHeaderView::OnToggleToggled(bool is_on) { + delegate()->OnMobileToggleClicked(is_on); +} + +BEGIN_METADATA(NetworkListMobileHeaderView) END_METADATA } // namespace ash
diff --git a/ash/system/network/network_list_mobile_header_view.h b/ash/system/network/network_list_mobile_header_view.h index 692a56e..3ad4e49 100644 --- a/ash/system/network/network_list_mobile_header_view.h +++ b/ash/system/network/network_list_mobile_header_view.h
@@ -7,24 +7,30 @@ #include "ash/ash_export.h" #include "ash/system/network/network_list_network_header_view.h" -#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/metadata/metadata_header_macros.h" namespace ash { -// This class is the interface used to create network list header for Mobile -// networks, and is responsible for the creation of mobile-specific buttons. -// TODO(b/251724646): remove this interface after the QsRevamp clean up. +// Creates network list header for Mobile networks. class ASH_EXPORT NetworkListMobileHeaderView : public NetworkListNetworkHeaderView { - public: METADATA_HEADER(NetworkListMobileHeaderView); + public: explicit NetworkListMobileHeaderView( NetworkListNetworkHeaderView::Delegate* delegate); NetworkListMobileHeaderView(const NetworkListMobileHeaderView&) = delete; NetworkListMobileHeaderView& operator=(const NetworkListMobileHeaderView&) = delete; ~NetworkListMobileHeaderView() override; + + // NetworkListNetworkHeaderView: + void SetToggleState(bool enabled, bool is_on, bool animate_toggle) override; + void OnToggleToggled(bool is_on) override; + + private: + friend class NetworkListMobileHeaderViewTest; + friend class NetworkListViewControllerTest; }; } // namespace ash
diff --git a/ash/system/network/network_list_mobile_header_view_impl.cc b/ash/system/network/network_list_mobile_header_view_impl.cc deleted file mode 100644 index 33864586..0000000 --- a/ash/system/network/network_list_mobile_header_view_impl.cc +++ /dev/null
@@ -1,42 +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 "ash/system/network/network_list_mobile_header_view_impl.h" - -#include "ash/strings/grit/ash_strings.h" -#include "ash/system/network/network_list_mobile_header_view.h" -#include "ash/system/network/network_list_network_header_view.h" -#include "ash/system/tray/hover_highlight_view.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" - -namespace ash { - -NetworkListMobileHeaderViewImpl::NetworkListMobileHeaderViewImpl( - NetworkListNetworkHeaderView::Delegate* delegate) - : NetworkListMobileHeaderView(delegate) {} - -NetworkListMobileHeaderViewImpl::~NetworkListMobileHeaderViewImpl() = default; - -void NetworkListMobileHeaderViewImpl::SetToggleState(bool enabled, - bool is_on, - bool animate_toggle) { - std::u16string tooltip_text = l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_TOGGLE_MOBILE, - l10n_util::GetStringUTF16( - is_on ? IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_ENABLED - : IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLED)); - entry_row()->SetTooltipText(tooltip_text); - toggle()->SetTooltipText(tooltip_text); - NetworkListMobileHeaderView::SetToggleState(enabled, is_on, animate_toggle); -} - -void NetworkListMobileHeaderViewImpl::OnToggleToggled(bool is_on) { - delegate()->OnMobileToggleClicked(is_on); -} - -BEGIN_METADATA(NetworkListMobileHeaderViewImpl) -END_METADATA - -} // namespace ash
diff --git a/ash/system/network/network_list_mobile_header_view_impl.h b/ash/system/network/network_list_mobile_header_view_impl.h deleted file mode 100644 index 44d7137..0000000 --- a/ash/system/network/network_list_mobile_header_view_impl.h +++ /dev/null
@@ -1,41 +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. - -#ifndef ASH_SYSTEM_NETWORK_NETWORK_LIST_MOBILE_HEADER_VIEW_IMPL_H_ -#define ASH_SYSTEM_NETWORK_NETWORK_LIST_MOBILE_HEADER_VIEW_IMPL_H_ - -#include "ash/ash_export.h" -#include "ash/system/network/network_list_mobile_header_view.h" -#include "ui/base/metadata/metadata_header_macros.h" - -namespace ash { - -class NetworkListNetworkHeaderView; - -// Implementation of NetworkListMobileHeaderView. -class ASH_EXPORT NetworkListMobileHeaderViewImpl - : public NetworkListMobileHeaderView { - METADATA_HEADER(NetworkListMobileHeaderViewImpl, NetworkListMobileHeaderView) - - public: - explicit NetworkListMobileHeaderViewImpl( - NetworkListNetworkHeaderView::Delegate* delegate); - NetworkListMobileHeaderViewImpl(const NetworkListMobileHeaderViewImpl&) = - delete; - NetworkListMobileHeaderViewImpl& operator=( - const NetworkListMobileHeaderViewImpl&) = delete; - ~NetworkListMobileHeaderViewImpl() override; - - private: - friend class NetworkListMobileHeaderViewTest; - friend class NetworkListViewControllerTest; - - // NetworkListNetworkHeaderView: - void SetToggleState(bool enabled, bool is_on, bool animate_toggle) override; - void OnToggleToggled(bool is_on) override; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_NETWORK_NETWORK_LIST_MOBILE_HEADER_VIEW_IMPL_H_
diff --git a/ash/system/network/network_list_mobile_header_view_unittest.cc b/ash/system/network/network_list_mobile_header_view_unittest.cc index bb4f5b69..0a3598b 100644 --- a/ash/system/network/network_list_mobile_header_view_unittest.cc +++ b/ash/system/network/network_list_mobile_header_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/system/network/network_list_mobile_header_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include <memory> @@ -64,9 +64,9 @@ } void Init() { - std::unique_ptr<NetworkListMobileHeaderViewImpl> + std::unique_ptr<NetworkListMobileHeaderView> network_list_mobile_header_view = - std::make_unique<NetworkListMobileHeaderViewImpl>( + std::make_unique<NetworkListMobileHeaderView>( &fake_network_list_network_header_delegate_); widget_ = CreateFramelessTestWidget(); @@ -109,7 +109,7 @@ network_config::CrosNetworkConfigTestHelper network_config_helper_; FakeNetworkListNetworkHeaderViewDelegate fake_network_list_network_header_delegate_; - raw_ptr<NetworkListMobileHeaderViewImpl, DanglingUntriaged | ExperimentalAsh> + raw_ptr<NetworkListMobileHeaderView, DanglingUntriaged | ExperimentalAsh> network_list_mobile_header_view_; };
diff --git a/ash/system/network/network_list_wifi_header_view.cc b/ash/system/network/network_list_wifi_header_view.cc index bafed30..dc50273 100644 --- a/ash/system/network/network_list_wifi_header_view.cc +++ b/ash/system/network/network_list_wifi_header_view.cc
@@ -7,7 +7,8 @@ #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/network/network_list_network_header_view.h" -#include "components/vector_icons/vector_icons.h" +#include "ash/system/tray/hover_highlight_view.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" namespace ash { @@ -20,7 +21,26 @@ NetworkListWifiHeaderView::~NetworkListWifiHeaderView() = default; -BEGIN_METADATA(NetworkListWifiHeaderView, NetworkListNetworkHeaderView) +void NetworkListWifiHeaderView::SetToggleState(bool enabled, + bool is_on, + bool animate_toggle) { + std::u16string tooltip_text = l10n_util::GetStringFUTF16( + IDS_ASH_STATUS_TRAY_NETWORK_TOGGLE_WIFI, + l10n_util::GetStringUTF16( + is_on ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED + : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED)); + entry_row()->SetTooltipText(tooltip_text); + toggle()->SetTooltipText(tooltip_text); + NetworkListNetworkHeaderView::SetToggleState(enabled, is_on, animate_toggle); +} + +void NetworkListWifiHeaderView::OnToggleToggled(bool is_on) { + // Join wifi entry is not updated here, it will be updated when WiFi device + // state changes. + delegate()->OnWifiToggleClicked(is_on); +} + +BEGIN_METADATA(NetworkListWifiHeaderView) END_METADATA -} // namespace ash \ No newline at end of file +} // namespace ash
diff --git a/ash/system/network/network_list_wifi_header_view.h b/ash/system/network/network_list_wifi_header_view.h index 207d89d7..64ec39d 100644 --- a/ash/system/network/network_list_wifi_header_view.h +++ b/ash/system/network/network_list_wifi_header_view.h
@@ -11,20 +11,25 @@ namespace ash { -// This class is the interface used to create network list header for Wifi -// networks, and is responsible for the creation of wifi-specific buttons. -// TODO(b/251724646): remove this interface after the QsRevamp clean up. +// Creates network list header for Wifi networks. class ASH_EXPORT NetworkListWifiHeaderView : public NetworkListNetworkHeaderView { - public: METADATA_HEADER(NetworkListWifiHeaderView); + public: explicit NetworkListWifiHeaderView( NetworkListNetworkHeaderView::Delegate* delegate); NetworkListWifiHeaderView(const NetworkListWifiHeaderView&) = delete; NetworkListWifiHeaderView& operator=(const NetworkListWifiHeaderView&) = delete; ~NetworkListWifiHeaderView() override; + + // NetworkListNetworkHeaderView: + void SetToggleState(bool enabled, bool is_on, bool animate_toggle) override; + void OnToggleToggled(bool is_on) override; + + private: + friend class NetworkListWifiHeaderViewTest; }; } // namespace ash
diff --git a/ash/system/network/network_list_wifi_header_view_impl.cc b/ash/system/network/network_list_wifi_header_view_impl.cc deleted file mode 100644 index 37e8dfc..0000000 --- a/ash/system/network/network_list_wifi_header_view_impl.cc +++ /dev/null
@@ -1,44 +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 "ash/system/network/network_list_wifi_header_view_impl.h" - -#include "ash/strings/grit/ash_strings.h" -#include "ash/system/network/network_list_network_header_view.h" -#include "ash/system/network/network_list_wifi_header_view.h" -#include "ash/system/tray/hover_highlight_view.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" - -namespace ash { - -NetworkListWifiHeaderViewImpl::NetworkListWifiHeaderViewImpl( - NetworkListNetworkHeaderView::Delegate* delegate) - : NetworkListWifiHeaderView(delegate) {} - -NetworkListWifiHeaderViewImpl::~NetworkListWifiHeaderViewImpl() = default; - -void NetworkListWifiHeaderViewImpl::SetToggleState(bool enabled, - bool is_on, - bool animate_toggle) { - std::u16string tooltip_text = l10n_util::GetStringFUTF16( - IDS_ASH_STATUS_TRAY_NETWORK_TOGGLE_WIFI, - l10n_util::GetStringUTF16( - is_on ? IDS_ASH_STATUS_TRAY_NETWORK_WIFI_ENABLED - : IDS_ASH_STATUS_TRAY_NETWORK_WIFI_DISABLED)); - entry_row()->SetTooltipText(tooltip_text); - toggle()->SetTooltipText(tooltip_text); - NetworkListNetworkHeaderView::SetToggleState(enabled, is_on, animate_toggle); -} - -void NetworkListWifiHeaderViewImpl::OnToggleToggled(bool is_on) { - // Join wifi entry is not updated here, it will be updated when WiFi device - // state changes. - delegate()->OnWifiToggleClicked(is_on); -} - -BEGIN_METADATA(NetworkListWifiHeaderViewImpl) -END_METADATA - -} // namespace ash
diff --git a/ash/system/network/network_list_wifi_header_view_impl.h b/ash/system/network/network_list_wifi_header_view_impl.h deleted file mode 100644 index 6bf028c..0000000 --- a/ash/system/network/network_list_wifi_header_view_impl.h +++ /dev/null
@@ -1,42 +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. - -#ifndef ASH_SYSTEM_NETWORK_NETWORK_LIST_WIFI_HEADER_VIEW_IMPL_H_ -#define ASH_SYSTEM_NETWORK_NETWORK_LIST_WIFI_HEADER_VIEW_IMPL_H_ - -#include "ash/ash_export.h" -#include "ash/style/icon_button.h" -#include "ash/system/network/network_list_wifi_header_view.h" -#include "ash/system/tray/tri_view.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/views/view.h" - -namespace ash { - -// Implementation of NetworkListWifiHeaderView. -class ASH_EXPORT NetworkListWifiHeaderViewImpl - : public NetworkListWifiHeaderView { - METADATA_HEADER(NetworkListWifiHeaderViewImpl, NetworkListWifiHeaderView) - - public: - explicit NetworkListWifiHeaderViewImpl( - NetworkListNetworkHeaderView::Delegate* delegate); - NetworkListWifiHeaderViewImpl(const NetworkListWifiHeaderViewImpl&) = delete; - NetworkListWifiHeaderViewImpl& operator=( - const NetworkListWifiHeaderViewImpl&) = delete; - ~NetworkListWifiHeaderViewImpl() override; - - private: - friend class NetworkListWifiHeaderViewTest; - - // NetworkListNetworkHeaderView: - void SetToggleState(bool enabled, bool is_on, bool animate_toggle) override; - void OnToggleToggled(bool is_on) override; -}; - -} // namespace ash - -#endif // ASH_SYSTEM_NETWORK_NETWORK_LIST_WIFI_HEADER_VIEW_IMPL_H_
diff --git a/ash/system/network/network_list_wifi_header_view_unittest.cc b/ash/system/network/network_list_wifi_header_view_unittest.cc index c5c37a1c..3e3d8d8 100644 --- a/ash/system/network/network_list_wifi_header_view_unittest.cc +++ b/ash/system/network/network_list_wifi_header_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/system/network/network_list_wifi_header_view_impl.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include <memory> @@ -29,10 +29,9 @@ void SetUp() override { AshTestBase::SetUp(); - std::unique_ptr<NetworkListWifiHeaderViewImpl> - network_list_wifi_header_view = - std::make_unique<NetworkListWifiHeaderViewImpl>( - &fake_network_list_network_header_delegate_); + std::unique_ptr<NetworkListWifiHeaderView> network_list_wifi_header_view = + std::make_unique<NetworkListWifiHeaderView>( + &fake_network_list_network_header_delegate_); widget_ = CreateFramelessTestWidget(); widget_->SetFullscreen(true); @@ -71,7 +70,7 @@ network_config::CrosNetworkConfigTestHelper network_config_helper_; FakeNetworkListNetworkHeaderViewDelegate fake_network_list_network_header_delegate_; - raw_ptr<NetworkListWifiHeaderViewImpl, DanglingUntriaged | ExperimentalAsh> + raw_ptr<NetworkListWifiHeaderView, DanglingUntriaged | ExperimentalAsh> network_list_wifi_header_view_; };
diff --git a/ash/wallpaper/sea_pen_wallpaper_manager.cc b/ash/wallpaper/sea_pen_wallpaper_manager.cc index a7a2610..64ad376 100644 --- a/ash/wallpaper/sea_pen_wallpaper_manager.cc +++ b/ash/wallpaper/sea_pen_wallpaper_manager.cc
@@ -40,13 +40,13 @@ const gfx::ImageSkia& image_skia) { if (image_skia.isNull()) { LOG(ERROR) << __func__ << "Failed to decode Sea Pen image"; - std::move(callback).Run(sea_pen_image_id, gfx::ImageSkia()); + std::move(callback).Run(gfx::ImageSkia()); return; } std::string file_name = base::NumberToString(sea_pen_image_id) + ".jpg"; auto on_saved = base::BindOnce(&SeaPenWallpaperManager::OnSeaPenImageSaved, - weak_factory_.GetWeakPtr(), sea_pen_image_id, - image_skia, std::move(callback)); + weak_factory_.GetWeakPtr(), image_skia, + std::move(callback)); wallpaper_file_manager_->SaveWallpaperToDisk( WallpaperType::kSeaPen, wallpaper_dir, file_name, WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED, image_skia, @@ -54,16 +54,15 @@ } void SeaPenWallpaperManager::OnSeaPenImageSaved( - uint32_t sea_pen_image_id, const gfx::ImageSkia& image_skia, DecodeAndSaveSeaPenImageCallback callback, const base::FilePath& file_path) { if (file_path.empty()) { LOG(ERROR) << __func__ << "Failed to save Sea Pen image into disk"; - std::move(callback).Run(sea_pen_image_id, gfx::ImageSkia()); + std::move(callback).Run(gfx::ImageSkia()); return; } - std::move(callback).Run(sea_pen_image_id, image_skia); + std::move(callback).Run(image_skia); } } // namespace ash
diff --git a/ash/wallpaper/sea_pen_wallpaper_manager.h b/ash/wallpaper/sea_pen_wallpaper_manager.h index 59f789c..d570c6e 100644 --- a/ash/wallpaper/sea_pen_wallpaper_manager.h +++ b/ash/wallpaper/sea_pen_wallpaper_manager.h
@@ -28,8 +28,7 @@ ~SeaPenWallpaperManager(); using DecodeAndSaveSeaPenImageCallback = - base::OnceCallback<void(uint32_t sea_pen_image_id, - const gfx::ImageSkia& image_skia)>; + base::OnceCallback<void(const gfx::ImageSkia& image_skia)>; // Decodes Sea Pen image then save the decoded image into disk. Calls // `callback` with the image id and the decoded image. Responds with an empty @@ -44,8 +43,7 @@ DecodeAndSaveSeaPenImageCallback callback, const gfx::ImageSkia& image_skia); - void OnSeaPenImageSaved(uint32_t sea_pen_image_id, - const gfx::ImageSkia& image_skia, + void OnSeaPenImageSaved(const gfx::ImageSkia& image_skia, DecodeAndSaveSeaPenImageCallback callback, const base::FilePath& file_path);
diff --git a/ash/wallpaper/sea_pen_wallpaper_manager_unittest.cc b/ash/wallpaper/sea_pen_wallpaper_manager_unittest.cc index e6f4a9c..1da17ff 100644 --- a/ash/wallpaper/sea_pen_wallpaper_manager_unittest.cc +++ b/ash/wallpaper/sea_pen_wallpaper_manager_unittest.cc
@@ -82,8 +82,7 @@ }; TEST_F(SeaPenWallpaperManagerTest, DecodesImageAndReturnsId) { - base::test::TestFuture<uint32_t, const gfx::ImageSkia&> - decode_sea_pen_image_future; + base::test::TestFuture<const gfx::ImageSkia&> decode_sea_pen_image_future; const base::FilePath file_path = CreateFilePath("111.jpg"); ASSERT_FALSE(base::PathExists(file_path)); sea_pen_wallpaper_manager().DecodeAndSaveSeaPenImage( @@ -91,7 +90,6 @@ manta::proto::ImageResolution::RESOLUTION_64}, GetTempFileDirectory(), decode_sea_pen_image_future.GetCallback()); - EXPECT_EQ(111u, decode_sea_pen_image_future.Get<uint32_t>()); // Use `AreBitmapsClose` because JPG encoding/decoding can alter the color // slightly. EXPECT_TRUE(gfx::test::AreBitmapsClose(
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index e49b1de..2bce42a 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1118,11 +1118,38 @@ return; } + const std::string sea_pen_file_name = + base::NumberToString(sea_pen_image.id) + ".jpg"; + const base::FilePath sea_pen_wallpaper_path = + GetUserSeaPenWallpaperDir(account_id).Append(sea_pen_file_name); + sea_pen_wallpaper_manager_.DecodeAndSaveSeaPenImage( sea_pen_image, GetUserSeaPenWallpaperDir(account_id), base::BindOnce(&WallpaperControllerImpl::OnSeaPenWallpaperDecoded, set_wallpaper_weak_factory_.GetWeakPtr(), account_id, - std::move(callback))); + sea_pen_wallpaper_path, std::move(callback))); +} + +void WallpaperControllerImpl::SetSeaPenWallpaperFromFile( + const AccountId& account_id, + const base::FilePath& file_path, + SetWallpaperCallback callback) { + DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted()); + if (!CanSetUserWallpaper(account_id)) { + wallpaper_metrics_manager_->LogWallpaperResult( + WallpaperType::kSeaPen, SetWallpaperResult::kPermissionDenied); + // Return early to skip the work of decoding. + std::move(callback).Run(/*success=*/false); + return; + } + + // Invalidate weak ptrs to cancel prior requests to set wallpaper. + set_wallpaper_weak_factory_.InvalidateWeakPtrs(); + wallpaper_file_manager_->LoadWallpaper( + WallpaperType::kSeaPen, file_path.DirName(), file_path.BaseName().value(), + base::BindOnce(&WallpaperControllerImpl::OnSeaPenWallpaperDecoded, + set_wallpaper_weak_factory_.GetWeakPtr(), account_id, + file_path, std::move(callback))); } void WallpaperControllerImpl::ConfirmPreviewWallpaper() { @@ -2338,8 +2365,8 @@ void WallpaperControllerImpl::OnSeaPenWallpaperDecoded( const AccountId& account_id, + const base::FilePath& file_path, SetWallpaperCallback callback, - uint32_t sea_pen_image_id, const gfx::ImageSkia& image_skia) { if (image_skia.isNull()) { wallpaper_metrics_manager_->LogWallpaperResult( @@ -2355,9 +2382,10 @@ } std::move(callback).Run(true); - // TODO(b/307591556) set location and user_file_path. - WallpaperInfo wallpaper_info(std::string(), WALLPAPER_LAYOUT_CENTER_CROPPED, - WallpaperType::kSeaPen, base::Time::Now()); + WallpaperInfo wallpaper_info(file_path.BaseName().RemoveExtension().value(), + WALLPAPER_LAYOUT_CENTER_CROPPED, + WallpaperType::kSeaPen, base::Time::Now(), + file_path.value()); SetWallpaperImpl(account_id, wallpaper_info, image_skia, /*show_wallpaper=*/IsActiveUser(account_id));
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index 504abee1..2583570 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -295,6 +295,11 @@ void SetSeaPenWallpaper(const AccountId& account_id, const SeaPenImage& sea_pen_image, SetWallpaperCallback callback) override; + + void SetSeaPenWallpaperFromFile(const AccountId& account_id, + const base::FilePath& file_path, + SetWallpaperCallback callback) override; + void ConfirmPreviewWallpaper() override; void CancelPreviewWallpaper() override; void UpdateCurrentWallpaperLayout(const AccountId& account_id, @@ -556,8 +561,8 @@ // Used as the callback of SeaPen wallpaper decoding. Shows the wallpaper // immediately if `account_id` is for the active user. void OnSeaPenWallpaperDecoded(const AccountId& account_id, + const base::FilePath& file_path, SetWallpaperCallback callback, - uint32_t sea_pen_image_id, const gfx::ImageSkia& image_skia); // Saves |image| to disk if the user's data is not ephemeral, or if it is a
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index eb7cdc31..de34f1b4 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -2059,6 +2059,43 @@ /*max_deviation=*/1)); } +TEST_P(WallpaperControllerTest, SetSeaPenWallpaperFromFile) { + SimulateUserLogin(kAccountId1); + TestWallpaperControllerObserver observer(controller_); + + WallpaperInfo wallpaper_info; + ASSERT_FALSE( + pref_manager_->GetUserWallpaperInfo(kAccountId1, &wallpaper_info)); + + gfx::ImageSkia expected_image; + std::string jpg_bytes = CreateEncodedImageForTesting( + {1, 1}, SK_ColorGREEN, data_decoder::mojom::ImageCodec::kDefault, + &expected_image); + ASSERT_TRUE(!jpg_bytes.empty()); + + base::ScopedTempDir scoped_temp_dir; + ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); + base::FilePath file_path = scoped_temp_dir.GetPath().Append("111.jpg"); + ASSERT_TRUE(base::WriteFile(file_path, jpg_bytes)); + + base::test::TestFuture<bool> set_wallpaper_future; + controller_->SetSeaPenWallpaperFromFile(kAccountId1, file_path, + set_wallpaper_future.GetCallback()); + + EXPECT_TRUE(set_wallpaper_future.Take()); + EXPECT_TRUE( + pref_manager_->GetUserWallpaperInfo(kAccountId1, &wallpaper_info)); + EXPECT_EQ(WallpaperType::kSeaPen, wallpaper_info.type); + EXPECT_EQ(1, observer.wallpaper_changed_count()); + histogram_tester().ExpectUniqueSample("Ash.Wallpaper.SeaPen.Result2", + SetWallpaperResult::kSuccess, 1); + // Use `AreBitmapsClose` because jpg encoding/decoding can alter the color + // channels +- 1. + EXPECT_TRUE(gfx::test::AreBitmapsClose( + *expected_image.bitmap(), *controller_->GetWallpaperImage().bitmap(), + /*max_deviation=*/1)); +} + TEST_P(WallpaperControllerTest, SetDefaultWallpaperForRegularAccount) { gfx::ImageSkia image = CreateImage(640, 480, kWallpaperColor); SimulateUserLogin(kAccountId1);
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_pa.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_pa.xtb index 9a0eb38c..e78bdca3 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_pa.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_pa.xtb
@@ -59,7 +59,7 @@ <translation id="3583444040776960729">ਦਸਤਾਵੇਜ਼ ਦਾ ਹੇਠਲਾ-ਖੱਬਾ ਕੋਨਾ</translation> <translation id="3642192109456033823">ਵੀਡੀਓ ’ਤੇ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...</translation> <translation id="3789724198583203151">ਘੜੀ ਦੀ ਉਲਟੀ ਦਿਸ਼ਾ ਵਿੱਚ 90 ਡਿਗਰੀ ਘੁਮਾਓ</translation> -<translation id="3810838688059735925">ਵੀਡਿਓ</translation> +<translation id="3810838688059735925">ਵੀਡੀਓ</translation> <translation id="3892148308691398805">ਲਿਖਤ ਕਾਪੀ ਕਰੋ</translation> <translation id="4060608699153044055">ਡੀਵਾਈਸ ਦੀ ਸਟੋਰੇਜ ਜਗ੍ਹਾ ਘੱਟ ਹੋਣ ਕਰਕੇ ਤੁਸੀਂ ਰਿਕਾਰਡ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਆਪਣੇ ਡੀਵਾਈਸ ਵਿੱਚ ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਨੀ ਪਵੇਗੀ।</translation> <translation id="4061162772429051350"><ph name="MAGAPIXELS_AMOUNT" /> MP</translation>
diff --git a/ash/webui/common/resources/network/network_list_item.js b/ash/webui/common/resources/network/network_list_item.js index fba2f23..6a5b559 100644 --- a/ash/webui/common/resources/network/network_list_item.js +++ b/ash/webui/common/resources/network/network_list_item.js
@@ -23,6 +23,7 @@ import {I18nBehavior} from '//resources/ash/common/i18n_behavior.js'; import {loadTimeData} from '//resources/ash/common/load_time_data.m.js'; import {Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {mojoString16ToString} from 'chrome://resources/js/mojo_type_util.js'; import {ActivationStateType, CrosNetworkConfigInterface, GlobalPolicy, ManagedCellularProperties, ManagedProperties, SecurityType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType, NetworkType, OncSource, PortalState} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; @@ -344,9 +345,7 @@ // Service provider from mojo API is a string16 value represented as an // array of characters. Convert to string for display. - this.subtitle_ = properties.serviceProvider.data - .map((charCode) => String.fromCharCode(charCode)) - .join(''); + this.subtitle_ = mojoString16ToString(properties.serviceProvider); }, /** @private */
diff --git a/ash/webui/personalization_app/mojom/sea_pen.mojom b/ash/webui/personalization_app/mojom/sea_pen.mojom index aecc126..38d5e01 100644 --- a/ash/webui/personalization_app/mojom/sea_pen.mojom +++ b/ash/webui/personalization_app/mojom/sea_pen.mojom
@@ -4,6 +4,7 @@ module ash.personalization_app.mojom; +import "mojo/public/mojom/base/file_path.mojom"; import "url/mojom/url.mojom"; // Encapsulates metadata for a thumbnail image, which can be displayed as an @@ -37,4 +38,7 @@ // Select a thumbnail and set as the system wallpaper for the current user. SelectSeaPenThumbnail(uint32 id) => (bool success); + + // Sets the given Sea Pen image as the user's background. + SelectRecentSeaPenImage(mojo_base.mojom.FilePath path) => (bool success); };
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/constants.ts b/ash/webui/personalization_app/resources/js/wallpaper/constants.ts index 8afe896..f9496a38 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/constants.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/constants.ts
@@ -16,8 +16,8 @@ export type DefaultImageSymbol = typeof kDefaultImageSymbol; -export type DisplayableImage = - FilePath|GooglePhotosPhoto|WallpaperImage|DefaultImageSymbol; +export type DisplayableImage = FilePath|GooglePhotosPhoto|WallpaperImage| + DefaultImageSymbol|SeaPenWallpaper; export const kMaximumLocalImagePreviews = 4;
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.html b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.html index 5014554..51a371a 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.html
@@ -67,6 +67,42 @@ background-color: var(--cros-sys-app_base_shaded); margin-inline: 0; } + + .recent-wallpaper[aria-selected='true']::part(icon) { + --cr-icon-button-size: 20px; + background-color: var(--cros-bg-color); + border-bottom-right-radius: 50%; + left: -8px; + padding: 8px; + top: -8px; + } + + .recent-wallpaper[aria-selected='true']::part(item) { + border-radius: var(--personalization-app-grid-item-border-radius); + } + + .recent-wallpaper[aria-selected='true']::part(icon):before { + border-top-left-radius: 50%; + top: 8px; + box-shadow: 0 -8px 0 0 var(--cros-bg-color); + content: ""; + height: 16px; + left: 36px; + position: absolute; + width: 16px; + } + + .recent-wallpaper[aria-selected='true']::part(icon):after { + border-top-left-radius: 50%; + box-shadow: -8px 0px 0 0 var(--cros-bg-color); + content: ""; + height: 16px; + left: 8px; + position: absolute; + top: 36px; + width: 16px; + } + </style> <template is="dom-if" if="[[shouldShowRecentlyUsedWallpapers_(recentWallpapers_)]]"> <!-- TODO(b/308200616): Add finalized strings --> @@ -86,7 +122,7 @@ aria-posinset$="[[getAriaIndex_(index)]]" on-wallpaper-grid-item-selected="onRecentWallpaperSelected_" role="option" - selected="[[isRecentWallpaperSelected_(image, selectedWallpaper_)]]" + selected="[[isRecentWallpaperSelected_(image, currentSelected_, pendingSelected_)]]" src="[[image.url]]" tabindex$="[[tabIndex]]"> </wallpaper-grid-item>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.ts index 9fff051..91b09eb 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_recent_wallpapers_element.ts
@@ -12,12 +12,17 @@ import '../../../css/wallpaper.css.js'; import {AnchorAlignment} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import {assert} from 'chrome://resources/js/assert.js'; +import {CurrentWallpaper} from '../../../personalization_app.mojom-webui.js'; import {WithPersonalizationStore} from '../../personalization_store.js'; import {isNonEmptyArray} from '../../utils.js'; -import {SeaPenWallpaper} from '../constants.js'; -import {getRecentWallpaperImages} from '../wallpaper_controller.js'; +import {DisplayableImage, SeaPenWallpaper} from '../constants.js'; +import {isImageAMatchForKey, isImageEqualToSelected, isSeaPenWallpaper} from '../utils.js'; +import {getRecentWallpaperImages, selectRecentSeaPenImage} from '../wallpaper_controller.js'; +import {WallpaperGridItemSelectedEvent} from '../wallpaper_grid_item_element.js'; +import {getSeaPenProvider} from './sea_pen_interface_provider.js'; import {getTemplate} from './sea_pen_recent_wallpapers_element.html.js'; export class SeaPenRecentWallpapersElement extends WithPersonalizationStore { @@ -36,16 +41,26 @@ type: Number, value: null, }, + + currentSelected_: Object, + + pendingSelected_: Object, }; } private recentWallpapers_: SeaPenWallpaper[]|null; private currentShowWallpaperInfoDialog_: number|null; + private currentSelected_: CurrentWallpaper|null; + private pendingSelected_: DisplayableImage|null; override connectedCallback() { super.connectedCallback(); this.watch<SeaPenRecentWallpapersElement['recentWallpapers_']>( 'recentWallpapers_', state => state.wallpaper.seaPen.recentWallpapers); + this.watch<SeaPenRecentWallpapersElement['currentSelected_']>( + 'currentSelected_', state => state.wallpaper.currentSelected); + this.watch<SeaPenRecentWallpapersElement['pendingSelected_']>( + 'pendingSelected_', state => state.wallpaper.pendingSelected); this.updateFromStore(); // TODO(b/304576846): remove the function and use sea pen observer instead. getRecentWallpaperImages(this.getStore()); @@ -60,9 +75,26 @@ return isNonEmptyArray(recentWallpapers); } - private isRecentWallpaperSelected_() { - // TODO(b/307592600): set recent Sea Pen Wallpaper as wallpaper and update - // timestamp. + private isRecentWallpaperSelected_( + image: SeaPenWallpaper, + currentSelected: SeaPenRecentWallpapersElement['currentSelected_'], + pendingSelected: SeaPenRecentWallpapersElement['pendingSelected_']) { + if (!isSeaPenWallpaper(image)) { + return false; + } + return (isSeaPenWallpaper(pendingSelected) && + isImageAMatchForKey(image, pendingSelected.file_path.path)) || + (!pendingSelected && !!currentSelected && + isImageEqualToSelected(image, currentSelected)); + } + + private onRecentWallpaperSelected_(event: WallpaperGridItemSelectedEvent& + {model: {image: SeaPenWallpaper}}) { + assert( + isSeaPenWallpaper(event.model.image), + 'recent wallpaper image is a Sea Pen wallpaper image'); + selectRecentSeaPenImage( + event.model.image, getSeaPenProvider(), this.getStore()); } private onClickMenuIcon_(e: Event) { @@ -120,7 +152,7 @@ } private getWallpaperInfoMessage_(image: SeaPenWallpaper): string { - return `Image was generated using the text - ${image.query_info}`; + return `Query - ${image.query_info}`; } } customElements.define(
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/utils.ts b/ash/webui/personalization_app/resources/js/wallpaper/utils.ts index 3ae15e5..58338ce5 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/utils.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/utils.ts
@@ -11,7 +11,7 @@ import {CurrentAttribution, CurrentWallpaper, GooglePhotosAlbum, GooglePhotosPhoto, WallpaperImage, WallpaperLayout, WallpaperType} from '../../personalization_app.mojom-webui.js'; import {getNumberOfGridItemsPerRow, isNonEmptyArray, isNonEmptyString} from '../utils.js'; -import {DefaultImageSymbol, DisplayableImage, kDefaultImageSymbol} from './constants.js'; +import {DefaultImageSymbol, DisplayableImage, kDefaultImageSymbol, SeaPenWallpaper} from './constants.js'; import {SeaPenTemplate} from './sea_pen/sea_pen_collection_element.js'; import {DailyRefreshState} from './wallpaper_state.js'; @@ -34,6 +34,11 @@ return !!obj && typeof obj.id === 'string'; } +/** Checks whether |obj| is an instance of |SeaPenWallpaper|. */ +export function isSeaPenWallpaper(obj: any): obj is SeaPenWallpaper { + return !!obj && isFilePath(obj.file_path); +} + /** Returns whether |image| is a match for the specified |key|. */ export function isImageAMatchForKey( image: DisplayableImage, key: string|DefaultImageSymbol): boolean { @@ -46,6 +51,9 @@ if (isFilePath(image)) { return key === image.path; } + if (isSeaPenWallpaper(image)) { + return key === image.file_path.path; + } assert(isGooglePhotosPhoto(image)); // NOTE: Old clients may not support |dedupKey| when setting Google Photos // wallpaper, so use |id| in such cases for backwards compatibility.
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_controller.ts b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_controller.ts index ad16f66c..1ca842d 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_controller.ts +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_controller.ts
@@ -13,7 +13,7 @@ import {PersonalizationStore} from '../personalization_store.js'; import {isNonEmptyArray} from '../utils.js'; -import {DisplayableImage} from './constants.js'; +import {DisplayableImage, SeaPenWallpaper} from './constants.js'; import {isDefaultImage, isFilePath, isGooglePhotosPhoto, isImageAMatchForKey, isImageEqualToSelected, isWallpaperImage} from './utils.js'; import * as action from './wallpaper_actions.js'; import {DailyRefreshType} from './wallpaper_state.js'; @@ -284,6 +284,34 @@ await provider.selectSeaPenThumbnail(thumbnail.id); } +export async function selectRecentSeaPenImage( + image: SeaPenWallpaper, provider: SeaPenProviderInterface, + store: PersonalizationStore): Promise<void> { + const currentWallpaper = store.data.wallpaper.currentSelected; + if (currentWallpaper && isImageEqualToSelected(image, currentWallpaper)) { + return; + } + // Batch these changes together to reduce polymer churn as multiple state + // fields change quickly. + store.beginBatchUpdate(); + store.dispatch(action.beginSelectImageAction(image)); + store.dispatch(action.beginLoadSelectedImageAction()); + store.endBatchUpdate(); + + const {success} = await provider.selectRecentSeaPenImage(image.file_path); + + store.beginBatchUpdate(); + store.dispatch(action.endSelectImageAction(image, success)); + if (!success) { + console.warn('Error setting wallpaper'); + store.dispatch( + action.setAttributionAction(store.data.wallpaper.attribution)); + store.dispatch( + action.setSelectedImageAction(store.data.wallpaper.currentSelected)); + } + store.endBatchUpdate(); +} + export async function getDefaultImageThumbnail( provider: WallpaperProviderInterface, store: PersonalizationStore): Promise<void> { @@ -603,7 +631,7 @@ url: 'https://lh5.googleusercontent.com/proxy/POggSGKiyt380V63sTRjua4Q6s6v02wNfTyeDhTK1TKjlZrEnRiZNHa4lDSXu_3mvdUGQe2HF0s_Z8J45ygrJ3jM9R6bZUcF-CN61iacGXrOVWr6YdbaDwuhZu7N2RxJRMKT2Wnrifc', }, - file_path: {path: '/sea_pen/image_1.jpg'}, + file_path: {path: '/sea_pen/111.jpg'}, }, { query_info: @@ -612,7 +640,7 @@ url: 'https://lh4.googleusercontent.com/proxy/yRB8hlnV86jWE3XgtAOd2Hniso9cv5YynGEBQrnVr26onWSvNWARKahdFxiSgv5CKVDnpgZ4LunQ7cxTX5ZGf4nZNVHjQ88xJzQnZ9yMWeOtA7r69Ep6G6Ns9fl5TwdHIC6M_YSLtFGjg_z3fHq5ooqyCTgq', }, - file_path: {'path': '/sea_pen/image_2.jpg'}, + file_path: {path: '/sea_pen/222.jpg'}, }, { query_info: 'a large rock sitting on top of a hill in the desert', @@ -620,7 +648,7 @@ url: 'https://lh5.googleusercontent.com/proxy/Don1aDsf2x5AOn25kN1-NdumW-Dc2QF5wbOVmn2WTpgC8ja0YfBZqqajhIXWsoqvnXdn6u57tHsAjD_ht6JywKiFFjAaum99YjAlkXuSX_Uwvi_OXuKyznUc4TR44bUlAXSYOhGeUn6pv-3vEXec', }, - file_path: {'path': '/sea_pen/image_3.jpg'}, + file_path: {path: '/sea_pen/333.jpg'}, }, ]; store.dispatch(action.setRecentWallpaperImagesAction(images));
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html index 91123cb5..d04ee2f 100644 --- a/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html +++ b/ash/webui/personalization_app/resources/js/wallpaper/wallpaper_grid_item_element.html
@@ -185,16 +185,20 @@ top: 8px; } + .check-mark-icon-container { + left: 8px; + position: absolute; + top: 8px; + z-index: 2; + } + iron-icon { --iron-icon-height: 20px; --iron-icon-width: 20px; animation-duration: 200ms; animation-name: iron-icon-scale; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1.0); - left: 8px; - position: absolute; - top: 8px; - z-index: 2; + margin-inline: 0; } @keyframes iron-icon-scale { @@ -246,5 +250,7 @@ restamp> <info-svg id="infoIcon" title$="[[infoText]]" part="info-icon"></info-svg> </template> - <iron-icon part="icon" icon="[[checkmarkIcon_]]"></iron-icon> + <div class="check-mark-icon-container" part="icon"> + <iron-icon icon="[[checkmarkIcon_]]"></iron-icon> + </div> </div>
diff --git a/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc b/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc index bb42893..a811153b 100644 --- a/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc +++ b/ash/webui/personalization_app/test/personalization_app_mojom_banned_mocha_test_base.cc
@@ -114,6 +114,11 @@ SelectSeaPenThumbnail, (uint32_t, SelectSeaPenThumbnailCallback), (override)); + MOCK_METHOD(void, + SelectRecentSeaPenImage, + (const base::FilePath& file_path, + SelectRecentSeaPenImageCallback), + (override)); }; class MockPersonalizationAppThemeProvider
diff --git a/ash/wm/desks/templates/saved_desk_presenter.cc b/ash/wm/desks/templates/saved_desk_presenter.cc index a147c385..02c0587 100644 --- a/ash/wm/desks/templates/saved_desk_presenter.cc +++ b/ash/wm/desks/templates/saved_desk_presenter.cc
@@ -411,8 +411,13 @@ // Copy fields we need from `desk_template` since we're about to move it. const auto saved_desk_type = saved_desk->type(); - const Desk* new_desk = desks_controller->CreateNewDeskForSavedDesk( + Desk* new_desk = desks_controller->CreateNewDeskForSavedDesk( saved_desk_type, saved_desk->template_name()); + + // Set the lacros profile ID for the newly created desk. This is effectively a + // no-op if `lacros_profile_id` returns zero. + new_desk->SetLacrosProfileId(saved_desk->lacros_profile_id()); + LaunchSavedDeskIntoNewDesk(std::move(saved_desk), root_window, new_desk); // Note: `LaunchSavedDeskIntoNewDesk` *may* cause overview mode to exit. This
diff --git a/ash/wm/overview/overview_focus_cycler_unittest.cc b/ash/wm/overview/overview_focus_cycler_unittest.cc index 7460e8b..06a9a3d 100644 --- a/ash/wm/overview/overview_focus_cycler_unittest.cc +++ b/ash/wm/overview/overview_focus_cycler_unittest.cc
@@ -27,7 +27,6 @@ #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" #include "ash/wm/window_util.h" #include "base/test/scoped_feature_list.h" -#include "chromeos/constants/chromeos_features.h" #include "ui/aura/window.h" #include "ui/display/manager/display_manager.h" #include "ui/display/test/display_manager_test_api.h" @@ -737,17 +736,9 @@ EXPECT_EQ(1u, desks_controller->desks().size()); EXPECT_NE(desk2, desks_controller->GetDeskAtIndex(0)); - if (chromeos::features::IsJellyrollEnabled()) { - // When Jellyroll is enabled, desks bar never goes back to zero state after - // it's initialized. - EXPECT_FALSE(desk_bar_view->IsZeroState()); - EXPECT_FALSE(desk_bar_view->mini_views().empty()); - } else { - // Go back to zero state since there is only a single desk and mini views - // are empty in zero state. - EXPECT_TRUE(desk_bar_view->IsZeroState()); - EXPECT_TRUE(desk_bar_view->mini_views().empty()); - } + // Desks bar never goes back to zero state after it's initialized. + EXPECT_FALSE(desk_bar_view->IsZeroState()); + EXPECT_FALSE(desk_bar_view->mini_views().empty()); } TEST_P(DesksOverviewFocusCyclerTest, ActivateDeskNameView) { @@ -817,15 +808,8 @@ EXPECT_EQ(nullptr, GetHighlightedView()); SendKey(ui::VKEY_TAB); - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - // When Jellyroll is enabled, desks bar never goes back to zero state after - // it's initialized. - if (is_jellyroll_enabled) { - EXPECT_FALSE(desk_bar_view->IsZeroState()); - } else { - EXPECT_TRUE(desk_bar_view->IsZeroState()); - } - + // Desks bar never goes back to zero state after it's initialized. + EXPECT_FALSE(desk_bar_view->IsZeroState()); EXPECT_EQ(desk_bar_view->mini_views()[0]->desk_preview(), GetHighlightedView()); } @@ -882,23 +866,14 @@ ASSERT_EQ(2u, desks_bar_view->mini_views().size()); // Remove one desk to enter zero state desks bar. - auto* event_generator = GetEventGenerator(); auto* mini_view = desks_bar_view->mini_views()[1]; - event_generator->MoveMouseTo(mini_view->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->MoveMouseTo( + mini_view->GetBoundsInScreen().CenterPoint()); EXPECT_TRUE(GetDeskActionVisibilityForMiniView(mini_view)); - event_generator->MoveMouseTo(GetCloseDeskButtonForMiniView(mini_view) - ->GetBoundsInScreen() - .CenterPoint()); - event_generator->ClickLeftButton(); + LeftClickOn(GetCloseDeskButtonForMiniView(mini_view)); - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - // When Jellyroll is enabled, desks bar never goes back to zero state after - // it's initialized. - if (is_jellyroll_enabled) { - ASSERT_FALSE(desks_bar_view->IsZeroState()); - } else { - ASSERT_TRUE(desks_bar_view->IsZeroState()); - } + // Desks bar never goes back to zero state after it's initialized. + ASSERT_FALSE(desks_bar_view->IsZeroState()); // Both zero state default desk button and zero state new desk button can be // focused in overview mode. @@ -970,22 +945,14 @@ GetHighlightedView()); // Remove one desk to have only one desk left. - auto* event_generator = GetEventGenerator(); auto* mini_view = desks_bar_view->mini_views()[1]; - event_generator->MoveMouseTo(mini_view->GetBoundsInScreen().CenterPoint()); + GetEventGenerator()->MoveMouseTo( + mini_view->GetBoundsInScreen().CenterPoint()); ASSERT_TRUE(GetDeskActionVisibilityForMiniView(mini_view)); - event_generator->MoveMouseTo(GetCloseDeskButtonForMiniView(mini_view) - ->GetBoundsInScreen() - .CenterPoint()); - event_generator->ClickLeftButton(); + LeftClickOn(GetCloseDeskButtonForMiniView(mini_view)); - // When Jellyroll is enabled, desks bar never goes back to zero state after - // it's initialized. - if (chromeos::features::IsJellyrollEnabled()) { - ASSERT_FALSE(desks_bar_view->IsZeroState()); - } else { - ASSERT_TRUE(desks_bar_view->IsZeroState()); - } + // Desks bar never goes back to zero state after it's initialized. + ASSERT_FALSE(desks_bar_view->IsZeroState()); // Try tabbing after removing the second desk triggers us to transition to // zero state desks bar. There should not be a crash.
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index d5e517d..c6ac457 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -74,7 +74,6 @@ #include "base/numerics/safe_conversions.h" #include "base/ranges/algorithm.h" #include "base/trace_event/trace_event.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/window_properties.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/l10n/l10n_util.h" @@ -581,8 +580,7 @@ // After this, the desk bar widget will not be owned by this overview grid // anymore. if (desks_widget_) { - if (chromeos::features::IsJellyrollEnabled() && - exit_type != OverviewEnterExitType::kImmediateExit) { + if (exit_type != OverviewEnterExitType::kImmediateExit) { PerformDeskBarSlideAnimation(std::move(desks_widget_), desks_bar_view_->IsZeroState()); } @@ -1587,7 +1585,6 @@ return true; }; - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); for (auto* mini_view : desks_bar_view_->mini_views()) { if (!mini_view->IsPointOnMiniView(screen_location)) continue; @@ -1596,14 +1593,11 @@ if (target_desk == desks_controller->active_desk()) return false; - if (is_jellyroll_enabled) { - // Make sure that new desk button goes back to the expanded state after - // the window is dropped on an existing desk. - desks_bar_view_->UpdateDeskIconButtonState( - desks_bar_view_->new_desk_button(), - /*target_state=*/CrOSNextDeskIconButton::State::kExpanded); - } - + // Make sure that new desk button goes back to the expanded state after + // the window is dropped on an existing desk. + desks_bar_view_->UpdateDeskIconButtonState( + desks_bar_view_->new_desk_button(), + /*target_state=*/CrOSNextDeskIconButton::State::kExpanded); return move_windows_to_target_desk(target_desk); } @@ -1888,7 +1882,7 @@ if (desks_bar_view_->IsZeroState()) { desks_bar_view_->UpdateNewMiniViews(/*initializing_bar_view=*/false, /*expanding_bar_view=*/true); - } else if (chromeos::features::IsJellyrollEnabled()) { + } else { desks_bar_view_->UpdateDeskIconButtonState( desks_bar_view_->library_button(), /*target_state=*/CrOSNextDeskIconButton::State::kActive); @@ -1944,14 +1938,12 @@ /*animate=*/true, base::BindOnce(&OverviewGrid::OnSavedDeskGridFadedOut, weak_ptr_factory_.GetWeakPtr())); - if (chromeos::features::IsJellyrollEnabled()) { - // The saved desk library is hidden because of a new desk is created for - // saved desk. We have animation of adding a new desk for the library - // button, thus to avoid the animation glitches, directly update the state - // for the library button instead of applying the scale animation to it. - desks_bar_view_->library_button()->UpdateState( - CrOSNextDeskIconButton::State::kExpanded); - } + // The saved desk library is hidden because of a new desk is created for + // saved desk. We have animation of adding a new desk for the library + // button, thus to avoid the animation glitches, directly update the state + // for the library button instead of applying the scale animation to it. + desks_bar_view_->library_button()->UpdateState( + CrOSNextDeskIconButton::State::kExpanded); } bool OverviewGrid::IsShowingSavedDeskLibrary() const {
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 5839afd..215567f 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -44,7 +44,6 @@ #include "base/functional/callback_helpers.h" #include "base/metrics/user_metrics.h" #include "base/trace_event/trace_event.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/window_state_type.h" #include "ui/aura/client/aura_constants.h" #include "ui/base/l10n/l10n_util.h" @@ -873,8 +872,7 @@ DCHECK_GT(Shell::GetAllRootWindows().size(), 1u); const bool minimized_or_tucked = transform_window_.IsMinimizedOrTucked(); - // With Jellyroll, header is visible while dragging. - if (minimized_or_tucked || chromeos::features::IsJellyrollEnabled()) { + if (minimized_or_tucked) { if (!item_mirror_for_dragging_) { item_mirror_for_dragging_ = std::make_unique<DragWindowController>( item_widget_->GetNativeWindow(), is_touch_dragging);
diff --git a/ash/wm/overview/overview_item_base.cc b/ash/wm/overview/overview_item_base.cc index c2337a3..0f625df 100644 --- a/ash/wm/overview/overview_item_base.cc +++ b/ash/wm/overview/overview_item_base.cc
@@ -21,7 +21,6 @@ #include "ash/wm/snap_group/snap_group.h" #include "ash/wm/snap_group/snap_group_controller.h" #include "ash/wm/splitview/split_view_utils.h" -#include "chromeos/constants/chromeos_features.h" namespace ash { @@ -69,9 +68,7 @@ return; } - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - const gfx::RectF shadow_bounds_in_screen = - is_jellyroll_enabled ? target_bounds_ : GetTargetBoundsWithInsets(); + const gfx::RectF shadow_bounds_in_screen = target_bounds_; auto* shadow_layer = shadow_->GetLayer(); if (!shadow_visible || shadow_bounds_in_screen.IsEmpty()) { shadow_layer->SetVisible(false); @@ -83,8 +80,7 @@ gfx::Rect shadow_content_bounds( gfx::ToRoundedRect(shadow_bounds_in_screen).size()); shadow_->SetContentBounds(shadow_content_bounds); - shadow_->SetRoundedCornerRadius( - is_jellyroll_enabled ? kOverviewItemCornerRadius : 0); + shadow_->SetRoundedCornerRadius(kOverviewItemCornerRadius); } void OverviewItemBase::UpdateShadowTypeForDrag(bool is_dragging) {
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index 3592383..730e300 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -34,7 +34,6 @@ #include "base/functional/callback_helpers.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" -#include "chromeos/constants/chromeos_features.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/compositor/layer.h" @@ -128,25 +127,23 @@ overview_grid->root_window()->bounds().height(); gfx::SizeF scaled_size = gfx::ScaleSize(window_original_size, scale_factor); - if (chromeos::features::IsJellyrollEnabled()) { - // Adjust the scaled size to ensure that its smaller side length is equal or - // larger than the `minimum_size_length`, and then adjust the larger size - // length to preserve the ratio of the original size. - const float minimum_size_length = - expanded_desks_bar_height * kScaleFactorForMinimumSideLength; - const float scaled_size_height = scaled_size.height(); - const float scaled_size_width = scaled_size.width(); - if (scaled_size_height < minimum_size_length || - scaled_size_width < minimum_size_length) { - if (scaled_size_height < scaled_size_width) { - scaled_size.set_height(minimum_size_length); - scaled_size.set_width(scaled_size_width / scaled_size_height * - minimum_size_length); - } else { - scaled_size.set_width(minimum_size_length); - scaled_size.set_height(scaled_size_height / scaled_size_width * - minimum_size_length); - } + // Adjust the scaled size to ensure that its smaller side length is equal or + // larger than the `minimum_size_length`, and then adjust the larger size + // length to preserve the ratio of the original size. + const float minimum_size_length = + expanded_desks_bar_height * kScaleFactorForMinimumSideLength; + const float scaled_size_height = scaled_size.height(); + const float scaled_size_width = scaled_size.width(); + if (scaled_size_height < minimum_size_length || + scaled_size_width < minimum_size_length) { + if (scaled_size_height < scaled_size_width) { + scaled_size.set_height(minimum_size_length); + scaled_size.set_width(scaled_size_width / scaled_size_height * + minimum_size_length); + } else { + scaled_size.set_width(minimum_size_length); + scaled_size.set_height(scaled_size_height / scaled_size_width * + minimum_size_length); } } @@ -360,11 +357,10 @@ auto* overview_grid = item_->overview_grid(); overview_grid->AddDropTargetForDraggingFromThisGrid(item_); - // Expand desks bar when normal drag starts and desks bar is in zero state for - // feature Jellyroll. + // Expand desks bar when normal drag starts and desks bar is in zero state. + // The bar may be null if we have no desks in tablet mode. if (auto* desks_bar_view = overview_grid->desks_bar_view(); - desks_bar_view && desks_bar_view->IsZeroState() && - chromeos::features::IsJellyrollEnabled()) { + desks_bar_view && desks_bar_view->IsZeroState()) { desks_bar_view->UpdateNewMiniViews(/*initializing_bar_view=*/false, /*expanding_bar_view=*/true); } @@ -624,19 +620,6 @@ // can satisfy all cases. centerpoint = location_in_screen; - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - - // When `Jellyroll` is enabled, the header is shown for the item being - // dragged, thus no need to adjust the centerpoint in this case. - if (!is_jellyroll_enabled) { - // To make the dragged window contents appear centered around the drag - // location, we need to take into account the margins applied on the - // target bounds, and offset up the centerpoint by half that amount, so - // that the transformed bounds of the window contents move up to be - // centered around the cursor. - centerpoint.Offset(0, -kHeaderHeightDp / 2); - } - const auto iter = per_grid_desks_bar_data_.find(overview_grid); DCHECK(iter != per_grid_desks_bar_data_.end()); const GridDesksBarData& desks_bar_data = iter->second; @@ -702,12 +685,12 @@ bounds.set_y(centerpoint.y() - bounds.height() / 2.f); item_->SetBounds(bounds, OVERVIEW_ANIMATION_NONE); - auto* desks_bar_view = overview_grid->desks_bar_view(); - if (desks_bar_view) { + // The bar may be null if we have no desks in tablet mode. + if (auto* desks_bar_view = overview_grid->desks_bar_view()) { auto* new_desk_button = desks_bar_view->new_desk_button(); - // When `Jellyroll` is enabled, the header of window is shown during - // dragging. Overview item should be hovered on the new desk button with + // The header of window is shown during dragging. Overview item should be + // hovered on the new desk button with // `kVerticalOverlappedLengthToActivateNewDeskButton` overlapped vertical // area in order to activate the new desk button. There could be a lot of // mistriggers with header shown if the new desk button is activated when
diff --git a/ash/wm/overview/overview_window_drag_controller_unittest.cc b/ash/wm/overview/overview_window_drag_controller_unittest.cc index a176139..c009d758 100644 --- a/ash/wm/overview/overview_window_drag_controller_unittest.cc +++ b/ash/wm/overview/overview_window_drag_controller_unittest.cc
@@ -28,7 +28,6 @@ #include "base/containers/contains.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" -#include "chromeos/constants/chromeos_features.h" #include "ui/aura/window_tree_host.h" #include "ui/display/test/display_manager_test_api.h" #include "ui/events/test/event_generator.h" @@ -358,14 +357,9 @@ const auto* desks_bar_view = overview_grid()->desks_bar_view(); ASSERT_TRUE(desks_bar_view); - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - - // Check the height of the desks bar view. - // When Jellyroll is enabled, desks bar is transformed to expanded state - // immediately at the beginning of the drag. - EXPECT_EQ(is_jellyroll_enabled - ? GetDesksBarViewExpandedStateHeight(desks_bar_view) - : kDeskBarZeroStateHeight, + // Check the height of the desks bar view. Desks bar is transformed to + // expanded state immediately at the beginning of the drag. + EXPECT_EQ(GetDesksBarViewExpandedStateHeight(desks_bar_view), desks_bar_view->bounds().height()); // Now drop `window`. Check the height of the desks bar view. It should still @@ -373,39 +367,27 @@ auto* event_generator = GetEventGenerator(); event_generator->ReleaseLeftButton(); - // When Jellyroll is enabled, desks bar never goes back to zero state after - // it's initialized. - EXPECT_EQ(is_jellyroll_enabled - ? GetDesksBarViewExpandedStateHeight(desks_bar_view) - : kDeskBarZeroStateHeight, + // Desks bar never goes back to zero state after it is initialized. + EXPECT_EQ(GetDesksBarViewExpandedStateHeight(desks_bar_view), desks_bar_view->bounds().height()); // Click on the zero state new desk button to create a new desk. This // shouldn't end overview mode. The desks bar view should be transformed to // the expanded state. - auto* new_desk_button = desks_bar_view->new_desk_button(); - - const gfx::Point new_desk_button_center = - new_desk_button->GetBoundsInScreen().CenterPoint(); EXPECT_TRUE(OverviewController::Get()->InOverviewSession()); - event_generator->MoveMouseTo(new_desk_button_center); - event_generator->ClickLeftButton(); + LeftClickOn(desks_bar_view->new_desk_button()); EXPECT_EQ(GetDesksBarViewExpandedStateHeight(desks_bar_view), desks_bar_view->bounds().height()); // Now remove the newly created desk. This shouldn't end overview mode. The - // desks bar view should be transformed to the zero state. + // desks bar view should stay in expanded state. auto* controller = Shell::Get()->desks_controller(); controller->RemoveDesk(controller->desks().back().get(), DesksCreationRemovalSource::kButton, DeskCloseType::kCombineDesks); EXPECT_TRUE(OverviewController::Get()->InOverviewSession()); - EXPECT_EQ(is_jellyroll_enabled ? DeskBarViewBase::State::kExpanded - : DeskBarViewBase::State::kZero, - desks_bar_view->state()); - EXPECT_EQ(is_jellyroll_enabled - ? GetDesksBarViewExpandedStateHeight(desks_bar_view) - : kDeskBarZeroStateHeight, + EXPECT_EQ(DeskBarViewBase::State::kExpanded, desks_bar_view->state()); + EXPECT_EQ(GetDesksBarViewExpandedStateHeight(desks_bar_view), desks_bar_view->bounds().height()); }
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc index 8c085aa..cd96962c 100644 --- a/ash/wm/overview/scoped_overview_transform_window.cc +++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -30,7 +30,6 @@ #include "ash/wm/window_util.h" #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/window_properties.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/transient_window_client.h" @@ -45,7 +44,6 @@ #include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/gfx/geometry/transform_util.h" #include "ui/gfx/geometry/vector2d_f.h" -#include "ui/views/layout/layout_provider.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/shadow_controller.h" @@ -600,19 +598,12 @@ return; } - const float scale = layer->transform().To2dScale().x(); - if (!chromeos::features::IsJellyrollEnabled()) { - const int radius = views::LayoutProvider::Get()->GetCornerRadiusMetric( - views::Emphasis::kLow); - layer->SetRoundedCornerRadius(gfx::RoundedCornersF(radius / scale)); - return; - } - // Depending on the size of `backdrop_view`, we might not want to round the // window associated with `layer`. const bool has_rounding = window_util::ShouldRoundThumbnailWindow( overview_item_->GetBackDropView(), GetTransformedBounds()); + const float scale = layer->transform().To2dScale().x(); layer->SetRoundedCornerRadius( has_rounding ? GetRoundedCornersForTransformWindow(window_, scale) : gfx::RoundedCornersF(0));
diff --git a/ash/wm/splitview/split_view_divider_view.cc b/ash/wm/splitview/split_view_divider_view.cc index 546d390..b1da7a9 100644 --- a/ash/wm/splitview/split_view_divider_view.cc +++ b/ash/wm/splitview/split_view_divider_view.cc
@@ -7,7 +7,6 @@ #include "ash/display/screen_orientation_controller.h" #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" -#include "ash/style/ash_color_id.h" #include "ash/utility/cursor_setter.h" #include "ash/wm/snap_group/snap_group.h" #include "ash/wm/splitview/split_view_constants.h" @@ -15,7 +14,6 @@ #include "ash/wm/splitview/split_view_divider.h" #include "ash/wm/splitview/split_view_divider_handler_view.h" #include "ash/wm/splitview/split_view_utils.h" -#include "chromeos/constants/chromeos_features.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/compositor/layer.h" @@ -39,17 +37,11 @@ SetPaintToLayer(ui::LAYER_TEXTURED); layer()->SetFillsBoundsOpaquely(false); - const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled(); - SetBackground(views::CreateThemedSolidBackground( - is_jellyroll_enabled - ? static_cast<ui::ColorId>(cros_tokens::kCrosSysSystemBaseElevated) - : kColorAshShieldAndBaseOpaque)); + cros_tokens::kCrosSysSystemBaseElevated)); SetBorder(std::make_unique<views::HighlightBorder>( /*corner_radius=*/0, - is_jellyroll_enabled - ? views::HighlightBorder::Type::kHighlightBorderNoShadow - : views::HighlightBorder::Type::kHighlightBorder1)); + views::HighlightBorder::Type::kHighlightBorderNoShadow)); } SplitViewDividerView::~SplitViewDividerView() = default;
diff --git a/base/android/jank_metric_uma_recorder.cc b/base/android/jank_metric_uma_recorder.cc index 2c9c1b5a9..bca271ee 100644 --- a/base/android/jank_metric_uma_recorder.cc +++ b/base/android/jank_metric_uma_recorder.cc
@@ -110,11 +110,11 @@ void JNI_JankMetricUMARecorder_RecordJankMetrics( JNIEnv* env, const base::android::JavaParamRef<jlongArray>& java_durations_ns, - const base::android::JavaParamRef<jbooleanArray>& java_jank_status, + const base::android::JavaParamRef<jintArray>& java_missed_vsyncs, jlong java_reporting_interval_start_time, jlong java_reporting_interval_duration, jint java_scenario_enum) { - RecordJankMetrics(env, java_durations_ns, java_jank_status, + RecordJankMetrics(env, java_durations_ns, java_missed_vsyncs, java_reporting_interval_start_time, java_reporting_interval_duration, java_scenario_enum); } @@ -122,15 +122,15 @@ void RecordJankMetrics( JNIEnv* env, const base::android::JavaParamRef<jlongArray>& java_durations_ns, - const base::android::JavaParamRef<jbooleanArray>& java_jank_status, + const base::android::JavaParamRef<jintArray>& java_missed_vsyncs, jlong java_reporting_interval_start_time, jlong java_reporting_interval_duration, jint java_scenario_enum) { std::vector<int64_t> durations_ns; JavaLongArrayToInt64Vector(env, java_durations_ns, &durations_ns); - std::vector<bool> jank_status; - JavaBooleanArrayToBoolVector(env, java_jank_status, &jank_status); + std::vector<int> missed_vsyncs; + JavaIntArrayToIntVector(env, java_missed_vsyncs, &missed_vsyncs); JankScenario scenario = static_cast<JankScenario>(java_scenario_enum); @@ -146,7 +146,8 @@ uint64_t janky_frame_count = 0; - for (bool is_janky : jank_status) { + for (int curr_frame_missed_vsyncs : missed_vsyncs) { + bool is_janky = curr_frame_missed_vsyncs > 0; base::UmaHistogramEnumeration( janky_frames_per_scenario_histogram_name, is_janky ? FrameJankStatus::kJanky : FrameJankStatus::kNonJanky); @@ -157,7 +158,7 @@ RecordJankMetricReportingIntervalTraceEvent( java_reporting_interval_start_time, java_reporting_interval_duration, - janky_frame_count, jank_status.size() - janky_frame_count, + janky_frame_count, missed_vsyncs.size() - janky_frame_count, java_scenario_enum); }
diff --git a/base/android/jank_metric_uma_recorder.h b/base/android/jank_metric_uma_recorder.h index 18fb1d48..a889a5e 100644 --- a/base/android/jank_metric_uma_recorder.h +++ b/base/android/jank_metric_uma_recorder.h
@@ -47,7 +47,7 @@ BASE_EXPORT void RecordJankMetrics( JNIEnv* env, const base::android::JavaParamRef<jlongArray>& java_durations_ns, - const base::android::JavaParamRef<jbooleanArray>& java_jank_status, + const base::android::JavaParamRef<jintArray>& java_missed_vsyncs, jlong java_reporting_interval_start_time, jlong java_reporting_interval_duration, jint java_scenario_enum);
diff --git a/base/android/jank_metric_uma_recorder_unittest.cc b/base/android/jank_metric_uma_recorder_unittest.cc index 38bb1b0e..4659d4ac 100644 --- a/base/android/jank_metric_uma_recorder_unittest.cc +++ b/base/android/jank_metric_uma_recorder_unittest.cc
@@ -46,19 +46,19 @@ }; const size_t kDurationsLen = std::size(kDurations); -jbooleanArray GenerateJavaBooleanArray(JNIEnv* env, - const bool bool_array[], - const size_t array_length) { - ScopedJavaLocalRef<jbooleanArray> java_bool_array = - ToJavaBooleanArray(env, bool_array, array_length); +jintArray GenerateJavaIntArray(JNIEnv* env, + const int int_array[], + const size_t array_length) { + ScopedJavaLocalRef<jintArray> java_int_array = + ToJavaIntArray(env, int_array, array_length); - return java_bool_array.Release(); + return java_int_array.Release(); } -const bool kJankStatus[] = { - false, false, true, false, true, false, false, false, +const int kMissedVsyncs[] = { + 0, 0, 2, 0, 1, 0, 0, 0, }; -const size_t kJankStatusLen = kDurationsLen; +const size_t kMissedVsyncsLen = kDurationsLen; } // namespace @@ -69,8 +69,8 @@ jlongArray java_durations = GenerateJavaLongArray(env, kDurations, kDurationsLen); - jbooleanArray java_jank_status = - GenerateJavaBooleanArray(env, kJankStatus, kJankStatusLen); + jintArray java_missed_vsyncs = + GenerateJavaIntArray(env, kMissedVsyncs, kMissedVsyncsLen); const int kMinScenario = static_cast<int>(JankScenario::PERIODIC_REPORTING); const int kMaxScenario = static_cast<int>(JankScenario::MAX_VALUE); @@ -87,8 +87,8 @@ env, /* java_durations_ns= */ base::android::JavaParamRef<jlongArray>(env, java_durations), - /* java_jank_status = */ - base::android::JavaParamRef<jbooleanArray>(env, java_jank_status), + /* java_missed_vsyncs = */ + base::android::JavaParamRef<jintArray>(env, java_missed_vsyncs), /* java_reporting_interval_start_time = */ 0, /* java_reporting_interval_duration = */ 1000, /* java_scenario_enum = */ i);
diff --git a/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java b/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java index 51493ac..673afb3 100644 --- a/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java +++ b/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsListener.java
@@ -4,13 +4,19 @@ package org.chromium.base.jank_tracker; +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; import android.os.Build.VERSION_CODES; +import android.view.Display; import android.view.FrameMetrics; import android.view.Window; import android.view.Window.OnFrameMetricsAvailableListener; import androidx.annotation.RequiresApi; +import org.chromium.base.ContextUtils; +import org.chromium.base.TimeUtils; import org.chromium.base.TraceEvent; import java.util.concurrent.atomic.AtomicBoolean; @@ -21,11 +27,52 @@ */ @RequiresApi(api = VERSION_CODES.N) public class FrameMetricsListener implements OnFrameMetricsAvailableListener { + private class DisplayListenerBackend implements DisplayListener { + public void startListening() { + Context appCtx = ContextUtils.getApplicationContext(); + DisplayManager displayManager = + (DisplayManager) appCtx.getSystemService(Context.DISPLAY_SERVICE); + displayManager.registerDisplayListener(this, /* handler= */ null); + } + + @Override + public void onDisplayAdded(int sdkDisplayId) {} + + @Override + public void onDisplayRemoved(int sdkDisplayId) {} + + @Override + public void onDisplayChanged(int sdkDisplayId) { + maybeUpdateRefreshRate(); + } + } + + private DisplayListenerBackend mBackend = new DisplayListenerBackend(); + private final FrameMetricsStore mFrameMetricsStore; private AtomicBoolean mIsRecording = new AtomicBoolean(false); + // Microseconds between each frame. + private long mVsyncInterval; public FrameMetricsListener(FrameMetricsStore frameMetricsStore) { mFrameMetricsStore = frameMetricsStore; + mBackend.startListening(); + maybeUpdateRefreshRate(); + } + + private void maybeUpdateRefreshRate() { + Context appCtx = ContextUtils.getApplicationContext(); + DisplayManager displayManager = + (DisplayManager) appCtx.getSystemService(Context.DISPLAY_SERVICE); + Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + if (display == null) { + return; + } + float refreshRate = display.getRefreshRate(); + final long kMicrosecondsPerSecond = 1000_000L; + mVsyncInterval = kMicrosecondsPerSecond / ((long) refreshRate); + TraceEvent.instant( + "FrameMetricsListener.maybeUpdateRefreshRate", Long.toString(mVsyncInterval)); } /** @@ -50,10 +97,17 @@ try (TraceEvent e = TraceEvent.scoped( "onFrameMetricsAvailable", Long.toString(frameTotalDurationNs))) { + // FrameMetrics.DEADLINE was added in API level 31(S). + // TODO(b/311139161): Update RequiresApi level to Android S. long deadlineNs = frameMetrics.getMetric(FrameMetrics.DEADLINE); - boolean isJanky = frameTotalDurationNs >= deadlineNs; + int missedVsyncs = 0; + if (frameTotalDurationNs >= deadlineNs) { + long frameDeadlineDeltaUs = + (frameTotalDurationNs - deadlineNs) / TimeUtils.NANOSECONDS_PER_MICROSECOND; + missedVsyncs = (int) ((frameDeadlineDeltaUs + mVsyncInterval) / mVsyncInterval); + } mFrameMetricsStore.addFrameMeasurement( - frameTotalDurationNs, isJanky, frame_start_vsync_ts); + frameTotalDurationNs, missedVsyncs, frame_start_vsync_ts); } } }
diff --git a/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsStore.java b/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsStore.java index 97866b0..ccdfcc9 100644 --- a/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsStore.java +++ b/base/android/java/src/org/chromium/base/jank_tracker/FrameMetricsStore.java
@@ -35,9 +35,10 @@ // Array of total durations stored in nanoseconds, they represent how long each frame took to // draw. private final ArrayList<Long> mTotalDurationsNs = new ArrayList<>(); - // Array of boolean values denoting whether a given frame is janky or not. Must always be the - // same size as mTotalDurationsNs. - private final ArrayList<Boolean> mIsJanky = new ArrayList<>(); + // Array of integers denoting number of vsyncs we missed for given frame. 0 missed vsyncs mean + // no jank, while >0 missed vsyncs mean the frame was janky. Must always be the same size as + // mTotalDurationsNs. + private final ArrayList<Integer> mNumMissedVsyncs = new ArrayList<>(); // Stores the timestamp (nanoseconds) of the most recent frame metric as a scenario started. // Zero if no FrameMetrics have been received. private final HashMap<Integer, Long> mScenarioPreviousFrameTimestampNs = new HashMap<>(); @@ -51,7 +52,7 @@ // Add arbitrary values to related arrays as well since we always want them to be of same // size. mTotalDurationsNs.add(0L); - mIsJanky.add(false); + mNumMissedVsyncs.add(0); } // Convert an enum value to string to use as an UMA histogram name, changes to strings should be @@ -91,13 +92,11 @@ mThreadChecker = new ThreadChecker(); } - /** - * Records the total draw duration and jankiness for a single frame. - */ - void addFrameMeasurement(long totalDurationNs, boolean isJanky, long frameStartVsyncTs) { + /** Records the total draw duration and jankiness for a single frame. */ + void addFrameMeasurement(long totalDurationNs, int numMissedVsyncs, long frameStartVsyncTs) { mThreadChecker.assertOnValidThread(); mTotalDurationsNs.add(totalDurationNs); - mIsJanky.add(isJanky); + mNumMissedVsyncs.add(numMissedVsyncs); mTimestampsNs.add(frameStartVsyncTs); mMaxTimestamp = frameStartVsyncTs; } @@ -185,9 +184,10 @@ } JankMetrics jankMetrics = - convertArraysToJankMetrics(mTimestampsNs.subList(startingIndex, endingIndex), + convertArraysToJankMetrics( + mTimestampsNs.subList(startingIndex, endingIndex), mTotalDurationsNs.subList(startingIndex, endingIndex), - mIsJanky.subList(startingIndex, endingIndex)); + mNumMissedVsyncs.subList(startingIndex, endingIndex)); removeUnusedFrames(); Long pendingStartTimestampNs = mPendingStartTimestampNs.remove(scenario); @@ -203,7 +203,7 @@ TraceEvent.instant("removeUnusedFrames", Long.toString(mTimestampsNs.size())); mTimestampsNs.subList(1, mTimestampsNs.size()).clear(); mTotalDurationsNs.subList(1, mTotalDurationsNs.size()).clear(); - mIsJanky.subList(1, mIsJanky.size()).clear(); + mNumMissedVsyncs.subList(1, mNumMissedVsyncs.size()).clear(); return; } @@ -226,7 +226,7 @@ mTimestampsNs.subList(1, firstUsedIndex).clear(); mTotalDurationsNs.subList(1, firstUsedIndex).clear(); - mIsJanky.subList(1, firstUsedIndex).clear(); + mNumMissedVsyncs.subList(1, firstUsedIndex).clear(); } private long findFirstUsedTimestamp() { @@ -241,7 +241,9 @@ } private JankMetrics convertArraysToJankMetrics( - List<Long> longTimestampsNs, List<Long> longDurations, List<Boolean> booleanIsJanky) { + List<Long> longTimestampsNs, + List<Long> longDurations, + List<Integer> intNumMissedVsyncs) { long[] timestamps = new long[longTimestampsNs.size()]; for (int i = 0; i < longTimestampsNs.size(); i++) { timestamps[i] = longTimestampsNs.get(i).longValue(); @@ -252,12 +254,12 @@ durations[i] = longDurations.get(i).longValue(); } - boolean[] isJanky = new boolean[booleanIsJanky.size()]; - for (int i = 0; i < booleanIsJanky.size(); i++) { - isJanky[i] = booleanIsJanky.get(i).booleanValue(); + int[] numMissedVsyncs = new int[intNumMissedVsyncs.size()]; + for (int i = 0; i < intNumMissedVsyncs.size(); i++) { + numMissedVsyncs[i] = intNumMissedVsyncs.get(i).intValue(); } - JankMetrics jankMetrics = new JankMetrics(timestamps, durations, isJanky); + JankMetrics jankMetrics = new JankMetrics(timestamps, durations, numMissedVsyncs); return jankMetrics; } }
diff --git a/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java b/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java index fb3ee8a2..d5a5ce8f 100644 --- a/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java +++ b/base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java
@@ -17,13 +17,22 @@ if (metric == null) { return; } - JankMetricUMARecorderJni.get().recordJankMetrics(metric.durationsNs, metric.isJanky, - reportingIntervalStartTime, reportingIntervalDuration, scenario); + JankMetricUMARecorderJni.get() + .recordJankMetrics( + metric.durationsNs, + metric.missedVsyncs, + reportingIntervalStartTime, + reportingIntervalDuration, + scenario); } @NativeMethods public interface Natives { - void recordJankMetrics(long[] durationsNs, boolean[] jankStatus, - long reportingIntervalStartTime, long reportingIntervalDuration, int scenario); + void recordJankMetrics( + long[] durationsNs, + int[] missedVsyncs, + long reportingIntervalStartTime, + long reportingIntervalDuration, + int scenario); } }
diff --git a/base/android/java/src/org/chromium/base/jank_tracker/JankMetrics.java b/base/android/java/src/org/chromium/base/jank_tracker/JankMetrics.java index 36b84e9..62daec4 100644 --- a/base/android/java/src/org/chromium/base/jank_tracker/JankMetrics.java +++ b/base/android/java/src/org/chromium/base/jank_tracker/JankMetrics.java
@@ -11,15 +11,20 @@ class JankMetrics { public final long[] timestampsNs; public final long[] durationsNs; + public final int[] missedVsyncs; public final boolean[] isJanky; + public JankMetrics() { timestampsNs = new long[0]; durationsNs = new long[0]; + missedVsyncs = new int[0]; isJanky = new boolean[0]; } - public JankMetrics(long[] timestampsNs, long[] durationsNs, boolean[] isJanky) { + + public JankMetrics(long[] timestampsNs, long[] durationsNs, int[] missedVsyncs) { this.timestampsNs = timestampsNs; this.durationsNs = durationsNs; - this.isJanky = isJanky; + this.missedVsyncs = missedVsyncs; + isJanky = new boolean[0]; } }
diff --git a/base/android/junit/src/org/chromium/base/jank_tracker/FrameMetricsStoreTest.java b/base/android/junit/src/org/chromium/base/jank_tracker/FrameMetricsStoreTest.java index 8971092..4797e2a 100644 --- a/base/android/junit/src/org/chromium/base/jank_tracker/FrameMetricsStoreTest.java +++ b/base/android/junit/src/org/chromium/base/jank_tracker/FrameMetricsStoreTest.java
@@ -30,17 +30,17 @@ store.startTrackingScenario(JankScenario.NEW_TAB_PAGE); long frame_start_vsync_ts = 0; - store.addFrameMeasurement(10_000_000L, false, frame_start_vsync_ts); - store.addFrameMeasurement(12_000_000L, false, frame_start_vsync_ts); - store.addFrameMeasurement(20_000_000L, true, frame_start_vsync_ts); - store.addFrameMeasurement(8_000_000L, true, frame_start_vsync_ts); + store.addFrameMeasurement(10_000_000L, 0, frame_start_vsync_ts); + store.addFrameMeasurement(12_000_000L, 0, frame_start_vsync_ts); + store.addFrameMeasurement(20_000_000L, 1, frame_start_vsync_ts); + store.addFrameMeasurement(8_000_000L, 2, frame_start_vsync_ts); JankMetrics metrics = store.stopTrackingScenario(JankScenario.NEW_TAB_PAGE); assertArrayEquals( new long[] {10_000_000L, 12_000_000L, 20_000_000L, 8_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false, false, true, true}, metrics.isJanky); + assertArrayEquals(new int[] {0, 0, 1, 2}, metrics.missedVsyncs); metrics = store.stopTrackingScenario(JankScenario.NEW_TAB_PAGE); assertEquals(0, metrics.durationsNs.length); @@ -69,11 +69,11 @@ store.startTrackingScenario(JankScenario.NEW_TAB_PAGE); long frame_start_vsync_ts = 1_000_000L; - store.addFrameMeasurement(10_000_000L, false, frame_start_vsync_ts); - store.addFrameMeasurement(12_000_000L, false, frame_start_vsync_ts + 1); + store.addFrameMeasurement(10_000_000L, 0, frame_start_vsync_ts); + store.addFrameMeasurement(12_000_000L, 0, frame_start_vsync_ts + 1); store.startTrackingScenario(JankScenario.FEED_SCROLLING); - store.addFrameMeasurement(20_000_000L, true, frame_start_vsync_ts + 2); - store.addFrameMeasurement(8_000_000L, true, frame_start_vsync_ts + 3); + store.addFrameMeasurement(20_000_000L, 2, frame_start_vsync_ts + 2); + store.addFrameMeasurement(8_000_000L, 1, frame_start_vsync_ts + 3); // Stop NEW_TAB_PAGE and now the first two frames will be deleted from the // FrameMetricsStore(). @@ -82,7 +82,7 @@ assertArrayEquals( new long[] {10_000_000L, 12_000_000L, 20_000_000L, 8_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false, false, true, true}, metrics.isJanky); + assertArrayEquals(new int[] {0, 0, 2, 1}, metrics.missedVsyncs); metrics = store.stopTrackingScenario(JankScenario.NEW_TAB_PAGE); assertEquals(0, metrics.durationsNs.length); @@ -90,7 +90,7 @@ // Only after that will we stop FEED_SCROLLING and we should only see the last two frames. metrics = store.stopTrackingScenario(JankScenario.FEED_SCROLLING); assertArrayEquals(new long[] {20_000_000L, 8_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {true, true}, metrics.isJanky); + assertArrayEquals(new int[] {2, 1}, metrics.missedVsyncs); } @Test @@ -102,30 +102,30 @@ store.startTrackingScenario(JankScenario.WEBVIEW_SCROLLING); long frame_start_vsync_ts = 1_000_000L; - store.addFrameMeasurement(10_000_000L, false, frame_start_vsync_ts); - store.addFrameMeasurement(12_000_000L, true, frame_start_vsync_ts + 1); + store.addFrameMeasurement(10_000_000L, 0, frame_start_vsync_ts); + store.addFrameMeasurement(12_000_000L, 1, frame_start_vsync_ts + 1); JankMetrics metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING); assertArrayEquals(new long[] {10_000_000L, 12_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false, true}, metrics.isJanky); + assertArrayEquals(new int[] {0, 1}, metrics.missedVsyncs); store.startTrackingScenario(JankScenario.WEBVIEW_SCROLLING); - store.addFrameMeasurement(10_000_100L, true, frame_start_vsync_ts + 2); - store.addFrameMeasurement(11_000_100L, false, frame_start_vsync_ts + 3); + store.addFrameMeasurement(10_000_100L, 2, frame_start_vsync_ts + 2); + store.addFrameMeasurement(11_000_100L, 0, frame_start_vsync_ts + 3); store.startTrackingScenario(JankScenario.NEW_TAB_PAGE); - store.addFrameMeasurement(12_000_100L, false, frame_start_vsync_ts + 4); + store.addFrameMeasurement(12_000_100L, 0, frame_start_vsync_ts + 4); metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING); assertArrayEquals(new long[] {10_000_100L, 11_000_100L, 12_000_100L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {true, false, false}, metrics.isJanky); + assertArrayEquals(new int[] {2, 0, 0}, metrics.missedVsyncs); metrics = store.stopTrackingScenario(JankScenario.NEW_TAB_PAGE); assertArrayEquals(new long[] {12_000_100L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false}, metrics.isJanky); + assertArrayEquals(new int[] {0}, metrics.missedVsyncs); } @Test @@ -147,8 +147,8 @@ (now + 5) * TimeUtils.NANOSECONDS_PER_MILLISECOND, // Frame4 start time }; - store.addFrameMeasurement(10_000_000L, false, frame_timestamps_ns[0]); - store.addFrameMeasurement(12_000_000L, true, frame_timestamps_ns[1]); + store.addFrameMeasurement(10_000_000L, 0, frame_timestamps_ns[0]); + store.addFrameMeasurement(12_000_000L, 3, frame_timestamps_ns[1]); // This start scenario shouldn't be blanket ignored instead this should // trigger start of the scenario after stop scenario call. @@ -163,15 +163,15 @@ store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING, frame_timestamps_ns[2]); assertArrayEquals(new long[] {10_000_000L, 12_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false, true}, metrics.isJanky); + assertArrayEquals(new int[] {0, 3}, metrics.missedVsyncs); - store.addFrameMeasurement(10_000_100L, true, frame_timestamps_ns[4]); - store.addFrameMeasurement(11_000_100L, false, frame_timestamps_ns[5]); + store.addFrameMeasurement(10_000_100L, 2, frame_timestamps_ns[4]); + store.addFrameMeasurement(11_000_100L, 0, frame_timestamps_ns[5]); metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING); assertArrayEquals(new long[] {10_000_100L, 11_000_100L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {true, false}, metrics.isJanky); + assertArrayEquals(new int[] {2, 0}, metrics.missedVsyncs); } @Test @@ -214,41 +214,41 @@ (now + 10) * TimeUtils.NANOSECONDS_PER_MILLISECOND, // Scroll3 end time }; - store.addFrameMeasurement(10_000_000L, false, frame_timestamps_ns[0]); // Frame1 - store.addFrameMeasurement(12_000_000L, true, frame_timestamps_ns[1]); // Frame2 + store.addFrameMeasurement(10_000_000L, 0, frame_timestamps_ns[0]); // Frame1 + store.addFrameMeasurement(12_000_000L, 1, frame_timestamps_ns[1]); // Frame2 mFakeTimeTestRule.advanceMillis( (frame_timestamps_ns[3] / TimeUtils.NANOSECONDS_PER_MILLISECOND) - now); store.startTrackingScenario(JankScenario.WEBVIEW_SCROLLING); // Scroll2 start - store.addFrameMeasurement(10_000_100L, true, frame_timestamps_ns[4]); // Frame3 - store.addFrameMeasurement(11_000_100L, false, frame_timestamps_ns[5]); // Frame4 + store.addFrameMeasurement(10_000_100L, 2, frame_timestamps_ns[4]); // Frame3 + store.addFrameMeasurement(11_000_100L, 0, frame_timestamps_ns[5]); // Frame4 mFakeTimeTestRule.advanceMillis( (frame_timestamps_ns[7] / TimeUtils.NANOSECONDS_PER_MILLISECOND) - (frame_timestamps_ns[3] / TimeUtils.NANOSECONDS_PER_MILLISECOND)); store.startTrackingScenario(JankScenario.WEBVIEW_SCROLLING); // Scroll3 start - store.addFrameMeasurement(10_000_100L, true, frame_timestamps_ns[8]); // Frame5 - store.addFrameMeasurement(11_000_100L, false, frame_timestamps_ns[9]); // Frame6 + store.addFrameMeasurement(10_000_100L, 1, frame_timestamps_ns[8]); // Frame5 + store.addFrameMeasurement(11_000_100L, 0, frame_timestamps_ns[9]); // Frame6 // Scroll1 end. JankMetrics metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING, frame_timestamps_ns[2]); assertArrayEquals(new long[] {10_000_000L, 12_000_000L}, metrics.durationsNs); - assertArrayEquals(new boolean[] {false, true}, metrics.isJanky); + assertArrayEquals(new int[] {0, 1}, metrics.missedVsyncs); // Scroll2 end. metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING, frame_timestamps_ns[6]); assertArrayEquals(new long[] {}, metrics.durationsNs); - assertArrayEquals(new boolean[] {}, metrics.isJanky); + assertArrayEquals(new int[] {}, metrics.missedVsyncs); // Scroll3 end. metrics = store.stopTrackingScenario(JankScenario.WEBVIEW_SCROLLING, frame_timestamps_ns[10]); assertArrayEquals(new long[] {}, metrics.durationsNs); - assertArrayEquals(new boolean[] {}, metrics.isJanky); + assertArrayEquals(new int[] {}, metrics.missedVsyncs); } }
diff --git a/base/android/junit/src/org/chromium/base/jank_tracker/JankMetricUMARecorderTest.java b/base/android/junit/src/org/chromium/base/jank_tracker/JankMetricUMARecorderTest.java index 414afd1..3bfedcb 100644 --- a/base/android/junit/src/org/chromium/base/jank_tracker/JankMetricUMARecorderTest.java +++ b/base/android/junit/src/org/chromium/base/jank_tracker/JankMetricUMARecorderTest.java
@@ -37,14 +37,14 @@ public void testRecordMetricsToNative() { long[] timestampsNs = new long[] {5L, 8L, 3L}; long[] durationsNs = new long[] {5_000_000L, 8_000_000L, 30_000_000L}; - boolean[] jankyFrames = new boolean[] {false, false, true}; + int[] missedVsyncs = new int[] {0, 0, 1}; - JankMetrics metric = new JankMetrics(timestampsNs, durationsNs, jankyFrames); + JankMetrics metric = new JankMetrics(timestampsNs, durationsNs, missedVsyncs); JankMetricUMARecorder.recordJankMetricsToUMA(metric, 0, 1000, 1); // Ensure that the relevant fields are sent down to native. - verify(mNativeMock).recordJankMetrics(durationsNs, jankyFrames, 0, 1000, 1); + verify(mNativeMock).recordJankMetrics(durationsNs, missedVsyncs, 0, 1000, 1); } @Test
diff --git a/base/android/junit/src/org/chromium/base/jank_tracker/JankReportingRunnableTest.java b/base/android/junit/src/org/chromium/base/jank_tracker/JankReportingRunnableTest.java index b377a074..847c417 100644 --- a/base/android/junit/src/org/chromium/base/jank_tracker/JankReportingRunnableTest.java +++ b/base/android/junit/src/org/chromium/base/jank_tracker/JankReportingRunnableTest.java
@@ -74,7 +74,7 @@ null); startReportingRunnable.run(); - metricsStore.addFrameMeasurement(1_000_000L, true, 1); + metricsStore.addFrameMeasurement(1_000_000L, 2, 1); JankReportingRunnable stopReportingRunnable = new JankReportingRunnable( @@ -91,11 +91,7 @@ verify(mNativeMock) .recordJankMetrics( - new long[] {1_000_000L}, - new boolean[] {true}, - 0L, - 1L, - JankScenario.TAB_SWITCHER); + new long[] {1_000_000L}, new int[] {2}, 0L, 1L, JankScenario.TAB_SWITCHER); } @Test @@ -117,8 +113,7 @@ endScenarioTime); startReportingRunnable.run(); - metricsStore.addFrameMeasurement( - 1_000_000L, true, 1 * TimeUtils.NANOSECONDS_PER_MILLISECOND); + metricsStore.addFrameMeasurement(1_000_000L, 2, 1 * TimeUtils.NANOSECONDS_PER_MILLISECOND); JankReportingRunnable stopReportingRunnable = new JankReportingRunnable( @@ -131,10 +126,9 @@ // Add two frames, one added before the frame time of 50ms above and one after. The first // should be included and the second ignored. + metricsStore.addFrameMeasurement(1_000_001L, 0, 5 * TimeUtils.NANOSECONDS_PER_MILLISECOND); metricsStore.addFrameMeasurement( - 1_000_001L, false, 5 * TimeUtils.NANOSECONDS_PER_MILLISECOND); - metricsStore.addFrameMeasurement( - 1_000_002L, true, (frameTime + 5) * TimeUtils.NANOSECONDS_PER_MILLISECOND); + 1_000_002L, 1, (frameTime + 5) * TimeUtils.NANOSECONDS_PER_MILLISECOND); mShadowLooper.runOneTask(); @@ -145,7 +139,7 @@ verify(mNativeMock) .recordJankMetrics( new long[] {1_000_000L, 1_000_001L}, - new boolean[] {true, false}, + new int[] {2, 0}, 1L, 5L, JankScenario.TAB_SWITCHER);
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc index 8069a51..44d7a51 100644 --- a/base/metrics/statistics_recorder.cc +++ b/base/metrics/statistics_recorder.cc
@@ -6,7 +6,6 @@ #include "base/at_exit.h" #include "base/barrier_closure.h" -#include "base/command_line.h" #include "base/containers/contains.h" #include "base/debug/leak_annotations.h" #include "base/json/string_escape.h" @@ -17,7 +16,6 @@ #include "base/metrics/metrics_hashes.h" #include "base/metrics/persistent_histogram_allocator.h" #include "base/metrics/record_histogram_checker.h" -#include "base/rand_util.h" #include "base/ranges/algorithm.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -27,29 +25,6 @@ namespace base { namespace { -// Whether a 50/50 trial for using a R/W lock should be run. -// Restrict it to Windows for now as other platforms show poor results. -#if BUILDFLAG(IS_WIN) -constexpr bool kRunRwLockTrial = true; -#else -constexpr bool kRunRwLockTrial = false; -#endif // BUILDFLAG(IS_WIN) - -// Whether the R/W lock should be used when the trial is not active. -// Only enabled on Windows for now, since other platforms show poor results. -#if BUILDFLAG(IS_WIN) -constexpr bool kUseRwLockByDefault = true; -#else -constexpr bool kUseRwLockByDefault = false; -#endif // BUILDFLAG(IS_WIN) - -bool EnableBenchmarking() { - // TODO(asvitkine): If this code ends up not being temporary, refactor it to - // not duplicate the constant name. (Right now it's at a different layer.) - return CommandLine::InitializedForCurrentProcess() && - CommandLine::ForCurrentProcess()->HasSwitch("enable-benchmarking"); -} - bool HistogramNameLesser(const base::HistogramBase* a, const base::HistogramBase* b) { return strcmp(a->histogram_name(), b->histogram_name()) < 0; @@ -58,11 +33,10 @@ } // namespace // static -LazyInstance<StatisticsRecorder::SrLock>::Leaky StatisticsRecorder::lock_ = - LAZY_INSTANCE_INITIALIZER; +LazyInstance<Lock>::Leaky StatisticsRecorder::lock_ = LAZY_INSTANCE_INITIALIZER; // static -LazyInstance<base::Lock>::Leaky StatisticsRecorder::snapshot_lock_ = +LazyInstance<Lock>::Leaky StatisticsRecorder::snapshot_lock_ = LAZY_INSTANCE_INITIALIZER; // static @@ -102,7 +76,7 @@ } StatisticsRecorder::~StatisticsRecorder() { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); DCHECK_EQ(this, top_); top_ = previous_; } @@ -123,7 +97,7 @@ // static void StatisticsRecorder::RegisterHistogramProvider( const WeakPtr<HistogramProvider>& provider) { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); top_->providers_.push_back(provider); } @@ -140,7 +114,7 @@ // Declared before |auto_lock| so that the histogram is deleted after the lock // is released (no point in holding the lock longer than needed). std::unique_ptr<HistogramBase> histogram_deleter; - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); HistogramBase*& registered = top_->histograms_[hash]; @@ -188,7 +162,7 @@ const BucketRanges* ranges) { const BucketRanges* registered; { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); registered = top_->ranges_manager_.GetOrRegisterCanonicalRanges(ranges); @@ -236,7 +210,7 @@ // static std::vector<const BucketRanges*> StatisticsRecorder::GetBucketRanges() { - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -256,10 +230,7 @@ // will acquire the lock at that time. ImportGlobalPersistentHistograms(); - // Acquire the lock in "read" mode since we're only reading the data, not - // modifying anything. This allows multiple readers to look up histograms - // concurrently. - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -273,7 +244,7 @@ // static StatisticsRecorder::HistogramProviders StatisticsRecorder::GetHistogramProviders() { - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -313,7 +284,7 @@ HistogramBase::Flags required_flags, HistogramSnapshotManager* snapshot_manager) { Histograms histograms = Sort(GetHistograms(include_persistent)); - base::AutoLock lock(snapshot_lock_.Get()); + AutoLock lock(snapshot_lock_.Get()); snapshot_manager->PrepareDeltas(std::move(histograms), flags_to_set, required_flags); return ++last_snapshot_transaction_id_; @@ -325,7 +296,7 @@ HistogramBase::Flags required_flags, HistogramSnapshotManager* snapshot_manager) { Histograms histograms = Sort(GetHistograms()); - base::AutoLock lock(snapshot_lock_.Get()); + AutoLock lock(snapshot_lock_.Get()); snapshot_manager->SnapshotUnloggedSamples(std::move(histograms), required_flags); return ++last_snapshot_transaction_id_; @@ -334,33 +305,16 @@ // static StatisticsRecorder::SnapshotTransactionId StatisticsRecorder::GetLastSnapshotTransactionId() { - base::AutoLock lock(snapshot_lock_.Get()); + AutoLock lock(snapshot_lock_.Get()); return last_snapshot_transaction_id_; } // static void StatisticsRecorder::InitLogOnShutdown() { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); InitLogOnShutdownWhileLocked(); } -// static -StringPiece StatisticsRecorder::GetLockTrialGroup() { - if (kRunRwLockTrial && !EnableBenchmarking()) { - return lock_.Get().use_shared_mutex() ? "Enabled" : "Disabled"; - } - return StringPiece(); -} - -// static -bool StatisticsRecorder::SrLock::ShouldUseSharedMutex() { - // Force deterministic results for benchmarks. - if (kRunRwLockTrial && !EnableBenchmarking()) { - return RandInt(0, 1) == 1; - } - return kUseRwLockByDefault; -} - HistogramBase* StatisticsRecorder::FindHistogramByHashInternal( uint64_t hash, StringPiece name) const { @@ -391,7 +345,7 @@ DCHECK(observer); uint64_t hash = HashMetricName(name); - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); auto iter = top_->observers_.find(hash); @@ -420,7 +374,7 @@ StatisticsRecorder::ScopedHistogramSampleObserver* observer) { uint64_t hash = HashMetricName(name); - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); auto iter = top_->observers_.find(hash); @@ -453,7 +407,7 @@ HistogramBase::Sample sample) { DCHECK_EQ(name_hash, HashMetricName(histogram_name)); - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -476,7 +430,7 @@ // static void StatisticsRecorder::SetGlobalSampleCallback( const GlobalSampleCallback& new_global_sample_callback) { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); DCHECK(!global_sample_callback() || !new_global_sample_callback); @@ -489,7 +443,7 @@ // static size_t StatisticsRecorder::GetHistogramCount() { - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -501,7 +455,7 @@ // static void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); uint64_t hash = HashMetricName(name); @@ -526,7 +480,7 @@ // static std::unique_ptr<StatisticsRecorder> StatisticsRecorder::CreateTemporaryForTesting() { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); std::unique_ptr<StatisticsRecorder> temporary_recorder = WrapUnique(new StatisticsRecorder()); temporary_recorder->ranges_manager_ @@ -537,14 +491,14 @@ // static void StatisticsRecorder::SetRecordChecker( std::unique_ptr<RecordHistogramChecker> record_checker) { - const SrAutoWriterLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); EnsureGlobalRecorderWhileLocked(); top_->record_checker_ = std::move(record_checker); } // static bool StatisticsRecorder::ShouldRecordHistogram(uint32_t histogram_hash) { - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_; @@ -562,7 +516,7 @@ Histograms out; - const SrAutoReaderLock auto_lock(GetLock()); + const AutoLock auto_lock(GetLock()); // Manipulate |top_| through a const variable to ensure it is not mutated. const auto* const_top = top_;
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h index 76bc21c..d1d933b 100644 --- a/base/metrics/statistics_recorder.h +++ b/base/metrics/statistics_recorder.h
@@ -14,18 +14,15 @@ #include <atomic> // For std::memory_order_*. #include <memory> -#include <shared_mutex> #include <string> #include <unordered_map> #include <vector> -#include "base/atomicops.h" #include "base/base_export.h" #include "base/functional/callback.h" #include "base/gtest_prod_util.h" #include "base/lazy_instance.h" #include "base/memory/raw_ptr.h" -#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_base.h" #include "base/metrics/ranges_manager.h" @@ -324,125 +321,8 @@ return have_active_callbacks_.load(std::memory_order_relaxed); } -#ifdef ARCH_CPU_64_BITS - static base::TimeDelta GetAndClearTotalWaitTime() { - return lock_.Get().GetAndClearTotalWaitTime(); - } -#endif // ARCH_CPU_64_BITS - - // Returns the synthetic trial group name for the R/W lock trial being ran, - // or an empty string if no trial is being run and should not be reported. - static StringPiece GetLockTrialGroup(); - private: - // Wrapper lock class that provides A/B testing between a base::Lock and a - // std::shared_mutex and tracks lock wait times. Additionally, allows the use - // of thread locking annotations, which are not otherwise supported by - // std::shared_mutex. - // - // Note: std::shared_mutex is currently not generally allowed in Chromium but - // this specific use has been explicitly discussed and agreed on - // cxx@chromium.org here: - // https://groups.google.com/a/chromium.org/g/cxx/c/bIlGr1URn8I/m/ftvVCQPiAQAJ - class BASE_EXPORT LOCKABLE SrLock { - public: - SrLock() : use_shared_mutex_(ShouldUseSharedMutex()) {} - ~SrLock() = default; - - void Acquire() EXCLUSIVE_LOCK_FUNCTION() { - TimeTicks start = TimeTicks::Now(); - if (use_shared_mutex_) { - mutex_.lock(); - } else { - lock_.Acquire(); - } - IncrementLockWaitTime(TimeTicks::Now() - start); - } - - void Release() UNLOCK_FUNCTION() { - if (use_shared_mutex_) { - mutex_.unlock(); - } else { - lock_.Release(); - } - } - - void AcquireShared() SHARED_LOCK_FUNCTION() { - TimeTicks start = TimeTicks::Now(); - if (use_shared_mutex_) { - mutex_.lock_shared(); - } else { - lock_.Acquire(); - } - IncrementLockWaitTime(TimeTicks::Now() - start); - } - - void ReleaseShared() UNLOCK_FUNCTION() { - if (use_shared_mutex_) { - mutex_.unlock_shared(); - } else { - lock_.Release(); - } - } - - void AssertAcquired() { - if (use_shared_mutex_) { - // Not available with std::shared_mutex. This can be implemented on top - // of that API, similar to what base::Lock does. - } else { - lock_.AssertAcquired(); - } - } - -#ifdef ARCH_CPU_64_BITS - TimeDelta GetAndClearTotalWaitTime() { - return Microseconds( - subtle::NoBarrier_AtomicExchange(&total_lock_wait_time_micros_, 0)); - } -#endif // ARCH_CPU_64_BITS - - bool use_shared_mutex() const { return use_shared_mutex_; } - - private: - // Determines if the shared mutex should be used. Should only be called - // once when the lock is created. - static bool ShouldUseSharedMutex(); - - void IncrementLockWaitTime(TimeDelta delta) { -#ifdef ARCH_CPU_64_BITS - subtle::NoBarrier_AtomicIncrement(&total_lock_wait_time_micros_, - delta.InMicroseconds()); -#endif // ARCH_CPU_64_BITS - } - -#ifdef ARCH_CPU_64_BITS - // Cumulative wait time on acquiring the lock (both R and W modes) since the - // the last call to GetAndClearTotalWaitTime(). - // Note: Requires 64-bit arch for atomic increments. - subtle::Atomic64 total_lock_wait_time_micros_ = 0; -#endif // ARCH_CPU_64_BITS - - // If true, |mutex_| will be used in R/W mode; otherwise |lock_| is used. - const bool use_shared_mutex_; - std::shared_mutex mutex_; - Lock lock_; - }; - - class SCOPED_LOCKABLE SrAutoReaderLock { - public: - explicit SrAutoReaderLock(SrLock& lock) EXCLUSIVE_LOCK_FUNCTION(lock) - : lock_(lock) { - lock_->AcquireShared(); - } - - ~SrAutoReaderLock() UNLOCK_FUNCTION() { lock_->ReleaseShared(); } - - private: - raw_ref<SrLock> lock_; - }; - - using SrAutoWriterLock = internal::BasicAutoLock<SrLock>; - static SrLock& GetLock() { return lock_.Get(); } + static Lock& GetLock() { return lock_.Get(); } static void AssertLockHeld() { lock_.Get().AssertAcquired(); } // Returns the histogram registered with |hash|, if there is one. Returns @@ -525,7 +405,7 @@ // Global lock for internal synchronization. // Note: Care must be taken to not read or write anything to persistent memory // while holding this lock, as that could cause a file I/O stall. - static LazyInstance<SrLock>::Leaky lock_; + static LazyInstance<Lock>::Leaky lock_; // Global lock for internal synchronization of histogram snapshots. static LazyInstance<base::Lock>::Leaky snapshot_lock_;
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc index eae7bcc..fa8efca 100644 --- a/base/metrics/statistics_recorder_unittest.cc +++ b/base/metrics/statistics_recorder_unittest.cc
@@ -103,8 +103,7 @@ // Note: We can't clear |top_| in the locked block, because the // StatisticsRecorder destructor expects that the lock isn't already held. { - const StatisticsRecorder::SrAutoWriterLock auto_lock( - StatisticsRecorder::GetLock()); + const AutoLock auto_lock(StatisticsRecorder::GetLock()); statistics_recorder_.reset(StatisticsRecorder::top_); if (statistics_recorder_) { // Prevent releasing ranges in test to avoid dangling pointers in @@ -118,8 +117,7 @@ } bool HasGlobalRecorder() { - const StatisticsRecorder::SrAutoReaderLock auto_lock( - StatisticsRecorder::GetLock()); + const AutoLock auto_lock(StatisticsRecorder::GetLock()); return StatisticsRecorder::top_ != nullptr; } @@ -390,22 +388,35 @@ const Value::List* buckets_list = histogram_dict->FindList("buckets"); ASSERT_TRUE(buckets_list); EXPECT_EQ(2u, buckets_list->size()); +} - // Check the serialized JSON with a different verbosity level. - json = StatisticsRecorder::ToJSON(JSON_VERBOSITY_LEVEL_OMIT_BUCKETS); - root = JSONReader::Read(json); +// Check the serialized JSON with a different verbosity level. +TEST_P(StatisticsRecorderTest, ToJSONOmitBuckets) { + Histogram::FactoryGet("TestHistogram1", 1, 1000, 50, HistogramBase::kNoFlags) + ->Add(30); + Histogram::FactoryGet("TestHistogram1", 1, 1000, 50, HistogramBase::kNoFlags) + ->Add(40); + Histogram::FactoryGet("TestHistogram2", 1, 1000, 50, HistogramBase::kNoFlags) + ->Add(30); + Histogram::FactoryGet("TestHistogram2", 1, 1000, 50, HistogramBase::kNoFlags) + ->Add(40); + + std::string json = + StatisticsRecorder::ToJSON(JSON_VERBOSITY_LEVEL_OMIT_BUCKETS); + absl::optional<Value> root = JSONReader::Read(json); ASSERT_TRUE(root); - root_dict = root->GetIfDict(); + Value::Dict* root_dict = root->GetIfDict(); ASSERT_TRUE(root_dict); - histogram_list = root_dict->FindList("histograms"); + const Value::List* histogram_list = root_dict->FindList("histograms"); ASSERT_TRUE(histogram_list); + ASSERT_EQ(2u, histogram_list->size()); const Value::Dict* histogram_dict2 = (*histogram_list)[0].GetIfDict(); ASSERT_TRUE(histogram_dict2); - sample_count = histogram_dict2->FindInt("count"); + auto sample_count = histogram_dict2->FindInt("count"); ASSERT_TRUE(sample_count); EXPECT_EQ(2, *sample_count); - buckets_list = histogram_dict2->FindList("buckets"); + const Value::List* buckets_list = histogram_dict2->FindList("buckets"); // Bucket information should be omitted. ASSERT_FALSE(buckets_list); }
diff --git a/base/numerics/checked_math.h b/base/numerics/checked_math.h index c25bef0d..bc1959e 100644 --- a/base/numerics/checked_math.h +++ b/base/numerics/checked_math.h
@@ -41,8 +41,8 @@ // This is not an explicit constructor because we implicitly upgrade regular // numerics to CheckedNumerics to make them easier to use. - template <typename Src, - typename = std::enable_if_t<std::is_arithmetic_v<Src>>> + template <typename Src> + requires(std::is_arithmetic_v<Src>) // NOLINTNEXTLINE(google-explicit-constructor) constexpr CheckedNumeric(Src value) : state_(value) {} @@ -211,9 +211,7 @@ // These perform the actual math operations on the CheckedNumerics. // Binary arithmetic operations. - template <template <typename, typename, typename> class M, - typename L, - typename R> + template <template <typename, typename> class M, typename L, typename R> static constexpr CheckedNumeric MathOp(const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math; T result = 0; @@ -224,7 +222,7 @@ } // Assignment arithmetic operations. - template <template <typename, typename, typename> class M, typename R> + template <template <typename, typename> class M, typename R> constexpr CheckedNumeric& MathOp(const R rhs) { using Math = typename MathWrapper<M, T, R>::math; T result = 0; // Using T as the destination saves a range check. @@ -303,9 +301,7 @@ } // These implement the variadic wrapper for the math operations. -template <template <typename, typename, typename> class M, - typename L, - typename R> +template <template <typename, typename> class M, typename L, typename R> constexpr CheckedNumeric<typename MathWrapper<M, L, R>::type> CheckMathOp( const L lhs, const R rhs) { @@ -315,7 +311,7 @@ } // General purpose wrapper template for arithmetic operations. -template <template <typename, typename, typename> class M, +template <template <typename, typename> class M, typename L, typename R, typename... Args>
diff --git a/base/numerics/checked_math_impl.h b/base/numerics/checked_math_impl.h index e8dbd3e..03e86bae 100644 --- a/base/numerics/checked_math_impl.h +++ b/base/numerics/checked_math_impl.h
@@ -10,6 +10,7 @@ #include <climits> #include <cmath> +#include <concepts> #include <cstdlib> #include <limits> #include <type_traits> @@ -41,14 +42,12 @@ return true; } -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedAddOp {}; template <typename T, typename U> -struct CheckedAddOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedAddOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -105,14 +104,12 @@ return true; } -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedSubOp {}; template <typename T, typename U> -struct CheckedSubOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedSubOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -171,14 +168,12 @@ return true; } -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedMulOp {}; template <typename T, typename U> -struct CheckedMulOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedMulOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -216,14 +211,12 @@ // Division just requires a check for a zero denominator or an invalid negation // on signed min/-1. -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedDivOp {}; template <typename T, typename U> -struct CheckedDivOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedDivOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -257,14 +250,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedModOp {}; template <typename T, typename U> -struct CheckedModOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedModOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -291,17 +282,15 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedLshOp {}; // Left shift. Shifts less than 0 or greater than or equal to the number // of bits in the promoted type are undefined. Shifts of negative values // are undefined. Otherwise it is defined when the result fits. template <typename T, typename U> -struct CheckedLshOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedLshOp<T, U> { using result_type = T; template <typename V> static constexpr bool Do(T x, U shift, V* result) { @@ -325,17 +314,15 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedRshOp {}; // Right shift. Shifts less than 0 or greater than or equal to the number // of bits in the promoted type are undefined. Otherwise, it is always defined, // but a right shift of a negative value is implementation-dependent. template <typename T, typename U> -struct CheckedRshOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedRshOp<T, U> { using result_type = T; template <typename V> static constexpr bool Do(T x, U shift, V* result) { @@ -353,15 +340,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedAndOp {}; // For simplicity we support only unsigned integer results. template <typename T, typename U> -struct CheckedAndOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedAndOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -375,15 +360,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedOrOp {}; // For simplicity we support only unsigned integers. template <typename T, typename U> -struct CheckedOrOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedOrOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -397,15 +380,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedXorOp {}; // For simplicity we support only unsigned integers. template <typename T, typename U> -struct CheckedXorOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct CheckedXorOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -421,14 +402,12 @@ // Max doesn't really need to be implemented this way because it can't fail, // but it makes the code much cleaner to use the MathOp wrappers. -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedMaxOp {}; template <typename T, typename U> -struct CheckedMaxOp< - T, - U, - std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>> { + requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<U>) +struct CheckedMaxOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -444,14 +423,12 @@ // Min doesn't really need to be implemented this way because it can't fail, // but it makes the code much cleaner to use the MathOp wrappers. -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct CheckedMinOp {}; template <typename T, typename U> -struct CheckedMinOp< - T, - U, - std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>> { + requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<U>) +struct CheckedMinOp<T, U> { using result_type = typename LowestValuePromotion<T, U>::type; template <typename V> static constexpr bool Do(T x, U y, V* result) { @@ -467,21 +444,20 @@ // This is just boilerplate that wraps the standard floating point arithmetic. // A macro isn't the nicest solution, but it beats rewriting these repeatedly. -#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \ - template <typename T, typename U> \ - struct Checked##NAME##Op<T, U, \ - std::enable_if_t<std::is_floating_point_v<T> || \ - std::is_floating_point_v<U>>> { \ - using result_type = typename MaxExponentPromotion<T, U>::type; \ - template <typename V> \ - static constexpr bool Do(T x, U y, V* result) { \ - using Promotion = typename MaxExponentPromotion<T, U>::type; \ - const Promotion presult = x OP y; \ - if (!IsValueInRangeForNumericType<V>(presult)) \ - return false; \ - *result = static_cast<V>(presult); \ - return true; \ - } \ +#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \ + template <typename T, typename U> \ + requires(std::is_floating_point_v<T> || std::is_floating_point_v<U>) \ + struct Checked##NAME##Op<T, U> { \ + using result_type = typename MaxExponentPromotion<T, U>::type; \ + template <typename V> \ + static constexpr bool Do(T x, U y, V* result) { \ + using Promotion = typename MaxExponentPromotion<T, U>::type; \ + const Promotion presult = x OP y; \ + if (!IsValueInRangeForNumericType<V>(presult)) \ + return false; \ + *result = static_cast<V>(presult); \ + return true; \ + } \ }; BASE_FLOAT_ARITHMETIC_OPS(Add, +)
diff --git a/base/numerics/clamped_math.h b/base/numerics/clamped_math.h index 66112edb..fad5bba1 100644 --- a/base/numerics/clamped_math.h +++ b/base/numerics/clamped_math.h
@@ -148,9 +148,7 @@ // These perform the actual math operations on the ClampedNumerics. // Binary arithmetic operations. - template <template <typename, typename, typename> class M, - typename L, - typename R> + template <template <typename, typename> class M, typename L, typename R> static constexpr ClampedNumeric MathOp(const L lhs, const R rhs) { using Math = typename MathWrapper<M, L, R>::math; return ClampedNumeric<T>( @@ -158,7 +156,7 @@ } // Assignment arithmetic operations. - template <template <typename, typename, typename> class M, typename R> + template <template <typename, typename> class M, typename R> constexpr ClampedNumeric& MathOp(const R rhs) { using Math = typename MathWrapper<M, T, R>::math; *this = @@ -199,9 +197,7 @@ } // These implement the variadic wrapper for the math operations. -template <template <typename, typename, typename> class M, - typename L, - typename R> +template <template <typename, typename> class M, typename L, typename R> constexpr ClampedNumeric<typename MathWrapper<M, L, R>::type> ClampMathOp( const L lhs, const R rhs) { @@ -211,7 +207,7 @@ } // General purpose wrapper template for arithmetic operations. -template <template <typename, typename, typename> class M, +template <template <typename, typename> class M, typename L, typename R, typename... Args>
diff --git a/base/numerics/clamped_math_impl.h b/base/numerics/clamped_math_impl.h index 46088868..6e411071 100644 --- a/base/numerics/clamped_math_impl.h +++ b/base/numerics/clamped_math_impl.h
@@ -10,6 +10,7 @@ #include <climits> #include <cmath> +#include <concepts> #include <cstdlib> #include <limits> #include <type_traits> @@ -21,9 +22,8 @@ namespace base { namespace internal { -template < - typename T, - std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr> +template <typename T> + requires(std::signed_integral<T>) constexpr T SaturatedNegWrapper(T value) { return IsConstantEvaluated() || !ClampedNegFastOp<T>::is_supported ? (NegateWrapper(value) != std::numeric_limits<T>::lowest() @@ -32,19 +32,20 @@ : ClampedNegFastOp<T>::Do(value); } -template < - typename T, - std::enable_if_t<std::is_integral_v<T> && !std::is_signed_v<T>>* = nullptr> +template <typename T> + requires(std::unsigned_integral<T>) constexpr T SaturatedNegWrapper(T value) { return T(0); } -template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr> +template <typename T> + requires(std::floating_point<T>) constexpr T SaturatedNegWrapper(T value) { return -value; } -template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr> +template <typename T> + requires(std::integral<T>) constexpr T SaturatedAbsWrapper(T value) { // The calculation below is a static identity for unsigned types, but for // signed integer types it provides a non-branching, saturated absolute value. @@ -59,19 +60,18 @@ IsValueNegative<T>(static_cast<T>(SafeUnsignedAbs(value)))); } -template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr> +template <typename T> + requires(std::floating_point<T>) constexpr T SaturatedAbsWrapper(T value) { return value < 0 ? -value : value; } -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedAddOp {}; template <typename T, typename U> -struct ClampedAddOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedAddOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -90,14 +90,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedSubOp {}; template <typename T, typename U> -struct ClampedSubOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedSubOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -116,14 +114,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedMulOp {}; template <typename T, typename U> -struct ClampedMulOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedMulOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -139,14 +135,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedDivOp {}; template <typename T, typename U> -struct ClampedDivOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedDivOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -159,14 +153,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedModOp {}; template <typename T, typename U> -struct ClampedModOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedModOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -177,16 +169,14 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedLshOp {}; // Left shift. Non-zero values saturate in the direction of the sign. A zero // shifted by any value always results in zero. template <typename T, typename U> -struct ClampedLshOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedLshOp<T, U> { using result_type = T; template <typename V = result_type> static constexpr V Do(T x, U shift) { @@ -202,15 +192,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedRshOp {}; // Right shift. Negative values saturate to -1. Positive or 0 saturates to 0. template <typename T, typename U> -struct ClampedRshOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedRshOp<T, U> { using result_type = T; template <typename V = result_type> static constexpr V Do(T x, U shift) { @@ -223,14 +211,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedAndOp {}; template <typename T, typename U> -struct ClampedAndOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedAndOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -239,15 +225,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedOrOp {}; // For simplicity we promote to unsigned integers. template <typename T, typename U> -struct ClampedOrOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedOrOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -256,15 +240,13 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedXorOp {}; // For simplicity we support only unsigned integers. template <typename T, typename U> -struct ClampedXorOp< - T, - U, - std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>>> { + requires(std::integral<T> && std::integral<U>) +struct ClampedXorOp<T, U> { using result_type = typename std::make_unsigned< typename MaxExponentPromotion<T, U>::type>::type; template <typename V> @@ -273,14 +255,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedMaxOp {}; template <typename T, typename U> -struct ClampedMaxOp< - T, - U, - std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>> { + requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<U>) +struct ClampedMaxOp<T, U> { using result_type = typename MaxExponentPromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -289,14 +269,12 @@ } }; -template <typename T, typename U, class Enable = void> +template <typename T, typename U> struct ClampedMinOp {}; template <typename T, typename U> -struct ClampedMinOp< - T, - U, - std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>> { + requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<U>) +struct ClampedMinOp<T, U> { using result_type = typename LowestValuePromotion<T, U>::type; template <typename V = result_type> static constexpr V Do(T x, U y) { @@ -307,16 +285,15 @@ // This is just boilerplate that wraps the standard floating point arithmetic. // A macro isn't the nicest solution, but it beats rewriting these repeatedly. -#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \ - template <typename T, typename U> \ - struct Clamped##NAME##Op<T, U, \ - std::enable_if_t<std::is_floating_point_v<T> || \ - std::is_floating_point_v<U>>> { \ - using result_type = typename MaxExponentPromotion<T, U>::type; \ - template <typename V = result_type> \ - static constexpr V Do(T x, U y) { \ - return saturated_cast<V>(x OP y); \ - } \ +#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \ + template <typename T, typename U> \ + requires(std::floating_point<T> || std::floating_point<U>) \ + struct Clamped##NAME##Op<T, U> { \ + using result_type = typename MaxExponentPromotion<T, U>::type; \ + template <typename V = result_type> \ + static constexpr V Do(T x, U y) { \ + return saturated_cast<V>(x OP y); \ + } \ }; BASE_FLOAT_ARITHMETIC_OPS(Add, +)
diff --git a/base/numerics/safe_conversions.h b/base/numerics/safe_conversions.h index 83fbd1c..34e3f12c 100644 --- a/base/numerics/safe_conversions.h +++ b/base/numerics/safe_conversions.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <cmath> +#include <concepts> #include <limits> #include <type_traits> @@ -37,7 +38,7 @@ // The following special case a few specific integer conversions where we can // eke out better performance than range checking. -template <typename Dst, typename Src, typename Enable = void> +template <typename Dst, typename Src> struct IsValueInRangeFastOp { static constexpr bool is_supported = false; static constexpr bool Do(Src value) { @@ -48,12 +49,9 @@ // Signed to signed range comparison. template <typename Dst, typename Src> -struct IsValueInRangeFastOp< - Dst, - Src, - std::enable_if_t<std::is_integral_v<Dst> && std::is_integral_v<Src> && - std::is_signed_v<Dst> && std::is_signed_v<Src> && - !IsTypeInRangeForNumericType<Dst, Src>::value>> { + requires(std::signed_integral<Dst> && std::signed_integral<Src> && + !IsTypeInRangeForNumericType<Dst, Src>::value) +struct IsValueInRangeFastOp<Dst, Src> { static constexpr bool is_supported = true; static constexpr bool Do(Src value) { @@ -65,12 +63,9 @@ // Signed to unsigned range comparison. template <typename Dst, typename Src> -struct IsValueInRangeFastOp< - Dst, - Src, - std::enable_if_t<std::is_integral_v<Dst> && std::is_integral_v<Src> && - !std::is_signed_v<Dst> && std::is_signed_v<Src> && - !IsTypeInRangeForNumericType<Dst, Src>::value>> { + requires(std::unsigned_integral<Dst> && std::signed_integral<Src> && + !IsTypeInRangeForNumericType<Dst, Src>::value) +struct IsValueInRangeFastOp<Dst, Src> { static constexpr bool is_supported = true; static constexpr bool Do(Src value) { @@ -154,7 +149,7 @@ // We can reduce the number of conditions and get slightly better performance // for normal signed and unsigned integer ranges. And in the specific case of // Arm, we can use the optimized saturation instructions. -template <typename Dst, typename Src, typename Enable = void> +template <typename Dst, typename Src> struct SaturateFastOp { static constexpr bool is_supported = false; static constexpr Dst Do(Src value) { @@ -164,11 +159,9 @@ }; template <typename Dst, typename Src> -struct SaturateFastOp< - Dst, - Src, - std::enable_if_t<std::is_integral_v<Src> && std::is_integral_v<Dst> && - SaturateFastAsmOp<Dst, Src>::is_supported>> { + requires(std::integral<Src> && std::integral<Dst> && + SaturateFastAsmOp<Dst, Src>::is_supported) +struct SaturateFastOp<Dst, Src> { static constexpr bool is_supported = true; static constexpr Dst Do(Src value) { return SaturateFastAsmOp<Dst, Src>::Do(value); @@ -176,11 +169,9 @@ }; template <typename Dst, typename Src> -struct SaturateFastOp< - Dst, - Src, - std::enable_if_t<std::is_integral_v<Src> && std::is_integral_v<Dst> && - !SaturateFastAsmOp<Dst, Src>::is_supported>> { + requires(std::integral<Src> && std::integral<Dst> && + !SaturateFastAsmOp<Dst, Src>::is_supported) +struct SaturateFastOp<Dst, Src> { static constexpr bool is_supported = true; static constexpr Dst Do(Src value) { // The exact order of the following is structured to hit the correct @@ -238,17 +229,15 @@ } // Some wrappers to statically check that a type is in range. -template <typename Dst, typename Src, class Enable = void> +template <typename Dst, typename Src> struct IsNumericRangeContained { static constexpr bool value = false; }; template <typename Dst, typename Src> -struct IsNumericRangeContained< - Dst, - Src, - std::enable_if_t<ArithmeticOrUnderlyingEnum<Dst>::value && - ArithmeticOrUnderlyingEnum<Src>::value>> { + requires(ArithmeticOrUnderlyingEnum<Dst>::value && + ArithmeticOrUnderlyingEnum<Src>::value) +struct IsNumericRangeContained<Dst, Src> { static constexpr bool value = StaticDstRangeRelationToSrcRange<Dst, Src>::value == NUMERIC_RANGE_CONTAINED; @@ -300,8 +289,8 @@ // to explicitly cast the result to the destination type. // If none of that works, you may be better served with the checked_cast<> or // saturated_cast<> template functions for your particular use case. - template <typename Dst, - std::enable_if_t<IsNumericRangeContained<Dst, T>::value>* = nullptr> + template <typename Dst> + requires(IsNumericRangeContained<Dst, T>::value) constexpr operator Dst() const { return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_); } @@ -318,12 +307,12 @@ return value; } -#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP) \ - template <typename L, typename R, \ - std::enable_if_t<internal::Is##CLASS##Op<L, R>::value>* = nullptr> \ - constexpr bool operator OP(const L lhs, const R rhs) { \ - return SafeCompare<NAME, typename UnderlyingType<L>::type, \ - typename UnderlyingType<R>::type>(lhs, rhs); \ +#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP) \ + template <typename L, typename R> \ + requires(internal::Is##CLASS##Op<L, R>::value) \ + constexpr bool operator OP(const L lhs, const R rhs) { \ + return SafeCompare<NAME, typename UnderlyingType<L>::type, \ + typename UnderlyingType<R>::type>(lhs, rhs); \ } BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLess, <) @@ -363,19 +352,15 @@ // they round in nonstandard directions and will generally be slower. // Rounds towards negative infinity (i.e., down). -template <typename Dst = int, - typename Src, - typename = std::enable_if_t<std::is_integral_v<Dst> && - std::is_floating_point_v<Src>>> +template <typename Dst = int, typename Src> + requires(std::integral<Dst> && std::floating_point<Src>) Dst ClampFloor(Src value) { return saturated_cast<Dst>(std::floor(value)); } // Rounds towards positive infinity (i.e., up). -template <typename Dst = int, - typename Src, - typename = std::enable_if_t<std::is_integral_v<Dst> && - std::is_floating_point_v<Src>>> +template <typename Dst = int, typename Src> + requires(std::integral<Dst> && std::floating_point<Src>) Dst ClampCeil(Src value) { return saturated_cast<Dst>(std::ceil(value)); } @@ -389,10 +374,8 @@ // existing code expects. Compare with saturated_cast<Dst>(std::nearbyint(x)) // or std::lrint(x), which would round 0.5 and -0.5 to 0 but 1.5 to 2 and // -1.5 to -2. -template <typename Dst = int, - typename Src, - typename = std::enable_if_t<std::is_integral_v<Dst> && - std::is_floating_point_v<Src>>> +template <typename Dst = int, typename Src> + requires(std::integral<Dst> && std::floating_point<Src>) Dst ClampRound(Src value) { const Src rounded = std::round(value); return saturated_cast<Dst>(rounded);
diff --git a/base/numerics/safe_conversions_impl.h b/base/numerics/safe_conversions_impl.h index 9231468..c5c4726c 100644 --- a/base/numerics/safe_conversions_impl.h +++ b/base/numerics/safe_conversions_impl.h
@@ -7,6 +7,7 @@ #include <stdint.h> +#include <concepts> #include <limits> #include <type_traits> @@ -47,15 +48,15 @@ // Determines if a numeric value is negative without throwing compiler // warnings on: unsigned(value) < 0. -template <typename T, std::enable_if_t<std::is_signed_v<T>>* = nullptr> +template <typename T> + requires(std::is_arithmetic_v<T> && std::is_signed_v<T>) constexpr bool IsValueNegative(T value) { - static_assert(std::is_arithmetic_v<T>, "Argument must be numeric."); return value < 0; } -template <typename T, std::enable_if_t<!std::is_signed_v<T>>* = nullptr> +template <typename T> + requires(std::is_arithmetic_v<T> && std::is_unsigned_v<T>) constexpr bool IsValueNegative(T) { - static_assert(std::is_arithmetic_v<T>, "Argument must be numeric."); return false; } @@ -234,8 +235,9 @@ SrcLimits::digits < DstLimits::digits) ? (DstLimits::digits - SrcLimits::digits) : 0; - template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr> + template <typename T> + requires(std::integral<T>) // Masks out the integer bits that are beyond the precision of the // intermediate type used for comparison. static constexpr T Adjust(T value) { @@ -247,8 +249,8 @@ IsValueNegative(value))); } - template <typename T, - std::enable_if_t<std::is_floating_point_v<T>>* = nullptr> + template <typename T> + requires(std::floating_point<T>) static constexpr T Adjust(T value) { static_assert(std::is_same_v<T, Dst>, ""); static_assert(kShift == 0, ""); @@ -542,18 +544,19 @@ // Promotes to a type that can represent any possible result of a binary // arithmetic operation with the source types. -template <typename Lhs, - typename Rhs, - bool is_promotion_possible = IsIntegerArithmeticSafe< - typename std::conditional<std::is_signed_v<Lhs> || - std::is_signed_v<Rhs>, - intmax_t, - uintmax_t>::type, - typename MaxExponentPromotion<Lhs, Rhs>::type>::value> -struct FastIntegerArithmeticPromotion; +template <typename Lhs, typename Rhs> +struct FastIntegerArithmeticPromotion { + using type = typename BigEnoughPromotion<Lhs, Rhs>::type; + static const bool is_contained = false; +}; template <typename Lhs, typename Rhs> -struct FastIntegerArithmeticPromotion<Lhs, Rhs, true> { + requires(IsIntegerArithmeticSafe< + std::conditional_t<std::is_signed_v<Lhs> || std::is_signed_v<Rhs>, + intmax_t, + uintmax_t>, + typename MaxExponentPromotion<Lhs, Rhs>::type>::value) +struct FastIntegerArithmeticPromotion<Lhs, Rhs> { using type = typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type, std::is_signed_v<Lhs> || @@ -562,25 +565,17 @@ static const bool is_contained = true; }; -template <typename Lhs, typename Rhs> -struct FastIntegerArithmeticPromotion<Lhs, Rhs, false> { - using type = typename BigEnoughPromotion<Lhs, Rhs>::type; - static const bool is_contained = false; -}; - // Extracts the underlying type from an enum. -template <typename T, bool is_enum = std::is_enum_v<T>> -struct ArithmeticOrUnderlyingEnum; - template <typename T> -struct ArithmeticOrUnderlyingEnum<T, true> { - using type = typename std::underlying_type<T>::type; +struct ArithmeticOrUnderlyingEnum { + using type = T; static const bool value = std::is_arithmetic_v<type>; }; template <typename T> -struct ArithmeticOrUnderlyingEnum<T, false> { - using type = T; + requires(std::is_enum_v<T>) +struct ArithmeticOrUnderlyingEnum<T> { + using type = typename std::underlying_type<T>::type; static const bool value = std::is_arithmetic_v<type>; };
diff --git a/base/numerics/safe_math_shared_impl.h b/base/numerics/safe_math_shared_impl.h index 46ec883..8f567f3 100644 --- a/base/numerics/safe_math_shared_impl.h +++ b/base/numerics/safe_math_shared_impl.h
@@ -11,6 +11,7 @@ #include <cassert> #include <climits> #include <cmath> +#include <concepts> #include <cstdlib> #include <limits> #include <type_traits> @@ -114,18 +115,18 @@ // template instantiations even though we don't actually support the operations. // However, there is no corresponding implementation of e.g. SafeUnsignedAbs, // so the float versions will not compile. -template <typename Numeric, - bool IsInteger = std::is_integral_v<Numeric>, - bool IsFloat = std::is_floating_point_v<Numeric>> +template <typename Numeric> struct UnsignedOrFloatForSize; template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, true, false> { + requires(std::integral<Numeric>) +struct UnsignedOrFloatForSize<Numeric> { using type = typename std::make_unsigned<Numeric>::type; }; template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, false, true> { + requires(std::floating_point<Numeric>) +struct UnsignedOrFloatForSize<Numeric> { using type = Numeric; }; @@ -134,40 +135,42 @@ // exhibit well-defined overflow semantics and rely on the caller to detect // if an overflow occurred. -template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr> +template <typename T> + requires(std::integral<T>) constexpr T NegateWrapper(T value) { using UnsignedT = typename std::make_unsigned<T>::type; // This will compile to a NEG on Intel, and is normal negation on ARM. return static_cast<T>(UnsignedT(0) - static_cast<UnsignedT>(value)); } -template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr> +template <typename T> + requires(std::floating_point<T>) constexpr T NegateWrapper(T value) { return -value; } -template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr> +template <typename T> + requires(std::integral<T>) constexpr typename std::make_unsigned<T>::type InvertWrapper(T value) { return ~value; } -template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr> +template <typename T> + requires(std::integral<T>) constexpr T AbsWrapper(T value) { return static_cast<T>(SafeUnsignedAbs(value)); } -template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr> +template <typename T> + requires(std::floating_point<T>) constexpr T AbsWrapper(T value) { return value < 0 ? -value : value; } -template <template <typename, typename, typename> class M, - typename L, - typename R> +template <template <typename, typename> class M, typename L, typename R> struct MathWrapper { - using math = M<typename UnderlyingType<L>::type, - typename UnderlyingType<R>::type, - void>; + using math = + M<typename UnderlyingType<L>::type, typename UnderlyingType<R>::type>; using type = typename math::result_type; }; @@ -185,7 +188,7 @@ #define BASE_NUMERIC_ARITHMETIC_OPERATORS(CLASS, CL_ABBR, OP_NAME, OP, CMP_OP) \ /* Binary arithmetic operator for all CLASS##Numeric operations. */ \ template <typename L, typename R, \ - std::enable_if_t<Is##CLASS##Op<L, R>::value>* = nullptr> \ + typename = std::enable_if_t<Is##CLASS##Op<L, R>::value>> \ constexpr CLASS##Numeric< \ typename MathWrapper<CLASS##OP_NAME##Op, L, R>::type> \ operator OP(const L lhs, const R rhs) { \
diff --git a/build/config/OWNERS b/build/config/OWNERS index 580fa2e..3787744a 100644 --- a/build/config/OWNERS +++ b/build/config/OWNERS
@@ -1,4 +1,4 @@ per-file ozone.gni=file://ui/ozone/OWNERS per-file ozone_extra.gni=file://ui/ozone/OWNERS per-file rust.gni=file://build/rust/OWNERS -per-file chromecast_build.gni=file://build/config/chromecast/OWNERS +per-file cast.gni=file://build/config/chromecast/OWNERS
diff --git a/build/config/chromecast_build.gni b/build/config/chromecast_build.gni deleted file mode 100644 index 905241c..0000000 --- a/build/config/chromecast_build.gni +++ /dev/null
@@ -1,11 +0,0 @@ -# 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. - -# !!! DO NOT ADD NEW USAGES. !!! -# !!! This file is deprecated and only exists for backwards compatility !!! -# !!! with third party repos that include it directly :( !!! -# -# TODO(crbug.com/1294964): Update those usages and remove this file. - -import("//build/config/cast.gni")
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 90dc163..72d06a1 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 = "a96e76348a51cb38e2120a7333c49884e5737768" + libcxx_revision = "434a8efe28c23fda34464701cd4c7640b1f4c1c8" }
diff --git a/cc/input/scroll_snap_data.cc b/cc/input/scroll_snap_data.cc index 0f70fc4645..d69045e 100644 --- a/cc/input/scroll_snap_data.cc +++ b/cc/input/scroll_snap_data.cc
@@ -855,6 +855,8 @@ SnappedTargetData::SnappedTargetData() = default; SnappedTargetData::SnappedTargetData(const SnappedTargetData& other) = default; +SnappedTargetData::SnappedTargetData(const std::set<ElementId>& ids) + : snapped_target_ids_(std::move(ids)) {} SnappedTargetData::~SnappedTargetData() = default; std::ostream& operator<<(std::ostream& ostream, const SnapAreaData& area_data) {
diff --git a/cc/input/scroll_snap_data.h b/cc/input/scroll_snap_data.h index 711234f..990a51c1 100644 --- a/cc/input/scroll_snap_data.h +++ b/cc/input/scroll_snap_data.h
@@ -225,6 +225,7 @@ public: SnappedTargetData(); SnappedTargetData(const SnappedTargetData&); + explicit SnappedTargetData(const std::set<ElementId>& ids); ~SnappedTargetData(); const std::set<ElementId>& GetSnappedTargetIds() const { return snapped_target_ids_;
diff --git a/cc/slim/frame_sink_impl.cc b/cc/slim/frame_sink_impl.cc index d6410b8a..26dd621b 100644 --- a/cc/slim/frame_sink_impl.cc +++ b/cc/slim/frame_sink_impl.cc
@@ -63,12 +63,18 @@ } FrameSinkImpl::~FrameSinkImpl() { - // Iterate a copy of `uploaded_resources_` since it might be modified - // when `UIResourceReleased()` is called. - for (const auto& uploaded_resource_pair : - UploadedResourceMap(uploaded_resources_)) { - resource_provider_.RemoveImportedResource( - uploaded_resource_pair.second.viz_resource_id); + // Iterate a copy of the viz_resource_ids since `uploaded_resources_` might + // be modified when `UIResourceReleased()` is called. + // Also note that the DestroySharedImage() call in UIResourceRelease() + // requires the `ClientSharedImage` stored in the to-be-released resource to + // have precisely one reference. Therefore, it is advisable to avoid any + // operation that might alter the `ClientSharedImage`'s refcount, e.g. + // creating a full copy of `uploaded_resources_`. + auto resource_ids = base::MakeFlatSet<viz::ResourceId>( + uploaded_resources_, {}, + [](auto& resource_pair) { return resource_pair.second.viz_resource_id; }); + for (const auto& uploaded_resource_id : resource_ids) { + resource_provider_.RemoveImportedResource(uploaded_resource_id); } resource_provider_.ShutdownAndReleaseAllResources(); } @@ -162,13 +168,12 @@ auto* sii = context_provider_->SharedImageInterface(); constexpr gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ; - auto client_shared_image = sii->CreateSharedImage( + uploaded_resource.shared_image = sii->CreateSharedImage( format, resource_bitmap.GetSize(), color_space, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, shared_image_usage, "SlimCompositorUIResource", base::span<const uint8_t>(resource_bitmap.GetPixels(), resource_bitmap.SizeInBytes())); - CHECK(client_shared_image); - uploaded_resource.mailbox = client_shared_image->mailbox(); + CHECK(uploaded_resource.shared_image); gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken(); GLenum texture_target = gpu::GetBufferTextureTarget( @@ -176,7 +181,7 @@ viz::SinglePlaneSharedImageFormatToBufferFormat(format), caps); uploaded_resource.viz_resource_id = resource_provider_.ImportResource( viz::TransferableResource::MakeGpu( - uploaded_resource.mailbox, texture_target, sync_token, + uploaded_resource.shared_image, texture_target, sync_token, resource_bitmap.GetSize(), format, /*is_overlay_candidate=*/false, viz::TransferableResource::ResourceSource::kUI), base::BindOnce(&FrameSinkImpl::UIResourceReleased, base::Unretained(this), @@ -194,7 +199,7 @@ auto itr = uploaded_resources_.find(ui_resource_id); DCHECK(itr != uploaded_resources_.end()); auto* sii = context_provider_->SharedImageInterface(); - sii->DestroySharedImage(sync_token, itr->second.mailbox); + sii->DestroySharedImage(sync_token, std::move(itr->second.shared_image)); uploaded_resources_.erase(itr); }
diff --git a/cc/slim/frame_sink_impl.h b/cc/slim/frame_sink_impl.h index c66c727..e62e263 100644 --- a/cc/slim/frame_sink_impl.h +++ b/cc/slim/frame_sink_impl.h
@@ -26,7 +26,6 @@ #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/common/hit_test/hit_test_region_list.h" #include "components/viz/common/surfaces/local_surface_id.h" -#include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" @@ -34,6 +33,10 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" +namespace gpu { +class ClientSharedImage; +} + namespace cc::slim { class FrameSinkImplClient; @@ -105,7 +108,7 @@ UploadedUIResource(const UploadedUIResource&); UploadedUIResource& operator=(const UploadedUIResource&); - gpu::Mailbox mailbox; + scoped_refptr<gpu::ClientSharedImage> shared_image; gfx::Size size; bool is_opaque = true; viz::ResourceId viz_resource_id;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 3ad1a48..3e760870 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -2946,13 +2946,10 @@ raster_caps_.can_use_msaa = !context_caps.msaa_is_slow && !context_caps.avoid_stencil_buffers; - // Note this uses compositor context capabilities instead of worker since - // relevant capabilities are not set by raster decoder. raster_caps_.tile_format = settings_.use_rgba_4444 ? viz::SinglePlaneFormat::kRGBA_4444 - : viz::PlatformColor::BestSupportedRenderBufferFormat( - context_provider->ContextCapabilities()); + : viz::PlatformColor::BestSupportedRenderBufferFormat(context_caps); if (raster_caps_.tile_overlay_candidate) { raster_caps_.tile_texture_target = gpu::GetBufferTextureTarget( @@ -4643,7 +4640,7 @@ // For gpu compositing, a SharedImage mailbox will be allocated and the // UIResource will be uploaded into it. - gpu::Mailbox mailbox; + scoped_refptr<gpu::ClientSharedImage> client_shared_image; uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ; // For gpu compositing, we also calculate the GL texture target. // TODO(ericrk): Remove references to GL from this code. @@ -4682,12 +4679,11 @@ viz::RasterContextProvider* context_provider = layer_tree_frame_sink_->context_provider(); auto* sii = context_provider->SharedImageInterface(); - auto client_shared_image = sii->CreateSharedImage( + client_shared_image = sii->CreateSharedImage( format, upload_size, color_space, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource", base::span<const uint8_t>(bitmap.GetPixels(), bitmap.SizeInBytes())); CHECK(client_shared_image); - mailbox = client_shared_image->mailbox(); } else { DCHECK_EQ(bitmap.GetFormat(), UIResourceBitmap::RGBA8); SkImageInfo src_info = @@ -4751,14 +4747,13 @@ viz::RasterContextProvider* context_provider = layer_tree_frame_sink_->context_provider(); auto* sii = context_provider->SharedImageInterface(); - auto client_shared_image = sii->CreateSharedImage( + client_shared_image = sii->CreateSharedImage( format, upload_size, color_space, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, shared_image_usage, "LayerTreeHostUIResource", base::span<const uint8_t>( reinterpret_cast<const uint8_t*>(pixmap.addr()), pixmap.computeByteSize())); CHECK(client_shared_image); - mailbox = client_shared_image->mailbox(); } } @@ -4776,7 +4771,7 @@ ->GenUnverifiedSyncToken(); transferable = viz::TransferableResource::MakeGpu( - mailbox, texture_target, sync_token, upload_size, format, + client_shared_image, texture_target, sync_token, upload_size, format, overlay_candidate, viz::TransferableResource::ResourceSource::kUI); } else { layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region), @@ -4800,7 +4795,7 @@ data.format = format; data.shared_bitmap_id = shared_bitmap_id; data.shared_mapping = std::move(shm.mapping); - data.mailbox = mailbox; + data.shared_image = std::move(client_shared_image); data.resource_id_for_export = id; ui_resource_map_[uid] = std::move(data); @@ -4829,13 +4824,13 @@ UIResourceData data, const gpu::SyncToken& sync_token) { // Resources are either software or gpu backed, not both. - DCHECK(!(data.shared_mapping.IsValid() && !data.mailbox.IsZero())); + DCHECK(!(data.shared_mapping.IsValid() && data.shared_image)); if (data.shared_mapping.IsValid()) layer_tree_frame_sink_->DidDeleteSharedBitmap(data.shared_bitmap_id); - if (!data.mailbox.IsZero()) { + if (data.shared_image) { auto* sii = layer_tree_frame_sink_->context_provider()->SharedImageInterface(); - sii->DestroySharedImage(sync_token, data.mailbox); + sii->DestroySharedImage(sync_token, std::move(data.shared_image)); } // |data| goes out of scope and deletes anything it owned. }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 316a9865..3a40cc5 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -251,7 +251,7 @@ viz::SharedBitmapId shared_bitmap_id; base::WritableSharedMemoryMapping shared_mapping; // Backing for gpu compositing. - gpu::Mailbox mailbox; + scoped_refptr<gpu::ClientSharedImage> shared_image; // The name with which to refer to the resource in frames submitted to the // display compositor.
diff --git a/chrome/VERSION b/chrome/VERSION index 5391372a..7a85a74 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=121 MINOR=0 -BUILD=6138 +BUILD=6139 PATCH=0
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/PasswordGenerationIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/PasswordGenerationIntegrationTest.java index 172e10e..989e58f 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/PasswordGenerationIntegrationTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/PasswordGenerationIntegrationTest.java
@@ -190,6 +190,7 @@ @Test @IntegrationTest + @DisabledTest(message = "crbug.com/1502972") public void testManualGenerationCancel() throws InterruptedException, TimeoutException { waitForGenerationLabel(); focusField(PASSWORD_NODE_ID_MANUAL);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index a6e743c3..a30fb152 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -518,9 +518,17 @@ ntpHeader != null && ChromeFeatureList.sSurfacePolish.isEnabled() && DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity); - mMediator = new FeedSurfaceMediator(this, mActivity, snapScrollHelper, mSectionHeaderModel, - getTabIdFromLaunchOrigin(launchOrigin), actionDelegate, optionsCoordinator, - useUiConfig ? mUiConfig : null); + mMediator = + new FeedSurfaceMediator( + this, + mActivity, + snapScrollHelper, + mSectionHeaderModel, + getTabIdFromLaunchOrigin(launchOrigin), + actionDelegate, + optionsCoordinator, + useUiConfig ? mUiConfig : null, + profile); FeedSurfaceTracker.getInstance().trackSurface(this);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java index e5d86f2..ea4b4c1 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -257,16 +257,23 @@ * @param openingTabId The {@link FeedSurfaceCoordinator.StreamTabId} the feed should open to. * @param optionsCoordinator The {@link FeedOptionsCoordinator} for the feed. * @param uiConfig The {@link UiConfig} for screen display. + * @param profile The {@link Profile} for the current user. */ - FeedSurfaceMediator(FeedSurfaceCoordinator coordinator, Context context, - @Nullable SnapScrollHelper snapScrollHelper, PropertyModel headerModel, - @FeedSurfaceCoordinator.StreamTabId int openingTabId, FeedActionDelegate actionDelegate, - FeedOptionsCoordinator optionsCoordinator, @Nullable UiConfig uiConfig) { + FeedSurfaceMediator( + FeedSurfaceCoordinator coordinator, + Context context, + @Nullable SnapScrollHelper snapScrollHelper, + PropertyModel headerModel, + @FeedSurfaceCoordinator.StreamTabId int openingTabId, + FeedActionDelegate actionDelegate, + FeedOptionsCoordinator optionsCoordinator, + @Nullable UiConfig uiConfig, + Profile profile) { mCoordinator = coordinator; mHasContentListener = coordinator; mContext = context; mSnapScrollHelper = snapScrollHelper; - mProfile = Profile.getLastUsedRegularProfile(); + mProfile = profile; mSigninManager = IdentityServicesProvider.get().getSigninManager(mProfile); mTemplateUrlService = TemplateUrlServiceFactory.getForProfile(mProfile); mActionDelegate = actionDelegate; @@ -644,7 +651,7 @@ } int tabId = getTabIdForSection(StreamKind.FOLLOWING); boolean hasWebFeedTab = tabId != -1; - boolean shouldHaveWebFeedTab = FeedFeatures.isWebFeedUIEnabled(); + boolean shouldHaveWebFeedTab = FeedFeatures.isWebFeedUIEnabled(mProfile); if (hasWebFeedTab == shouldHaveWebFeedTab) return; if (shouldHaveWebFeedTab) { addHeaderAndStream(mContext.getResources().getString(R.string.ntp_following), @@ -850,7 +857,8 @@ private void setHeaderIndicatorState(boolean suggestionsVisible) { boolean isSignedIn = FeedServiceBridge.isSignedIn(); - boolean isTabMode = isSignedIn && FeedFeatures.isWebFeedUIEnabled() && suggestionsVisible; + boolean isTabMode = + isSignedIn && FeedFeatures.isWebFeedUIEnabled(mProfile) && suggestionsVisible; // If we're in tab mode now, make sure webfeed tab is set up. if (isTabMode) { setUpWebFeedTab();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index f819372..27f77068 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -1235,6 +1235,10 @@ // so we can't create the native page. The native page will be created once reparenting is // completed. if (isDetached()) return false; + // TODO(crbug/1503182): Remove the assert after determining why WebContents can be null. + WebContents webContents = getWebContents(); + assert webContents != null; + if (webContents == null) return false; NativePage candidateForReuse = forceReload ? null : getNativePage(); NativePage nativePage = mDelegateFactory.createNativePage(url, candidateForReuse, this); if (nativePage != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java index a92d555..536d62e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java
@@ -69,13 +69,13 @@ } private boolean shouldShowWebFeedMenuItem() { - if (!FeedFeatures.isWebFeedUIEnabled()) { - return false; - } Tab tab = mActivityTabProvider.get(); if (tab == null || tab.isIncognito() || OfflinePageUtils.isOfflinePage(tab)) { return false; } + if (!FeedFeatures.isWebFeedUIEnabled(tab.getProfile())) { + return false; + } String url = tab.getOriginalUrl().getSpec(); return url.startsWith(UrlConstants.HTTP_URL_PREFIX) || url.startsWith(UrlConstants.HTTPS_URL_PREFIX);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java index 202f249..bd2bc4c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java
@@ -12,7 +12,6 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import org.jni_zero.CalledByNative; @@ -52,19 +51,6 @@ ResettersForTesting.register(() -> sWebappInfoForTesting = null); } - /** - * Converts a color value to a hex string. - * - * @param color The color to convert. - * @return The RGB values of the color, as string presented in hex (prefixed with #). For - * example: '#FF0000' (for red). - */ - private static String colorToHexString(@ColorInt long color) { - return String.format( - "#%02X%02X%02X", - (((color) >> 16) & 0xFF), (((color) >> 8) & 0xFF), (((color) >> 0) & 0xFF)); - } - public static WebappInfo getPartialWebappInfo(String url) { if (sWebappInfoForTesting != null) return sWebappInfoForTesting;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java index c94d55f..bdf88462 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -345,6 +345,7 @@ @Test @SmallTest @EnableFeatures(ChromeFeatureList.CCT_REPORT_PARALLEL_REQUEST_STATUS) + @DisableFeatures(ChromeFeatureList.TRACKING_PROTECTION_3PCD) public void testCanSetCookie() throws Exception { testCanSetCookie(true); } @@ -638,7 +639,6 @@ customTabsCallback.waitForCompletion(0, 1); } - @DisableFeatures(ChromeFeatureList.TRACKING_PROTECTION_3PCD) private void testCanSetCookie(boolean afterNative) throws Exception { mServer = EmbeddedTestServer.createAndStartHTTPSServer(mContext, ServerCertificate.CERT_OK); final Uri url = Uri.parse(mServer.getURL("/set-cookie?acookie;SameSite=none;Secure"));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java index 80d3985..10cebda 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageTest.java
@@ -46,7 +46,10 @@ /** Integration tests for IncognitoNewTabPage. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) -@DisableFeatures({ChromeFeatureList.INCOGNITO_NTP_REVAMP}) +@DisableFeatures({ + ChromeFeatureList.INCOGNITO_NTP_REVAMP, + ChromeFeatureList.TRACKING_PROTECTION_3PCD +}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class IncognitoNewTabPageTest { @ClassRule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RevampedIncognitoNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RevampedIncognitoNewTabPageTest.java index f63d37a7..19368d12 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RevampedIncognitoNewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/RevampedIncognitoNewTabPageTest.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.R; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.content_settings.PrefNames; @@ -47,6 +48,7 @@ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @EnableFeatures({ChromeFeatureList.INCOGNITO_NTP_REVAMP}) +@DisableFeatures({ChromeFeatureList.TRACKING_PROTECTION_3PCD}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class RevampedIncognitoNewTabPageTest { @ClassRule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index a7cb628..09464ea9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -122,6 +122,8 @@ ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1" }) @Batch(PER_CLASS) +// Disable TrackingProtection3pcd as we use prefs instead of the feature in these tests. +@DisableFeatures(ChromeFeatureList.TRACKING_PROTECTION_3PCD) public class PageInfoViewTest { private static final String sSimpleHtml = "/chrome/test/data/android/simple.html"; private static final String sSiteDataHtml = "/content/test/data/browsing_data/site_data.html";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java index 2b32f6d..bae3062 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/PrivacySettingsFragmentTest.java
@@ -54,6 +54,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.R; import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.SigninTestRule; import org.chromium.components.policy.test.annotations.Policies; @@ -68,6 +69,8 @@ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @DoNotBatch(reason = "Child account can leak to other tests in the suite.") +// Disable TrackingProtection3pcd as we use prefs instead of the feature in these tests. +@DisableFeatures({ChromeFeatureList.TRACKING_PROTECTION_3PCD}) public class PrivacySettingsFragmentTest { // Index of the Privacy Sandbox row entry in the settings list. public static final int PRIVACY_SANDBOX_V4_POS_IDX = 4;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsBridgeTest.java index b1234483..4cc48de 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsBridgeTest.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.browsing_data.BrowsingDataBridge; import org.chromium.chrome.browser.browsing_data.BrowsingDataType; import org.chromium.chrome.browser.browsing_data.TimePeriod; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; @@ -165,7 +166,10 @@ */ @Test @SmallTest - @DisableFeatures(PageInfoFeatures.USER_BYPASS_UI_NAME) + @DisableFeatures({ + PageInfoFeatures.USER_BYPASS_UI_NAME, + ChromeFeatureList.TRACKING_PROTECTION_3PCD + }) public void testCookieBridgeWithTPCookiesDisabled() throws Exception { TestThreadUtils.runOnUiThreadBlocking( () -> { @@ -199,7 +203,10 @@ */ @Test @SmallTest - @DisableFeatures(PageInfoFeatures.USER_BYPASS_UI_NAME) + @DisableFeatures({ + PageInfoFeatures.USER_BYPASS_UI_NAME, + ChromeFeatureList.TRACKING_PROTECTION_3PCD + }) public void testCookieBridgeWith3PCookiesEnabled() throws Exception { TestThreadUtils.runOnUiThreadBlocking( () -> { @@ -234,7 +241,10 @@ */ @Test @SmallTest - @DisableFeatures(PageInfoFeatures.USER_BYPASS_UI_NAME) + @DisableFeatures({ + PageInfoFeatures.USER_BYPASS_UI_NAME, + ChromeFeatureList.TRACKING_PROTECTION_3PCD + }) public void testCookieBridgeWithChangingAllowedCookiesCount() throws Exception { int currentCallCount = mCallbackHelper.getCallCount(); @@ -269,7 +279,10 @@ */ @Test @SmallTest - @DisableFeatures(PageInfoFeatures.USER_BYPASS_UI_NAME) + @DisableFeatures({ + PageInfoFeatures.USER_BYPASS_UI_NAME, + ChromeFeatureList.TRACKING_PROTECTION_3PCD + }) public void testCookieBridgeWithChangingBlockedCookiesCount() throws Exception { TestThreadUtils.runOnUiThreadBlocking( () -> { @@ -313,7 +326,10 @@ /** Test blocked cookies works with CookieControlsMode.INCOGNITO_ONLY. */ @Test @SmallTest - @DisableFeatures(PageInfoFeatures.USER_BYPASS_UI_NAME) + @DisableFeatures({ + PageInfoFeatures.USER_BYPASS_UI_NAME, + ChromeFeatureList.TRACKING_PROTECTION_3PCD + }) public void testCookieBridgeWithIncognitoSetting() throws Exception { TestThreadUtils.runOnUiThreadBlocking( () -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsServiceBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsServiceBridgeTest.java index 4e3163e..00e9eec 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsServiceBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieControlsServiceBridgeTest.java
@@ -17,12 +17,14 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.components.content_settings.CookieControlsEnforcement; import org.chromium.components.content_settings.CookieControlsMode; import org.chromium.components.content_settings.PrefNames; @@ -95,6 +97,7 @@ /** Test changing the bridge triggers callback for correct toggle state. */ @Test @SmallTest + @DisableFeatures(ChromeFeatureList.TRACKING_PROTECTION_3PCD) public void testCookieSettingsCheckedChanges() throws Exception { setCookieControlsMode(CookieControlsMode.OFF); final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); @@ -142,6 +145,7 @@ /** Test the ability to set the cookie controls mode pref through the bridge. */ @Test @SmallTest + @DisableFeatures(ChromeFeatureList.TRACKING_PROTECTION_3PCD) public void testCookieBridgeWithTPCookiesDisabled() throws Exception { setCookieControlsMode(CookieControlsMode.OFF); final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html");
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java index 8de13ba..ee75702 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderPickerMediatorTest.java
@@ -11,10 +11,11 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; +import static org.chromium.ui.test.util.MockitoHelper.doCallback; + import android.app.Activity; import android.graphics.drawable.Drawable; import android.util.Pair; @@ -32,7 +33,7 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import org.robolectric.annotation.Config; +import org.mockito.quality.Strictness; import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; @@ -57,9 +58,9 @@ /** Unit tests for {@link BookmarkFolderPickerMediator}. */ @Batch(Batch.UNIT_TESTS) @RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) public class BookmarkFolderPickerMediatorTest { - @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT); @Rule public final ActivityScenarioRule<TestActivity> mActivityScenarioRule = @@ -278,27 +279,20 @@ doReturn(mReadingListItem1).when(mBookmarkModel).getBookmarkById(mReadingListItemId1); doReturn(mReadingListItem2).when(mBookmarkModel).getBookmarkById(mReadingListItemId2); doReturn(true).when(mBookmarkModel).doesBookmarkExist(any()); - doAnswer( - (invocation) -> { - Runnable runnable = invocation.getArgument(0); - runnable.run(); - return null; - }) + doCallback((Runnable runnable) -> runnable.run()) .when(mBookmarkModel) .finishLoadingBookmarkModel(any()); - // Setup menu + // Setup menu. doReturn(mMenuItem).when(mMenu).add(anyInt()); doReturn(mMenuItem).when(mMenuItem).setIcon(any()); doReturn(mMenuItem).when(mMenuItem).setShowAsActionFlags(anyInt()); // Setup BookmarkImageFetcher. - doAnswer( - (invocation) -> { - Callback<Pair<Drawable, Drawable>> callback = invocation.getArgument(1); - callback.onResult(new Pair<>(null, null)); - return null; - }) + doCallback( + /* index= */ 1, + (Callback<Pair<Drawable, Drawable>> callback) -> + callback.onResult(new Pair<>(null, null))) .when(mBookmarkImageFetcher) .fetchFirstTwoImagesForFolder(any(), any()); @@ -321,25 +315,34 @@ mShoppingService); } - @Test - public void testMoveFolder() { + private void remakeMediator(BookmarkId... bookmarkIds) { + if (mMediator != null) { + mMediator.destroy(); + } + ImprovedBookmarkRowCoordinator rowCoordinator = + new ImprovedBookmarkRowCoordinator( + mActivity, + mBookmarkImageFetcher, + mBookmarkModel, + mBookmarkUiPrefs, + mShoppingService); mMediator = new BookmarkFolderPickerMediator( mActivity, mBookmarkModel, - Arrays.asList(mUserFolderId), + Arrays.asList(bookmarkIds), mFinishRunnable, mBookmarkUiPrefs, mModel, mModelList, mAddNewFolderCoordinator, - new ImprovedBookmarkRowCoordinator( - mActivity, - mBookmarkImageFetcher, - mBookmarkModel, - mBookmarkUiPrefs, - mShoppingService), + rowCoordinator, mShoppingService); + } + + @Test + public void testMoveFolder() { + remakeMediator(mUserFolderId); mMediator.populateFoldersForParentId(mMobileFolderId); // Check that the UserFolder isn't a row since it should be filtered out because it's the @@ -442,72 +445,21 @@ @Test public void testMoveMultiple_sharedParent() { - mMediator = - new BookmarkFolderPickerMediator( - mActivity, - mBookmarkModel, - Arrays.asList(mUserBookmarkId, mUserBookmarkId1), - mFinishRunnable, - mBookmarkUiPrefs, - mModel, - mModelList, - mAddNewFolderCoordinator, - new ImprovedBookmarkRowCoordinator( - mActivity, - mBookmarkImageFetcher, - mBookmarkModel, - mBookmarkUiPrefs, - mShoppingService), - mShoppingService); - + remakeMediator(mUserBookmarkId, mUserBookmarkId1); assertEquals("UserFolder", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); } @Test public void testMoveMultiple_noSharedParent() { - mMediator = - new BookmarkFolderPickerMediator( - mActivity, - mBookmarkModel, - Arrays.asList(mUserFolderId, mUserBookmarkId1), - mFinishRunnable, - mBookmarkUiPrefs, - mModel, - mModelList, - mAddNewFolderCoordinator, - new ImprovedBookmarkRowCoordinator( - mActivity, - mBookmarkImageFetcher, - mBookmarkModel, - mBookmarkUiPrefs, - mShoppingService), - mShoppingService); - + remakeMediator(mUserFolderId, mUserBookmarkId1); assertEquals("Move to…", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); } @Test public void testMoveMultiple_readingList() { - mMediator = - new BookmarkFolderPickerMediator( - mActivity, - mBookmarkModel, - Arrays.asList(mReadingListItemId1, mReadingListItemId2), - mFinishRunnable, - mBookmarkUiPrefs, - mModel, - mModelList, - mAddNewFolderCoordinator, - new ImprovedBookmarkRowCoordinator( - mActivity, - mBookmarkImageFetcher, - mBookmarkModel, - mBookmarkUiPrefs, - mShoppingService), - mShoppingService); - + remakeMediator(mReadingListItemId1, mReadingListItemId2); assertEquals("Reading List", mModel.get(BookmarkFolderPickerProperties.TOOLBAR_TITLE)); assertFalse(mModel.get(BookmarkFolderPickerProperties.MOVE_BUTTON_ENABLED)); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java index cd247f1..1ae61b52 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FeedSurfaceMediatorTest.java
@@ -1153,6 +1153,7 @@ tabId, /* actionDelegate= */ null, mOptionsCoordinator, - uiConfig); + uiConfig, + mProfileMock); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java index a4131d5..694ab88 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
@@ -190,6 +190,7 @@ when(mTabModelSelector.getTabModelFilterProvider()).thenReturn(mTabModelFilterProvider); when(mTabModelFilterProvider.getCurrentTabModelFilter()).thenReturn(mTabModelFilter); when(mTabModelFilter.getTabModel()).thenReturn(mTabModel); + when(mTabModel.getProfile()).thenReturn(mProfile); jniMocker.mock(ManagedBrowserUtilsJni.TEST_HOOKS, mManagedBrowserUtilsJniMock); Profile.setLastUsedProfileForTesting(mProfile); jniMocker.mock(WebsitePreferenceBridgeJni.TEST_HOOKS, mWebsitePreferenceBridgeJniMock);
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java index 644f407..1aa0353 100644 --- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java +++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java
@@ -78,9 +78,9 @@ } /** - * Tests that for WebAPKs with shell APK version lower than the - * {@link WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST}, - * the backs-WebAPK-check returns false if the browser does NOT match the WebAPK's runtime host + * Tests that for WebAPKs with shell APK version lower than the {@link + * WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST}, the + * backs-WebAPK-check returns false if the browser does NOT match the WebAPK's runtime host * specified in the metaData. */ @Test @@ -96,10 +96,10 @@ } /** - * Tests that for WebAPKs with shell APK version lower than the - * {@link WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST}, - * the backs-WebAPK-check returns true if the browser matches the WebAPK's runtime host - * specified in the metaData. + * Tests that for WebAPKs with shell APK version lower than the {@link + * WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST}, the + * backs-WebAPK-check returns true if the browser matches the WebAPK's runtime host specified in + * the metaData. */ @Test public void testReturnsTrueWhenMatchesRuntimeHostBeforeIntroduceHostBrowserSwitchLogic() { @@ -114,9 +114,9 @@ } /** - * Tests that for WebAPKs with shell APK version equal or higher than the - * {@link WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST} but - * doesn't have Identity Service, the backs-WebAPK-check returns false. + * Tests that for WebAPKs with shell APK version equal or higher than the {@link + * WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST} but doesn't + * have Identity Service, the backs-WebAPK-check returns false. */ @Test public void testBacksWebApkCheckForWebApkWithHostBrowserSwitchLogicButWithoutIdentityService() {
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java index 7058e3b1..ba95c1f 100644 --- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java +++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java
@@ -178,8 +178,8 @@ } /** - * Context which records order of {@link Context#bindService()} and - * {@link Context#unbindService()} calls. + * Context which records order of {@link Context#bindService()} and {@link + * Context#unbindService()} calls. */ private static class BindUnbindRecordingContext extends ContextWrapper { private String mRecordPackage;
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java index edc85df..9a39480 100644 --- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClient.java
@@ -24,7 +24,7 @@ public class WebApkIdentityServiceClient { /** * Used to notify the consumer after checking whether the caller browser backs the WebAPK. - * |browserPackageName| is the package name of the browser which backs the WebAPK. + * |browserPackageName| is the package name of the browser which backs the WebAPK. */ public interface CheckBrowserBacksWebApkCallback { void onChecked(boolean doesBrowserBackWebApk, String browserPackageName); @@ -60,25 +60,30 @@ } private WebApkIdentityServiceClient(@TaskTraits int uiThreadTaskTraits) { - mConnectionManager = new WebApkServiceConnectionManager( - uiThreadTaskTraits, null /* category */, ACTION_WEBAPK_IDENTITY_SERVICE); + mConnectionManager = + new WebApkServiceConnectionManager( + uiThreadTaskTraits, /* category= */ null, ACTION_WEBAPK_IDENTITY_SERVICE); } /** * Checks whether a WebAPK is backed by the browser with {@link browserContext}. + * * @param browserContext The browser context. * @param webApkPackageName The package name of the WebAPK. * @param callback The callback to be called after querying the runtime host is done. */ - public void checkBrowserBacksWebApkAsync(final Context browserContext, - final String webApkPackageName, final CheckBrowserBacksWebApkCallback callback) { + public void checkBrowserBacksWebApkAsync( + final Context browserContext, + final String webApkPackageName, + final CheckBrowserBacksWebApkCallback callback) { WebApkServiceConnectionManager.ConnectionCallback connectionCallback = new WebApkServiceConnectionManager.ConnectionCallback() { @Override public void onConnected(IBinder service) { String browserPackageName = browserContext.getPackageName(); if (service == null) { - onGotWebApkRuntimeHost(browserPackageName, + onGotWebApkRuntimeHost( + browserPackageName, maybeExtractRuntimeHostFromMetaData( browserContext, webApkPackageName), callback); @@ -103,20 +108,24 @@ /** * Called after fetching the WebAPK's backing browser. + * * @param browserPackageName The browser's package name. * @param webApkBackingBrowserPackageName The package name of the WebAPK's backing browser. * @param callback The callback to notify whether {@link browserPackageName} backs the WebAPK. */ - private static void onGotWebApkRuntimeHost(String browserPackageName, - String webApkBackingBrowserPackageName, CheckBrowserBacksWebApkCallback callback) { - callback.onChecked(TextUtils.equals(webApkBackingBrowserPackageName, browserPackageName), + private static void onGotWebApkRuntimeHost( + String browserPackageName, + String webApkBackingBrowserPackageName, + CheckBrowserBacksWebApkCallback callback) { + callback.onChecked( + TextUtils.equals(webApkBackingBrowserPackageName, browserPackageName), webApkBackingBrowserPackageName); } /** - * Extracts the backing browser from the WebAPK's meta data. - * See {@link WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST} for - * more details. + * Extracts the backing browser from the WebAPK's meta data. See {@link + * WebApkIdentityServiceClient#SHELL_APK_VERSION_SUPPORTING_SWITCH_RUNTIME_HOST} for more + * details. */ private static String maybeExtractRuntimeHostFromMetaData( Context context, String webApkPackageName) { @@ -136,8 +145,9 @@ private static Bundle readMetaData(Context context, String packageName) { ApplicationInfo ai = null; try { - ai = context.getPackageManager().getApplicationInfo( - packageName, PackageManager.GET_META_DATA); + ai = + context.getPackageManager() + .getApplicationInfo(packageName, PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { return null; }
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkNavigationClient.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkNavigationClient.java index 09089ca..1036cd7 100644 --- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkNavigationClient.java +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkNavigationClient.java
@@ -9,17 +9,16 @@ import org.chromium.webapk.lib.common.WebApkConstants; -/** - * WebApkNavigationClient provides an API to get an intent to launch a WebAPK. - */ +/** WebApkNavigationClient provides an API to get an intent to launch a WebAPK. */ public class WebApkNavigationClient { /** * Creates intent to launch a WebAPK. + * * @param webApkPackageName Package name of the WebAPK to launch. * @param url URL to navigate WebAPK to. * @param forceNavigation Whether the WebAPK should be navigated to the url if the WebAPK is - * already open. If {@link forceNavigation} is false and the WebAPK is already running, - * the WebAPK will be brought to the foreground. + * already open. If {@link forceNavigation} is false and the WebAPK is already running, the + * WebAPK will be brought to the foreground. * @return The intent. */ public static Intent createLaunchWebApkIntent(
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java index 41b54567..84c3354f 100644 --- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
@@ -22,13 +22,11 @@ import java.util.concurrent.Callable; /** - * Each WebAPK has several services. This class manages static global connections between the - * Chrome application and the "WebAPK services." + * Each WebAPK has several services. This class manages static global connections between the Chrome + * application and the "WebAPK services." */ public class WebApkServiceConnectionManager { - /** - * Interface for getting notified once Chrome is connected to a WebAPK service. - */ + /** Interface for getting notified once Chrome is connected to a WebAPK service. */ public interface ConnectionCallback { /** * Called once Chrome is connected to the WebAPK service. @@ -148,24 +146,27 @@ mConnections.put(webApkPackage, newConnection); newConnection.addCallback(callback); - Callable<Boolean> backgroundTask = () -> { - Intent intent = createConnectIntent(webApkPackage); - try { - if (appContext.bindService(intent, newConnection, Context.BIND_AUTO_CREATE)) { - return true; - } else { - appContext.unbindService(newConnection); - } - } catch (SecurityException e) { - Log.w(TAG, "Security exception binding.", e); - } - return false; - }; - Callback<Boolean> uiThreadReply = (bindSuccessful) -> { - if (!bindSuccessful) { - newConnection.onServiceConnected(null, null); - } - }; + Callable<Boolean> backgroundTask = + () -> { + Intent intent = createConnectIntent(webApkPackage); + try { + if (appContext.bindService( + intent, newConnection, Context.BIND_AUTO_CREATE)) { + return true; + } else { + appContext.unbindService(newConnection); + } + } catch (SecurityException e) { + Log.w(TAG, "Security exception binding.", e); + } + return false; + }; + Callback<Boolean> uiThreadReply = + (bindSuccessful) -> { + if (!bindSuccessful) { + newConnection.onServiceConnected(null, null); + } + }; postTaskAndReply(backgroundTask, uiThreadReply); } @@ -188,17 +189,19 @@ connectionToDisconnect.onServiceConnected(null, null); } - Callable<Boolean> backgroundTask = () -> { - for (Connection connectionToDisconnect : connectionsToDisconnect) { - appContext.unbindService(connectionToDisconnect); - } - return true; - }; - Callback<Boolean> uiThreadReply = (unused) -> { - if (mConnections.isEmpty() && mNumPendingPostedTasks == 0) { - destroyTaskRunner(); - } - }; + Callable<Boolean> backgroundTask = + () -> { + for (Connection connectionToDisconnect : connectionsToDisconnect) { + appContext.unbindService(connectionToDisconnect); + } + return true; + }; + Callback<Boolean> uiThreadReply = + (unused) -> { + if (mConnections.isEmpty() && mNumPendingPostedTasks == 0) { + destroyTaskRunner(); + } + }; postTaskAndReply(backgroundTask, uiThreadReply); } @@ -210,19 +213,23 @@ private void postTaskAndReply( final Callable<Boolean> backgroundTask, final Callback<Boolean> uiThreadReply) { ++mNumPendingPostedTasks; - getTaskRunner().postTask(() -> { - Boolean result = false; - try { - result = backgroundTask.call(); - } catch (Exception e) { - } + getTaskRunner() + .postTask( + () -> { + Boolean result = false; + try { + result = backgroundTask.call(); + } catch (Exception e) { + } - final Boolean finalResult = result; - PostTask.postTask(mUiThreadTaskTraits, () -> { - --mNumPendingPostedTasks; - uiThreadReply.onResult(finalResult); - }); - }); + final Boolean finalResult = result; + PostTask.postTask( + mUiThreadTaskTraits, + () -> { + --mNumPendingPostedTasks; + uiThreadReply.onResult(finalResult); + }); + }); } /**
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkCommonUtils.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkCommonUtils.java index e4e5e9c..d6ad5c45 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkCommonUtils.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkCommonUtils.java
@@ -8,6 +8,7 @@ public class WebApkCommonUtils { /** * Returns name of "Runtime Dex" asset in Chrome APK based on version. + * * @param version * @return Dex asset name. */ @@ -28,7 +29,8 @@ * WebAPK. */ public static String generateSplashContentProviderUri(String webApkPackageName) { - return "content://" + generateSplashContentProviderAuthority(webApkPackageName) + return "content://" + + generateSplashContentProviderAuthority(webApkPackageName) + "/cached_splash_image"; } }
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java index ec1873d..a0345b5 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkConstants.java
@@ -4,16 +4,13 @@ package org.chromium.webapk.lib.common; -/** - * Stores WebAPK related constants. - */ +/** Stores WebAPK related constants. */ public final class WebApkConstants { // WebAPK id prefix. The id is used for storing WebAPK data in Chrome's SharedPreferences. public static final String WEBAPK_ID_PREFIX = "webapk-"; - /** These EXTRA_* values must stay in sync with - * {@link org.chromium.chrome.browser.ShortcutHelper}. - */ + // These EXTRA_* values must stay in sync with {@link + // org.chromium.chrome.browser.ShortcutHelper}. public static final String EXTRA_URL = "org.chromium.chrome.browser.webapp_url"; public static final String EXTRA_SOURCE = "org.chromium.chrome.browser.webapp_source"; public static final String EXTRA_WEBAPK_PACKAGE_NAME =
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkMetaDataUtils.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkMetaDataUtils.java index a677e78..a340d03 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkMetaDataUtils.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/WebApkMetaDataUtils.java
@@ -10,6 +10,7 @@ public class WebApkMetaDataUtils { /** * Extracts long value from the WebAPK's meta data. + * * @param metaData WebAPK meta data to extract the long from. * @param name Name of the <meta-data> tag to extract the value from. * @param defaultValue Value to return if long value could not be extracted.
diff --git a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/splash/SplashLayout.java b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/splash/SplashLayout.java index e9031c2..5e69cc6 100644 --- a/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/splash/SplashLayout.java +++ b/chrome/android/webapk/libs/common/src/org/chromium/webapk/lib/common/splash/SplashLayout.java
@@ -26,9 +26,9 @@ } /** - * Selects the splash screen layout based on: - * - Whether the icon is appropriate to display on the splash screen. - * - The icon size. + * Selects the splash screen layout based on whether the icon is appropriate to display. For + * example, the icon must not be generated (nor missing) and has to have the length of both its + * edges above `R.dimen.webapp_splash_image_size_minimum` to be usable. */ public static int selectLayout(Resources resources, Bitmap icon, boolean wasIconGenerated) { if (icon == null || wasIconGenerated) { @@ -52,8 +52,13 @@ } /** Builds splash screen and attaches it to the parent view. */ - public static void createLayout(Context appContext, ViewGroup parentView, Bitmap icon, - boolean isIconAdaptive, boolean isIconGenerated, String text, + public static void createLayout( + Context appContext, + ViewGroup parentView, + Bitmap icon, + boolean isIconAdaptive, + boolean isIconGenerated, + String text, boolean useLightTextColor) { int layoutId = selectLayout(appContext.getResources(), icon, isIconGenerated); ViewGroup layout = @@ -62,8 +67,9 @@ TextView appNameView = (TextView) layout.findViewById(R.id.webapp_splash_screen_name); appNameView.setText(text); if (useLightTextColor) { - appNameView.setTextColor(getColorCompatibility( - appContext.getResources(), R.color.webapp_splash_title_light)); + appNameView.setTextColor( + getColorCompatibility( + appContext.getResources(), R.color.webapp_splash_title_light)); } ImageView splashIconView = (ImageView) layout.findViewById(R.id.webapp_splash_screen_icon);
diff --git a/chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service/src/org/chromium/webapk/lib/runtime_library/test/TestWebApkServiceImplWrapper.java b/chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service/src/org/chromium/webapk/lib/runtime_library/test/TestWebApkServiceImplWrapper.java index 555436f..4945529 100644 --- a/chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service/src/org/chromium/webapk/lib/runtime_library/test/TestWebApkServiceImplWrapper.java +++ b/chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service/src/org/chromium/webapk/lib/runtime_library/test/TestWebApkServiceImplWrapper.java
@@ -11,9 +11,7 @@ import org.chromium.webapk.lib.runtime_library.WebApkServiceImpl; -/** - * Simple service which uses {@link WebApkServiceImpl} for testing. - */ +/** Simple service which uses {@link WebApkServiceImpl} for testing. */ public class TestWebApkServiceImplWrapper extends Service { @Override public IBinder onBind(Intent intent) {
diff --git a/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java b/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java index 5ada232..ac7c904 100644 --- a/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java +++ b/chrome/android/webapk/libs/runtime_library/javatests/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImplTest.java
@@ -110,9 +110,10 @@ /** * Binds to the WebAPK service and blocks till the service is connected. + * * @param context The context for the application containing the WebAPK service to bind to. * @param authorizedUid The uid of the only application allowed to use the WebAPK service's - * methods. + * methods. * @param smallIconId The real small icon id. * @return IWebApkApi to use to communicate with the service. */
diff --git a/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java b/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java index 1fcf6c7f..dcef69b 100644 --- a/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java +++ b/chrome/android/webapk/libs/runtime_library/src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java
@@ -19,9 +19,7 @@ import android.text.TextUtils; import android.util.Log; -/** - * Implements services offered by the WebAPK to Chrome. - */ +/** Implements services offered by the WebAPK to Chrome. */ public class WebApkServiceImpl extends IWebApkApi.Stub { public static final String KEY_SMALL_ICON_ID = "small_icon_id"; @@ -31,9 +29,7 @@ private final Context mContext; - /** - * Id of icon to represent WebAPK notifications in status bar. - */ + /** Id of icon to represent WebAPK notifications in status bar. */ private final int mSmallIconId; /** @@ -44,6 +40,7 @@ /** * Creates an instance of WebApkServiceImpl. + * * @param context * @param bundle Bundle with additional constructor parameters. */ @@ -59,8 +56,11 @@ throws RemoteException { int callingUid = Binder.getCallingUid(); if (mHostUid != callingUid) { - throw new RemoteException("Unauthorized caller " + callingUid - + " does not match expected host=" + mHostUid); + throw new RemoteException( + "Unauthorized caller " + + callingUid + + " does not match expected host=" + + mHostUid); } return super.onTransact(code, data, reply, flags); } @@ -72,7 +72,8 @@ @Override public void notifyNotification(String platformTag, int platformID, Notification notification) { - Log.w(TAG, + Log.w( + TAG, "Should NOT reach WebApkServiceImpl#notifyNotification(String, int," + " Notification)."); } @@ -84,7 +85,8 @@ @Override public boolean notificationPermissionEnabled() { - Log.w(TAG, + Log.w( + TAG, "Should NOT reach WebApkServiceImpl#notificationPermissionEnabled() because it is" + " deprecated."); NotificationManager notificationManager = @@ -115,7 +117,8 @@ @Override public PendingIntent requestNotificationPermission(String channelName, String channelId) { - Log.w(TAG, + Log.w( + TAG, "Should NOT reach WebApkServiceImpl#requestNotificationPermission(String," + " String)."); return null; @@ -139,8 +142,11 @@ String platformTag, int platformID, Notification notification, String channelName) { NotificationManager notificationManager = getNotificationManager(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notification.getChannelId() != null) { - NotificationChannel channel = new NotificationChannel(notification.getChannelId(), - channelName, NotificationManager.IMPORTANCE_DEFAULT); + NotificationChannel channel = + new NotificationChannel( + notification.getChannelId(), + channelName, + NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); }
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni index a5e4f275..58c051d 100644 --- a/chrome/android/webapk/shell_apk/current_version/current_version.gni +++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@ # //chrome/android/webapk/shell_apk:webapk is changed. This includes # Java files, Android resource files and AndroidManifest.xml. Does not affect # Chrome.apk -current_shell_apk_version = 166 +current_shell_apk_version = 167
diff --git a/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary.java b/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary.java index 334b7928..f8f13369 100644 --- a/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary.java +++ b/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary.java
@@ -5,8 +5,7 @@ package org.chromium.webapk.shell_apk.test.canary; /** - * Class to put into DexOptimizer.apk's assets in order to test creating - * ClassLoader from .dex in remote APK. + * Class to put into DexOptimizer.apk's assets in order to test creating ClassLoader from .dex in + * remote APK. */ -public class Canary { -} +public class Canary {}
diff --git a/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary2.java b/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary2.java index 45b5658..6e00864 100644 --- a/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary2.java +++ b/chrome/android/webapk/shell_apk/javatests/canary_lib/src/org/chromium/webapk/shell_apk/test/canary/Canary2.java
@@ -5,8 +5,7 @@ package org.chromium.webapk.shell_apk.test.canary; /** - * Class to put into DexOptimizer.apk's assets in order to test creating - * ClassLoader from .dex in remote APK. + * Class to put into DexOptimizer.apk's assets in order to test creating ClassLoader from .dex in + * remote APK. */ -public class Canary2 { -} +public class Canary2 {}
diff --git a/chrome/android/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java b/chrome/android/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java index d62f146..0b2e35d 100644 --- a/chrome/android/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java +++ b/chrome/android/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java
@@ -196,6 +196,7 @@ /** * Returns the Context of the APK which contains dex with canary class implementation. + * * @param context The test application's Context. * @return Context of the APK whcih provide DexOptimizerService. */
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/CustomAndroidOsShadowAsyncTask.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/CustomAndroidOsShadowAsyncTask.java index 60d7f6c..689d363 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/CustomAndroidOsShadowAsyncTask.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/CustomAndroidOsShadowAsyncTask.java
@@ -11,8 +11,8 @@ import java.util.concurrent.Executor; /** - * Forces async tasks to execute with the default executor. - * This works around Robolectric not working out of the box with custom executors. + * Forces async tasks to execute with the default executor. This works around the problem of + * Robolectric not working out of the box with custom executors. * * @param <Params> * @param <Progress>
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java index e1182e60..288fa26c 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java
@@ -150,8 +150,9 @@ /** * Verifies {@link DexLoader#load()} call. - * @param expectedDexName The name of the dex in the remote host browser's assets that - * {@link DexLoader#load()} should have been called with. + * + * @param expectedDexName The name of the dex in the remote host browser's assets that {@link + * DexLoader#load()} should have been called with. */ public void verifyDexLoaderLoadCall(String expectedDexName) { Mockito.verify(mMockDexLoader)
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserUtilsTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserUtilsTest.java index b9dc00a..f323f01c 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserUtilsTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserUtilsTest.java
@@ -82,9 +82,9 @@ } /** - * Tests that both {@link #computeHostBrowserPackageClearCachedDataOnChange()} - * and {@link #getCachedHostBrowserPackage()} return null if there isn't any - * browser installed on the device. + * Tests that both {@link #computeHostBrowserPackageClearCachedDataOnChange()} and {@link + * #getCachedHostBrowserPackage()} return null if there isn't any browser installed on the + * device. */ @Test public void testReturnsNullWhenNoBrowserInstalled() { @@ -97,15 +97,13 @@ Assert.assertNull(HostBrowserUtils.getCachedHostBrowserPackage(mContext)); } - /** - * Tests the order of precedence for bound WebAPKs for - * {@link #computeHostBrowserPackageClearCachedDataOnChange()}. The expected order of precedence - * is: - * 1) Browser specified in shared preferences if it is still installed. - * 2) Bound browser specified in AndroidManifest.xml - * The default browser and the number of installed browsers which support WebAPKs should - * have no effect. - */ + // Tests the order of precedence for bound WebAPKs for + // {@link #computeHostBrowserPackageClearCachedDataOnChange()}. The expected order of precedence + // is: + // 1) Browser specified in shared preferences if it is still installed. + // 2) Bound browser specified in AndroidManifest.xml + // The default browser and the number of installed browsers which support WebAPKs should + // have no effect. @Test public void testComputeHostBrowserBoundWebApkPrecedence() { if (!mIsBoundWebApk) return; @@ -149,14 +147,12 @@ HostBrowserUtils.computeHostBrowserPackageClearCachedDataOnChange(mContext)); } - /** - * Tests the order of precedence for unbound WebAPKs for - * {@link #computeHostBrowserPackageClearCachedDataOnChange()}. The expected order of precedence - * is: - * 1) Browser specified in shared preferences if it is still installed. - * 2) Default browser if the default browser supports WebAPKs. - * 3) The browser which supports WebAPKs if there is just one. - */ + // Tests the order of precedence for unbound WebAPKs for + // {@link #computeHostBrowserPackageClearCachedDataOnChange()}. The expected order of precedence + // is: + // 1) Browser specified in shared preferences if it is still installed. + // 2) Default browser if the default browser supports WebAPKs. + // 3) The browser which supports WebAPKs if there is just one. @Test public void testComputeHostBrowserUnboundWebApkPrecedence() { if (mIsBoundWebApk) return; @@ -246,9 +242,9 @@ } /** - * Tests that neither {@link #computeHostBrowserPackageClearCachedDataOnChange()} nor - * {@link #getCachedHostBrowserPackage()} return the cached browser in - * {@link HostBrowserUtils#sHostPackage} if the cached browser was uninstalled. + * Tests that neither {@link #computeHostBrowserPackageClearCachedDataOnChange()} nor {@link + * #getCachedHostBrowserPackage()} return the cached browser in {@link + * HostBrowserUtils#sHostPackage} if the cached browser was uninstalled. */ @Test public void testDoesNotReturnTheCurrentHostBrowserAfterUninstall() {
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/MainActivityTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/MainActivityTest.java index d01bc74b..24298eb 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/MainActivityTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/MainActivityTest.java
@@ -24,10 +24,11 @@ import org.chromium.webapk.shell_apk.h2o.H2OMainActivity; import org.chromium.webapk.test.WebApkTestHelper; -/** Unit tests for {@link MainActivity}. +/** + * Unit tests for {@link MainActivity}. * - * Note: In real word, |loggedIntentUrlParam| is set to be nonempty iff intent url is outside of the - * scope specified in the Android manifest, so in the test we always have these two conditions + * <p>Note: In real word, |loggedIntentUrlParam| is set to be nonempty iff intent url is outside of + * the scope specified in the Android manifest, so in the test we always have these two conditions * together. */ @RunWith(RobolectricTestRunner.class)
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/TestBrowserInstaller.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/TestBrowserInstaller.java index 1fa54c41..fbdd71c7 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/TestBrowserInstaller.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/TestBrowserInstaller.java
@@ -24,9 +24,7 @@ public class TestBrowserInstaller { Set<String> mInstalledBrowsers = new HashSet<String>(); - /** - * Changes the installed browsers to the passed-in list. - */ + /** Changes the installed browsers to the passed-in list. */ public void setInstalledModernBrowsers(String defaultBrowserPackage, String[] newPackages) { uninstallAllBrowsers(); @@ -38,24 +36,18 @@ } } - /** - * Changes the installed browser to a browser with the passed-in package and version name. - */ + /** Changes the installed browser to a browser with the passed-in package and version name. */ public void setInstalledBrowserWithVersion(String browser, String versionName) { uninstallAllBrowsers(); installBrowserWithVersion(browser, versionName); } - /** - * Installs browser with the passed-in package name and large version name. - */ + /** Installs browser with the passed-in package name and large version name. */ public void installModernBrowser(String packageName) { installBrowserWithVersion(packageName, "10000.0.0.0"); } - /** - * Installs browser with the passed-in package name and version name. - */ + /** Installs browser with the passed-in package name and version name. */ public void installBrowserWithVersion(String packageName, String versionName) { if (mInstalledBrowsers.contains(packageName)) return; @@ -67,18 +59,14 @@ mInstalledBrowsers.add(packageName); } - /** - * Uninstalls all browsers. - */ + /** Uninstalls all browsers. */ public void uninstallAllBrowsers() { while (!mInstalledBrowsers.isEmpty()) { uninstallBrowser(mInstalledBrowsers.iterator().next()); } } - /** - * Uninstalls browser with the given package name. - */ + /** Uninstalls browser with the given package name. */ public void uninstallBrowser(String packageName) { if (!mInstalledBrowsers.contains(packageName)) return;
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java index 2c85b887..6b84f33d1 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/LaunchTest.java
@@ -89,13 +89,11 @@ mShadowPackageManager = Shadows.shadowOf(mPackageManager); } - /** - * Test launching via a deep link on Android N+. - * Check: - * 1) That the host browser was launched. - * 2) Which activities were launched between the activity which handled - * the intent and the host browser getting launched. - */ + // Test launching via a deep link on Android N+. + // Check: + // 1) That the host browser was launched. + // 2) Which activities were launched between the activity which handled + // the intent and the host browser getting launched. @Test public void testDeepLink() { registerWebApk(/* isNewStyleWebApk= */ true); @@ -211,8 +209,8 @@ } /** - * Tests that the target share activity is propagated to the host browser launch intent in - * the scenario where there are several hops between the share intent getting handled and the + * Tests that the target share activity is propagated to the host browser launch intent in the + * scenario where there are several hops between the share intent getting handled and the * browser getting launched. */ @Test @@ -249,8 +247,8 @@ /** * Tests that the EXTRA_SOURCE intent extra in the launch intent is propagated to the host - * browser launch intent in the scenario where there are several activity hops between - * the deep link getting handled and the host browser getting launched. + * browser launch intent in the scenario where there are several activity hops between the deep + * link getting handled and the host browser getting launched. */ @Test public void testSourcePropagated() { @@ -277,10 +275,9 @@ } /** - * Check that the WebAPK does not propagate the {@link EXTRA_RELAUNCH} extra. When - * the host browser relaunches the WebAPK, the host browser might copy over all of - * the extras and not remove the relaunch intent. Check that this scenario does not - * yield an infinite loop. + * Check that the WebAPK does not propagate the {@link EXTRA_RELAUNCH} extra. When the host + * browser relaunches the WebAPK, the host browser might copy over all of the extras and not + * remove the relaunch intent. Check that this scenario does not yield an infinite loop. */ @Test public void testDoesNotPropagateRelaunchDirective() { @@ -396,12 +393,10 @@ DEFAULT_START_URL); } - /** - * Test launching old-style WebAPK via deep link: - * Check that: - * 1) Chrome is launched. - * 2) No activities have been enabled/disabled. - */ + // Test launching old-style WebAPK via deep link: + // Check that: + // 1) Chrome is launched. + // 2) No activities have been enabled/disabled. @Test public void testDeepLinkOldStyle() { registerWebApk(/* isNewStyleWebApk= */ false); @@ -421,12 +416,10 @@ assertOnlyEnabledMainIntentHandler(H2OMainActivity.class); } - /** - * Test launching old-style WebAPK via main intent. - * Check that: - * 1) Chrome is launched. - * 2) No activities have been enabled/disabled. - */ + // Test launching old-style WebAPK via main intent. + // Check that: + // 1) Chrome is launched. + // 2) No activities have been enabled/disabled. @Test public void testMainIntentOldStyle() { registerWebApk(/* isNewStyleWebApk= */ false); @@ -446,8 +439,8 @@ } /** - * Test {@link H2OOpaqueMainActivity#checkComponentEnabled()} when: - * - Component enabled setting is default + * Test {@link H2OOpaqueMainActivity#checkComponentEnabled()} when component enabled setting is + * default */ @Test public void testCheckH2OOpaqueMainActivityEnabled() { @@ -464,8 +457,8 @@ } /** - * Test {@link H2OMainActivity#checkComponentEnabled()} when: - * - Component enabled setting is default + * Test {@link H2OMainActivity#checkComponentEnabled()} when component enabled setting is + * default. */ @Test public void testCheckH2OMainActivityEnabled() { @@ -482,8 +475,8 @@ } /** - * Tests that we add site settings shortcuts both when - * opaque main activity is enabled and when it is not enabled. + * Tests that we add site settings shortcuts both when opaque main activity is enabled and when + * it is not enabled. */ @Test public void testAddsSiteSettings() {
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java index cad066d..eac2149 100644 --- a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java +++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/h2o/SplashActivityTest.java
@@ -112,11 +112,9 @@ HostBrowserUtils.MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH)); } - /** - * Test common cases that SplashActivity: - * - Does not finish itself when the WebAPK is launched from the app list. - * - Finishes itself when the user backs out of the activity stacked on top. - */ + // Test common cases that SplashActivity: + // - Does not finish itself when the WebAPK is launched from the app list. + // - Finishes itself when the user backs out of the activity stacked on top. @Test public void testNormalLaunch() { ActivityController<SplashActivity> splashActivityController = @@ -134,13 +132,11 @@ assertTrue(splashActivityController.get().isFinishing()); } - /** - * Test that SplashActivity finishes itself when: - * - the user backs out of the activity stacked on top - * AND - * - the activity is recreated because it was previously killed by the Android OS due to memory - * pressure. - */ + // Test that SplashActivity finishes itself when: + // - the user backs out of the activity stacked on top + // AND + // - the activity is recreated because it was previously killed by the Android OS due to memory + // pressure. @Test public void testWebApkKilledByOomFinishOnBack() { ActivityController<SplashActivity> splashActivityController = @@ -155,13 +151,11 @@ assertTrue(splashActivityController.get().isFinishing()); } - /** - * Test that SplashActivity does not finish itself when: - * - the choose-host-browser dialog is up - * AND - * - the activity is recreated because it was previously killed by the Android OS due to memory - * pressure. - */ + // Test that SplashActivity does not finish itself when: + // - the choose-host-browser dialog is up + // AND + // - the activity is recreated because it was previously killed by the Android OS due to memory + // pressure. @Test public void testWebApkKilledByOomHostBrowserNotSelected() { ActivityController<SplashActivity> splashActivityController = @@ -178,15 +172,13 @@ assertFalse(splashActivityController.get().isFinishing()); } - /** - * Test that SplashActivity does not finish itself when: - * - the WebAPK is launched from Android Recents on Android O+ - * AND - * - the activity is recreated because it was previously killed by the Android OS due to memory - * pressure. - * On pre-O, the activity stacked on top of SplashActivity is recreated but SplashActivity isn't - * when the user taps the WebAPK in Android recents. - */ + // Test that SplashActivity does not finish itself when: + // - the WebAPK is launched from Android Recents on Android O+ + // AND + // - the activity is recreated because it was previously killed by the Android OS due to memory + // pressure. + // On pre-O, the activity stacked on top of SplashActivity is recreated but SplashActivity isn't + // when the user taps the WebAPK in Android recents. @Test public void testWebApkKilledByOomRecreatedViaRecentsAndroidOPlus() { ActivityController<SplashActivity> splashActivityController = @@ -198,13 +190,11 @@ assertFalse(splashActivityController.get().isFinishing()); } - /** - * Test that SplashActivity does not finish itself when: - * - the WebAPK is launched from a deep link. - * AND - * - the WebAPK is already running, but SplashActivity is not running because it was killed by - * the Android OS due to memory pressure. - */ + // Test that SplashActivity does not finish itself when: + // - the WebAPK is launched from a deep link. + // AND + // - the WebAPK is already running, but SplashActivity is not running because it was killed by + // the Android OS due to memory pressure. @Test public void testDeepLink() { ActivityController<SplashActivity> splashActivityController = @@ -221,8 +211,8 @@ } /** - * Test that SplashActivity does not finish itself when it receives onActivityResult() - * prior to onNewIntent(). + * Test that SplashActivity does not finish itself when it receives onActivityResult() prior to + * onNewIntent(). */ @Test public void testActivityResultBeforeNewIntent() { @@ -259,8 +249,8 @@ } /** - * Test that SplashActivity sets the light theme color when the system is in night mode - * and the dark theme color is invalid. + * Test that SplashActivity sets the light theme color when the system is in night mode and the + * dark theme color is invalid. */ @Test @Config(qualifiers = "night") @@ -279,8 +269,8 @@ } /** - * Test that SplashActivity sets the light theme color when the system is in night mode - * and the dark theme color is missing. + * Test that SplashActivity sets the light theme color when the system is in night mode and the + * dark theme color is missing. */ @Test @Config(qualifiers = "night")
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/lib/runtime_library/IWebApkApi.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/lib/runtime_library/IWebApkApi.java index addd05d8..10a976b0 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/lib/runtime_library/IWebApkApi.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/lib/runtime_library/IWebApkApi.java
@@ -2,9 +2,9 @@ * This file is auto-generated. DO NOT MODIFY. */ package org.chromium.webapk.lib.runtime_library; + /** Interface for communicating between WebAPK service and Chrome. */ -public interface IWebApkApi extends android.os.IInterface -{ +public interface IWebApkApi extends android.os.IInterface { /** Default implementation for IWebApkApi. */ public static class Default implements org.chromium.webapk.lib.runtime_library.IWebApkApi { // Gets the id of the icon to represent WebAPK notifications in status bar. @@ -12,54 +12,69 @@ public int getSmallIconId() throws android.os.RemoteException { return 0; } + // Display a notification. // DEPRECATED: Use notifyNotificationWithChannel. @Override - public void notifyNotification(java.lang.String platformTag, int platformID, - android.app.Notification notification) throws android.os.RemoteException {} + public void notifyNotification( + java.lang.String platformTag, int platformID, android.app.Notification notification) + throws android.os.RemoteException {} + // Cancel a notification. @Override public void cancelNotification(java.lang.String platformTag, int platformID) throws android.os.RemoteException {} + // Get if notification permission is enabled. // DEPRECATED: Use checkNotificationPermission instead. @Override public boolean notificationPermissionEnabled() throws android.os.RemoteException { return false; } + // Display a notification with a specified channel name. @Override - public void notifyNotificationWithChannel(java.lang.String platformTag, int platformID, - android.app.Notification notification, java.lang.String channelName) + public void notifyNotificationWithChannel( + java.lang.String platformTag, + int platformID, + android.app.Notification notification, + java.lang.String channelName) throws android.os.RemoteException {} + // Finishes and removes the WebAPK's task. Returns true on success. @Override public boolean finishAndRemoveTaskSdk23() throws android.os.RemoteException { return false; } + // Gets the notification permission status. @Override public int checkNotificationPermission() throws android.os.RemoteException { return 0; } + // Creates a pending intent for requesting notification permission. @Override - public android.app.PendingIntent requestNotificationPermission(java.lang.String channelName, - java.lang.String channelId) throws android.os.RemoteException { + public android.app.PendingIntent requestNotificationPermission( + java.lang.String channelName, java.lang.String channelId) + throws android.os.RemoteException { return null; } + @Override public android.os.IBinder asBinder() { return null; } } + /** Local-side IPC implementation stub class. */ - public static abstract class Stub extends android.os.Binder + public abstract static class Stub extends android.os.Binder implements org.chromium.webapk.lib.runtime_library.IWebApkApi { /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } + /** * Cast an IBinder object into an org.chromium.webapk.lib.runtime_library.IWebApkApi * interface, generating a proxy if needed. @@ -71,28 +86,30 @@ } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) - && (iin instanceof org.chromium.webapk.lib.runtime_library.IWebApkApi))) { + && (iin instanceof org.chromium.webapk.lib.runtime_library.IWebApkApi))) { return ((org.chromium.webapk.lib.runtime_library.IWebApkApi) iin); } return new org.chromium.webapk.lib.runtime_library.IWebApkApi.Stub.Proxy(obj); } + @Override public android.os.IBinder asBinder() { return this; } + @Override - public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, - int flags) throws android.os.RemoteException { + public boolean onTransact( + int code, android.os.Parcel data, android.os.Parcel reply, int flags) + throws android.os.RemoteException { java.lang.String descriptor = DESCRIPTOR; if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) { data.enforceInterface(descriptor); } switch (code) { - case INTERFACE_TRANSACTION: { + case INTERFACE_TRANSACTION: reply.writeString(descriptor); return true; - } } switch (code) { case TRANSACTION_getSmallIconId: { @@ -170,18 +187,23 @@ } return true; } + private static class Proxy implements org.chromium.webapk.lib.runtime_library.IWebApkApi { private android.os.IBinder mRemote; + Proxy(android.os.IBinder remote) { mRemote = remote; } + @Override public android.os.IBinder asBinder() { return mRemote; } + public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } + // Gets the id of the icon to represent WebAPK notifications in status bar. @Override public int getSmallIconId() throws android.os.RemoteException { @@ -200,11 +222,15 @@ } return _result; } + // Display a notification. // DEPRECATED: Use notifyNotificationWithChannel. @Override - public void notifyNotification(java.lang.String platformTag, int platformID, - android.app.Notification notification) throws android.os.RemoteException { + public void notifyNotification( + java.lang.String platformTag, + int platformID, + android.app.Notification notification) + throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { @@ -220,6 +246,7 @@ _data.recycle(); } } + // Cancel a notification. @Override public void cancelNotification(java.lang.String platformTag, int platformID) @@ -238,6 +265,7 @@ _data.recycle(); } } + // Get if notification permission is enabled. // DEPRECATED: Use checkNotificationPermission instead. @Override @@ -247,8 +275,12 @@ boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); - boolean _status = mRemote.transact( - Stub.TRANSACTION_notificationPermissionEnabled, _data, _reply, 0); + boolean _status = + mRemote.transact( + Stub.TRANSACTION_notificationPermissionEnabled, + _data, + _reply, + 0); _reply.readException(); _result = (0 != _reply.readInt()); } finally { @@ -257,10 +289,14 @@ } return _result; } + // Display a notification with a specified channel name. @Override - public void notifyNotificationWithChannel(java.lang.String platformTag, int platformID, - android.app.Notification notification, java.lang.String channelName) + public void notifyNotificationWithChannel( + java.lang.String platformTag, + int platformID, + android.app.Notification notification, + java.lang.String channelName) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); @@ -270,14 +306,19 @@ _data.writeInt(platformID); _Parcel.writeTypedObject(_data, notification, 0); _data.writeString(channelName); - boolean _status = mRemote.transact( - Stub.TRANSACTION_notifyNotificationWithChannel, _data, _reply, 0); + boolean _status = + mRemote.transact( + Stub.TRANSACTION_notifyNotificationWithChannel, + _data, + _reply, + 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } + // Finishes and removes the WebAPK's task. Returns true on success. @Override public boolean finishAndRemoveTaskSdk23() throws android.os.RemoteException { @@ -286,8 +327,9 @@ boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); - boolean _status = mRemote.transact( - Stub.TRANSACTION_finishAndRemoveTaskSdk23, _data, _reply, 0); + boolean _status = + mRemote.transact( + Stub.TRANSACTION_finishAndRemoveTaskSdk23, _data, _reply, 0); _reply.readException(); _result = (0 != _reply.readInt()); } finally { @@ -296,6 +338,7 @@ } return _result; } + // Gets the notification permission status. @Override public int checkNotificationPermission() throws android.os.RemoteException { @@ -304,8 +347,9 @@ int _result; try { _data.writeInterfaceToken(DESCRIPTOR); - boolean _status = mRemote.transact( - Stub.TRANSACTION_checkNotificationPermission, _data, _reply, 0); + boolean _status = + mRemote.transact( + Stub.TRANSACTION_checkNotificationPermission, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { @@ -314,6 +358,7 @@ } return _result; } + // Creates a pending intent for requesting notification permission. @Override public android.app.PendingIntent requestNotificationPermission( @@ -326,8 +371,12 @@ _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(channelName); _data.writeString(channelId); - boolean _status = mRemote.transact( - Stub.TRANSACTION_requestNotificationPermission, _data, _reply, 0); + boolean _status = + mRemote.transact( + Stub.TRANSACTION_requestNotificationPermission, + _data, + _reply, + 0); _reply.readException(); _result = _Parcel.readTypedObject(_reply, android.app.PendingIntent.CREATOR); } finally { @@ -337,6 +386,7 @@ return _result; } } + static final int TRANSACTION_getSmallIconId = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_notifyNotification = @@ -354,34 +404,49 @@ static final int TRANSACTION_requestNotificationPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); } + public static final java.lang.String DESCRIPTOR = "org.chromium.webapk.lib.runtime_library.IWebApkApi"; + // Gets the id of the icon to represent WebAPK notifications in status bar. public int getSmallIconId() throws android.os.RemoteException; + // Display a notification. // DEPRECATED: Use notifyNotificationWithChannel. - public void notifyNotification(java.lang.String platformTag, int platformID, - android.app.Notification notification) throws android.os.RemoteException; + public void notifyNotification( + java.lang.String platformTag, int platformID, android.app.Notification notification) + throws android.os.RemoteException; + // Cancel a notification. public void cancelNotification(java.lang.String platformTag, int platformID) throws android.os.RemoteException; + // Get if notification permission is enabled. // DEPRECATED: Use checkNotificationPermission instead. public boolean notificationPermissionEnabled() throws android.os.RemoteException; + // Display a notification with a specified channel name. - public void notifyNotificationWithChannel(java.lang.String platformTag, int platformID, - android.app.Notification notification, java.lang.String channelName) + public void notifyNotificationWithChannel( + java.lang.String platformTag, + int platformID, + android.app.Notification notification, + java.lang.String channelName) throws android.os.RemoteException; + // Finishes and removes the WebAPK's task. Returns true on success. public boolean finishAndRemoveTaskSdk23() throws android.os.RemoteException; + // Gets the notification permission status. public int checkNotificationPermission() throws android.os.RemoteException; + // Creates a pending intent for requesting notification permission. - public android.app.PendingIntent requestNotificationPermission(java.lang.String channelName, - java.lang.String channelId) throws android.os.RemoteException; + public android.app.PendingIntent requestNotificationPermission( + java.lang.String channelName, java.lang.String channelId) + throws android.os.RemoteException; + /** @hide */ static class _Parcel { - static private <T> T readTypedObject( + private static <T> T readTypedObject( android.os.Parcel parcel, android.os.Parcelable.Creator<T> c) { if (parcel.readInt() != 0) { return c.createFromParcel(parcel); @@ -389,7 +454,8 @@ return null; } } - static private <T extends android.os.Parcelable> void writeTypedObject( + + private static <T extends android.os.Parcelable> void writeTypedObject( android.os.Parcel parcel, T value, int parcelableFlags) { if (value != null) { parcel.writeInt(1);
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ChooseHostBrowserDialog.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ChooseHostBrowserDialog.java index a005d6e..eb33f072 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ChooseHostBrowserDialog.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ChooseHostBrowserDialog.java
@@ -40,11 +40,14 @@ */ public interface DialogListener { void onHostBrowserSelected(String selectedHostBrowser); + void onQuit(); } /** Checked prior to running the {@link DialogInterface.OnDismissListener}. */ - private static class OnDismissListenerCanceler { public boolean canceled; } + private static class OnDismissListenerCanceler { + public boolean canceled; + } /** Stores information about a potential host browser for the WebAPK. */ public static class BrowserItem { @@ -84,13 +87,17 @@ /** * Shows the dialog for choosing a host browser. + * * @param context The current Context. * @param listener The listener for the dialog. * @param infos Browser-package-name->ResolveInfo mapping for all of the installed browsers. * @param appName The name of the WebAPK for which the dialog is shown. */ - public static void show(Context context, final DialogListener listener, - Map<String, ResolveInfo> infos, String appName) { + public static void show( + Context context, + final DialogListener listener, + Map<String, ResolveInfo> infos, + String appName) { final List<BrowserItem> browserItems = getBrowserInfosForHostBrowserSelection(context.getPackageManager(), infos); @@ -112,39 +119,48 @@ OnDismissListenerCanceler onDismissCanceler = new OnDismissListenerCanceler(); // The context theme wrapper is needed for pre-L. - AlertDialog.Builder builder = new AlertDialog.Builder( - new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light_Dialog)); - builder.setCustomTitle(title).setView(view).setNegativeButton( - R.string.choose_host_browser_dialog_quit, new DialogInterface.OnClickListener() { + AlertDialog.Builder builder = + new AlertDialog.Builder( + new ContextThemeWrapper( + context, android.R.style.Theme_DeviceDefault_Light_Dialog)); + builder.setCustomTitle(title) + .setView(view) + .setNegativeButton( + R.string.choose_host_browser_dialog_quit, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + + final AlertDialog dialog = builder.create(); + browserList.setOnItemClickListener( + new AdapterView.OnItemClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); + public void onItemClick( + AdapterView<?> parent, View view, int position, long id) { + BrowserItem browserItem = browserItems.get(position); + if (browserItem.enable()) { + onDismissCanceler.canceled = true; + listener.onHostBrowserSelected(browserItem.getPackageName()); + dialog.cancel(); + } } }); - final AlertDialog dialog = builder.create(); - browserList.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - BrowserItem browserItem = browserItems.get(position); - if (browserItem.enable()) { - onDismissCanceler.canceled = true; - listener.onHostBrowserSelected(browserItem.getPackageName()); - dialog.cancel(); - } - } - }); + dialog.setOnDismissListener( + new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + if (onDismissCanceler.canceled) return; - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialogInterface) { - if (onDismissCanceler.canceled) return; - - listener.onQuit(); - } - }); + listener.onQuit(); + } + }); dialog.show(); - }; + } + ; /** Returns a list of BrowserItem for all of the installed browsers. */ private static List<BrowserItem> getBrowserInfosForHostBrowserSelection( @@ -161,23 +177,30 @@ for (Map.Entry<String, ResolveInfo> entry : resolveInfos.entrySet()) { String browserPackage = entry.getKey(); ResolveInfo info = entry.getValue(); - boolean enable = !hasBrowserSupportingWebApk - || HostBrowserUtils.doesBrowserSupportWebApks(browserPackage); - browsers.add(new BrowserItem(browserPackage, info.loadLabel(packageManager), - info.loadIcon(packageManager), enable)); + boolean enable = + !hasBrowserSupportingWebApk + || HostBrowserUtils.doesBrowserSupportWebApks(browserPackage); + browsers.add( + new BrowserItem( + browserPackage, + info.loadLabel(packageManager), + info.loadIcon(packageManager), + enable)); } if (browsers.size() <= 1) return browsers; - Collections.sort(browsers, new Comparator<BrowserItem>() { - @Override - public int compare(BrowserItem a, BrowserItem b) { - if (a.mEnable == b.mEnable) { - return a.getPackageName().compareTo(b.getPackageName()); - } - return a.mEnable ? -1 : 1; - } - }); + Collections.sort( + browsers, + new Comparator<BrowserItem>() { + @Override + public int compare(BrowserItem a, BrowserItem b) { + if (a.mEnable == b.mEnable) { + return a.getPackageName().compareTo(b.getPackageName()); + } + return a.mEnable ? -1 : 1; + } + }); return browsers; } @@ -198,8 +221,9 @@ @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { - convertView = LayoutInflater.from(mContext).inflate( - R.layout.host_browser_list_item, parent, false); + convertView = + LayoutInflater.from(mContext) + .inflate(R.layout.host_browser_list_item, parent, false); } Resources res = mContext.getResources(); @@ -215,14 +239,19 @@ name.setTextColor(WebApkUtils.getColor(res, R.color.webapk_black_alpha_87)); icon.setAlpha(SUPPORTED_ICON_OPACITY); } else { - String text = mContext.getString(R.string.host_browser_item_not_supporting_webapks, - item.getApplicationName()); + String text = + mContext.getString( + R.string.host_browser_item_not_supporting_webapks, + item.getApplicationName()); SpannableString spannableName = new SpannableString(text); float descriptionProportion = res.getDimension(R.dimen.webapk_text_size_medium_dense) - / res.getDimension(R.dimen.webapk_text_size_large); - spannableName.setSpan(new RelativeSizeSpan(descriptionProportion), - item.getApplicationName().length() + 1, spannableName.length(), 0); + / res.getDimension(R.dimen.webapk_text_size_large); + spannableName.setSpan( + new RelativeSizeSpan(descriptionProportion), + item.getApplicationName().length() + 1, + spannableName.length(), + 0); name.setText(spannableName); name.setSingleLine(false); name.setTextColor(WebApkUtils.getColor(res, R.color.webapk_black_alpha_38));
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java index d15f7b9..bfdb3bf 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/DexLoader.java
@@ -16,8 +16,7 @@ import java.io.OutputStream; /** - * Creates ClassLoader for .dex file in a remote Context's APK. - * Non static for the sake of tests. + * Creates ClassLoader for .dex file in a remote Context's APK. Non static for the sake of tests. */ public class DexLoader { private static final int BUFFER_SIZE = 16 * 1024; @@ -43,12 +42,13 @@ /** * Creates ClassLoader for .dex file in {@link remoteContext}'s APK. + * * @param remoteContext The context with the APK with the .dex file. * @param dexName The name of the .dex file in the APK. * @param canaryClassName Name of class in the .dex file. Used for testing the ClassLoader - * before returning it. - * @param localDexDir Writable directory for caching data to speed up future calls to - * {@link #load()}. + * before returning it. + * @param localDexDir Writable directory for caching data to speed up future calls to {@link + * #load()}. * @return The ClassLoader. Returns null on an error. */ public ClassLoader load( @@ -78,6 +78,7 @@ /** * Deletes any files cached by {@link #load()}. + * * @param localDexDir Cache directory passed to {@link #load()}. */ public void deleteCachedDexes(File localDexDir) { @@ -86,6 +87,7 @@ /** * Extracts an asset from {@link context}'s APK to a file. + * * @param context * @param assetName Name of the asset to extract. * @param destFile File to extract the asset to. @@ -124,8 +126,9 @@ /** * Tries to create ClassLoader with the given .dex file and optimized dex directory. + * * @param canaryClassName Name of class in the .dex file. Used for testing the ClassLoader - * before returning it. + * before returning it. * @param dexFile .dex file to create ClassLoader for. * @param optimizedDir Directory for storing the optimized dex file. * @return The ClassLoader. Returns null on an error. @@ -133,15 +136,23 @@ private static ClassLoader tryCreatingClassLoader( String canaryClassName, File dexFile, File optimizedDir) { try { - ClassLoader loader = new BaseDexClassLoader( - dexFile.getPath(), optimizedDir, null, ClassLoader.getSystemClassLoader()); + ClassLoader loader = + new BaseDexClassLoader( + dexFile.getPath(), + optimizedDir, + null, + ClassLoader.getSystemClassLoader()); // Loading {@link canaryClassName} will throw an exception if the .dex file cannot be // loaded. loader.loadClass(canaryClassName); return loader; } catch (Exception e) { String optimizedDirPath = (optimizedDir == null) ? null : optimizedDir.getPath(); - Log.w(TAG, "Could not load dex from " + dexFile.getPath() + " with optimized directory " + Log.w( + TAG, + "Could not load dex from " + + dexFile.getPath() + + " with optimized directory " + optimizedDirPath); e.printStackTrace(); return null;
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java index f7abf4f..d30ab4b 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserClassLoader.java
@@ -15,9 +15,7 @@ import java.io.File; import java.util.Scanner; -/** - * Creates ClassLoader for WebAPK-specific dex file in Chrome APK's assets. - */ +/** Creates ClassLoader for WebAPK-specific dex file in Chrome APK's assets. */ public class HostBrowserClassLoader { /** Directory for storing cached dex files. */ public static final String DEX_DIR_NAME = "dex"; @@ -33,6 +31,7 @@ /** * Gets / creates ClassLoader for WebAPK dex. + * * @param context WebAPK's context. * @param canaryClassname Class to load to check that ClassLoader is valid. * @return The ClassLoader. @@ -55,6 +54,7 @@ /** * Creates ClassLoader for WebAPK dex. + * * @param context WebAPK's context. * @param remoteContext Host browser's context. * @param canaryClassName Class to load to check that ClassLoader is valid. @@ -81,9 +81,7 @@ return dexLoader.load(remoteContext, dexAssetName, canaryClassName, localDexDir); } - /** - * Returns whether {@link sClassLoader} can be reused. - */ + /** Returns whether {@link sClassLoader} can be reused. */ public static boolean canReuseClassLoaderInstance(Context context, Context remoteContext) { // WebAPK may still be running when the host browser gets upgraded. Prevent ClassLoader from // getting reused in this scenario. @@ -97,6 +95,7 @@ /** * Checks if there is a new "runtime dex" version number. If there is a new version number, * updates SharedPreferences. + * * @param preferences WebAPK's SharedPreferences. * @param remoteContext * @return The new "runtime dex" version number. -1 if there is no new version number. @@ -121,9 +120,7 @@ return runtimeDexVersion; } - /** - * Returns version code of {@link context}'s APK. - */ + /** Returns version code of {@link context}'s APK. */ private static int getVersionCode(Context context) { try { return context.getPackageManager() @@ -137,6 +134,7 @@ /** * Returns the first integer in an asset file's contents. + * * @param context * @param assetName The name of the asset. * @return The first integer. @@ -160,9 +158,7 @@ return value; } - /** - * Asserts that current thread is the UI thread. - */ + /** Asserts that current thread is the UI thread. */ private static void assertRunningOnUiThread() { assert Looper.getMainLooper().equals(Looper.myLooper()); }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java index 0d449bd..0fc9b12 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java
@@ -30,8 +30,8 @@ "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB"; /** - * Launches host browser in WebAPK mode if the browser is WebAPK-compatible. - * Otherwise, launches the host browser in tabbed mode. + * Launches host browser in WebAPK mode if the browser is WebAPK-compatible. Otherwise, launches + * the host browser in tabbed mode. */ public static void launch(Activity activity, HostBrowserLauncherParams params) { if (HostBrowserUtils.shouldLaunchInTab(params)) { @@ -44,8 +44,12 @@ } /** Launches host browser in WebAPK mode. */ - public static void launchBrowserInWebApkMode(Activity activity, - HostBrowserLauncherParams params, Bundle extraExtras, int flags, boolean expectResult) { + public static void launchBrowserInWebApkMode( + Activity activity, + HostBrowserLauncherParams params, + Bundle extraExtras, + int flags, + boolean expectResult) { ManageDataLauncherActivity.updateSiteSettingsShortcut( activity.getApplicationContext(), params); Intent intent = new Intent(); @@ -66,7 +70,8 @@ intent.putExtra(WebApkConstants.EXTRA_URL, params.getStartUrl()) .putExtra(WebApkConstants.EXTRA_SOURCE, params.getSource()) .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, activity.getPackageName()) - .putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME, + .putExtra( + WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME, params.getSelectedShareTargetActivityClassName()) .putExtra(WebApkConstants.EXTRA_FORCE_NAVIGATION, params.getForceNavigation()); @@ -83,7 +88,8 @@ } if (params.getSplashShownTimeMs() >= 0) { - intent.putExtra(WebApkConstants.EXTRA_NEW_STYLE_SPLASH_SHOWN_TIME, + intent.putExtra( + WebApkConstants.EXTRA_NEW_STYLE_SPLASH_SHOWN_TIME, params.getSplashShownTimeMs()); }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncherParams.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncherParams.java index 7e9d4c4..fcf3997 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncherParams.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncherParams.java
@@ -38,14 +38,19 @@ * Constructs a HostBrowserLauncherParams object from the passed in Intent and from <meta-data> * in the Android Manifest. */ - public static HostBrowserLauncherParams createForIntent(Context context, Intent intent, - String hostBrowserPackageName, boolean dialogShown, long launchTimeMs, + public static HostBrowserLauncherParams createForIntent( + Context context, + Intent intent, + String hostBrowserPackageName, + boolean dialogShown, + long launchTimeMs, long splashShownTimeMs) { Bundle metadata = WebApkUtils.readMetaData(context); if (metadata == null) return null; - int hostBrowserMajorChromiumVersion = HostBrowserUtils.queryHostBrowserMajorChromiumVersion( - context, hostBrowserPackageName); + int hostBrowserMajorChromiumVersion = + HostBrowserUtils.queryHostBrowserMajorChromiumVersion( + context, hostBrowserPackageName); long intentLaunchTimeMs = intent.getLongExtra(WebApkConstants.EXTRA_WEBAPK_LAUNCH_TIME, -1); if (intentLaunchTimeMs > 0) { launchTimeMs = intentLaunchTimeMs; @@ -58,8 +63,9 @@ // If the intent was from the WebAPK relaunching itself or from the host browser relaunching // the WebAPK via {@link H2OLauncher#requestRelaunchFromHostBrowser()}, we cannot determine // whether the intent is a share intent from the intent's action. - String selectedShareTargetActivityClassName = intent.getStringExtra( - WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME); + String selectedShareTargetActivityClassName = + intent.getStringExtra( + WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME); if (Intent.ACTION_SEND.equals(intent.getAction()) || Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) { @@ -67,16 +73,21 @@ } if (selectedShareTargetActivityClassName != null) { - Bundle shareTargetMetaData = fetchActivityMetaData(context, - new ComponentName( - context.getPackageName(), selectedShareTargetActivityClassName)); + Bundle shareTargetMetaData = + fetchActivityMetaData( + context, + new ComponentName( + context.getPackageName(), + selectedShareTargetActivityClassName)); startUrl = computeStartUrlForShareTarget(shareTargetMetaData, intent); source = WebApkConstants.ShortcutSource.WEBAPK_SHARE_TARGET; forceNavigation = true; } else if (!TextUtils.isEmpty(intent.getDataString())) { startUrl = intent.getDataString(); - source = intent.getIntExtra( - WebApkConstants.EXTRA_SOURCE, WebApkConstants.ShortcutSource.EXTERNAL_INTENT); + source = + intent.getIntExtra( + WebApkConstants.EXTRA_SOURCE, + WebApkConstants.ShortcutSource.EXTERNAL_INTENT); forceNavigation = intent.getBooleanExtra(WebApkConstants.EXTRA_FORCE_NAVIGATION, true); } else { startUrl = metadata.getString(WebApkMetaDataKeys.START_URL); @@ -93,9 +104,17 @@ boolean isNewStyleWebApk = metadata.getBoolean(WebApkMetaDataKeys.IS_NEW_STYLE_WEBAPK); - return new HostBrowserLauncherParams(isNewStyleWebApk, hostBrowserPackageName, - hostBrowserMajorChromiumVersion, dialogShown, intent, startUrl, source, - forceNavigation, launchTimeMs, splashShownTimeMs, + return new HostBrowserLauncherParams( + isNewStyleWebApk, + hostBrowserPackageName, + hostBrowserMajorChromiumVersion, + dialogShown, + intent, + startUrl, + source, + forceNavigation, + launchTimeMs, + splashShownTimeMs, selectedShareTargetActivityClassName); } @@ -103,8 +122,10 @@ Context context, ComponentName shareTargetComponentName) { ActivityInfo shareActivityInfo; try { - shareActivityInfo = context.getPackageManager().getActivityInfo( - shareTargetComponentName, PackageManager.GET_META_DATA); + shareActivityInfo = + context.getPackageManager() + .getActivityInfo( + shareTargetComponentName, PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { return null; } @@ -124,6 +145,7 @@ /** * Computes the start URL for the given share intent and share activity. + * * @param shareTargetMetaData Meta data for the share target activity selected by the user. * @param intent Share intent. */ @@ -141,10 +163,10 @@ /** * Computes the start URL for the given share intent and share activity which sends GET HTTP * requests. + * * @param shareTargetMetaData Meta data for the share target activity selected by the user. * @param intent Share intent. */ - private static String computeStartUrlForGETShareTarget( Bundle shareTargetMetaData, Intent intent) { String shareAction = shareTargetMetaData.getString(WebApkMetaDataKeys.SHARE_ACTION); @@ -155,28 +177,29 @@ // These can be null, they are checked downstream. ArrayList<Pair<String, String>> entryList = new ArrayList<>(); entryList.add( - new Pair<>(shareTargetMetaData.getString(WebApkMetaDataKeys.SHARE_PARAM_TITLE), + new Pair<>( + shareTargetMetaData.getString(WebApkMetaDataKeys.SHARE_PARAM_TITLE), intent.getStringExtra(Intent.EXTRA_SUBJECT))); - entryList.add(new Pair<>(shareTargetMetaData.getString(WebApkMetaDataKeys.SHARE_PARAM_TEXT), - intent.getStringExtra(Intent.EXTRA_TEXT))); + entryList.add( + new Pair<>( + shareTargetMetaData.getString(WebApkMetaDataKeys.SHARE_PARAM_TEXT), + intent.getStringExtra(Intent.EXTRA_TEXT))); return createGETWebShareTargetUriString(shareAction, entryList); } - /** - * Converts the action url and parameters of a GET webshare target into a URI. - * Example: - * - action = "https://example.org/includinator/share.html" - * - params - * title param: "title" - * title intent: "news" - * text param: "description" - * text intent: "story" - * Becomes: - * https://example.org/includinator/share.html?title=news&description=story - * TODO(ckitagawa): The escaping behavior isn't entirely correct. The exact encoding is still - * being discussed at https://github.com/WICG/web-share-target/issues/59. - */ + // Converts the action url and parameters of a GET webshare target into a URI. + // Example: + // - action = "https://example.org/includinator/share.html" + // - params + // title param: "title" + // title intent: "news" + // text param: "description" + // text intent: "story" + // Becomes: + // https://example.org/includinator/share.html?title=news&description=story + // TODO(ckitagawa): The escaping behavior isn't entirely correct. The exact encoding is still + // being discussed at https://github.com/WICG/web-share-target/issues/59. protected static String createGETWebShareTargetUriString( String action, ArrayList<Pair<String, String>> entryList) { // Building the query string here is unnecessary if the host browser is M83+. M83+ Chrome @@ -205,10 +228,18 @@ return url != null && (url.startsWith("http:") || url.startsWith("https:")); } - private HostBrowserLauncherParams(boolean isNewStyleWebApk, String hostBrowserPackageName, - int hostBrowserMajorChromiumVersion, boolean dialogShown, Intent originalIntent, - String startUrl, int source, boolean forceNavigation, long launchTimeMs, - long splashShownTimeMs, String selectedShareTargetActivityClassName) { + private HostBrowserLauncherParams( + boolean isNewStyleWebApk, + String hostBrowserPackageName, + int hostBrowserMajorChromiumVersion, + boolean dialogShown, + Intent originalIntent, + String startUrl, + int source, + boolean forceNavigation, + long launchTimeMs, + long splashShownTimeMs, + String selectedShareTargetActivityClassName) { mIsNewStyleWebApk = isNewStyleWebApk; mHostBrowserPackageName = hostBrowserPackageName; mHostBrowserMajorChromiumVersion = hostBrowserMajorChromiumVersion; @@ -236,8 +267,8 @@ } /** - * Returns the major version of the host browser. Currently, only Chromium host browsers - * (Chrome Canary, Chrome Dev ...) are supported. + * Returns the major version of the host browser. Currently, only Chromium host browsers (Chrome + * Canary, Chrome Dev ...) are supported. */ public int getHostBrowserMajorChromiumVersion() { return mHostBrowserMajorChromiumVersion; @@ -264,8 +295,7 @@ } /** - * Returns whether the WebAPK should be navigated to {@link mStartUrl} if it is already - * running. + * Returns whether the WebAPK should be navigated to {@link mStartUrl} if it is already running. */ public boolean getForceNavigation() { return mForceNavigation;
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java index d7df4af..59a6d749a6 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
@@ -19,9 +19,7 @@ import java.util.Map; import java.util.Set; -/** - * Contains methods for getting information about host browser. - */ +/** Contains methods for getting information about host browser. */ public class HostBrowserUtils { private static final int MINIMUM_REQUIRED_CHROME_VERSION = 57; @@ -39,10 +37,18 @@ /** * The package names of the browsers that support WebAPKs. The most preferred one comes first. */ - private static Set<String> sBrowsersSupportingWebApk = new HashSet<String>( - Arrays.asList("com.google.android.apps.chrome", "com.android.chrome", "com.chrome.beta", - "com.chrome.dev", "com.chrome.canary", "org.chromium.chrome", - "org.chromium.chrome.tests", ARC_INTENT_HELPER_BROWSER, ARC_WEBAPK_BROWSER)); + private static Set<String> sBrowsersSupportingWebApk = + new HashSet<String>( + Arrays.asList( + "com.google.android.apps.chrome", + "com.android.chrome", + "com.chrome.beta", + "com.chrome.dev", + "com.chrome.canary", + "org.chromium.chrome", + "org.chromium.chrome.tests", + ARC_INTENT_HELPER_BROWSER, + ARC_WEBAPK_BROWSER)); /** Caches the package name of the host browser. */ private static String sHostPackage; @@ -170,7 +176,7 @@ && !params.getHostBrowserPackageName().equals(ARC_INTENT_HELPER_BROWSER) && !params.getHostBrowserPackageName().equals(ARC_WEBAPK_BROWSER) && params.getHostBrowserMajorChromiumVersion() - >= MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH; + >= MINIMUM_REQUIRED_CHROMIUM_VERSION_NEW_SPLASH; } /** @@ -200,7 +206,8 @@ // Gets the package name of the default browser on the Android device. // TODO(hanxi): Investigate the best way to know which browser supports WebAPKs. String defaultBrowser = getDefaultBrowserPackageName(packageManager); - if (!TextUtils.isEmpty(defaultBrowser) && doesBrowserSupportWebApks(defaultBrowser) + if (!TextUtils.isEmpty(defaultBrowser) + && doesBrowserSupportWebApks(defaultBrowser) && WebApkUtils.isInstalled(packageManager, defaultBrowser)) { return defaultBrowser; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/IdentityService.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/IdentityService.java index e89888ae..7a5b33a3 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/IdentityService.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/IdentityService.java
@@ -12,13 +12,14 @@ /** IdentityService allows browsers to query information about the WebAPK. */ public class IdentityService extends Service { - private final IIdentityService.Stub mBinder = new IIdentityService.Stub() { - @Override - public String getRuntimeHostBrowserPackageName() { - return HostBrowserUtils.computeHostBrowserPackageClearCachedDataOnChange( - getApplicationContext()); - } - }; + private final IIdentityService.Stub mBinder = + new IIdentityService.Stub() { + @Override + public String getRuntimeHostBrowserPackageName() { + return HostBrowserUtils.computeHostBrowserPackageClearCachedDataOnChange( + getApplicationContext()); + } + }; @Override public IBinder onBind(Intent intent) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/InstallHostBrowserDialog.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/InstallHostBrowserDialog.java index e08a475..44aa513 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/InstallHostBrowserDialog.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/InstallHostBrowserDialog.java
@@ -21,14 +21,18 @@ */ public interface DialogListener { void onConfirmInstall(String packageName); + void onConfirmQuit(); } /** Checked prior to running the {@link DialogInterface.OnDismissListener}. */ - private static class OnDismissListenerCanceler { public boolean canceled; } + private static class OnDismissListenerCanceler { + public boolean canceled; + } /** * Shows the dialog to install a host browser. + * * @param context The current context. * @param listener The listener for the dialog. * @param appName The name of the WebAPK for which the dialog is shown. @@ -36,8 +40,12 @@ * @param hostBrowserApplicationName The application name of the host browser. * @param hostBrowserIconId The resource id of the icon of the host browser. */ - public static void show(Context context, final DialogListener listener, String appName, - final String hostBrowserPackageName, String hostBrowserApplicationName, + public static void show( + Context context, + final DialogListener listener, + String appName, + final String hostBrowserPackageName, + String hostBrowserApplicationName, int hostBrowserIconId) { View view = LayoutInflater.from(context).inflate(R.layout.host_browser_list_item, null); TextView title = new TextView(context); @@ -55,18 +63,22 @@ OnDismissListenerCanceler onDismissCanceler = new OnDismissListenerCanceler(); // The context theme wrapper is needed for pre-L. - AlertDialog.Builder builder = new AlertDialog.Builder( - new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light_Dialog)); + AlertDialog.Builder builder = + new AlertDialog.Builder( + new ContextThemeWrapper( + context, android.R.style.Theme_DeviceDefault_Light_Dialog)); builder.setCustomTitle(title) .setView(view) - .setNegativeButton(R.string.choose_host_browser_dialog_quit, + .setNegativeButton( + R.string.choose_host_browser_dialog_quit, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }) - .setPositiveButton(R.string.install_host_browser_dialog_install_button, + .setPositiveButton( + R.string.install_host_browser_dialog_install_button, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -76,14 +88,16 @@ }); AlertDialog dialog = builder.create(); - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialogInterface) { - if (onDismissCanceler.canceled) return; + dialog.setOnDismissListener( + new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + if (onDismissCanceler.canceled) return; - listener.onConfirmQuit(); - } - }); + listener.onConfirmQuit(); + } + }); dialog.show(); - }; + } + ; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java index 13667857..d41459e 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java
@@ -30,9 +30,8 @@ private Activity mParentActivity; /** - * Called once {@link #selectHostBrowser()} has selected the host browser either - * via a shared preferences/<meta-data> lookup or via the user selecting the host - * browser from a dialog. + * Called once {@link #selectHostBrowser()} has selected the host browser either via a shared + * preferences/<meta-data> lookup or via the user selecting the host browser from a dialog. */ public static interface Callback { void onBrowserSelected(String hostBrowserPackageName, boolean dialogShown); @@ -45,6 +44,7 @@ /** * Creates install Intent. + * * @param packageName Package to install. * @return The intent. */ @@ -56,8 +56,8 @@ } /** - * Selects host browser to launch, showing a dialog to select browser if necessary. Calls - * {@link selectCallback} with the result. + * Selects host browser to launch, showing a dialog to select browser if necessary. Calls {@link + * selectCallback} with the result. */ public void selectHostBrowser(Callback selectCallback) { Bundle metadata = WebApkUtils.readMetaData(mContext); @@ -85,9 +85,7 @@ } } - /** - * Launches the Play Store with the host browser's page. - */ + /** Launches the Play Store with the host browser's page. */ private void installBrowser(String hostBrowserPackageName) { try { mParentActivity.startActivity(createInstallIntent(hostBrowserPackageName)); @@ -107,6 +105,7 @@ selectCallback.onBrowserSelected( selectedHostBrowser, true /* dialogShown */); } + @Override public void onQuit() { selectCallback.onBrowserSelected(null, true /* dialogShown */); @@ -138,14 +137,19 @@ HostBrowserUtils.writeHostBrowserToSharedPref(mContext, packageName); selectCallback.onBrowserSelected(null, true /* dialogShown */); } + @Override public void onConfirmQuit() { selectCallback.onBrowserSelected(null, true /* dialogShown */); } }; - InstallHostBrowserDialog.show(mParentActivity, listener, mContext.getString(R.string.name), - lastResortHostBrowserPackageName, lastResortHostBrowserApplicationName, + InstallHostBrowserDialog.show( + mParentActivity, + listener, + mContext.getString(R.string.name), + lastResortHostBrowserPackageName, + lastResortHostBrowserApplicationName, R.drawable.last_resort_runtime_host_logo); } }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java index 560c192..3328d9e1 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/ManageDataLauncherActivity.java
@@ -34,8 +34,8 @@ import java.util.List; /** - * Handles site settings shortcuts for WebApks. The shortcut opens the web - * browser's site settings for the start url associated with the WebApk. + * Handles site settings shortcuts for WebApks. The shortcut opens the web browser's site settings + * for the start url associated with the WebApk. */ public class ManageDataLauncherActivity extends Activity { public static final String ACTION_SITE_SETTINGS = @@ -56,8 +56,8 @@ private String mProviderPackage; /** - * The url of the page for which the settings will be shown. Must be provided as an intent - * extra to {@link ManageDataLauncherActivity}. + * The url of the page for which the settings will be shown. Must be provided as an intent extra + * to {@link ManageDataLauncherActivity}. */ private Uri mUrl; @@ -75,9 +75,7 @@ launchSettings(); } - /** - * Returns a view with a loading spinner. - */ + /** Returns a view with a loading spinner. */ private View createLoadingView() { ProgressBar progressBar = new ProgressBar(this); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); @@ -101,8 +99,10 @@ appName = mProviderPackage; } - Toast.makeText(this, getString(R.string.no_support_for_launch_settings, appName), - Toast.LENGTH_LONG) + Toast.makeText( + this, + getString(R.string.no_support_for_launch_settings, appName), + Toast.LENGTH_LONG) .show(); finish(); } @@ -138,22 +138,23 @@ Intent intent = new Intent(ACTION_CUSTOM_TABS_CONNECTION); intent.addCategory(CATEGORY_LAUNCH_WEBAPK_SITE_SETTINGS); intent.setPackage(providerPackage); - List<ResolveInfo> services = context.getPackageManager().queryIntentServices( - intent, PackageManager.GET_RESOLVED_FILTER); + List<ResolveInfo> services = + context.getPackageManager() + .queryIntentServices(intent, PackageManager.GET_RESOLVED_FILTER); return services.size() > 0; } /** - * Returns the {@link ShortcutInfo} for a dynamic shortcut into site settings, - * provided that {@link ManageDataLauncherActivity} is present in the manifest - * and an Intent for managing site settings is available. + * Returns the {@link ShortcutInfo} for a dynamic shortcut into site settings, provided that + * {@link ManageDataLauncherActivity} is present in the manifest and an Intent for managing site + * settings is available. * - * Otherwise returns null if {@link ManageDataLauncherActivity} is not launchable - * or if shortcuts are not supported by the Android SDK version. + * <p>Otherwise returns null if {@link ManageDataLauncherActivity} is not launchable or if + * shortcuts are not supported by the Android SDK version. * - * The shortcut returned does not specify an activity. Thus when the shortcut is added, - * the app's main activity will be used by default. This activity needs to define the - * MAIN action and LAUNCHER category in order to attach the shortcut. + * <p>The shortcut returned does not specify an activity. Thus when the shortcut is added, the + * app's main activity will be used by default. This activity needs to define the MAIN action + * and LAUNCHER category in order to attach the shortcut. */ @RequiresApi(Build.VERSION_CODES.N_MR1) private static ShortcutInfo createSiteSettingsShortcutInfo( @@ -175,8 +176,8 @@ /** * Adds dynamic shortcut to site settings if the provider and android version support it. * - * Removes previously added site settings shortcut if it is no longer supported, e.g. the user - * changed their default browser. + * <p>Removes previously added site settings shortcut if it is no longer supported, e.g. the + * user changed their default browser. */ public static void updateSiteSettingsShortcut( Context context, HostBrowserLauncherParams params) { @@ -186,13 +187,15 @@ // Remove potentially existing shortcut if package does not support shortcuts. if (!siteSettingsShortcutEnabled(context, params.getHostBrowserPackageName())) { - shortcutManager.removeDynamicShortcuts(Collections.singletonList( - ManageDataLauncherActivity.SITE_SETTINGS_SHORTCUT_ID)); + shortcutManager.removeDynamicShortcuts( + Collections.singletonList( + ManageDataLauncherActivity.SITE_SETTINGS_SHORTCUT_ID)); return; } - ShortcutInfo shortcut = createSiteSettingsShortcutInfo( - context, params.getStartUrl(), params.getHostBrowserPackageName()); + ShortcutInfo shortcut = + createSiteSettingsShortcutInfo( + context, params.getStartUrl(), params.getHostBrowserPackageName()); shortcutManager.addDynamicShortcuts(Collections.singletonList(shortcut)); } }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/NotificationPermissionRequestActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/NotificationPermissionRequestActivity.java index 197619d..2282099f 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/NotificationPermissionRequestActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/NotificationPermissionRequestActivity.java
@@ -50,8 +50,10 @@ */ public static PendingIntent createPermissionRequestPendingIntent( Context context, String channelName, String channelId) { - Intent intent = new Intent( - context.getApplicationContext(), NotificationPermissionRequestActivity.class); + Intent intent = + new Intent( + context.getApplicationContext(), + NotificationPermissionRequestActivity.class); intent.putExtra(EXTRA_NOTIFICATION_CHANNEL_NAME, channelName); intent.putExtra(EXTRA_NOTIFICATION_CHANNEL_ID, channelId); // Starting with Build.VERSION_CODES.S it is required to explicitly specify the mutability @@ -83,8 +85,9 @@ // the first time will trigger the permission dialog. if (getApplicationContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.TIRAMISU) { - NotificationChannel channel = new NotificationChannel( - mChannelId, mChannelName, NotificationManager.IMPORTANCE_DEFAULT); + NotificationChannel channel = + new NotificationChannel( + mChannelId, mChannelName, NotificationManager.IMPORTANCE_DEFAULT); getNotificationManager().createNotificationChannel(channel); } @@ -115,13 +118,10 @@ finish(); } - /** - * Sends a message to the messenger containing the permission status. - */ + /** Sends a message to the messenger containing the permission status. */ private static void sendPermissionMessage(Messenger messenger, boolean enabled) { Bundle data = new Bundle(); - @PermissionStatus - int status = enabled ? PermissionStatus.ALLOW : PermissionStatus.BLOCK; + @PermissionStatus int status = enabled ? PermissionStatus.ALLOW : PermissionStatus.BLOCK; data.putInt(KEY_PERMISSION_STATUS, status); Message message = Message.obtain(); message.setData(data);
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PermissionStatus.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PermissionStatus.java index 11c11e592..a64e3e4c 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PermissionStatus.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PermissionStatus.java
@@ -11,9 +11,7 @@ @IntDef({PermissionStatus.ALLOW, PermissionStatus.BLOCK, PermissionStatus.ASK}) @Retention(RetentionPolicy.SOURCE) -/** - * Represents the permission state in service calls. - */ +/** Represents the permission state in service calls. */ public @interface PermissionStatus { int ALLOW = 0; int BLOCK = 1;
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PrefUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PrefUtils.java index 99c182d..c773ff12 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PrefUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/PrefUtils.java
@@ -18,17 +18,15 @@ private static final String KEY_HAS_REQUESTED_NOTIFICATION_PERMISSION = "HAS_REQUESTED_NOTIFICATION_PERMISSION"; - /** - * Returns the application level {@link SharedPreferences} using the application context. - */ + /** Returns the application level {@link SharedPreferences} using the application context. */ public static SharedPreferences getAppSharedPreferences(Context context) { - return context.getApplicationContext().getSharedPreferences( - SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); + return context.getApplicationContext() + .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); } public static boolean hasRequestedNotificationPermission(Context context) { - return getAppSharedPreferences(context).getBoolean( - KEY_HAS_REQUESTED_NOTIFICATION_PERMISSION, false); + return getAppSharedPreferences(context) + .getBoolean(KEY_HAS_REQUESTED_NOTIFICATION_PERMISSION, false); } public static void setHasRequestedNotificationPermission(Context context) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/TransparentLauncherActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/TransparentLauncherActivity.java index 991ef71..fa607f81 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/TransparentLauncherActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/TransparentLauncherActivity.java
@@ -8,34 +8,36 @@ import android.os.Bundle; import android.os.SystemClock; -/** - * UI-less activity which launches host browser. - */ +/** UI-less activity which launches host browser. */ public class TransparentLauncherActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { long activityStartTimeMs = SystemClock.elapsedRealtime(); super.onCreate(savedInstanceState); - new LaunchHostBrowserSelector(this).selectHostBrowser( - new LaunchHostBrowserSelector.Callback() { - @Override - public void onBrowserSelected( - String hostBrowserPackageName, boolean dialogShown) { - if (hostBrowserPackageName == null) { - finish(); - return; - } - HostBrowserLauncherParams params = - HostBrowserLauncherParams.createForIntent( - TransparentLauncherActivity.this, getIntent(), - hostBrowserPackageName, dialogShown, activityStartTimeMs, - -1 /* splashShownTimeMs */); + new LaunchHostBrowserSelector(this) + .selectHostBrowser( + new LaunchHostBrowserSelector.Callback() { + @Override + public void onBrowserSelected( + String hostBrowserPackageName, boolean dialogShown) { + if (hostBrowserPackageName == null) { + finish(); + return; + } + HostBrowserLauncherParams params = + HostBrowserLauncherParams.createForIntent( + TransparentLauncherActivity.this, + getIntent(), + hostBrowserPackageName, + dialogShown, + activityStartTimeMs, + -1 /* splashShownTimeMs */); - onHostBrowserSelected(params); - finish(); - } - }); + onHostBrowserSelected(params); + finish(); + } + }); } protected void onHostBrowserSelected(HostBrowserLauncherParams params) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java index 056521f..638a1aaa 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceFactory.java
@@ -18,22 +18,16 @@ * services from .dex file in Chrome APK. */ public class WebApkServiceFactory extends Service { - /** - * Key for passing uid of only application allowed to call the service's methods. - */ + /** Key for passing uid of only application allowed to call the service's methods. */ public static final String KEY_HOST_BROWSER_UID = "host_browser_uid"; private static final String TAG = "cr_WebApkServiceFactory"; - /** - * Name of the class with IBinder API implementation. - */ + /** Name of the class with IBinder API implementation. */ private static final String WEBAPK_SERVICE_IMPL_CLASS_NAME = "org.chromium.webapk.lib.runtime_library.WebApkServiceImpl"; - /** - * Key for passing id of icon to represent WebAPK notifications in status bar. - */ + /** Key for passing id of icon to represent WebAPK notifications in status bar. */ private static final String KEY_SMALL_ICON_ID = "small_icon_id"; @Override @@ -43,8 +37,9 @@ Log.w(TAG, "Host browser does not support WebAPKs."); return null; } - ClassLoader webApkClassLoader = HostBrowserClassLoader.getClassLoaderInstance( - this, hostBrowserPackage, WEBAPK_SERVICE_IMPL_CLASS_NAME); + ClassLoader webApkClassLoader = + HostBrowserClassLoader.getClassLoaderInstance( + this, hostBrowserPackage, WEBAPK_SERVICE_IMPL_CLASS_NAME); if (webApkClassLoader == null) { Log.w(TAG, "Unable to create ClassLoader."); return null;
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceImplWrapper.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceImplWrapper.java index cb78ff1ed..8f1f279 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceImplWrapper.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkServiceImplWrapper.java
@@ -52,6 +52,7 @@ * The {@link org.chromium.webapk.lib.runtime_library.WebApkServiceImpl} that this class wraps. */ private IBinder mIBinderDelegate; + private Context mContext; public WebApkServiceImplWrapper(Context context, IBinder delegate, int hostBrowserUid) { @@ -65,8 +66,11 @@ throws RemoteException { int callingUid = Binder.getCallingUid(); if (mHostUid != callingUid) { - throw new RemoteException("Unauthorized caller " + callingUid - + " does not match expected host=" + mHostUid); + throw new RemoteException( + "Unauthorized caller " + + callingUid + + " does not match expected host=" + + mHostUid); } // For methods that we want to handle we defer to our parent's onTransact which will @@ -113,7 +117,8 @@ @Override public void notifyNotificationWithChannel( String platformTag, int platformID, Notification notification, String channelName) { - Log.w(TAG, + Log.w( + TAG, "Should NOT reach WebApkServiceImplWrapper#notifyNotificationWithChannel(" + "String, int, Notification, String)"); } @@ -128,8 +133,7 @@ public @PermissionStatus int checkNotificationPermission() { boolean enabled = getNotificationManager().areNotificationsEnabled(); - @PermissionStatus - int status = enabled ? PermissionStatus.ALLOW : PermissionStatus.BLOCK; + @PermissionStatus int status = enabled ? PermissionStatus.ALLOW : PermissionStatus.BLOCK; if (status == PermissionStatus.BLOCK && !PrefUtils.hasRequestedNotificationPermission(mContext) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @@ -152,9 +156,11 @@ /** Creates a WebAPK notification channel on Android O+ if one does not exist. */ protected void ensureNotificationChannelExists() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(DEFAULT_NOTIFICATION_CHANNEL_ID, - WebApkUtils.getNotificationChannelName(mContext), - NotificationManager.IMPORTANCE_DEFAULT); + NotificationChannel channel = + new NotificationChannel( + DEFAULT_NOTIFICATION_CHANNEL_ID, + WebApkUtils.getNotificationChannelName(mContext), + NotificationManager.IMPORTANCE_DEFAULT); getNotificationManager().createNotificationChannel(channel); } } @@ -179,8 +185,12 @@ if (mIBinderDelegate == null) return false; try { - Method onTransactMethod = mIBinderDelegate.getClass().getMethod( - "onTransact", new Class[] {int.class, Parcel.class, Parcel.class, int.class}); + Method onTransactMethod = + mIBinderDelegate + .getClass() + .getMethod( + "onTransact", + new Class[] {int.class, Parcel.class, Parcel.class, int.class}); onTransactMethod.setAccessible(true); return (boolean) onTransactMethod.invoke(mIBinderDelegate, code, data, reply, flags); } catch (Exception e) { @@ -205,8 +215,12 @@ if (mIBinderDelegate == null) return; try { - Method notifyMethod = mIBinderDelegate.getClass().getMethod("notifyNotification", - new Class[] {String.class, int.class, Notification.class}); + Method notifyMethod = + mIBinderDelegate + .getClass() + .getMethod( + "notifyNotification", + new Class[] {String.class, int.class, Notification.class}); notifyMethod.setAccessible(true); notifyMethod.invoke(mIBinderDelegate, platformTag, platformID, notification); } catch (Exception e) {
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkSharedPreferences.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkSharedPreferences.java index 54dc0b6..eb93f02 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkSharedPreferences.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkSharedPreferences.java
@@ -21,8 +21,7 @@ "org.chromium.webapk.shell_apk.version_code"; /** - * Shared preference for the version number of the dynamically loaded dex by the WebAPK - * service. + * Shared preference for the version number of the dynamically loaded dex by the WebAPK service. */ public static final String PREF_RUNTIME_DEX_VERSION = "org.chromium.webapk.shell_apk.dex_version";
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java index b1d5299..357fde6a 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/WebApkUtils.java
@@ -40,9 +40,7 @@ import java.util.List; import java.util.Map; -/** - * Contains utility methods for interacting with WebAPKs. - */ +/** Contains utility methods for interacting with WebAPKs. */ public class WebApkUtils { private static final String TAG = "cr_WebApkUtils"; private static final float CONTRAST_LIGHT_ITEM_THRESHOLD = 3f; @@ -72,8 +70,10 @@ public static Bundle readMetaData(Context context) { ApplicationInfo ai = null; try { - ai = context.getPackageManager().getApplicationInfo( - context.getPackageName(), PackageManager.GET_META_DATA); + ai = + context.getPackageManager() + .getApplicationInfo( + context.getPackageName(), PackageManager.GET_META_DATA); } catch (NameNotFoundException e) { return null; } @@ -94,7 +94,7 @@ if (intentStartUrl.startsWith(startUrl) && !TextUtils.isEmpty( - Uri.parse(intentStartUrl).getQueryParameter(loggedIntentUrlParam))) { + Uri.parse(intentStartUrl).getQueryParameter(loggedIntentUrlParam))) { return intentStartUrl; } @@ -111,8 +111,9 @@ // disabled browsers. List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(browserIntent, PackageManager.MATCH_ALL); - resolveInfos.addAll(packageManager.queryIntentActivities( - browserIntent, PackageManager.MATCH_DEFAULT_ONLY)); + resolveInfos.addAll( + packageManager.queryIntentActivities( + browserIntent, PackageManager.MATCH_DEFAULT_ONLY)); Map<String, ResolveInfo> result = new HashMap<>(); for (ResolveInfo resolveInfo : resolveInfos) { @@ -145,8 +146,9 @@ } try { PackageManager packageManager = context.getPackageManager(); - ApplicationInfo appInfo = packageManager.getApplicationInfo( - remotePackageName, PackageManager.GET_META_DATA); + ApplicationInfo appInfo = + packageManager.getApplicationInfo( + remotePackageName, PackageManager.GET_META_DATA); return appInfo.uid; } catch (NameNotFoundException e) { e.printStackTrace(); @@ -167,12 +169,18 @@ TypedValue.COMPLEX_UNIT_PX, res.getDimension(R.dimen.headline_size_medium)); int dialogContentPadding = res.getDimensionPixelSize(R.dimen.dialog_content_padding); int titleBottomPadding = res.getDimensionPixelSize(R.dimen.title_bottom_padding); - titleView.setPaddingRelative(dialogContentPadding, dialogContentPadding, - dialogContentPadding, titleBottomPadding); + titleView.setPaddingRelative( + dialogContentPadding, + dialogContentPadding, + dialogContentPadding, + titleBottomPadding); int dialogContentTopPadding = res.getDimensionPixelSize(R.dimen.dialog_content_top_padding); - contentView.setPaddingRelative(dialogContentPadding, dialogContentTopPadding, - dialogContentPadding, dialogContentPadding); + contentView.setPaddingRelative( + dialogContentPadding, + dialogContentTopPadding, + dialogContentPadding, + dialogContentPadding); } /** @@ -198,8 +206,9 @@ } /** - * Check whether lighter or darker foreground elements (i.e. text, drawables etc.) - * should be used depending on the given background color. + * Check whether lighter or darker foreground elements (i.e. text, drawables etc.) should be + * used depending on the given background color. + * * @param backgroundColor The background color value which is being queried. * @return Whether light colored elements should be used. */ @@ -226,7 +235,7 @@ /** * Sets the status bar icons to dark or light. * - * TODO: migrate to WindowInsetsController API for Android R+ (API 30+) + * <p>TODO: migrate to WindowInsetsController API for Android R+ (API 30+) * * @param rootView The root view used to request updates to the system UI theming. * @param useDarkIcons Whether the status bar icons should be dark. @@ -258,9 +267,7 @@ } } - /** - * Returns the Intent to query a list of installed browser apps. - */ + /** Returns the Intent to query a list of installed browser apps. */ public static Intent getQueryInstalledBrowsersIntent() { return new Intent() .setAction(Intent.ACTION_VIEW) @@ -276,7 +283,7 @@ return R.drawable.notification_badge; } - /** Computes the screen lock orientation from the passed-in metadata and the display size. */ + /** Computes the screen lock orientation from the passed-in metadata and the display size. */ public static int computeNaturalScreenLockOrientationFromMetaData( Context context, Bundle metadata) { String orientation = metadata.getString(WebApkMetaDataKeys.ORIENTATION); @@ -354,8 +361,10 @@ private static boolean isAutomotive(Context context) { boolean isAutomotive; try { - isAutomotive = context.getApplicationContext().getPackageManager().hasSystemFeature( - PackageManager.FEATURE_AUTOMOTIVE); + isAutomotive = + context.getApplicationContext() + .getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); } catch (SecurityException e) { Log.e(TAG, "Unable to query for Automotive system feature", e);
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java index f0221ac..6e14c0f 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OLauncher.java
@@ -27,8 +27,9 @@ Context context, long deltaMs) { SharedPreferences sharedPrefs = WebApkSharedPreferences.getPrefs(context); long now = System.currentTimeMillis(); - long lastRequestTimestamp = sharedPrefs.getLong( - WebApkSharedPreferences.PREF_REQUEST_HOST_BROWSER_RELAUNCH_TIMESTAMP, -1); + long lastRequestTimestamp = + sharedPrefs.getLong( + WebApkSharedPreferences.PREF_REQUEST_HOST_BROWSER_RELAUNCH_TIMESTAMP, -1); return (now - lastRequestTimestamp) <= deltaMs; } @@ -46,8 +47,10 @@ PackageManager pm = context.getPackageManager(); // The state change takes seconds if we do not let PackageManager kill the ShellAPK. - pm.setComponentEnabledSetting(enableComponent, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); + pm.setComponentEnabledSetting( + enableComponent, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); pm.setComponentEnabledSetting( disableComponent, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); } @@ -58,8 +61,12 @@ Bundle extraExtras = new Bundle(); extraExtras.putBoolean(WebApkConstants.EXTRA_SPLASH_PROVIDED_BY_WEBAPK, true); - HostBrowserLauncher.launchBrowserInWebApkMode(splashActivity, params, extraExtras, - Intent.FLAG_ACTIVITY_NO_ANIMATION, true /* expectResult */); + HostBrowserLauncher.launchBrowserInWebApkMode( + splashActivity, + params, + extraExtras, + Intent.FLAG_ACTIVITY_NO_ANIMATION, + /* expectResult= */ true); } /** @@ -69,11 +76,15 @@ * @param intentToCopy Intent whose extras should be copied. * @param selectedShareTargetActivity Class name of the share activity that the user selected. * @param launchTimeMs Timestamp of when WebAPK's initial activity was launched. -1 if the time - * is unknown. + * is unknown. * @param launchComponent Component to launch. */ - public static void copyIntentExtrasAndLaunch(Context context, Intent intentToCopy, - String selectedShareTargetActivity, long launchTimeMs, ComponentName launchComponent) { + public static void copyIntentExtrasAndLaunch( + Context context, + Intent intentToCopy, + String selectedShareTargetActivity, + long launchTimeMs, + ComponentName launchComponent) { Intent intent = new Intent(Intent.ACTION_VIEW, intentToCopy.getData()); intent.setComponent(launchComponent); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -85,7 +96,8 @@ // If the intent is a share, propagate which share target activity the user selected. if (selectedShareTargetActivity != null) { - intent.putExtra(WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME, + intent.putExtra( + WebApkConstants.EXTRA_WEBAPK_SELECTED_SHARE_TARGET_ACTIVITY_CLASS_NAME, selectedShareTargetActivity); } @@ -107,7 +119,11 @@ Bundle extraExtras = new Bundle(); extraExtras.putBoolean(WebApkConstants.EXTRA_RELAUNCH, true); - HostBrowserLauncher.launchBrowserInWebApkMode(activity, params, extraExtras, - Intent.FLAG_ACTIVITY_NEW_TASK, false /* expectResult */); + HostBrowserLauncher.launchBrowserInWebApkMode( + activity, + params, + extraExtras, + Intent.FLAG_ACTIVITY_NEW_TASK, + /* expectResult= */ false); } }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java index f733e34..81e00a2 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OMainActivity.java
@@ -32,8 +32,8 @@ // H2OMainActivity is enabled by default for old-style WebAPKs. // R.bool.transparent_main_activity_enabled_default is inaccurate for old-style WebAPKs. return !isNewStyleWebApk - || context.getResources().getBoolean( - R.bool.transparent_main_activity_enabled_default); + || context.getResources() + .getBoolean(R.bool.transparent_main_activity_enabled_default); } return enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; } @@ -53,8 +53,10 @@ // WebAPK app. We cannot use AlarmManager or JobScheduler because their minimum // delay (several seconds) is too high. H2OLauncher.requestRelaunchFromHostBrowser(this, params); - H2OLauncher.changeEnabledComponentsAndKillShellApk(appContext, - new ComponentName(appContext, H2OOpaqueMainActivity.class), getComponentName()); + H2OLauncher.changeEnabledComponentsAndKillShellApk( + appContext, + new ComponentName(appContext, H2OOpaqueMainActivity.class), + getComponentName()); return; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OOpaqueMainActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OOpaqueMainActivity.java index 8bf4d38..2e16509 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OOpaqueMainActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OOpaqueMainActivity.java
@@ -31,8 +31,8 @@ // H2OOpaqueMainActivity is disabled by default for old-style WebAPKs. // R.bool.opaque_main_activity_enabled_default is inaccurate for old-style WebAPKs. return isNewStyleWebApk - && context.getResources().getBoolean( - R.bool.opaque_main_activity_enabled_default); + && context.getResources() + .getBoolean(R.bool.opaque_main_activity_enabled_default); } return enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; } @@ -43,7 +43,11 @@ super.onCreate(savedInstanceState); Context appContext = getApplicationContext(); overridePendingTransition(0, 0); - H2OLauncher.copyIntentExtrasAndLaunch(appContext, getIntent(), null, launchTimeMs, + H2OLauncher.copyIntentExtrasAndLaunch( + appContext, + getIntent(), + null, + launchTimeMs, new ComponentName(appContext, SplashActivity.class)); finish(); }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java index 038c3480..fb9fb2e3 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/H2OTransparentLauncherActivity.java
@@ -38,8 +38,11 @@ // brings the WebAPK activity stack to the foreground and does not create a // new activity stack. Context appContext = getApplicationContext(); - H2OLauncher.copyIntentExtrasAndLaunch(appContext, getIntent(), - params.getSelectedShareTargetActivityClassName(), params.getLaunchTimeMs(), + H2OLauncher.copyIntentExtrasAndLaunch( + appContext, + getIntent(), + params.getSelectedShareTargetActivityClassName(), + params.getLaunchTimeMs(), new ComponentName(appContext, SplashActivity.class)); return; } @@ -62,7 +65,7 @@ if (shouldLaunchSplash) { // Relaunch if H2OOpaqueMainActivity is disabled. if (!H2OOpaqueMainActivity.checkComponentEnabled( - appContext, params.isNewStyleWebApk())) { + appContext, params.isNewStyleWebApk())) { relaunchComponent = new ComponentName(appContext, H2OMainActivity.class); } } else { @@ -76,8 +79,11 @@ return false; } - H2OLauncher.copyIntentExtrasAndLaunch(getApplicationContext(), getIntent(), - params.getSelectedShareTargetActivityClassName(), -1 /* launchTimeMs */, + H2OLauncher.copyIntentExtrasAndLaunch( + getApplicationContext(), + getIntent(), + params.getSelectedShareTargetActivityClassName(), + /* launchTimeMs= */ -1, relaunchComponent); return true; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/LaunchTrigger.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/LaunchTrigger.java index 2985e59e..4239d1d 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/LaunchTrigger.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/LaunchTrigger.java
@@ -7,7 +7,7 @@ /** * Controls when to launch the WebAPK for {@link SplashActivity}. * - * Executes the provided Runnable when all of {@link #onSplashScreenReady}, {@link #onWillLaunch} + * <p>Executes the provided Runnable when all of {@link #onSplashScreenReady}, {@link #onWillLaunch} * and {@link #onHostBrowserSelected} have been called. The provided Runnable is only called once, * but this can be reset by calling {@link #reset}. */
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java index a827443..1ecd3a5c 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashActivity.java
@@ -67,11 +67,14 @@ // SplashScreen.OnExitAnimationListener#onSplashScreenExit is not called. // Fall back to manually creating our own splash screen in that case. androidSSplashSuccess = - SplashUtilsForS.listenForSplashScreen(this, getWindow(), (view, bitmap) -> { - mSplashView = view; - mBitmap = bitmap; - mLaunchTrigger.onSplashScreenReady(); - }); + SplashUtilsForS.listenForSplashScreen( + this, + getWindow(), + (view, bitmap) -> { + mSplashView = view; + mBitmap = bitmap; + mLaunchTrigger.onSplashScreenReady(); + }); } if (!androidSSplashSuccess) { // Fall back to the old behaviour if our reflection based method to launch the Android S @@ -87,7 +90,7 @@ // both the SplashActivity and the browser activity are created when the user selects the // WebAPK in Android Recents. if (!new ComponentName(this, SplashActivity.class) - .equals(WebApkUtils.fetchTopActivityComponent(this, getTaskId()))) { + .equals(WebApkUtils.fetchTopActivityComponent(this, getTaskId()))) { return; } @@ -143,22 +146,27 @@ } private void selectHostBrowser(final long splashShownTimeMs) { - new LaunchHostBrowserSelector(this).selectHostBrowser( - new LaunchHostBrowserSelector.Callback() { - @Override - public void onBrowserSelected( - String hostBrowserPackageName, boolean dialogShown) { - if (hostBrowserPackageName == null) { - finish(); - return; - } - HostBrowserLauncherParams params = - HostBrowserLauncherParams.createForIntent(SplashActivity.this, - getIntent(), hostBrowserPackageName, dialogShown, - -1 /* launchTimeMs */, splashShownTimeMs); - onHostBrowserSelected(params); - } - }); + new LaunchHostBrowserSelector(this) + .selectHostBrowser( + new LaunchHostBrowserSelector.Callback() { + @Override + public void onBrowserSelected( + String hostBrowserPackageName, boolean dialogShown) { + if (hostBrowserPackageName == null) { + finish(); + return; + } + HostBrowserLauncherParams params = + HostBrowserLauncherParams.createForIntent( + SplashActivity.this, + getIntent(), + hostBrowserPackageName, + dialogShown, + /* launchTimeMs= */ -1, + splashShownTimeMs); + onHostBrowserSelected(params); + } + }); } private void showPreSSplashScreen() { @@ -177,32 +185,46 @@ } else { mSplashView = SplashUtils.createSplashView(this); } - mSplashView.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (mSplashView.getWidth() == 0 || mSplashView.getHeight() == 0) return; + mSplashView + .getViewTreeObserver() + .addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (mSplashView.getWidth() == 0 || mSplashView.getHeight() == 0) { + return; + } - mSplashView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - mBitmap = SplashUtils.screenshotView( - mSplashView, SplashContentProvider.MAX_TRANSFER_SIZE_BYTES); - mLaunchTrigger.onSplashScreenReady(); - } - }); + mSplashView + .getViewTreeObserver() + .removeOnGlobalLayoutListener(this); + mBitmap = + SplashUtils.screenshotView( + mSplashView, + SplashContentProvider.MAX_TRANSFER_SIZE_BYTES); + mLaunchTrigger.onSplashScreenReady(); + } + }); setContentView(mSplashView); } - /** - * Sets the the color of the status bar and status bar icons. - */ + /** Sets the the color of the status bar and status bar icons. */ @VisibleForTesting void updateStatusBar(Bundle metadata) { - int statusBarColor = (int) WebApkMetaDataUtils.getLongFromMetaData( - metadata, WebApkMetaDataKeys.THEME_COLOR, Color.WHITE); - int defaultDarkStatusBarColor = (int) WebApkMetaDataUtils.getLongFromMetaData( - metadata, WebApkMetaDataKeys.THEME_COLOR, Color.BLACK); - int darkStatusBarColor = (int) WebApkMetaDataUtils.getLongFromMetaData( - metadata, WebApkMetaDataKeys.DARK_THEME_COLOR, defaultDarkStatusBarColor); + int statusBarColor = + (int) + WebApkMetaDataUtils.getLongFromMetaData( + metadata, WebApkMetaDataKeys.THEME_COLOR, Color.WHITE); + int defaultDarkStatusBarColor = + (int) + WebApkMetaDataUtils.getLongFromMetaData( + metadata, WebApkMetaDataKeys.THEME_COLOR, Color.BLACK); + int darkStatusBarColor = + (int) + WebApkMetaDataUtils.getLongFromMetaData( + metadata, + WebApkMetaDataKeys.DARK_THEME_COLOR, + defaultDarkStatusBarColor); WebApkUtils.setStatusBarColor( this, WebApkUtils.inDarkMode(this) ? darkStatusBarColor : statusBarColor); boolean needsDarkStatusBarIcons = @@ -222,7 +244,8 @@ if (!HostBrowserUtils.shouldIntentLaunchSplashActivity(params)) { HostBrowserLauncher.launch(this, params); - H2OLauncher.changeEnabledComponentsAndKillShellApk(appContext, + H2OLauncher.changeEnabledComponentsAndKillShellApk( + appContext, new ComponentName(appContext, H2OMainActivity.class), new ComponentName(appContext, H2OOpaqueMainActivity.class)); finish(); @@ -235,19 +258,22 @@ /** * Launches the host browser on top of {@link SplashActivity}. + * * @param splashEncoded Encoded screenshot of {@link mSplashView}. * @param encodingFormat The screenshot's encoding format. */ private void launch(byte[] splashEncoded, Bitmap.CompressFormat encodingFormat) { - SplashContentProvider.cache(this, splashEncoded, encodingFormat, mSplashView.getWidth(), + SplashContentProvider.cache( + this, + splashEncoded, + encodingFormat, + mSplashView.getWidth(), mSplashView.getHeight()); H2OLauncher.launch(this, mParams); mParams = null; } - /** - * Screenshots and encodes {@link mSplashView} on a background thread. - */ + /** Screenshots and encodes {@link mSplashView} on a background thread. */ @SuppressWarnings("NoAndroidAsyncTaskCheck") private void encodeSplashInBackground() { if (mBitmap == null) { @@ -256,34 +282,33 @@ } mScreenshotSplashTask = - new android.os - .AsyncTask<Void, Void, Pair<byte[], Bitmap.CompressFormat>>() { - @Override - protected Pair<byte[], Bitmap.CompressFormat> doInBackground( - Void... args) { - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - Bitmap.CompressFormat encodingFormat = - SplashUtils.selectBitmapEncoding( - mBitmap.getWidth(), mBitmap.getHeight()); - mBitmap.compress(encodingFormat, 100, out); - return Pair.create(out.toByteArray(), encodingFormat); - } catch (IOException e) { - } - return null; - } - - @Override - protected void onPostExecute( - Pair<byte[], Bitmap.CompressFormat> splashEncoded) { - mScreenshotSplashTask = null; - launch((splashEncoded == null) ? null : splashEncoded.first, - (splashEncoded == null) ? Bitmap.CompressFormat.PNG - : splashEncoded.second); - } - - // Do nothing if task was cancelled. + new android.os.AsyncTask<Void, Void, Pair<byte[], Bitmap.CompressFormat>>() { + @Override + protected Pair<byte[], Bitmap.CompressFormat> doInBackground(Void... args) { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + Bitmap.CompressFormat encodingFormat = + SplashUtils.selectBitmapEncoding( + mBitmap.getWidth(), mBitmap.getHeight()); + mBitmap.compress(encodingFormat, 100, out); + return Pair.create(out.toByteArray(), encodingFormat); + } catch (IOException e) { } - .executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR); + return null; + } + + @Override + protected void onPostExecute( + Pair<byte[], Bitmap.CompressFormat> splashEncoded) { + mScreenshotSplashTask = null; + launch( + (splashEncoded == null) ? null : splashEncoded.first, + (splashEncoded == null) + ? Bitmap.CompressFormat.PNG + : splashEncoded.second); + } + + // Do nothing if task was cancelled. + }.executeOnExecutor(android.os.AsyncTask.THREAD_POOL_EXECUTOR); } /** Whether we enable integration with Android S splash screens. */
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashContentProvider.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashContentProvider.java index c24523f3..c21a866 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashContentProvider.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashContentProvider.java
@@ -24,9 +24,9 @@ import java.util.concurrent.atomic.AtomicReference; /** ContentProvider for screenshot of splash screen. */ -public class SplashContentProvider - extends ContentProvider implements ContentProvider.PipeDataWriter<Void> { - /** Holds value which gets cleared after {@link ExpiringData#CLEAR_DATA_INTERVAL_MS}. */ +public class SplashContentProvider extends ContentProvider + implements ContentProvider.PipeDataWriter<Void> { + /** Holds value which gets cleared after {@link ExpiringData#CLEAR_DATA_INTERVAL_MS}. */ private static class ExpiringData { /** Time in milliseconds after constructing the object to clear the cached data. */ private static final int CLEAR_CACHED_DATA_INTERVAL_MS = 10000; @@ -51,14 +51,12 @@ /** * Maximum size in bytes of screenshot to transfer to browser. The screenshot should be - * downsampled to fit. Capping the maximum size of the screenshot decreases bitmap encoding - * time and image transfer time. + * downsampled to fit. Capping the maximum size of the screenshot decreases bitmap encoding time + * and image transfer time. */ public static final int MAX_TRANSFER_SIZE_BYTES = 1024 * 1024 * 12; - /** - * The encoding type of the last image vended by the ContentProvider. - */ + /** The encoding type of the last image vended by the ContentProvider. */ private static Bitmap.CompressFormat sEncodingFormat; private static AtomicReference<ExpiringData> sCachedSplashBytes = new AtomicReference<>(); @@ -70,8 +68,12 @@ * Temporarily caches the passed-in splash screen screenshot. To preserve memory, the cached * data is cleared after a delay. */ - public static void cache(Context context, byte[] splashBytes, - Bitmap.CompressFormat encodingFormat, int splashWidth, int splashHeight) { + public static void cache( + Context context, + byte[] splashBytes, + Bitmap.CompressFormat encodingFormat, + int splashWidth, + int splashHeight) { SharedPreferences.Editor editor = WebApkSharedPreferences.getPrefs(context).edit(); editor.putInt(WebApkSharedPreferences.PREF_SPLASH_WIDTH, splashWidth); editor.putInt(WebApkSharedPreferences.PREF_SPLASH_HEIGHT, splashHeight); @@ -86,8 +88,8 @@ } /** - * Sets the cached splash screen screenshot and returns the old one. - * Thread safety: Can be called from any thread. + * Sets the cached splash screen screenshot and returns the old one. Thread safety: Can be + * called from any thread. */ private static byte[] getAndSetCachedData(byte[] newSplashBytes) { ExpiringData newData = null; @@ -129,8 +131,9 @@ // not SplashActivity. Bitmap splashScreenshot = recreateAndScreenshotSplash(); if (splashScreenshot != null) { - sEncodingFormat = SplashUtils.selectBitmapEncoding( - splashScreenshot.getWidth(), splashScreenshot.getHeight()); + sEncodingFormat = + SplashUtils.selectBitmapEncoding( + splashScreenshot.getWidth(), splashScreenshot.getHeight()); splashScreenshot.compress(sEncodingFormat, 100, out); } } @@ -174,7 +177,11 @@ } @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + public Cursor query( + Uri uri, + String[] projection, + String selection, + String[] selectionArgs, String sortOrder) { throw new UnsupportedOperationException(); }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtils.java index 30001f7..7771610 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtils.java
@@ -40,21 +40,27 @@ public static View createSplashView(Context context) { Resources resources = context.getResources(); Bitmap icon = WebApkUtils.decodeBitmapFromDrawable(resources, R.drawable.splash_icon); - int backgroundColor = WebApkUtils.inDarkMode(context) - ? WebApkUtils.getColor(resources, R.color.dark_background_color_non_empty) - : WebApkUtils.getColor(resources, R.color.background_color_non_empty); + int backgroundColor = + WebApkUtils.inDarkMode(context) + ? WebApkUtils.getColor(resources, R.color.dark_background_color_non_empty) + : WebApkUtils.getColor(resources, R.color.background_color_non_empty); FrameLayout layout = new FrameLayout(context); - SplashLayout.createLayout(context, layout, icon, WebApkUtils.isSplashIconAdaptive(context), - false /* isIconGenerated */, resources.getString(R.string.name), + SplashLayout.createLayout( + context, + layout, + icon, + WebApkUtils.isSplashIconAdaptive(context), + /* isIconGenerated= */ false, + resources.getString(R.string.name), WebApkUtils.shouldUseLightForegroundOnBackground(backgroundColor)); layout.setBackgroundColor(backgroundColor); return layout; } /** - * Returns bitmap with screenshot of passed-in view. Downsamples screenshot so that it is - * no more than {@maxSizeInBytes}. + * Returns bitmap with screenshot of passed-in view. Downsamples screenshot so that it is no + * more than {@maxSizeInBytes}. */ public static Bitmap screenshotView(View view, int maxSizeBytes) { // Implementation copied from Android shared element code - @@ -70,9 +76,7 @@ return pair.bitmap; } - /** - * Creates a Bitmap of at most {@code maxSizeBytes} with an attached Canvas to draw on it. - */ + /** Creates a Bitmap of at most {@code maxSizeBytes} with an attached Canvas to draw on it. */ static BitmapAndCanvas createScaledBitmapAndCanvas(int width, int height, int maxSizeBytes) { float scale = Math.min(1f, ((float) maxSizeBytes) / (4 * width * height)); width = Math.round(width * scale); @@ -90,8 +94,9 @@ /** Selects encoding for the bitmap based on its size. */ public static Bitmap.CompressFormat selectBitmapEncoding(int width, int height) { - return (width * height <= MAX_SIZE_ENCODE_PNG) ? Bitmap.CompressFormat.PNG - : Bitmap.CompressFormat.JPEG; + return (width * height <= MAX_SIZE_ENCODE_PNG) + ? Bitmap.CompressFormat.PNG + : Bitmap.CompressFormat.JPEG; } /** Creates splash view with the passed-in dimensions and screenshots it. */ @@ -99,11 +104,13 @@ Context context, int splashWidth, int splashHeight, int maxSizeBytes) { if (splashWidth <= 0 || splashHeight <= 0) return null; - View splashView = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S - ? SplashUtilsForS.createSplashView(context) - : createSplashView(context); + View splashView = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + ? SplashUtilsForS.createSplashView(context) + : createSplashView(context); - splashView.measure(View.MeasureSpec.makeMeasureSpec(splashWidth, View.MeasureSpec.EXACTLY), + splashView.measure( + View.MeasureSpec.makeMeasureSpec(splashWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(splashHeight, View.MeasureSpec.EXACTLY)); splashView.layout(0, 0, splashWidth, splashHeight); return screenshotView(splashView, maxSizeBytes);
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtilsForS.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtilsForS.java index 6bd833e..0e23edb 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtilsForS.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/h2o/SplashUtilsForS.java
@@ -39,20 +39,31 @@ @RequiresApi(api = VERSION_CODES.S) public static boolean listenForSplashScreen( Activity activity, Window window, SplashscreenShownListener listener) { - activity.getSplashScreen().setOnExitAnimationListener(splashView -> { - WindowInsets insets = window.getDecorView().getRootWindowInsets(); - Insets systemBarInsets = insets.getInsets(WindowInsets.Type.systemBars()); + activity.getSplashScreen() + .setOnExitAnimationListener( + splashView -> { + WindowInsets insets = window.getDecorView().getRootWindowInsets(); + Insets systemBarInsets = + insets.getInsets(WindowInsets.Type.systemBars()); - Resources resources = activity.getResources(); - int backgroundColor = WebApkUtils.inDarkMode(activity) - ? WebApkUtils.getColor(resources, R.color.dark_background_color_non_empty) - : WebApkUtils.getColor(resources, R.color.background_color_non_empty); - Bitmap bitmap = screenshotSplashScreenView(splashView, splashView.getIconView(), - systemBarInsets, backgroundColor, - SplashContentProvider.MAX_TRANSFER_SIZE_BYTES); + Resources resources = activity.getResources(); + int backgroundColor = + WebApkUtils.inDarkMode(activity) + ? WebApkUtils.getColor( + resources, + R.color.dark_background_color_non_empty) + : WebApkUtils.getColor( + resources, R.color.background_color_non_empty); + Bitmap bitmap = + screenshotSplashScreenView( + splashView, + splashView.getIconView(), + systemBarInsets, + backgroundColor, + SplashContentProvider.MAX_TRANSFER_SIZE_BYTES); - listener.onSplashScreenShown(splashView, bitmap); - }); + listener.onSplashScreenShown(splashView, bitmap); + }); return true; } @@ -61,8 +72,8 @@ * Returns a screenshot of the passed in Android S SplashScreenView and renders a Bitmap * suitable for Chrome to display for a seamless WebAPK shell to Chrome transition. * - * Android S splash screens take the entire window (including the area normally covered by the - * status and navigation bars). Chrome displays the provided Bitmap in the normal Android + * <p>Android S splash screens take the entire window (including the area normally covered by + * the status and navigation bars). Chrome displays the provided Bitmap in the normal Android * Activity bounds, so to make sure that the screen doesn't change between the shell and Chrome, * we provide a screenshot without the areas normally covered by the status and navigation bar. */ @@ -93,11 +104,11 @@ /** * Creates a View with a splash screen. * - * Unlike {@link SplashUtils#createSplashView}, this splash screen will be an approximation of - * the splash screen generated by Android S+ (the main difference being that there is no app + * <p>Unlike {@link SplashUtils#createSplashView}, this splash screen will be an approximation + * of the splash screen generated by Android S+ (the main difference being that there is no app * title). * - * This is only used when the browser has been killed by Android for memory reasons, but the + * <p>This is only used when the browser has been killed by Android for memory reasons, but the * shell APK is still alive. When this happens we want to show a splash screen, but no longer * have access to the one that was used to launch the shell APK (since we don't want to keep the * ~12MB (see MAX_TRANSFER_SIZE_BYTES) image around for longer than needed). We create an @@ -108,8 +119,9 @@ static View createSplashView(Context context) { View view = LayoutInflater.from(context).inflate(R.layout.splash_screen_view, null); if (WebApkUtils.isSplashIconAdaptive(context)) { - Bitmap icon = WebApkUtils.decodeBitmapFromDrawable( - context.getResources(), R.drawable.splash_icon); + Bitmap icon = + WebApkUtils.decodeBitmapFromDrawable( + context.getResources(), R.drawable.splash_icon); ImageView imageView = view.findViewById(R.id.splashscreen_icon_view); imageView.setImageIcon(Icon.createWithAdaptiveBitmap(icon)); }
diff --git a/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java b/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java index 4a0e17ae..d853204 100644 --- a/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java +++ b/chrome/android/webapk/test/src/org/chromium/webapk/test/WebApkTestHelper.java
@@ -23,15 +23,11 @@ import java.net.URISyntaxException; -/** - * Helper class for WebAPK JUnit tests. - */ +/** Helper class for WebAPK JUnit tests. */ public class WebApkTestHelper { private static final String SHARE_TARGET_ACTIVITY_CLASS_NAME_PREFIX = "TestShareTargetActivity"; - /** - * Returns the simplest intent for launching a WebAPK. - */ + /** Returns the simplest intent for launching a WebAPK. */ public static Intent createMinimalWebApkIntent(String webApkPackageName, String url) { Intent intent = new Intent(); intent.setPackage(RuntimeEnvironment.application.getPackageName()); @@ -42,10 +38,11 @@ /** * Registers WebAPK. This function also creates an empty resource for the WebAPK. + * * @param packageName The package to register * @param metaData Bundle with application-level meta data from WebAPK's Android Manifest. * @param shareTargetMetaData Bundles with meta data for the share target activities. Null if - * the WebAPK does not have any share target activities. + * the WebAPK does not have any share target activities. */ public static void registerWebApkWithMetaData( String packageName, Bundle metaData, Bundle[] shareTargetMetaData) { @@ -66,14 +63,18 @@ shareTargetActivityClassNames = new String[shareTargetMetaData.length]; for (int i = 0; i < shareTargetMetaData.length; ++i) { shareTargetActivityClassNames[i] = getGeneratedShareTargetActivityClassName(i); - packageManager.addResolveInfoForIntent(shareIntent, - newResolveInfo(packageName, shareTargetActivityClassNames[i], + packageManager.addResolveInfoForIntent( + shareIntent, + newResolveInfo( + packageName, + shareTargetActivityClassNames[i], shareTargetMetaData[i])); } } - packageManager.addPackage(newPackageInfo( - packageName, metaData, shareTargetActivityClassNames, shareTargetMetaData)); + packageManager.addPackage( + newPackageInfo( + packageName, metaData, shareTargetActivityClassNames, shareTargetMetaData)); } /** Returns generated share activity class name for the given index. */ @@ -97,13 +98,14 @@ /** Sets the resource for the given package name. */ public static void setResource(String packageName, Resources res) { - ShadowPackageManager packageManager = - Shadows.shadowOf(RuntimeEnvironment.application.getPackageManager()); ShadowPackageManager.resources.put(packageName, res); } - private static PackageInfo newPackageInfo(String webApkPackageName, Bundle metaData, - String[] shareTargetActivityClassNames, Bundle[] shareTargetMetaData) { + private static PackageInfo newPackageInfo( + String webApkPackageName, + Bundle metaData, + String[] shareTargetActivityClassNames, + Bundle[] shareTargetMetaData) { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.metaData = metaData; PackageInfo packageInfo = new PackageInfo(); @@ -113,8 +115,11 @@ if (shareTargetMetaData != null) { packageInfo.activities = new ActivityInfo[shareTargetMetaData.length]; for (int i = 0; i < shareTargetMetaData.length; ++i) { - packageInfo.activities[i] = newActivityInfo(webApkPackageName, - shareTargetActivityClassNames[i], shareTargetMetaData[i]); + packageInfo.activities[i] = + newActivityInfo( + webApkPackageName, + shareTargetActivityClassNames[i], + shareTargetMetaData[i]); } }
diff --git a/chrome/app/resources/chromium_strings_en-GB.xtb b/chrome/app/resources/chromium_strings_en-GB.xtb index 9985844..21e2cc13 100644 --- a/chrome/app/resources/chromium_strings_en-GB.xtb +++ b/chrome/app/resources/chromium_strings_en-GB.xtb
@@ -277,6 +277,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> is dangerous, so Chromium has blocked it.</translation> <translation id="6132897690380286411">Chromium will soon close and delete data</translation> <translation id="6134968993075716475">Safe Browsing is off. Chromium recommends turning it on.</translation> +<translation id="6144416395842701622">Sign in to get the most out of Chromium</translation> <translation id="6145820983052037069">You can switch between Chromium profiles here</translation> <translation id="615103374448673771">If you allow cookies, Chrome may use them when preloading.</translation> <translation id="6175304430031192654">Depending on your settings, Chromium may also send cookies and your current URL</translation> @@ -434,6 +435,7 @@ <translation id="8648201657708811153">Google Chrome for testing cannot be made your default browser.</translation> <translation id="8697124171261953979">It also controls what page is shown when you start Chromium or search from the Omnibox.</translation> <translation id="8704119203788522458">This is your Chromium</translation> +<translation id="8719993436687031146">Sign in to Chromium?</translation> <translation id="878572486461146056">Install error: Your network administrator has applied a Group Policy that prevents installation: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium needs permission to access your camera and microphone for this site</translation> <translation id="8826492472752484139">Click 'Password Manager'</translation>
diff --git a/chrome/app/resources/chromium_strings_ja.xtb b/chrome/app/resources/chromium_strings_ja.xtb index d16caed..0bb1bfe 100644 --- a/chrome/app/resources/chromium_strings_ja.xtb +++ b/chrome/app/resources/chromium_strings_ja.xtb
@@ -275,6 +275,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> は危険なファイルであるため、Chromium でブロックしました。</translation> <translation id="6132897690380286411">Chromium はまもなく終了し、データが削除されます</translation> <translation id="6134968993075716475">セーフ ブラウジングがオフになっています。Chromium はオンにすることをおすすめしています。</translation> +<translation id="6144416395842701622">Chromium を最大限に活用するにはログインしてください</translation> <translation id="6145820983052037069">こちらで Chromium プロフィールを切り替えることができます</translation> <translation id="615103374448673771">Cookie を許可した場合、Chromium はプリロードの際に Cookie を使用することがあります。</translation> <translation id="6175304430031192654">設定によっては、Chromium から Cookie や現在の URL が送信されることもあります</translation> @@ -432,6 +433,7 @@ <translation id="8648201657708811153">Google Chrome for Testing は、既定のブラウザには設定できません。</translation> <translation id="8697124171261953979">この拡張機能では、Chromium の起動時、またはアドレスバーからの検索時に表示されるページも制御されます。</translation> <translation id="8704119203788522458">自分好みに設定</translation> +<translation id="8719993436687031146">Chromium にログインしますか?</translation> <translation id="878572486461146056">インストール エラー: ネットワーク管理者により、インストールを許可しないというグループ ポリシーが適用されています: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">このサイトを利用するには、Chromium でカメラとマイクの使用を許可する必要があります</translation> <translation id="8826492472752484139">[パスワード マネージャー] をクリックする</translation>
diff --git a/chrome/app/resources/chromium_strings_lt.xtb b/chrome/app/resources/chromium_strings_lt.xtb index d2e95b4d..213cff60 100644 --- a/chrome/app/resources/chromium_strings_lt.xtb +++ b/chrome/app/resources/chromium_strings_lt.xtb
@@ -277,6 +277,7 @@ <translation id="6129621093834146363">Failas „<ph name="FILE_NAME" />“ pavojingas, todėl „Chromium“ jį užblokavo.</translation> <translation id="6132897690380286411">„Chromium“ netrukus bus uždaryta ir ištrins duomenis</translation> <translation id="6134968993075716475">Saugaus naršymo funkcija išjungta. „Chromium“ rekomenduoja ją įjungti.</translation> +<translation id="6144416395842701622">Prisijunkite, kad išnaudotumėte visas „Chromium“ galimybes</translation> <translation id="6145820983052037069">Čia galite perjungti „Chromium“ profilius</translation> <translation id="615103374448673771">Jei leisite slapukus, „Chromium“ gali naudoti juos iš anksto įkeldama puslapius</translation> <translation id="6175304430031192654">Atsižvelgiant į nustatymus, „Chromium“ taip pat gali siųsti slapukus ir dabartinį URL</translation> @@ -435,6 +436,7 @@ <translation id="8648201657708811153">„Google Chrome for Testing“ negali būti nustatyta kaip numatytoji naršyklė.</translation> <translation id="8697124171261953979">Ji taip pat kontroliuoja, koks puslapis rodomas, kai paleidžiate „Chromium“ arba ieškote „Omnibox“.</translation> <translation id="8704119203788522458">Tai jūsų „Chromium“</translation> +<translation id="8719993436687031146">Prisijungti prie „Chromium“?</translation> <translation id="878572486461146056">Diegimo klaida: tinklo administratorius taiko grupių politiką, pagal kurią neleidžiama įdiegti: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">„Chromium“ reikia leidimo, kad galėtų naudoti fotoaparatą ir mikrofoną šioje svetainėje</translation> <translation id="8826492472752484139">Spustelėkite „Slaptažodžių tvarkyklė“</translation>
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb index 1bb8a28..db6f2e8 100644 --- a/chrome/app/resources/chromium_strings_ms.xtb +++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -275,6 +275,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> berbahaya, jadi Chromium telah menyekat fail itu.</translation> <translation id="6132897690380286411">Chromium akan ditutup dan data akan dipadamkan sebentar lagi</translation> <translation id="6134968993075716475">Penyemakan Imbas Selamat dimatikan. Chromium mengesyorkan agar ciri ini dihidupkan.</translation> +<translation id="6144416395842701622">Log masuk untuk memanfaatkan Chromium sepenuhnya</translation> <translation id="6145820983052037069">Anda boleh beralih antara profil Chromium di sini</translation> <translation id="615103374448673771">Jika anda membenarkan kuki, Chromium boleh menggunakan kuki tersebut semasa prapemuatan</translation> <translation id="6175304430031192654">Bergantung pada tetapan anda, Chromium juga mungkin menghantar kuki dan URL semasa anda</translation> @@ -433,6 +434,7 @@ <translation id="8648201657708811153">Google Chrome for Testing tidak boleh dijadikan penyemak imbas lalai anda.</translation> <translation id="8697124171261953979">Sambungan turut mengawal halaman yang ditunjukkan apabila anda memulakan Chromium atau membuat carian dari Kotak Omni.</translation> <translation id="8704119203788522458">Ini Chromium anda</translation> +<translation id="8719993436687031146">Log masuk ke Chromium?</translation> <translation id="878572486461146056">Ralat pemasangan: Pentadbir rangkaian anda telah menggunakan Dasar Kumpulan yang menghalang pemasangan: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium memerlukan kebenaran untuk mengakses kamera dan mikrofon anda bagi tapak ini</translation> <translation id="8826492472752484139">Klik “Password Manager”</translation>
diff --git a/chrome/app/resources/chromium_strings_ne.xtb b/chrome/app/resources/chromium_strings_ne.xtb index 9c9bbcc2..998d29b 100644 --- a/chrome/app/resources/chromium_strings_ne.xtb +++ b/chrome/app/resources/chromium_strings_ne.xtb
@@ -275,6 +275,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> खतरनाक छ, त्यसैले Chromium ले यसमाथि रोक लगाएको छ।</translation> <translation id="6132897690380286411">Chromium ले चाँडै नै विन्डोहरू बन्द गर्ने र डेटा मेटाउने छ</translation> <translation id="6134968993075716475">सुरक्षित ब्राउजिङ निष्क्रिय छ। Chromium ले यो सेवा सक्रिय गर्न सिफारिस गर्छ।</translation> +<translation id="6144416395842701622">Chromium बाट बढीभन्दा बढी फाइदा लिन साइन इन गर्नुहोस्</translation> <translation id="6145820983052037069">तपाईं यहाँबाट Chromium मा रहेको एक प्रोफाइलबाट अर्को प्रोफाइलमा जान सक्नुहुन्छ</translation> <translation id="615103374448673771">तपाईंले कुकीहरू प्रयोग गर्ने अनुमति दिनुभयो भने Chromium ले पेजहरू प्रिलोड गर्दा ती कुकीहरू प्रयोग गर्न सक्छ</translation> <translation id="6175304430031192654">तपाईंले तय गरेका सेटिङका आधारमा Chromium ले कुकी र हालको URL पनि पठाउन सक्छ</translation> @@ -433,6 +434,7 @@ <translation id="8648201657708811153">Google Chrome for Testing लाई तपाईंको डिफल्ट ब्राउजर बनाउन मिल्दैन।</translation> <translation id="8697124171261953979">तपाइँले Chromium सुरु गर्दा वा ओम्निबाकसबाट खोज्दा कुन पृष्ठ देखाउँछ भनेर पनि यसले नियन्त्रण गर्छ।</translation> <translation id="8704119203788522458">यो तपाइँको Chromium हो</translation> +<translation id="8719993436687031146">Chromium मा साइन इन गर्ने हो?</translation> <translation id="878572486461146056">इन्स्टल गर्ने क्रममा त्रुटि भयो: तपाईंका नेटवर्क एड्मिनले इन्स्टल गर्न रोक लगाउने समूहसम्बन्धी नीति लागू गरेका छन्: <ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium लाई यो साइटका लागि तपाईंको क्यामेरा र माइक्रोफोनमाथि पहुँच राख्ने अनुमति चाहिन्छ</translation> <translation id="8826492472752484139">“पासवर्ड म्यानेजर” मा क्लिक गर्नुहोस्</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-HK.xtb b/chrome/app/resources/chromium_strings_zh-HK.xtb index 8e0f5ff..47e2b0e0 100644 --- a/chrome/app/resources/chromium_strings_zh-HK.xtb +++ b/chrome/app/resources/chromium_strings_zh-HK.xtb
@@ -277,6 +277,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> 不安全,因此 Chromium 已封鎖此檔案。</translation> <translation id="6132897690380286411">Chromium 即將關閉並刪除資料</translation> <translation id="6134968993075716475">「安全瀏覽」功能已停用。Chromium 建議啟用此功能。</translation> +<translation id="6144416395842701622">登入後可充分運用 Chromium 的各項功能</translation> <translation id="6145820983052037069">您可在此處切換不同的 Chromium 設定檔</translation> <translation id="615103374448673771">如果你允許 Cookie,Chromium 可能會在預先載入時使用 Cookie</translation> <translation id="6175304430031192654">視乎你的設定,Chromium 亦可能會傳送 Cookie 和你目前的網址</translation> @@ -434,6 +435,7 @@ <translation id="8648201657708811153">Google Chrome for Testing 無法設為預設瀏覽器。</translation> <translation id="8697124171261953979">這個擴充功能也會控管 Chromium 啟動時或您使用網址列搜尋時所顯示的網頁。</translation> <translation id="8704119203788522458">這是您專屬的 Chromium</translation> +<translation id="8719993436687031146">要登入 Chromium 嗎?</translation> <translation id="878572486461146056">安裝錯誤:網絡管理員已套用防止安裝的群組政策:<ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium 需要取得權限,才能讓這個網站存取您的相機和麥克風</translation> <translation id="8826492472752484139">按一下 [密碼管理工具]</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-TW.xtb b/chrome/app/resources/chromium_strings_zh-TW.xtb index 39655f8..fb76199f 100644 --- a/chrome/app/resources/chromium_strings_zh-TW.xtb +++ b/chrome/app/resources/chromium_strings_zh-TW.xtb
@@ -275,6 +275,7 @@ <translation id="6129621093834146363"><ph name="FILE_NAME" /> 並不安全,因此遭到 Chromium 封鎖。</translation> <translation id="6132897690380286411">Chromium 即將關閉並刪除資料</translation> <translation id="6134968993075716475">安全瀏覽功能已停用。Chromium 建議啟用這項功能。</translation> +<translation id="6144416395842701622">登入後可充分運用 Chromium 的各項功能</translation> <translation id="6145820983052037069">你可以在這裡切換不同的 Chromium 設定檔</translation> <translation id="615103374448673771">如果你允許 Cookie,Chromium 可能會使用 Cookie 預先載入網頁</translation> <translation id="6175304430031192654">視你的設定而定,Chromium 也可能會傳送 Cookie 和你目前的網址</translation> @@ -433,6 +434,7 @@ <translation id="8648201657708811153">Google Chrome for Testing 無法設為預設瀏覽器。</translation> <translation id="8697124171261953979">這個擴充功能也會控管 Chromium 啟動時或你使用網址列搜尋時所顯示的網頁。</translation> <translation id="8704119203788522458">這是你專屬的 Chromium</translation> +<translation id="8719993436687031146">要登入 Chromium 嗎?</translation> <translation id="878572486461146056">安裝錯誤:網路管理員採用的「群組原則」不允許安裝應用程式:<ph name="INSTALL_ERROR" /></translation> <translation id="8796602469536043152">Chromium 需要相關權限,才能讓這個網站使用你的攝影機和麥克風</translation> <translation id="8826492472752484139">按一下「密碼管理工具」</translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb index 2fc37fe..d526072c 100644 --- a/chrome/app/resources/generated_resources_af.xtb +++ b/chrome/app/resources/generated_resources_af.xtb
@@ -1142,7 +1142,6 @@ NAS-sagteware?</translation> <translation id="1863047423483329595">Nasporing-beskerming is tydelik onbeskikbaar. Terwyl Chrome hierdie kenmerk opdateer, kan werwe derdepartywebkoekies tydelik gebruik tensy jy dit blokkeer. <ph name="BEGIN_LINK" />Kom meer te wete<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Geen reekspoorte is gevind nie</translation> -<translation id="1863207472175483351">installeer tans …</translation> <translation id="1864111464094315414">Meld aan</translation> <translation id="1864400682872660285">Koeler</translation> <translation id="1864454756846565995">USB C-toestel (poort aan agterkant)</translation> @@ -1859,6 +1858,7 @@ <translation id="2402226831639195063">Tone</translation> <translation id="2405887402346713222">Toestel- en komponentreeksnommers</translation> <translation id="2406153734066939945">Vee hierdie profiel en sy data uit?</translation> +<translation id="2407671304279211586">Kies DNS-verskaffer</translation> <translation id="2408018932941436077">Stoor tans kaart</translation> <translation id="2408955596600435184">Voer jou PIN in</translation> <translation id="2409268599591722235">Kom ons begin</translation> @@ -5130,7 +5130,6 @@ <translation id="4988526792673242964">Bladsye</translation> <translation id="49896407730300355">Draai antikloksgewys</translation> <translation id="4989966318180235467">Ondersoek agtergrondbladsy</translation> -<translation id="4990949771467040994">wag tans …</translation> <translation id="4991420928586866460">Behandel sleutels in die boonste ry soos funksiesleutels</translation> <translation id="4992458225095111526">Bevestig Powerwash</translation> <translation id="4992473555164495036">Jou administrateur het die beskikbare invoermetodes beperk.</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index ef31e38..ad6c751 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -1138,7 +1138,6 @@ <translation id="1862311223300693744">ማንኛውም ልዩ VPN፣ ተኪ፣ ኬላ ወይም የNAS ሶፍትዌር ጭነዋል?</translation> <translation id="1863047423483329595">የመከታተል ጥበቃ ለጊዜው አይገኝም። Chrome ይህን ባህሪ በማዘመን ላይ ሳለ ጣቢያዎች ካላገዷቸው በስተቀር የሦስተኛ ወገን ኩኪዎችን ለጊዜው መጠቀም ይችላሉ። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation> <translation id="1863182668524159459">ምንም ተከታታይ ወደቦች አልተገኙም</translation> -<translation id="1863207472175483351">በመጫን ላይ...</translation> <translation id="1864111464094315414">ግባ</translation> <translation id="1864400682872660285">ማቀዥቀዣ</translation> <translation id="1864454756846565995">USB-C መሣሪያ (የኋላ ወደብ)</translation> @@ -1853,6 +1852,7 @@ <translation id="2402226831639195063">ድምጾች</translation> <translation id="2405887402346713222">የመሣሪያ እና የክፍለ-አካል መለያ ቁጥሮች</translation> <translation id="2406153734066939945">ይህ መገለጫ እና ውሂቡ ይሰረዝ?</translation> +<translation id="2407671304279211586">የዲኤንኤስ አቅራቢ ይምረጡ</translation> <translation id="2408018932941436077">ካርድን በማስቀመጥ ላይ</translation> <translation id="2408955596600435184">የእርስዎን ፒን ያስገቡ</translation> <translation id="2409268599591722235">እንሂድ</translation> @@ -5121,7 +5121,6 @@ <translation id="4988526792673242964">ገፆች</translation> <translation id="49896407730300355">በሰዓት መዞሪያ አቅጣጫ &ተቃራኒ አሽከርክር</translation> <translation id="4989966318180235467">&የጀርባ ገፅ ይመርምሩ</translation> -<translation id="4990949771467040994">በመጠበቅ ላይ…</translation> <translation id="4991420928586866460">የላይኛው ረድፍ ቁልፎች እንደ የተግባር ቁልፍ ተጠቀምባቸው</translation> <translation id="4992458225095111526">Powerwashን ያረጋግጡ</translation> <translation id="4992473555164495036">የእርስዎ አስተዳዳሪ ሊገኙ የሚችሉትን የግቤት ዘዴዎች ገድቧቸዋል።</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 3f73d135..186a469a 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -1133,7 +1133,6 @@ <translation id="1862311223300693744">هل لديك شبكة افتراضية خاصة (VPN) أو خادم وكيل أو جدار ناري أو برنامج NAS مثبت؟</translation> <translation id="1863047423483329595">ميزة "الحماية من التتبُّع" غير متاحة مؤقتًا. ويمكن للمواقع الإلكترونية، أثناء تحديث Chrome لهذه الميزة، استخدام ملفات تعريف الارتباط التابعة لجهات خارجية مؤقتًا ما لم تحظرها. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation> <translation id="1863182668524159459">لم يتم العثور على منافذ تسلسلية</translation> -<translation id="1863207472175483351">جارٍ التثبيت…</translation> <translation id="1864111464094315414">تسجيل الدخول</translation> <translation id="1864400682872660285">أكثر برودة</translation> <translation id="1864454756846565995">جهاز USB-C (المنفذ الخلفي)</translation> @@ -5117,7 +5116,6 @@ <translation id="4988526792673242964">الصفحات</translation> <translation id="49896407730300355">تدوير ع&كس اتجاه عقارب الساعة</translation> <translation id="4989966318180235467">فحص &صفحة الخلفية</translation> -<translation id="4990949771467040994">قيد الإنتظار...</translation> <translation id="4991420928586866460">معالجة مفاتيح الصف العلوي باعتبارها مفاتيح الوظائف</translation> <translation id="4992458225095111526">تأكيد Powerwash</translation> <translation id="4992473555164495036">لقد قيّد المشرف طرق الإدخال المتاحة.</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb index 69bbdbb..35e3b8a 100644 --- a/chrome/app/resources/generated_resources_as.xtb +++ b/chrome/app/resources/generated_resources_as.xtb
@@ -1140,7 +1140,6 @@ আছে নেকি?</translation> <translation id="1863047423483329595">ট্ৰেক কৰাৰ পৰা সুৰক্ষিত কৰাৰ সুবিধাটো সাময়িকভাৱে উপলব্ধ নহয়। Chromeএ এই সুবিধাটো আপডে’ট কৰি থকাৰ সময়ত, ছাইটসমূহে তৃতীয় পক্ষৰ কুকিসমূহ সাময়িকভাৱে ব্যৱহাৰ কৰিব পাৰে যদিহে আপুনি সেইসমূহ অৱৰোধ নকৰে। <ph name="BEGIN_LINK" />অধিক জানক<ph name="END_LINK" /></translation> <translation id="1863182668524159459">কোনো ছিৰিয়েল প'ৰ্ট বিচাৰি পোৱা নগ'ল</translation> -<translation id="1863207472175483351">ইনষ্টল কৰি থকা হৈছে...</translation> <translation id="1864111464094315414">লগ ইন কৰক</translation> <translation id="1864400682872660285">শীতল</translation> <translation id="1864454756846565995">USB-C ডিভাইচ (পিছফালে থকা পর্ট)</translation> @@ -5128,7 +5127,6 @@ <translation id="4988526792673242964">পৃষ্ঠা</translation> <translation id="49896407730300355">ঘড়ীৰ কাঁটাৰ বি&পৰীত দিশত ঘূৰাওক</translation> <translation id="4989966318180235467">&বেকগ্ৰাউণ্ড পৃষ্ঠা পৰীক্ষা কৰক</translation> -<translation id="4990949771467040994">অপেক্ষাৰত...</translation> <translation id="4991420928586866460">ওপৰৰ শাৰীৰ কীসমূহ ফাংশ্বনৰ কী হিচাপে গণ্য কৰক</translation> <translation id="4992458225095111526">পাৱাৰৱাশ্ব কৰাটো নিশ্চিত কৰক</translation> <translation id="4992473555164495036">আপোনাৰ প্ৰশাসকে উপলব্ধ ইনপুটৰ পদ্ধতিসমূহ সীমিত কৰিছে৷</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb index e9272d2e..2165935 100644 --- a/chrome/app/resources/generated_resources_az.xtb +++ b/chrome/app/resources/generated_resources_az.xtb
@@ -1126,7 +1126,6 @@ <translation id="1862311223300693744">Quraşdırılmış istənilən xüsusi VPN, proksi, qoruyucu divar və ya NAS proqram təminatınız var?</translation> <translation id="1863047423483329595">İzləmədən qoruma müvəqqəti olaraq əlçatan deyil. Chrome bu funksiyanı yeniləyərkən saytlar üçüncü tərəf kukilərindən müvəqqəti istifadə edə bilər (bloklamamısınızsa). <ph name="BEGIN_LINK" />Ətraflı məlumat<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Seriya portu tapılmadı</translation> -<translation id="1863207472175483351">quraşdırılır…</translation> <translation id="1864111464094315414">Daxil olun</translation> <translation id="1864400682872660285">Daha soyuq</translation> <translation id="1864454756846565995">USB-C cihazı (arxa port)</translation> @@ -5111,7 +5110,6 @@ <translation id="4988526792673242964">Səhifələr</translation> <translation id="49896407730300355">Saat əqrəbi istiqaməti əksinə fırladın</translation> <translation id="4989966318180235467">Nəzərdən keçirmə və fon səhifəsi</translation> -<translation id="4990949771467040994">gözləyir...</translation> <translation id="4991420928586866460">Üst sıra açarlarını funksiya açarları hesab edin</translation> <translation id="4992458225095111526">Sıfırlamanı təsdiq edin</translation> <translation id="4992473555164495036">Administrator əlçatan giriş üsullarını məhdudlaşdırdı.</translation>
diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb index a576877..49aef47 100644 --- a/chrome/app/resources/generated_resources_be.xtb +++ b/chrome/app/resources/generated_resources_be.xtb
@@ -1133,7 +1133,6 @@ <translation id="1862311223300693744">Ці ўсталявана ў вас якое-небудзь спецыяльнае праграмнае забеспячэнне VPN, проксі-сервера, брандмаўара або NAS?</translation> <translation id="1863047423483329595">Абарона ад адсочвання часова недаступная. Пакуль гэта функцыя ў Chrome абнаўляецца, сайтам часова дазваляецца выкарыстоўваць староннія файлы cookie, калі вы не забароніце іх выкарыстанне. <ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Паслядоўныя парты не знойдзены</translation> -<translation id="1863207472175483351">Ідзе ўсталяванне...</translation> <translation id="1864111464094315414">Уваход</translation> <translation id="1864400682872660285">Халадней</translation> <translation id="1864454756846565995">Прылада USB-C (порт ззаду)</translation> @@ -5113,7 +5112,6 @@ <translation id="4988526792673242964">Старонкі</translation> <translation id="49896407730300355">Павярнуць су&праць гадзіннікавай стрэлкі</translation> <translation id="4989966318180235467">Праглядзець &фонавую старонку</translation> -<translation id="4990949771467040994">Чакаецца ўсталяванне...</translation> <translation id="4991420928586866460">Выкарыстоўваць клавішы верхняга рада як функцыянальныя клавішы</translation> <translation id="4992458225095111526">Пацвердзіць скід з дапамогай Powerwash</translation> <translation id="4992473555164495036">Ваш адміністратар абмежаваў даступныя метады ўводу.</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 52d770b..90b63be 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -1138,7 +1138,6 @@ мрежово хранилище (NAS)?</translation> <translation id="1863047423483329595">Функцията за защита от проследяване временно не е налице. Докато Chrome я актуализира, сайтовете могат временно да използват „бисквитки“ на трети страни, освен ако не ги блокирате. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Няма намерени серийни портове</translation> -<translation id="1863207472175483351">инсталира се...</translation> <translation id="1864111464094315414">Вход</translation> <translation id="1864400682872660285">По-студени цветове</translation> <translation id="1864454756846565995">USB-C устройство (задният порт)</translation> @@ -5128,7 +5127,6 @@ <translation id="4988526792673242964">Страници</translation> <translation id="49896407730300355">Завъртане о&братно на часовниковата стрелка</translation> <translation id="4989966318180235467">Инспектиране на &фоновата страница</translation> -<translation id="4990949771467040994">изчаква се...</translation> <translation id="4991420928586866460">Третиране на клавишите от най-горния ред като функционални</translation> <translation id="4992458225095111526">Потвърждаване на извършването на Powerwash</translation> <translation id="4992473555164495036">Администраторът ви е ограничил наличните методи на въвеждане.</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index 57f007ef..a9554501b 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -1143,7 +1143,6 @@ ইনস্টল করে রেখেছেন?</translation> <translation id="1863047423483329595">সুরক্ষা ট্র্যাক করার সুবিধা সাময়িকভাবে উপলভ্য নেই। Chrome এই ফিচার আপডেট করার সময়, আপনি থার্ড-পার্টি কুকি ব্লক না করা পর্যন্ত সাইট তা অস্থায়ীভাবে ব্যবহার করতে পারে। <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" /></translation> <translation id="1863182668524159459">কোনও সিরিয়াল পোর্ট পাওয়া যায়নি</translation> -<translation id="1863207472175483351">ইনস্টল করা হচ্ছে...</translation> <translation id="1864111464094315414">লগ-ইন করুন</translation> <translation id="1864400682872660285">কুলার</translation> <translation id="1864454756846565995">USB-C ডিভাইস (পিছনের পোর্ট)</translation> @@ -5132,7 +5131,6 @@ <translation id="4988526792673242964">পৃষ্ঠাসমূহ</translation> <translation id="49896407730300355">ঘড়ির কাঁটার &বিপরীত দিকে ঘোরান</translation> <translation id="4989966318180235467">&পশ্চাদপট পৃষ্ঠা পরিদর্শন করুন</translation> -<translation id="4990949771467040994">অপেক্ষা করা হচ্ছে...</translation> <translation id="4991420928586866460">উপরের-সারির কীগুলিকে ফাংশন কী হিসেবে ব্যবহার করুন</translation> <translation id="4992458225095111526">পাওয়ারওয়াশ নিশ্চিত করুন</translation> <translation id="4992473555164495036">আপনার অ্যাডমিনিস্ট্রেটর উপলভ্য ইনপুট পদ্ধতিগুলি সীমাবদ্ধ করেছেন।</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb index a88a52c..cfdb6c8 100644 --- a/chrome/app/resources/generated_resources_bs.xtb +++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -1141,7 +1141,6 @@ ili NAS?</translation> <translation id="1863047423483329595">Zaštita od praćenja privremeno nije dostupna. Dok Chrome ažurira ovu funkciju, web lokacije mogu privremeno koristiti kolačiće trećih strana ako ih ne blokirate. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nije pronađen nijedan serijski priključak</translation> -<translation id="1863207472175483351">instaliranje…</translation> <translation id="1864111464094315414">Prijava</translation> <translation id="1864400682872660285">Hladnije</translation> <translation id="1864454756846565995">USB-C uređaj (stražnji priključak)</translation> @@ -5130,7 +5129,6 @@ <translation id="4988526792673242964">Stranice</translation> <translation id="49896407730300355">Rotiraj u smjeru suprotnom od k&azaljke na satu</translation> <translation id="4989966318180235467">Pregledaj stranicu u &pozadini</translation> -<translation id="4990949771467040994">čekanje…</translation> <translation id="4991420928586866460">Tretirajte tipke u gornjem redu kao funkcijske tipke</translation> <translation id="4992458225095111526">Potvrdi Powerwash</translation> <translation id="4992473555164495036">Vaš administrator je ograničio dostupne načine unosa.</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index fe4884e..240a4883 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Tens instal·lat cap servidor intermediari, VPN, tallafoc o programari de NAS?</translation> <translation id="1863047423483329595">Protecció antiseguiment no està disponible temporalment. Mentre Chrome està actualitzant aquesta funció, els llocs web poden utilitzar temporalment galetes de tercers, tret que les bloquegis. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation> <translation id="1863182668524159459">No s'ha trobat cap port en sèrie</translation> -<translation id="1863207472175483351">s'està instal·lant...</translation> <translation id="1864111464094315414">Inicia la sessió</translation> <translation id="1864400682872660285">Més fred</translation> <translation id="1864454756846565995">Dispositiu USB-C (port posterior)</translation> @@ -5114,7 +5113,6 @@ <translation id="4988526792673242964">Pàgines</translation> <translation id="49896407730300355">Gira en el sentit con&trari a les agulles del rellotge</translation> <translation id="4989966318180235467">Inspecciona la &pàgina de fons</translation> -<translation id="4990949771467040994">s'està esperant…</translation> <translation id="4991420928586866460">Tracta les tecles de la fila superior com a tecles de funció</translation> <translation id="4992458225095111526">Confirmació de Powerwash</translation> <translation id="4992473555164495036">L'administrador ha limitat els mètodes d'entrada disponibles.</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index 000c70e..4f97470 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">Používáte zvláštní VPN, proxy, firewall nebo software NAS?</translation> <translation id="1863047423483329595">Ochrana před sledováním momentálně není k dispozici. Zatímco Chrome tuto funkci aktualizuje, weby mohou dočasně používat soubory cookie třetích stran, pokud je nezablokujete. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nebyly nalezeny žádné sériové porty</translation> -<translation id="1863207472175483351">instalace…</translation> <translation id="1864111464094315414">Přihlásit</translation> <translation id="1864400682872660285">Studenější</translation> <translation id="1864454756846565995">Zařízení USB Type-C (zadní port)</translation> @@ -5115,7 +5114,6 @@ <translation id="4988526792673242964">Stránky</translation> <translation id="49896407730300355">Otočit &proti směru hodinových ručiček</translation> <translation id="4989966318180235467">Prozkoumat stránku na &pozadí</translation> -<translation id="4990949771467040994">čekání…</translation> <translation id="4991420928586866460">Považovat klávesy v horní řadě za funkční klávesy</translation> <translation id="4992458225095111526">Potvrdit obnovení pomocí funkce Powerwash</translation> <translation id="4992473555164495036">Administrátor omezil dostupné metody zadávání.</translation>
diff --git a/chrome/app/resources/generated_resources_cy.xtb b/chrome/app/resources/generated_resources_cy.xtb index 0ddd2404..b2f56f1 100644 --- a/chrome/app/resources/generated_resources_cy.xtb +++ b/chrome/app/resources/generated_resources_cy.xtb
@@ -1145,7 +1145,6 @@ wedi'i gosod?</translation> <translation id="1863047423483329595">Nid yw Diogelwch Olrhain ar gael ar hyn o bryd. Tra bod Chrome yn diweddaru'r nodwedd hon, gall gwefannau ddefnyddio cwcis trydydd parti dros dro oni bai eich bod yn eu rhwystro. <ph name="BEGIN_LINK" />Dysgu rhagor<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Ni chanfuwyd unrhyw byrth cyfresol</translation> -<translation id="1863207472175483351">wrthi'n gosod...</translation> <translation id="1864111464094315414">Mewngofnodi</translation> <translation id="1864400682872660285">Oerach</translation> <translation id="1864454756846565995">Dyfais USB-C (porth cefn)</translation> @@ -1862,6 +1861,7 @@ <translation id="2402226831639195063">Tonau</translation> <translation id="2405887402346713222">Rhifau Cyfresol Dyfais a Chydrannau</translation> <translation id="2406153734066939945">Dileu'r proffil hwn a'i ddata?</translation> +<translation id="2407671304279211586">Dewis darparwr DNS</translation> <translation id="2408018932941436077">Wrthi'n cadw cerdyn</translation> <translation id="2408955596600435184">Rhowch eich PIN</translation> <translation id="2409268599591722235">I ffwrdd â ni</translation> @@ -5133,7 +5133,6 @@ <translation id="4988526792673242964">Tudalennau</translation> <translation id="49896407730300355">Cylchdroi yn w&rthglocwedd</translation> <translation id="4989966318180235467">Archwilio'r &dudalen gefndir</translation> -<translation id="4990949771467040994">wrthi'n aros...</translation> <translation id="4991420928586866460">Trin bysellau ar y rhes uchaf fel bysellau swyddogaeth</translation> <translation id="4992458225095111526">Cadarnhau Powerwash</translation> <translation id="4992473555164495036">Mae eich gweinyddwr wedi cyfyngu'r dulliau mewnbynnu sydd ar gael.</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index 552d932..60a5738 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -1143,7 +1143,6 @@ NAS-software?</translation> <translation id="1863047423483329595">Sporingsbeskyttelse er ikke tilgængelig i øjeblikket. Mens Chrome opdaterer denne funktion, kan websites midlertidigt bruge tredjepartscookies, medmindre du blokerer dem. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Der blev ikke fundet nogen serieporte</translation> -<translation id="1863207472175483351">installerer…</translation> <translation id="1864111464094315414">Login</translation> <translation id="1864400682872660285">Kølig</translation> <translation id="1864454756846565995">USB-C-enhed (port bagpå)</translation> @@ -1860,6 +1859,7 @@ <translation id="2402226831639195063">Toner</translation> <translation id="2405887402346713222">Enheds- og komponentserienumre</translation> <translation id="2406153734066939945">Vil du slette denne profil og de tilhørende data?</translation> +<translation id="2407671304279211586">Vælg DNS-udbyder</translation> <translation id="2408018932941436077">Gemmer kort</translation> <translation id="2408955596600435184">Angiv din pinkode</translation> <translation id="2409268599591722235">Start</translation> @@ -5131,7 +5131,6 @@ <translation id="4988526792673242964">Sider</translation> <translation id="49896407730300355">Roter m&od uret</translation> <translation id="4989966318180235467">Undersøg &baggrundsside</translation> -<translation id="4990949771467040994">venter…</translation> <translation id="4991420928586866460">Brug tasterne på øverste række som funktionstaster</translation> <translation id="4992458225095111526">Bekræft Powerwash</translation> <translation id="4992473555164495036">Din administrator har begrænset de tilgængelige indtastningsmetoder.</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index 09b646e7..67d4a36 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">Hast du ein spezielles VPN, einen speziellen Proxy oder eine spezielle Firewall- oder NAS-Software installiert?</translation> <translation id="1863047423483329595">Der Schutz vor Tracking ist vorübergehend nicht verfügbar. Während Chrome diese Funktion aktualisiert, können Websites vorübergehend Drittanbieter-Cookies verwenden, sofern du diese nicht blockierst. <ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Keine seriellen Schnittstellen gefunden</translation> -<translation id="1863207472175483351">Installation läuft…</translation> <translation id="1864111464094315414">Anmeldung</translation> <translation id="1864400682872660285">Kälter</translation> <translation id="1864454756846565995">USB-C-Gerät (Port hinten)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">Seiten</translation> <translation id="49896407730300355">&Gegen den Uhrzeigersinn drehen</translation> <translation id="4989966318180235467">&Hintergrundseite prüfen</translation> -<translation id="4990949771467040994">Warten…</translation> <translation id="4991420928586866460">Tasten der obersten Reihe als Funktionstasten nutzen</translation> <translation id="4992458225095111526">Powerwash bestätigen</translation> <translation id="4992473555164495036">Dein Administrator hat die verfügbaren Eingabemethoden eingeschränkt.</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 9f9b0fd..2bcd080 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -1142,7 +1142,6 @@ NAS;</translation> <translation id="1863047423483329595">Η Προστασία από παρακολούθηση δεν είναι διαθέσιμη προσωρινά. Ενώ το Chrome ενημερώνει αυτή τη λειτουργία, οι ιστότοποι μπορούν να χρησιμοποιήσουν προσωρινά cookie τρίτου μέρους, εκτός εάν τα αποκλείσετε. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Δεν βρέθηκαν σειριακές θύρες</translation> -<translation id="1863207472175483351">εγκατάσταση…</translation> <translation id="1864111464094315414">Σύνδεση</translation> <translation id="1864400682872660285">Ψυχρότερο</translation> <translation id="1864454756846565995">Συσκευή USB-C (πίσω θύρα)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">Σελίδες</translation> <translation id="49896407730300355">Περιστροφή προς τα &αριστερά</translation> <translation id="4989966318180235467">Έλεγχος &σελίδας παρασκηνίου</translation> -<translation id="4990949771467040994">αναμονή…</translation> <translation id="4991420928586866460">Χρήση πλήκτρων πρώτης σειράς ως πλήκτρων ενεργειών</translation> <translation id="4992458225095111526">Επιβεβαίωση Powerwash</translation> <translation id="4992473555164495036">Ο διαχειριστής σας περιόρισε τις διαθέσιμες μεθόδους εισαγωγής.</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index ad91bba..2464b00 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -1142,7 +1142,6 @@ installed?</translation> <translation id="1863047423483329595">Tracking Protection is temporarily unavailable. While Chrome is updating this feature, sites can temporarily use third-party cookies unless you block them. <ph name="BEGIN_LINK" />Learn more<ph name="END_LINK" /></translation> <translation id="1863182668524159459">No serial ports found</translation> -<translation id="1863207472175483351">installing...</translation> <translation id="1864111464094315414">Login</translation> <translation id="1864400682872660285">Cooler</translation> <translation id="1864454756846565995">USB-C device (rear port)</translation> @@ -2691,6 +2690,7 @@ <translation id="3021065318976393105">While on battery</translation> <translation id="3021066826692793094">Butterfly</translation> <translation id="3021678814754966447">&View Frame Source</translation> +<translation id="3021902017511220299">Scan failed. This action is blocked by your administrator.</translation> <translation id="3022361196600037287"><ph name="DEVICE" /> will be removed from this Chromebook and won’t be saved to <ph name="PRIMARY_EMAIL" />.</translation> <translation id="3022978424994383087">Didn't get that.</translation> <translation id="3023464535986383522">Select to speak</translation> @@ -5131,7 +5131,6 @@ <translation id="4988526792673242964">Pages</translation> <translation id="49896407730300355">Rotate a&nti-clockwise</translation> <translation id="4989966318180235467">Inspect &background page</translation> -<translation id="4990949771467040994">waiting...</translation> <translation id="4991420928586866460">Treat top-row keys as function keys</translation> <translation id="4992458225095111526">Confirm Powerwash</translation> <translation id="4992473555164495036">Your administrator has limited the available input methods.</translation> @@ -9063,6 +9062,7 @@ <translation id="811994229154425014">Double-space to type full stop</translation> <translation id="8120505434908124087">Install eSIM profile</translation> <translation id="8121750884985440809">You are currently casting your screen.</translation> +<translation id="8122898034710982882">Phone Hub, <ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">Yellow and white flower</translation> <translation id="8123975449645947908">Scroll backwards</translation> <translation id="8124313775439841391">Managed ONC</translation> @@ -9098,6 +9098,7 @@ <translation id="8148760431881541277">Limit sign-in</translation> <translation id="8149564499626272569">Verify via your phone with a USB cable</translation> <translation id="8149870652370242480">To use your saved passwords on your phone, download Chrome for iOS and sign in to your Google Account.</translation> +<translation id="8151057139207656239">Copied build details</translation> <translation id="815114315010033526">Use QR code instead</translation> <translation id="8151638057146502721">Configure</translation> <translation id="8154790740888707867">No file</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 2e27a2e..b45a4eb 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">¿Tienes instalado algún tipo especial de software NAS, firewall, proxy o red VPN?</translation> <translation id="1863047423483329595">La Protección contra seguimiento no está disponible en este momento. Mientras Chrome actualiza esta función, los sitios pueden usar cookies de terceros de forma temporal, a menos que las bloquees. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="1863182668524159459">No se encontraron puertos en serie</translation> -<translation id="1863207472175483351">instalando…</translation> <translation id="1864111464094315414">Acceder</translation> <translation id="1864400682872660285">Frío</translation> <translation id="1864454756846565995">Dispositivo USB-C (puerto trasero)</translation> @@ -5111,7 +5110,6 @@ <translation id="4988526792673242964">Páginas</translation> <translation id="49896407730300355">Girar &a la izquierda</translation> <translation id="4989966318180235467">Inspeccionar página &de fondo</translation> -<translation id="4990949771467040994">esperando…</translation> <translation id="4991420928586866460">Tratar las teclas de la fila superior como teclas de función</translation> <translation id="4992458225095111526">Confirmar Powerwash</translation> <translation id="4992473555164495036">Tu administrador limitó los métodos de entrada disponibles.</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index 30f5db3..ecae818d 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">¿Tienes instalado algún software especial de VPN, proxy, cortafuegos o NAS?</translation> <translation id="1863047423483329595">La Protección Antirrastreo no está disponible temporalmente. Mientras Chrome actualiza esta función, los sitios podrán usar cookies de terceros de forma temporal a menos que las bloquees. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="1863182668524159459">No se ha encontrado ningún puerto serie</translation> -<translation id="1863207472175483351">instalando…</translation> <translation id="1864111464094315414">Inicio de sesión</translation> <translation id="1864400682872660285">Más frío</translation> <translation id="1864454756846565995">Dispositivo USB-C (puerto trasero)</translation> @@ -5115,7 +5114,6 @@ <translation id="4988526792673242964">Páginas</translation> <translation id="49896407730300355">Girar a la &izquierda</translation> <translation id="4989966318180235467">Inspeccionar página &en segundo plano</translation> -<translation id="4990949771467040994">esperando…</translation> <translation id="4991420928586866460">Tratar las teclas de la fila superior como teclas de función</translation> <translation id="4992458225095111526">Confirmar Powerwash</translation> <translation id="4992473555164495036">Tu administrador ha limitado los métodos de introducción disponibles.</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index ce4ae85..ab16956 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -1133,7 +1133,6 @@ <translation id="1862311223300693744">Kas olete installinud spetsiaalse VPN-i, puhverserveri, tulemüüri või NAS-i tarkvara?</translation> <translation id="1863047423483329595">Jälgimiskaitse pole ajutiselt saadaval. Kui Chrome seda funktsiooni värskendab, saavad saidid ajutiselt kasutada kolmanda osapoole küpsisefaile (v.a juhul, kui need blokeerite). <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Jadaporte ei leitud</translation> -<translation id="1863207472175483351">Installimine …</translation> <translation id="1864111464094315414">Sisselogimine</translation> <translation id="1864400682872660285">Külmem</translation> <translation id="1864454756846565995">C-tüüpi USB-seade (tagumine port)</translation> @@ -1850,6 +1849,7 @@ <translation id="2402226831639195063">Toonid</translation> <translation id="2405887402346713222">Seadme ja selle komponentide seerianumbrid</translation> <translation id="2406153734066939945">Kas kustutada see profiil ja selle andmed?</translation> +<translation id="2407671304279211586">Valige DNS-i pakkuja</translation> <translation id="2408018932941436077">Kaardi salvestamine</translation> <translation id="2408955596600435184">Sisestage PIN-kood</translation> <translation id="2409268599591722235">Alusta</translation> @@ -5120,7 +5120,6 @@ <translation id="4988526792673242964">Leheküljed</translation> <translation id="49896407730300355">Pööra &vastupäeva</translation> <translation id="4989966318180235467">Uuri &taustalehte</translation> -<translation id="4990949771467040994">ootel …</translation> <translation id="4991420928586866460">Kasuta ülarea klahve funktsiooniklahvidena</translation> <translation id="4992458225095111526">Powerwashi kinnitamine</translation> <translation id="4992473555164495036">Administraator on saadaolevaid sisestusmeetodeid piiranud.</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index 78bb4231..c5b85dba 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Ba al duzu VPN, proxy, suebaki edo NAS software berezirik instalatuta?</translation> <translation id="1863047423483329595">Jarraipenaren aurkako babesa ez dago erabilgarri aldi baterako. Chrome eginbide hau eguneratzen ari den bitartean, webguneek hirugarrenen cookieak erabil ditzakete aldi baterako, haiek blokeatu ezean. <ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Ez da aurkitu serieko atakarik</translation> -<translation id="1863207472175483351">instalatzen…</translation> <translation id="1864111464094315414">Hasi saioa</translation> <translation id="1864400682872660285">Hotzagoa</translation> <translation id="1864454756846565995">USB-C gailua (atzealdeko ataka)</translation> @@ -5114,7 +5113,6 @@ <translation id="4988526792673242964">Orriak</translation> <translation id="49896407730300355">Biratu e&rlojuaren orratzen aurka</translation> <translation id="4989966318180235467">Ikuskatu &atzeko planoko orria</translation> -<translation id="4990949771467040994">zain…</translation> <translation id="4991420928586866460">Tratatu goiko errenkadako teklak funtzio-tekla gisa</translation> <translation id="4992458225095111526">Berretsi fabrikako ezarpenak Powerwash bidez berrezarri nahi dituzula</translation> <translation id="4992473555164495036">Administratzaileak erabil ditzakezun idazketa-metodoak mugatu ditu.</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index b1d1835..ef5300e 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -1139,7 +1139,6 @@ <translation id="1862311223300693744">آیا نرمافزار VPN، پراکسی، دیوار آتش، یا NAS خاصی نصب کردهاید؟</translation> <translation id="1863047423483329595">«محافظت دربرابر ردیابی» موقتاً دردسترس نیست. وقتی Chrome درحال بهروزرسانی این ویژگی است، سایتها میتوانند موقتاً از کوکیهای شخص ثالث استفاده کنند، مگر اینکه آنها را مسدود کنید. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation> <translation id="1863182668524159459">درگاه سریالی یافت نشد</translation> -<translation id="1863207472175483351">درحال نصب…</translation> <translation id="1864111464094315414">ورود به سیستم</translation> <translation id="1864400682872660285">سردتر</translation> <translation id="1864454756846565995">دستگاه USB-C (درگاه عقب)</translation> @@ -5128,7 +5127,6 @@ <translation id="4988526792673242964">صفحات</translation> <translation id="49896407730300355">چرخاندن خلاف جهت ع&قربههای ساعت</translation> <translation id="4989966318180235467">بازرسی صفحه &پسزمینه</translation> -<translation id="4990949771467040994">درانتظار…</translation> <translation id="4991420928586866460">در نظر گرفتن کلیدهای ردیف بالا به عنوان کلیدهای عملکرد</translation> <translation id="4992458225095111526">تأیید Powerwash</translation> <translation id="4992473555164495036">سرپرست سیستم روشهای ورودی دردسترس را محدود کرده است.</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index c6abf05..3e036058 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -1141,7 +1141,6 @@ NAS-ohjelmistoja?</translation> <translation id="1863047423483329595">Seurannan esto on tilapäisesti poissa käytöstä Kun Chrome päivittää ominaisuutta, sivustot voivat tilapäisesti käyttää kolmannen osapuolen evästeitä, ellet estä niitä. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Sarjaportteja ei löytynyt</translation> -<translation id="1863207472175483351">asennetaan…</translation> <translation id="1864111464094315414">Kirjaudu</translation> <translation id="1864400682872660285">Viileä</translation> <translation id="1864454756846565995">C-tyypin USB-laite (takaportti)</translation> @@ -1858,6 +1857,7 @@ <translation id="2402226831639195063">Toonit</translation> <translation id="2405887402346713222">Laitteen ja osien sarjanumerot</translation> <translation id="2406153734066939945">Poistetaanko tämä profiili ja sen data?</translation> +<translation id="2407671304279211586">Valitse DNS-tarjoaja</translation> <translation id="2408018932941436077">Tallennetaan korttia</translation> <translation id="2408955596600435184">Lisää PIN-koodi</translation> <translation id="2409268599591722235">Aloitetaan</translation> @@ -5126,7 +5126,6 @@ <translation id="4988526792673242964">Sivut</translation> <translation id="49896407730300355">Käännä &vastapäivään</translation> <translation id="4989966318180235467">Tarkista &taustasivu</translation> -<translation id="4990949771467040994">odottaa…</translation> <translation id="4991420928586866460">Käytä ylärivin näppäimiä toimintanäppäiminä</translation> <translation id="4992458225095111526">Vahvista powerwash</translation> <translation id="4992473555164495036">Järjestelmänvalvoja on rajoittanut syöttötapoja.</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index a4b9973c..29bd5b1 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -685,6 +685,7 @@ <translation id="1536754031901697553">Nagdidiskonekta...</translation> <translation id="1537254971476575106">Fullscreen magnifier</translation> <translation id="15373452373711364">Malaking mouse cursor</translation> +<translation id="1539727654733007771">Walang naka-set up na mobile network. Mag-download ng bagong <ph name="BEGIN_LINK" />profile.<ph name="END_LINK" /></translation> <translation id="1540265419569299117">Serbisyo ng App ng ChromeOS</translation> <translation id="1540605929960647700">I-enable ang demo mode</translation> <translation id="1541346352678737112">Walang nakitang network</translation> @@ -1143,7 +1144,6 @@ na naka-install?</translation> <translation id="1863047423483329595">Pansamantalang hindi available ang Proteksyon sa Pag-track. Habang ina-update ng Chrome ang feature na ito, pansamantalang makakagamit ang mga site ng third-party na cookies maliban na lang kung iba-block mo ang mga ito. <ph name="BEGIN_LINK" />Matuto pa<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Walang nakitang serial port</translation> -<translation id="1863207472175483351">ini-install...</translation> <translation id="1864111464094315414">Mag-login</translation> <translation id="1864400682872660285">Cooler</translation> <translation id="1864454756846565995">USB-C device (port sa rear)</translation> @@ -1264,6 +1264,7 @@ <translation id="1951012854035635156">Assistant</translation> <translation id="1954597385941141174">Puwedeng hilingin ng mga site na kumonekta sa mga USB device</translation> <translation id="1954813140452229842">Nagka-error sa pag-mount ng share. Pakitingnan ang iyong mga kredensyal at subukan ulit.</translation> +<translation id="1955313993396968525">Hanapin ang frame ng video gamit ang <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="1956050014111002555">Naglaman ang file ng maraming certificate, wala sa mga ito ang na-import:</translation> <translation id="1956167375087861299">Hindi pinapayagang gumamit ng mga identifier para mag-play ng pinoprotektahang content</translation> <translation id="1956390763342388273">Ia-upload nito ang lahat ng file mula sa "<ph name="FOLDER_PATH" />." Gawin lang ito kung pinagkakatiwalaan mo ang site.</translation> @@ -1837,6 +1838,7 @@ <translation id="237828693408258535">I-translate ang page na ito?</translation> <translation id="2378982052244864789">Piliin ang direktoryo ng extension.</translation> <translation id="2379281330731083556">I-print gamit ang dialog ng system... <ph name="SHORTCUT_KEY" /></translation> +<translation id="2381461748765773292">Posibleng madiskonekta ang iyong mobile network nang ilang minuto dahil dito</translation> <translation id="2381499968174336913">Preview ng nakabahaging tab</translation> <translation id="2382875860893882175">Kasalukuyang naka-pause ang pag-cast. Puwede mong ituloy ang pag-cast o ihinto ang pag-cast sa anumang oras.</translation> <translation id="2383825469508278924">Baguhin ang pagmamapa ng key ng keyboard, mga function key, at higit pa</translation> @@ -5132,7 +5134,6 @@ <translation id="4988526792673242964">Mga Page</translation> <translation id="49896407730300355">I-rotate p&akaliwa</translation> <translation id="4989966318180235467">Siyasatin ang pahina ng &background</translation> -<translation id="4990949771467040994">naghihintay…</translation> <translation id="4991420928586866460">Ituring ang mga top-row key bilang mga function key</translation> <translation id="4992458225095111526">Kumpirmahin ang Powerwash</translation> <translation id="4992473555164495036">Nilimitahan ng iyong administrator ang mga available na pamamaraan ng pag-input.</translation> @@ -6799,6 +6800,7 @@ <translation id="6344576354370880196">Mga naka-save na printer</translation> <translation id="6344608411615208519"><ph name="BEGIN_LINK" />Pinapamahalaan ang iyong browser<ph name="END_LINK" /> ng magulang mo</translation> <translation id="6344622098450209924">Proteksyon sa Pag-track</translation> +<translation id="6345203628032613660">Hanapin ang Frame ng Video gamit ang <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="6345418402353744910">Kailangan ang iyong username at password para sa proxy na <ph name="PROXY" /> para ma-configure ng admin ang network mo</translation> <translation id="6345566021391290381">May mga password na na-share sa iyo para sa <ph name="WEBSITE_NAME" />. Puwede mong gamitin ang mga ito sa form sa pag-sign in.</translation> <translation id="6345878117466430440">Markahang nabasa na</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb index 8b77c4d..8973911 100644 --- a/chrome/app/resources/generated_resources_fr-CA.xtb +++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -1131,7 +1131,6 @@ <translation id="1862311223300693744">Avez-vous installé un RPV, un mandataire, un pare-feu ou un logiciel pour serveur de stockage NAS?</translation> <translation id="1863047423483329595">La protection contre le suivi est temporairement inaccessible. Pendant que Chrome met à jour cette fonctionnalité, les sites peuvent temporairement utiliser des témoins tiers, sauf si vous les bloquez. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Aucun port série n'a été trouvé</translation> -<translation id="1863207472175483351">installation en cours…</translation> <translation id="1864111464094315414">Connexion</translation> <translation id="1864400682872660285">Plus froid</translation> <translation id="1864454756846565995">Appareil USB-C (port arrière)</translation> @@ -5116,7 +5115,6 @@ <translation id="4988526792673242964">Pages</translation> <translation id="49896407730300355">Rotation dans le sens antih&oraire</translation> <translation id="4989966318180235467">Inspecter la page d'&arrière-plan</translation> -<translation id="4990949771467040994">en attente…</translation> <translation id="4991420928586866460">Considérer les touches de la rangée supérieure comme des touches de fonction</translation> <translation id="4992458225095111526">Confirmer la fonctionnalité Powerwash</translation> <translation id="4992473555164495036">Votre administrateur a limité les méthodes d'entrée disponibles.</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index 056b9d3..69bc83e 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -1131,7 +1131,6 @@ <translation id="1862311223300693744">Avez-vous installé un VPN, un proxy, un pare-feu ou un serveur NAS spécifique ?</translation> <translation id="1863047423483329595">La Protection contre le suivi est temporairement indisponible. Pendant que Chrome met à jour cette fonctionnalité, les sites peuvent utiliser temporairement des cookies tiers, sauf si vous les bloquez. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Ports série introuvables</translation> -<translation id="1863207472175483351">installation...</translation> <translation id="1864111464094315414">Connexion</translation> <translation id="1864400682872660285">Plus froid</translation> <translation id="1864454756846565995">Appareil USB de type C (port situé sur l'arrière de l'appareil)</translation> @@ -5115,7 +5114,6 @@ <translation id="4988526792673242964">Pages</translation> <translation id="49896407730300355">Rotation &antihoraire</translation> <translation id="4989966318180235467">Inspecter la page d'&arrière-plan</translation> -<translation id="4990949771467040994">en attente...</translation> <translation id="4991420928586866460">Considérer les touches de la rangée supérieure comme des touches de fonction</translation> <translation id="4992458225095111526">Confirmer la réinitialisation Powerwash</translation> <translation id="4992473555164495036">Votre administrateur a limité les modes de saisie disponibles.</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb index 440ff84..dd334a9 100644 --- a/chrome/app/resources/generated_resources_gl.xtb +++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -1129,7 +1129,6 @@ <translation id="1862311223300693744">Tes algún proxy, VPN, firewall ou software NAS especial instalado?</translation> <translation id="1863047423483329595">A protección contra o seguimento non está dispoñible temporalmente. Mentres Chrome actualiza esta función, os sitios poden usar temporalmente cookies de terceiros, a menos que as bloquees na configuración. <ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Non se encontrou ningún porto de serie</translation> -<translation id="1863207472175483351">instalando…</translation> <translation id="1864111464094315414">Inicio de sesión</translation> <translation id="1864400682872660285">Cores máis frías</translation> <translation id="1864454756846565995">Dispositivo USB‑C (porto posterior)</translation> @@ -1843,6 +1842,7 @@ <translation id="2402226831639195063">Tons</translation> <translation id="2405887402346713222">Números de serie do dispositivo e dos compoñentes</translation> <translation id="2406153734066939945">Querer borrar este perfil e os seus datos?</translation> +<translation id="2407671304279211586">Seleccionar fornecedor de DNS</translation> <translation id="2408018932941436077">Gardando tarxeta</translation> <translation id="2408955596600435184">Introduce o PIN</translation> <translation id="2409268599591722235">Vamos aló</translation> @@ -5116,7 +5116,6 @@ <translation id="4988526792673242964">Páxinas</translation> <translation id="49896407730300355">Xirar cara á es&querda</translation> <translation id="4989966318180235467">Inspeccionar &páxina en segundo plano</translation> -<translation id="4990949771467040994">agardando…</translation> <translation id="4991420928586866460">Tratar as teclas da fila superior como teclas de función</translation> <translation id="4992458225095111526">Confirmar powerwash</translation> <translation id="4992473555164495036">O administrador limitou os métodos de introdución de texto dispoñibles.</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index 18f25822..e73b96a 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">શું તમે કોઈ વિશિષ્ટ VPN, પ્રૉક્સી, ફાયરવૉલ અથવા NAS સૉફ્ટવેર ઇન્સ્ટૉલ કરેલું છે?</translation> <translation id="1863047423483329595">ટ્રૅકિંગ સંબંધિત સુરક્ષાની સુવિધા હંગામી રીતે ઉપલબ્ધ નથી. જ્યારે Chrome આ સુવિધા અપડેટ કરી રહ્યું હોય, ત્યારે સાઇટ હંગામી રીતે ત્રીજા પક્ષની કુકીનો ઉપયોગ કરી શકે છે સિવાય કે તમે તેને બ્લૉક કરો. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation> <translation id="1863182668524159459">કોઈ સીરિયલ પોર્ટ મળ્યાં નથી</translation> -<translation id="1863207472175483351">ઇન્સ્ટૉલ કરી રહ્યાં છીએ…</translation> <translation id="1864111464094315414">લૉગિન</translation> <translation id="1864400682872660285">કૂલર</translation> <translation id="1864454756846565995">USB-C ઉપકરણ (પાછળનું પોર્ટ)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">પેજ</translation> <translation id="49896407730300355">ઘ&ડિયાળની વિપરિત દિશામાં ફેરવો</translation> <translation id="4989966318180235467">&બૅકગ્રાઉન્ડ પેજની તપાસ કરો</translation> -<translation id="4990949771467040994">રાહ જોઈ રહ્યાં છીએ…</translation> <translation id="4991420928586866460">શીર્ષ-પંક્તિની કીઝને ફંક્શન કીઝ તરીકે ધ્યાનમાં લો</translation> <translation id="4992458225095111526">Powerwash ની પુષ્ટિ કરો</translation> <translation id="4992473555164495036">તમારા વ્યવસ્થાપકે ઉપલબ્ધ ઇનપુટ પદ્ધતિઓને મર્યાદિત કરેલ છે.</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index 83a7e66..c0da24b 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -1143,7 +1143,6 @@ इंस्टॉल किया है?</translation> <translation id="1863047423483329595">ट्रैकिंग सुरक्षा की सुविधा कुछ समय के लिए उपलब्ध नहीं है. Chrome इस सुविधा को अपडेट कर रहा है. हालांकि, साइटें कुछ समय के लिए तीसरे पक्ष की कुकी का इस्तेमाल कर सकती हैं. ऐसा तब तक किया जा सकता है, जब तक कि उन्हें ब्लॉक नहीं किया जाता. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation> <translation id="1863182668524159459">काेई सीरियल पाेर्ट नहीं मिला</translation> -<translation id="1863207472175483351">इंस्टॉल हो रहा है...</translation> <translation id="1864111464094315414">लॉगिन करें</translation> <translation id="1864400682872660285">कूलर</translation> <translation id="1864454756846565995">USB-C डिवाइस (पिछला पोर्ट)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">पेज</translation> <translation id="49896407730300355">घड़ी की &विपरीत दिशा में घुमाएं</translation> <translation id="4989966318180235467">निरीक्षण और पेजभूमि पेज</translation> -<translation id="4990949771467040994">इंतज़ार किया जा रहा है...</translation> <translation id="4991420928586866460">शीर्ष पंक्ति कुंजियों को फ़ंक्शन कुंजियों के रूप में मानें</translation> <translation id="4992458225095111526">पावरवॉश की पुष्टि करें</translation> <translation id="4992473555164495036">आपके एडमिन ने इनपुट के उपलब्ध तरीके सीमित किए हुए हैं.</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index a005f2b..7cb2883 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">Jeste li instalirali neki posebni softver VPN-a, proxyja, vatrozida ili NAS-a?</translation> <translation id="1863047423483329595">Zaštita od praćenja privremeno nije dostupna. Dok Chrome ažurira tu značajku, web-lokacije mogu privremeno upotrebljavati kolačiće trećih strana ako ih ne blokirate. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nije pronađen nijedan serijski priključak</translation> -<translation id="1863207472175483351">instalira se...</translation> <translation id="1864111464094315414">Prijava</translation> <translation id="1864400682872660285">Hladnije</translation> <translation id="1864454756846565995">USB-C uređaj (stražnji priključak)</translation> @@ -5118,7 +5117,6 @@ <translation id="4988526792673242964">Stranice</translation> <translation id="49896407730300355">Zakreni u smjeru suprotnom od &kretanja kazaljke na satu</translation> <translation id="4989966318180235467">Provjeri &pozadinsku stranicu</translation> -<translation id="4990949771467040994">na čekanju…</translation> <translation id="4991420928586866460">Smatraj tipke najvišeg retka funkcijskim tipkama</translation> <translation id="4992458225095111526">Potvrda Powerwasha</translation> <translation id="4992473555164495036">Vaš je administrator ograničio dostupne načine unosa.</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index e3f482e..5f28e5a 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -1141,7 +1141,6 @@ <translation id="1862311223300693744">Rendelkezik telepített speciális VPN-, proxy-, tűzfal- vagy NAS-szoftverrel?</translation> <translation id="1863047423483329595">A Követés elleni védelem átmenetileg nem áll rendelkezésre. Amíg a Chrome frissíti ezt a funkciót, a webhelyek ideiglenesen használhatnak harmadik féltől származó cookie-kat, hacsak Ön le nem tiltja őket. <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation> <translation id="1863182668524159459">Nem található soros port</translation> -<translation id="1863207472175483351">telepítés…</translation> <translation id="1864111464094315414">Bejelentkezés</translation> <translation id="1864400682872660285">Hideg színek</translation> <translation id="1864454756846565995">C típusú USB-vel kompatibilis eszköz (hátsó port)</translation> @@ -1858,6 +1857,7 @@ <translation id="2402226831639195063">Hanglejtés</translation> <translation id="2405887402346713222">Eszköz- és összetevő-sorozatszámok</translation> <translation id="2406153734066939945">Törli ezt a profilt és a hozzá tartozó adatokat?</translation> +<translation id="2407671304279211586">DNS-szolgáltató kiválasztása</translation> <translation id="2408018932941436077">Kártya mentése folyamatban</translation> <translation id="2408955596600435184">PIN-kód megadása</translation> <translation id="2409268599591722235">Rajta</translation> @@ -5128,7 +5128,6 @@ <translation id="4988526792673242964">Oldal</translation> <translation id="49896407730300355">Forgatás &balra</translation> <translation id="4989966318180235467">&Háttéroldal vizsgálata</translation> -<translation id="4990949771467040994">várakozás…</translation> <translation id="4991420928586866460">A legfelső sor billentyűi legyenek funkcióbillentyűk</translation> <translation id="4992458225095111526">Powerwash megerősítése</translation> <translation id="4992473555164495036">A rendszergazda korlátozta a rendelkezésre álló beviteli módokat.</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb index 86887db..550a9ce 100644 --- a/chrome/app/resources/generated_resources_hy.xtb +++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">Ձեր համակարգչում տեղադրվա՞ծ է որևէ հատուկ VPN, պրոքսի, հրապատ կամ NAS ծրագրաշար։</translation> <translation id="1863047423483329595">Հետագծման արգելափակումը ժամանակավորապես անհասանելի է։ Քանի դեռ Chrome-ը թարմացնում է այս գործառույթը, կայքերը կարող են ժամանակավորապես օգտագործել երրորդ կողմի քուքիներ, եթե չարգելափակեք դրանք։ <ph name="BEGIN_LINK" />Իմանալ ավելին<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Հաջորդական միացքներ չեն գտնվել</translation> -<translation id="1863207472175483351">տեղադրում...</translation> <translation id="1864111464094315414">Մուտք</translation> <translation id="1864400682872660285">Սառը</translation> <translation id="1864454756846565995">USB-C սարք (հետևի միացք)</translation> @@ -1846,6 +1845,7 @@ <translation id="2402226831639195063">Տոնային նշաններ</translation> <translation id="2405887402346713222">Սարքի և բաղադրիչների սերիական համարները</translation> <translation id="2406153734066939945">Ջնջե՞լ այս պրոֆիլը և դրա տվյալները</translation> +<translation id="2407671304279211586">Ընտրել DNS ծառայություններ մատուցող</translation> <translation id="2408018932941436077">Քարտը պահվում է</translation> <translation id="2408955596600435184">Մուտքագրեք ձեր PIN կոդը</translation> <translation id="2409268599591722235">Սկսել</translation> @@ -5115,7 +5115,6 @@ <translation id="4988526792673242964">Էջեր</translation> <translation id="49896407730300355">Պտտել ժամացույցի &սլաքին հակառակ</translation> <translation id="4989966318180235467">Հետազոտել &հետնաշերտի էջը</translation> -<translation id="4990949771467040994">սպասեք…</translation> <translation id="4991420928586866460">Դարձնել վերին շարքի ստեղները գործառույթային ստեղներ</translation> <translation id="4992458225095111526">Powerwash-ի հաստատում</translation> <translation id="4992473555164495036">Ադմինիստրատորն սահմանափակել է հասանելի ներածման եղանակները։</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index d2f67dc..f8b07773 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -1142,7 +1142,6 @@ NAS khusus?</translation> <translation id="1863047423483329595">Fitur Anti-Pelacakan tidak tersedia untuk sementara. Saat Chrome sedang mengupdate fitur ini, situs dapat menggunakan cookie pihak ketiga untuk sementara, kecuali jika Anda memblokirnya. <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Port serial tidak ditemukan</translation> -<translation id="1863207472175483351">menginstal...</translation> <translation id="1864111464094315414">Login</translation> <translation id="1864400682872660285">Dingin</translation> <translation id="1864454756846565995">Perangkat USB-C (port belakang)</translation> @@ -1859,6 +1858,7 @@ <translation id="2402226831639195063">Nada</translation> <translation id="2405887402346713222">Nomor Seri Perangkat dan Komponen</translation> <translation id="2406153734066939945">Hapus profil ini dan datanya?</translation> +<translation id="2407671304279211586">Pilih penyedia DNS</translation> <translation id="2408018932941436077">Menyimpan kartu</translation> <translation id="2408955596600435184">Masukkan PIN</translation> <translation id="2409268599591722235">Ayo mulai!</translation> @@ -5130,7 +5130,6 @@ <translation id="4988526792673242964">Halaman</translation> <translation id="49896407730300355">Putar &berlawanan arah jarum jam</translation> <translation id="4989966318180235467">Periksa halaman latar &belakang</translation> -<translation id="4990949771467040994">menunggu...</translation> <translation id="4991420928586866460">Gunakan tombol baris atas sebagai tombol fungsi</translation> <translation id="4992458225095111526">Konfirmasi Powerwash</translation> <translation id="4992473555164495036">Administrator membatasi metode masukan yang tersedia.</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb index 3330578..a425177 100644 --- a/chrome/app/resources/generated_resources_is.xtb +++ b/chrome/app/resources/generated_resources_is.xtb
@@ -1143,7 +1143,6 @@ uppsettan?</translation> <translation id="1863047423483329595">Rakningarvörn er tímabundið ótiltæk. Á meðan Chrome uppfærir þennan eiginleika geta vefsvæði notað fótspor þriðju aðila tímabundið nema lokað sé á þau. <ph name="BEGIN_LINK" />Nánar<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Engin raðtengi fundust</translation> -<translation id="1863207472175483351">setur upp…</translation> <translation id="1864111464094315414">Innskráning</translation> <translation id="1864400682872660285">Kaldara</translation> <translation id="1864454756846565995">USB-C-tæki (tengi að aftan)</translation> @@ -5132,7 +5131,6 @@ <translation id="4988526792673242964">Síður</translation> <translation id="49896407730300355">Snúa rangsælis</translation> <translation id="4989966318180235467">Kanna &bakgrunnssíðu</translation> -<translation id="4990949771467040994">bíður…</translation> <translation id="4991420928586866460">Nota lykla í efstu röð sem aðgerðalykla</translation> <translation id="4992458225095111526">Staðfesta djúphreinsun</translation> <translation id="4992473555164495036">Stjórnandi þinn hefur takmarkað tiltækar innsláttaraðferðir.</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index feba299..e0389cd 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Hai installato VPN, proxy, firewall o software NAS particolari?</translation> <translation id="1863047423483329595">La Protezione antitracciamento non è al momento disponibile. Durante l'aggiornamento di questa funzionalità in Chrome, i siti possono usare temporaneamente i cookie di terze parti, a meno che tu non li blocchi. <ph name="BEGIN_LINK" />Scopri di più<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nessuna porta seriale trovata</translation> -<translation id="1863207472175483351">Installazione in corso…</translation> <translation id="1864111464094315414">Accesso</translation> <translation id="1864400682872660285">Più fredda</translation> <translation id="1864454756846565995">Dispositivo USB-C (porta posteriore)</translation> @@ -1844,6 +1843,7 @@ <translation id="2402226831639195063">Toni</translation> <translation id="2405887402346713222">Numeri di serie del dispositivo e del componente</translation> <translation id="2406153734066939945">Vuoi eliminare questo profilo e i relativi dati?</translation> +<translation id="2407671304279211586">Seleziona provider DNS</translation> <translation id="2408018932941436077">Salvataggio della carta</translation> <translation id="2408955596600435184">Inserisci il codice PIN</translation> <translation id="2409268599591722235">Iniziamo</translation> @@ -5114,7 +5114,6 @@ <translation id="4988526792673242964">Pagine</translation> <translation id="49896407730300355">Ruota in senso anti&orario</translation> <translation id="4989966318180235467">Ispeziona pagina in &background</translation> -<translation id="4990949771467040994">In attesa…</translation> <translation id="4991420928586866460">Considera i tasti della fila superiore come tasti funzione</translation> <translation id="4992458225095111526">Conferma Powerwash</translation> <translation id="4992473555164495036">L'amministratore ha limitato i metodi di immissione disponibili.</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 8edf7016..274bc74 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -1141,7 +1141,6 @@ או NAS?</translation> <translation id="1863047423483329595">חסימת המעקב לא זמינה באופן זמני. בזמן ש-Chrome מעדכן את התכונה הזו, אתרים יכולים להשתמש בקובצי Cookie של צד שלישי באופן זמני, אלא אם חוסמים אותם. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="1863182668524159459">לא נמצאו יציאות טוריות</translation> -<translation id="1863207472175483351">בתהליך התקנה…</translation> <translation id="1864111464094315414">התחברות</translation> <translation id="1864400682872660285">קריר יותר</translation> <translation id="1864454756846565995">מכשיר עם יציאת USB-C (יציאה אחורית)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">דפים</translation> <translation id="49896407730300355">סיבוב נ&גד כיוון השעון</translation> <translation id="4989966318180235467">בדיקת דף ה&רקע</translation> -<translation id="4990949771467040994">בהמתנה…</translation> <translation id="4991420928586866460">התייחסות למקשים בשורה העליונה כאל מקשי פונקציה</translation> <translation id="4992458225095111526">אישור פעולת Powerwash</translation> <translation id="4992473555164495036">מנהל המערכת הגביל את שיטות הקלט הזמינות.</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index 701c7a43..38ce4125 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">特殊な VPN、プロキシ、ファイアウォール、NAS ソフトウェアをインストールしていますか?</translation> <translation id="1863047423483329595">トラッキング防止機能は一時的に使用できなくなっています。Chrome でこの機能を更新している間は、サイトが一時的にサードパーティ Cookie を使用できます(ただし、ユーザーがブロックしている場合を除きます)。<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation> <translation id="1863182668524159459">シリアルポートが見つかりません</translation> -<translation id="1863207472175483351">インストール中…</translation> <translation id="1864111464094315414">ログイン</translation> <translation id="1864400682872660285">寒色</translation> <translation id="1864454756846565995">USB-C デバイス(背面のポート)</translation> @@ -2670,6 +2669,7 @@ <translation id="3021065318976393105">バッテリー駆動時</translation> <translation id="3021066826692793094">蝶</translation> <translation id="3021678814754966447">フレームのソースを表示(&V)</translation> +<translation id="3021902017511220299">スキャンに失敗しました。この操作は管理者によってブロックされています。</translation> <translation id="3022361196600037287"><ph name="DEVICE" /> がこの Chromebook から削除され、<ph name="PRIMARY_EMAIL" /> には保存されません。</translation> <translation id="3022978424994383087">聞き取れませんでした。</translation> <translation id="3023464535986383522">選択して読み上げ</translation> @@ -5107,7 +5107,6 @@ <translation id="4988526792673242964">ページ</translation> <translation id="49896407730300355">反時計回りに回転(&O)</translation> <translation id="4989966318180235467">バックグラウンド ページの検証(&B)</translation> -<translation id="4990949771467040994">待機中…</translation> <translation id="4991420928586866460">キーボードの最上段のキーをファンクション キーとして使用する</translation> <translation id="4992458225095111526">Powerwash の実行を確認</translation> <translation id="4992473555164495036">使用できる入力方法が管理者によって制限されています。</translation> @@ -9033,6 +9032,7 @@ <translation id="811994229154425014">スペース 2 つでピリオドを入力</translation> <translation id="8120505434908124087">eSIM プロファイルのインストール</translation> <translation id="8121750884985440809">現在、画面をキャストしています</translation> +<translation id="8122898034710982882">スマートフォン ハブ、<ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">黄色と白の花</translation> <translation id="8123975449645947908">後方スクロール</translation> <translation id="8124313775439841391">管理対象 ONC</translation> @@ -9068,6 +9068,7 @@ <translation id="8148760431881541277">ログインの制限</translation> <translation id="8149564499626272569">USB ケーブルで接続したスマートフォンで確認</translation> <translation id="8149870652370242480">スマートフォンに保存されているパスワードを使用するには、iOS 版 Chrome をダウンロードして Google アカウントにログインします。</translation> +<translation id="8151057139207656239">ビルドの詳細をコピーしました</translation> <translation id="815114315010033526">代わりに QR コードを使用</translation> <translation id="8151638057146502721">設定</translation> <translation id="8154790740888707867">ファイルがありません</translation>
diff --git a/chrome/app/resources/generated_resources_ka.xtb b/chrome/app/resources/generated_resources_ka.xtb index 1b12eb7e..0cb343c8 100644 --- a/chrome/app/resources/generated_resources_ka.xtb +++ b/chrome/app/resources/generated_resources_ka.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">გაქვთ თუ არა დაინსტალირებული სპეციალური პროგრამული უზრუნველყოფა VPN-ისთვის, პროქსისთვის, ქსელის დაცვისთვის ან NAS-ისთვის?</translation> <translation id="1863047423483329595">თვალის დევნებისგან დაცვა დროებით მიუწვდომელია. სანამ Chrome აახლებს ამ ფუნქციას, საიტებმა, შესაძლოა, დროებით გამოიყენონ მესამე მხარის ქუქი-ჩანაწერები, თუ მათ არ დაბლოკავთ. <ph name="BEGIN_LINK" />შეიტყვეთ მეტი<ph name="END_LINK" /></translation> <translation id="1863182668524159459">თანმიმდევრული პორტები ვერ მოიძებნა</translation> -<translation id="1863207472175483351">მიმდინარეობს ინსტალაცია...</translation> <translation id="1864111464094315414">შესვლა</translation> <translation id="1864400682872660285">უფრო ცივი</translation> <translation id="1864454756846565995">USB-C მოწყობილობა (უკანა პორტი)</translation> @@ -5116,7 +5115,6 @@ <translation id="4988526792673242964">გვერდები</translation> <translation id="49896407730300355">საათის ისრის სა&წინააღმდეგოდ შემოტრიალება</translation> <translation id="4989966318180235467">&ფონური გვერდის შემოწმება</translation> -<translation id="4990949771467040994">მოლოდინში...</translation> <translation id="4991420928586866460">ზედა სტრიქონის ღილაკების გამოყენება ფუნქციონალურ ღილაკებად</translation> <translation id="4992458225095111526">დაადასტურეთ Powerwash-ი</translation> <translation id="4992473555164495036">თქვენმა ადმინისტრატორმა შეზღუდა შეყვანის მეთოდების ხელმისაწვდომობა.</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb index 1ad2489..861c005 100644 --- a/chrome/app/resources/generated_resources_kk.xtb +++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">Арнайы VPN, прокси, брандмауэр немесе NAS бағдарламалық құралы орнатылған ба?</translation> <translation id="1863047423483329595">Бақылаудан қорғау функциясы уақытша қолжетімді емес. Chrome бұл функцияны жаңартқан кезде, үшінші тарап cookie файлдарын блоктамасаңыз, сайттар оларды уақытша қолдана алады. <ph name="BEGIN_LINK" />Толық ақпарат<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Сериялық порттар табылмады.</translation> -<translation id="1863207472175483351">Орнатылып жатыр...</translation> <translation id="1864111464094315414">Кіру</translation> <translation id="1864400682872660285">Салқындатқыш</translation> <translation id="1864454756846565995">USB-C құрылғысы (артқы ұяшық)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">Беттер</translation> <translation id="49896407730300355">С&ағат тіліне қарсы айналдыру</translation> <translation id="4989966318180235467">&Фондық бетті тексеру</translation> -<translation id="4990949771467040994">күте тұрыңыз...</translation> <translation id="4991420928586866460">Жоғарғы қатар пернелерін функционалдық пернелер ретінде пайдалану</translation> <translation id="4992458225095111526">Powerwash растау</translation> <translation id="4992473555164495036">Әкімшіңіз қолжетімді енгізу әдістерінің санын шектеді.</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb index 0160430f..1fda2fd 100644 --- a/chrome/app/resources/generated_resources_km.xtb +++ b/chrome/app/resources/generated_resources_km.xtb
@@ -1142,7 +1142,6 @@ ដែរទេ?</translation> <translation id="1863047423483329595">មិនអាចប្រើការការពារការតាមដានជាបណ្ដោះអាសន្ន។ នៅពេល Chrome កំពុងធ្វើបច្ចុប្បន្នភាពមុខងារនេះ គេហទំព័រអាចប្រើខូគីភាគីទីបីជាបណ្ដោះអាសន្ន ប្រសិនបើអ្នកមិនទប់ស្កាត់ខូគីភាគីទីបីទាំងនោះទេ។ <ph name="BEGIN_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LINK" /></translation> <translation id="1863182668524159459">រកមិនឃើញរន្ធស៊េរីទេ</translation> -<translation id="1863207472175483351">កំពុងដំឡើង...</translation> <translation id="1864111464094315414">ចូល</translation> <translation id="1864400682872660285">កាន់តែខៀវ</translation> <translation id="1864454756846565995">ឧបករណ៍ USB-C (រន្ធខាងក្រោយ)</translation> @@ -5132,7 +5131,6 @@ <translation id="4988526792673242964">ទំព័រ</translation> <translation id="49896407730300355">បង្វិលបញ្ច្រាសទ្រនិចនាឡិកា</translation> <translation id="4989966318180235467">តាមដានទំព័រផ្ទៃខាងក្រោយ</translation> -<translation id="4990949771467040994">កំពុងរង់ចាំ...</translation> <translation id="4991420928586866460">ប្រើប៊ូតុងជួរខាងលើជាប៊ូតុងមុខងារ</translation> <translation id="4992458225095111526">អះអាង Powerwash</translation> <translation id="4992473555164495036">អ្នកគ្រប់គ្រងរបស់អ្នកបានកម្រិតវិធីបញ្ចូលដែលអាចប្រើបាន។</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 4bf91ca9..6e8e94ba 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -1135,7 +1135,6 @@ <translation id="1862311223300693744">ನಿಮ್ಮಲ್ಲಿ ಯಾವುದೇ ವಿಶೇಷವಾದ VPN, ಪ್ರಾಕ್ಸಿ, ಫೈರ್ವಾಲ್ ಅಥವಾ NAS ಸಾಫ್ಟ್ವೇರ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆಯೇ?</translation> <translation id="1863047423483329595">ಟ್ರ್ಯಾಕಿಂಗ್ ಸಂರಕ್ಷಣೆಯು ತಾತ್ಕಾಲಿಕವಾಗಿ ಲಭ್ಯವಿಲ್ಲ. Chrome ಈ ಫೀಚರ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡುವಾಗ, ನೀವು ಥರ್ಡ್-ಪಾರ್ಟಿ ಕುಕಿಗಳನ್ನು ನಿರ್ಬಂಧಿಸದ ಹೊರತು ಸೈಟ್ಗಳು ತಾತ್ಕಾಲಿಕವಾಗಿ ಅವುಗಳನ್ನು ಬಳಸಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation> <translation id="1863182668524159459">ಯಾವುದೇ ಸೀರಿಯಲ್ ಪೋರ್ಟ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ</translation> -<translation id="1863207472175483351">ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ…</translation> <translation id="1864111464094315414">ಲಾಗಿನ್</translation> <translation id="1864400682872660285">ಕೂಲರ್</translation> <translation id="1864454756846565995">USB-C ಸಾಧನ (ಹಿಂದಿನ ಪೋರ್ಟ್)</translation> @@ -5125,7 +5124,6 @@ <translation id="4988526792673242964">ಪುಟಗಳು</translation> <translation id="49896407730300355">ಅಪ್ರ&ದಕ್ಷಿಣೆಯಂತೆ ತಿರುಗಿಸಿ</translation> <translation id="4989966318180235467">&ಹಿನ್ನಲೆ ಪುಟವನ್ನು ಪರಿಶೀಲಿಸಿ</translation> -<translation id="4990949771467040994">ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="4991420928586866460">ಮೇಲಿನ-ಸಾಲು ಕೀಲಿಗಳನ್ನು ಕಾರ್ಯದ ಕೀಲಿಗಳಂತೆ ಪರಿಗಣಿಸಿ</translation> <translation id="4992458225095111526">ಪವರ್ವಾಶ್ ಅನ್ನು ಖಚಿತಪಡಿಸಿ</translation> <translation id="4992473555164495036">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಲಭ್ಯವಿರುವ ಇನ್ಪುಟ್ ವಿಧಾನಗಳನ್ನು ಸೀಮಿತಗೊಳಿಸಿದ್ದಾರೆ.</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index db0c48c..bc6a2a36 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -1142,7 +1142,6 @@ 있나요?</translation> <translation id="1863047423483329595">추적 보호 기능을 일시적으로 사용할 수 없습니다. Chrome에서 이 기능을 업데이트하는 동안 사이트에서 서드 파티 쿠키를 차단하지 않으면 일시적으로 쿠키를 사용할 수 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation> <translation id="1863182668524159459">직렬 포트를 찾을 수 없음</translation> -<translation id="1863207472175483351">설치 중...</translation> <translation id="1864111464094315414">로그인</translation> <translation id="1864400682872660285">시원함</translation> <translation id="1864454756846565995">USB-C 기기(후면 포트)</translation> @@ -1861,6 +1860,7 @@ <translation id="2402226831639195063">신호음</translation> <translation id="2405887402346713222">기기 및 구성요소 일련번호</translation> <translation id="2406153734066939945">프로필과 데이터를 삭제하시겠습니까?</translation> +<translation id="2407671304279211586">DNS 제공업체 선택</translation> <translation id="2408018932941436077">카드 저장 중</translation> <translation id="2408955596600435184">PIN 입력</translation> <translation id="2409268599591722235">시작하기</translation> @@ -5130,7 +5130,6 @@ <translation id="4988526792673242964">페이지</translation> <translation id="49896407730300355">반시계 방향으로 회전(&O)</translation> <translation id="4989966318180235467">백그라운드 페이지 검사(&B)</translation> -<translation id="4990949771467040994">대기 중…</translation> <translation id="4991420928586866460">맨 위 키를 기능 키로 사용</translation> <translation id="4992458225095111526">Powerwash 확인</translation> <translation id="4992473555164495036">관리자가 사용 가능한 입력 방법을 제한했습니다.</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb index 84a3144..c445375 100644 --- a/chrome/app/resources/generated_resources_ky.xtb +++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -1142,7 +1142,6 @@ орноткон белеңиз?</translation> <translation id="1863047423483329595">Көз салуудан коргоо азырынча жеткиликсиз. Үчүнчү тараптын cookie файлдарын бөгөттөбөсөңүз, Chrome'до бул функция жаңыртылып жатканда сайттар аларды убактылуу колдоно алышат. <ph name="BEGIN_LINK" />Кеңири маалымат<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Сериялык порт табылган жок</translation> -<translation id="1863207472175483351">орнотулууда…</translation> <translation id="1864111464094315414">Кирүү</translation> <translation id="1864400682872660285">Салкыныраак</translation> <translation id="1864454756846565995">USB-C түзмөгү (арткы оюкча)</translation> @@ -5130,7 +5129,6 @@ <translation id="4988526792673242964">Барактар</translation> <translation id="49896407730300355">Саат ж&ебесине каршы айлантуу</translation> <translation id="4989966318180235467">&Фон баракчасын иликтөө</translation> -<translation id="4990949771467040994">күтүлүүдө…</translation> <translation id="4991420928586866460">Жогорку саптагы баскычтарды функция баскычтары катары колдонуу</translation> <translation id="4992458225095111526">Жууп салууну ырастоо</translation> <translation id="4992473555164495036">Администратор айрым киргизүү ыкмаларын колдонууга тыюу салды.</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb index d74f231a..e0b07b9 100644 --- a/chrome/app/resources/generated_resources_lo.xtb +++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -1139,7 +1139,6 @@ <translation id="1862311223300693744">ທ່ານມີ VPN, ພຣັອກຊີ, firewall ຫຼື ຊອບແວ NAS ພິເສດຕິດຕັ້ງໄວ້ບໍ່?</translation> <translation id="1863047423483329595">ບໍ່ສາມາດໃຊ້ການປົກປ້ອງການຕິດຕາມໄດ້ຊົ່ວຄາວ. ໃນຂະນະທີ່ Chrome ກໍາລັງອັບເດດຄຸນສົມບັດນີ້, ເວັບໄຊຕ່າງໆຈະສາມາດໃຊ້ຄຸກກີ້ພາກສ່ວນທີສາມຊົ່ວຄາວໄດ້ເວັ້ນເສຍແຕ່ທ່ານບລັອກພວກມັນໄວ້. <ph name="BEGIN_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LINK" /></translation> <translation id="1863182668524159459">ບໍ່ພົບຜອດອະນຸກຳ</translation> -<translation id="1863207472175483351">ກຳລັງຕິດຕັ້ງ...</translation> <translation id="1864111464094315414">ເຂົ້າສູ່ລະບົບ</translation> <translation id="1864400682872660285">ເຢັນກວ່າ</translation> <translation id="1864454756846565995">ອຸປະກອນ USB-C (ຜອດດ້ານຫຼັງ)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">ໜ້າ</translation> <translation id="49896407730300355">ໝຸນທວນເຂັມໂມງ</translation> <translation id="4989966318180235467">ກວດກາໜ້າພື້ນຫຼັງ</translation> -<translation id="4990949771467040994">ກຳລັງລໍຖ້າ...</translation> <translation id="4991420928586866460">ເອົາປຸ່ມແຖວເທິງເປັນປຸ່ມຟັງຄ໌ຊັນ</translation> <translation id="4992458225095111526">ຢືນຢັນ Powerwash</translation> <translation id="4992473555164495036">ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານໄດ້ຈຳກັດວິທີການປ້ອນຂໍ້ມູນທີ່ສາມາດໃຊ້ໄດ້ແລ້ວ.</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 00749d73..5b8baa2 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -1145,7 +1145,6 @@ programinę įrangą?</translation> <translation id="1863047423483329595">Stebėjimo apsauga laikinai nepasiekiama. Kol „Chrome“ atnaujina šią funkciją, svetainės gali laikinai naudoti trečiųjų šalių slapukus, nebent juos užblokuosite. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nuosekliųjų prievadų nerasta</translation> -<translation id="1863207472175483351">diegiama...</translation> <translation id="1864111464094315414">Prisijungimas</translation> <translation id="1864400682872660285">Šaltesnio atspalvio</translation> <translation id="1864454756846565995">USB-C įrenginys (prievadas gale)</translation> @@ -2693,6 +2692,7 @@ <translation id="3021065318976393105">Naudojant su akumuliatoriumi</translation> <translation id="3021066826692793094">Drugelis</translation> <translation id="3021678814754966447">&Žiūrėti rėmelio šaltinį</translation> +<translation id="3021902017511220299">Nepavyko nuskaityti. Administratorius užblokavo šį veiksmą.</translation> <translation id="3022361196600037287">„<ph name="DEVICE" />“ bus pašalintas iš šio „Chromebook“ ir nebus išsaugotas adresu <ph name="PRIMARY_EMAIL" />.</translation> <translation id="3022978424994383087">Nepavyko suprasti.</translation> <translation id="3023464535986383522">Teksto ištarimas</translation> @@ -5133,7 +5133,6 @@ <translation id="4988526792673242964">Psl.</translation> <translation id="49896407730300355">Sukti prieš l&aikrodžio rodyklę</translation> <translation id="4989966318180235467">Tikrinti fono puslapį</translation> -<translation id="4990949771467040994">laukiama…</translation> <translation id="4991420928586866460">Viršutinės eilutės klavišus naudoti kaip funkcijų klavišus</translation> <translation id="4992458225095111526">Patvirtinti „Powerwash“</translation> <translation id="4992473555164495036">Administratorius apribojo pasiekiamus įvesties metodus.</translation> @@ -9072,6 +9071,7 @@ <translation id="811994229154425014">Įvesti tašką dukart paspaudus tarpo klavišą</translation> <translation id="8120505434908124087">Įdiegti „eSIM“ kortelės profilį</translation> <translation id="8121750884985440809">Šiuo metu perduodate savo ekrano vaizdą</translation> +<translation id="8122898034710982882">„Phone Hub“, „<ph name="FEATURE_NAME" />“</translation> <translation id="81238879832906896">Geltonos ir baltos spalvos gėlė</translation> <translation id="8123975449645947908">Slinkti atgal</translation> <translation id="8124313775439841391">Tvarkoma ONC</translation> @@ -9107,6 +9107,7 @@ <translation id="8148760431881541277">Prisijungimo ribojimas</translation> <translation id="8149564499626272569">Patvirtinti telefonu, naudojant USB laidą</translation> <translation id="8149870652370242480">Jei norite naudoti išsaugotus slaptažodžius telefone, atsisiųskite „iOS“ skirtą „Chrome“ ir prisijunkite prie „Google“ paskyros.</translation> +<translation id="8151057139207656239">Nukopijuota išsami versijos informacija</translation> <translation id="815114315010033526">Vietoj to naudoti QR kodą</translation> <translation id="8151638057146502721">Konfigūruoti</translation> <translation id="8154790740888707867">Nėra failo</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index 308aeb12..49fa2d5a 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">Vai ir instalēta īpaša VPN, starpniekservera, ugunsmūra vai NAS programmatūra?</translation> <translation id="1863047423483329595">Izsekošanas aizsardzība īslaicīgi nav pieejama. Kamēr pārlūkā Chrome tiek atjaunināta šī funkcija, vietnes var īslaicīgi izmantot trešo pušu sīkfailus, ja vien neesat tos bloķējis. <ph name="BEGIN_LINK" />Uzziniet vairāk.<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Netika atrasti seriālie porti</translation> -<translation id="1863207472175483351">notiek instalēšana…</translation> <translation id="1864111464094315414">Pieteikties</translation> <translation id="1864400682872660285">Vēsāks</translation> <translation id="1864454756846565995">USB-C ierīce (aizmugurējā pieslēgvieta)</translation> @@ -5116,7 +5115,6 @@ <translation id="4988526792673242964">Lapas</translation> <translation id="49896407730300355">Pagriezt &pretēji pulksteņrādītāju kustības virzienam</translation> <translation id="4989966318180235467">Pārbaudīt &fona lapu</translation> -<translation id="4990949771467040994">gaida…</translation> <translation id="4991420928586866460">Uzskatīt augšējās rindas taustiņus par funkciju taustiņiem</translation> <translation id="4992458225095111526">Powerwash apstiprināšana</translation> <translation id="4992473555164495036">Administrators ir ierobežojis pieejamās ievades metodes.</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb index 8dc2dab6..11b8525 100644 --- a/chrome/app/resources/generated_resources_mk.xtb +++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -1143,7 +1143,6 @@ софтвер NAS?</translation> <translation id="1863047423483329595">„Заштитата од следење“ е привремено недостапна. Додека Chrome ја ажурира функцијава, сајтовите може привремено да користат колачиња од трети страни, освен ако ги блокирате. <ph name="BEGIN_LINK" />Дознајте повеќе<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Не се најдени сериски порти</translation> -<translation id="1863207472175483351">Се инсталира…</translation> <translation id="1864111464094315414">Најавување</translation> <translation id="1864400682872660285">Поладни</translation> <translation id="1864454756846565995">USB-Ц уред (задна порта)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">Страници</translation> <translation id="49896407730300355">Ротирај на&лево</translation> <translation id="4989966318180235467">Страница за проверка на &заднина</translation> -<translation id="4990949771467040994">се чека…</translation> <translation id="4991420928586866460">Сметајте дека копчињата во најгорниот ред се функциски копчиња</translation> <translation id="4992458225095111526">Потврди фабричко ресетирање</translation> <translation id="4992473555164495036">Администраторот ги ограничил достапните методи за внесување.</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index 61d8b008..9d7444d 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -1129,7 +1129,6 @@ <translation id="1862311223300693744">നിങ്ങൾക്ക് ഇൻസ്റ്റാൾ ചെയ്ത ഏതെങ്കിലും പ്രത്യേക VPN, പ്രോക്സി, ഫയർവാൾ അല്ലെങ്കിൽ NAS സോഫ്റ്റ്വെയർ ഉണ്ടോ?</translation> <translation id="1863047423483329595">ട്രാക്ക് ചെയ്യൽ പരിരക്ഷ താൽക്കാലികമായി ലഭ്യമല്ല. Chrome ഈ ഫീച്ചർ അപ്ഡേറ്റ് ചെയ്യുമ്പോൾ, മൂന്നാം-കക്ഷി കുക്കികൾ നിങ്ങൾ ബ്ലോക്ക് ചെയ്യുന്നില്ലെങ്കിൽ, സൈറ്റുകൾക്ക് അവ താൽക്കാലികമായി ഉപയോഗിക്കാനാകും. <ph name="BEGIN_LINK" />കൂടുതലറിയുക<ph name="END_LINK" /></translation> <translation id="1863182668524159459">സീരിയൽ പോർട്ടുകളൊന്നും കണ്ടെത്തിയില്ല</translation> -<translation id="1863207472175483351">ഇൻസ്റ്റാൾ ചെയ്യുന്നു...</translation> <translation id="1864111464094315414">സൈൻ ഇൻ</translation> <translation id="1864400682872660285">കൂളർ</translation> <translation id="1864454756846565995">USB-C ഉപകരണം (പുറകിലെ പോർട്ട്)</translation> @@ -5113,7 +5112,6 @@ <translation id="4988526792673242964">പേജുകള്</translation> <translation id="49896407730300355">എ&തിർ ഘടികാരദിശയിൽ തിരിക്കുക</translation> <translation id="4989966318180235467">&പശ്ചാത്തല പേജ് പരിശോധിക്കുക</translation> -<translation id="4990949771467040994">കാത്തിരിക്കുന്നു...</translation> <translation id="4991420928586866460">മുകളിലെ-വരി കീകൾ ഫംഗ്ഷൻ കീകളായി ഉപയോഗിക്കുക</translation> <translation id="4992458225095111526">പവർവാഷ് സ്ഥിരീകരിക്കുക</translation> <translation id="4992473555164495036">ലഭ്യമായ ഇൻപുട്ട് രീതികളെ നിങ്ങളുടെ അഡ്മിൻ പരിമിതപ്പെടുത്തി.</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb index b6c06947..2ff17ad0 100644 --- a/chrome/app/resources/generated_resources_mn.xtb +++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -1138,7 +1138,6 @@ байгаа юу?</translation> <translation id="1863047423483329595">Хяналтын хамгаалалт түр зуур боломжгүй байна. Chrome энэ онцлогийг шинэчилж байхад та гуравдагч талын күүкинүүдийг блоклоогүй бол сайтууд тэдгээрийг түр зуур ашиглах боломжтой. <ph name="BEGIN_LINK" />Нэмэлт мэдээлэл авах<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Цуваа порт олдсонгүй</translation> -<translation id="1863207472175483351">суулгаж байна...</translation> <translation id="1864111464094315414">Нэвтрэх</translation> <translation id="1864400682872660285">Хүйтэн</translation> <translation id="1864454756846565995">USB-C төхөөрөмж (ард талын порт)</translation> @@ -5126,7 +5125,6 @@ <translation id="4988526792673242964">Хуудас</translation> <translation id="49896407730300355">Цагийн зүүний эсрэг эргүүлэх</translation> <translation id="4989966318180235467">Дэвсгэр хуудсыг шалгах</translation> -<translation id="4990949771467040994">хүлээж байна…</translation> <translation id="4991420928586866460">Дээд эгнээний түлхүүрүүдийн үндсэн түлхүүр болгох</translation> <translation id="4992458225095111526">Powerwash-ийг батлах</translation> <translation id="4992473555164495036">Танай админ боломжит оруулах аргыг хязгаарласан байна.</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index c75f380..c1d1b9a3 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -1141,7 +1141,6 @@ इंस्टॉल केले आहे का?</translation> <translation id="1863047423483329595">ट्रॅकिंगपासून संरक्षण हे तात्पुरते उपलब्ध नाही. Chrome हे वैशिष्ट्य अपडेट करत असताना, तुम्ही तृतीय पक्ष कुकी ब्लॉक करत नाही तोपर्यंत साइट त्या तात्पुरत्या वापरू शकतात. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation> <translation id="1863182668524159459">सिरीअल पोर्ट सापडली नाहीत</translation> -<translation id="1863207472175483351">इंस्टॉल करत आहे...</translation> <translation id="1864111464094315414">लॉगिन</translation> <translation id="1864400682872660285">थंड</translation> <translation id="1864454756846565995">USB-C डिव्हाइस (मागील बाजूचे पोर्ट)</translation> @@ -5128,7 +5127,6 @@ <translation id="4988526792673242964">पेज</translation> <translation id="49896407730300355">घड्याळाच्या वि&रूद्ध दिशेने फिरवा</translation> <translation id="4989966318180235467">&पार्श्वभूमी पृष्ठाचे निरीक्षण करा</translation> -<translation id="4990949771467040994">प्रतीक्षा करत आहे...</translation> <translation id="4991420928586866460">कार्य की म्हणून शीर्ष-पंक्ती की हाताळा</translation> <translation id="4992458225095111526">Powerwash ची पुष्टी करा</translation> <translation id="4992473555164495036">तुमच्या ॲडमिनिस्ट्रेटरने उपलब्ध इनपुट पद्धती मर्यादित केल्या आहेत.</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index 1b92ba4..88e4e839 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -684,6 +684,7 @@ <translation id="1536754031901697553">Memutuskan sambungan...</translation> <translation id="1537254971476575106">Penggadang skrin penuh</translation> <translation id="15373452373711364">Kursor tetikus besar</translation> +<translation id="1539727654733007771">Tiada rangkaian mudah alih disediakan. Muat turun <ph name="BEGIN_LINK" />profil<ph name="END_LINK" /> baharu.</translation> <translation id="1540265419569299117">Perkhidmatan Apl ChromeOS</translation> <translation id="1540605929960647700">Dayakan mod tunjuk cara</translation> <translation id="1541346352678737112">Tiada rangkaian ditemukan</translation> @@ -1142,7 +1143,6 @@ dipasang?</translation> <translation id="1863047423483329595">Perlindungan Penjejakan tidak tersedia untuk sementara waktu. Sementara Chrome mengemaskinikan ciri ini, laman boleh menggunakan kuki pihak ketiga untuk sementara waktu melainkan anda menyekat ciri tersebut. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Tiada port siri ditemui</translation> -<translation id="1863207472175483351">memasang...</translation> <translation id="1864111464094315414">Log masuk</translation> <translation id="1864400682872660285">Dingin</translation> <translation id="1864454756846565995">Peranti USB-C (port belakang)</translation> @@ -1263,6 +1263,7 @@ <translation id="1951012854035635156">Pembantu</translation> <translation id="1954597385941141174">Tapak boleh meminta untuk menyambung kepada peranti USB</translation> <translation id="1954813140452229842">Ralat melekapkan perkongsian. Sila semak bukti kelayakan anda dan cuba lagi.</translation> +<translation id="1955313993396968525">Cari bingkai video dengan <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="1956050014111002555">Fail mengandungi berbilang sijil, tiada yang diimport:</translation> <translation id="1956167375087861299">Tidak dibenarkan menggunakan pengecam untuk memainkan kandungan yang dilindungi</translation> <translation id="1956390763342388273">Tindakan ini akan memuat naik semua fail daripada "<ph name="FOLDER_PATH" />". Lakukan tindakan ini hanya jika anda mempercayai tapak tersebut.</translation> @@ -1836,6 +1837,7 @@ <translation id="237828693408258535">Terjemah halaman ini?</translation> <translation id="2378982052244864789">Pilih direktori sambungan.</translation> <translation id="2379281330731083556">Cetak menggunakan dialog sistem... <ph name="SHORTCUT_KEY" /></translation> +<translation id="2381461748765773292">Tindakan ini boleh menyebabkan rangkaian mudah alih anda terputus sambungan selama beberapa minit</translation> <translation id="2381499968174336913">Pratonton tab yang dikongsi</translation> <translation id="2382875860893882175">Penghantaran dijeda pada masa ini. Anda boleh menyambung semula atau menghentikan penghantaran pada bila-bila masa.</translation> <translation id="2383825469508278924">Tukar pemetaan kekunci papan kekunci, kekunci fungsi dan pelbagai lagi</translation> @@ -2691,6 +2693,7 @@ <translation id="3021065318976393105">Semasa menggunakan bateri</translation> <translation id="3021066826692793094">Rama-rama</translation> <translation id="3021678814754966447">&Lihat Sumber Bingkai</translation> +<translation id="3021902017511220299">Imbasan gagal. Tindakan ini disekat oleh pentadbir anda.</translation> <translation id="3022361196600037287"><ph name="DEVICE" /> akan dialih keluar daripada Chromebook ini dan tidak akan disimpan pada <ph name="PRIMARY_EMAIL" />.</translation> <translation id="3022978424994383087">Tidak faham.</translation> <translation id="3023464535986383522">Pilih untuk bercakap</translation> @@ -5131,7 +5134,6 @@ <translation id="4988526792673242964">Halaman</translation> <translation id="49896407730300355">Putar m&elawan arah jam</translation> <translation id="4989966318180235467">Halaman periksa &latar belakang</translation> -<translation id="4990949771467040994">menunggu...</translation> <translation id="4991420928586866460">Kendalikan kekunci baris atas sebagai kekunci fungsi</translation> <translation id="4992458225095111526">Sahkan Powerwash</translation> <translation id="4992473555164495036">Pentadbir anda telah mengehadkan kaedah input yang tersedia.</translation> @@ -6798,6 +6800,7 @@ <translation id="6344576354370880196">Pencetak yang disimpan</translation> <translation id="6344608411615208519"><ph name="BEGIN_LINK" />Penyemak imbas anda diurus<ph name="END_LINK" /> oleh ibu/bapa anda</translation> <translation id="6344622098450209924">Perlindungan Penjejakan</translation> +<translation id="6345203628032613660">Cari Bingkai Video dengan <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="6345418402353744910">Nama pengguna dan kata laluan anda diperlukan untuk proksi <ph name="PROXY" /> agar pentadbir dapat mengkonfigurasikan rangkaian anda</translation> <translation id="6345566021391290381">Terdapat kata laluan yang dikongsi dengan anda pada <ph name="WEBSITE_NAME" />. Anda boleh menggunakan kata laluan tersebut dalam borang log masuk.</translation> <translation id="6345878117466430440">Tandai sebagai dibaca</translation> @@ -9063,6 +9066,7 @@ <translation id="811994229154425014">Dwiruang untuk menaip noktah</translation> <translation id="8120505434908124087">Pasang profil eSIM</translation> <translation id="8121750884985440809">Anda sedang menghantar skrin anda</translation> +<translation id="8122898034710982882">Hab Telefon, <ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">Bunga kuning dan putih</translation> <translation id="8123975449645947908">Tatal ke belakang</translation> <translation id="8124313775439841391">ONC Terurus</translation> @@ -9098,6 +9102,7 @@ <translation id="8148760431881541277">Hadkan log masuk</translation> <translation id="8149564499626272569">Sahkan melalui telefon anda dengan kabel USB</translation> <translation id="8149870652370242480">Untuk menggunakan kata laluan yang disimpan pada telefon anda, muat turun Chrome untuk iOS dan log masuk Google Account anda.</translation> +<translation id="8151057139207656239">Butiran binaan disalin</translation> <translation id="815114315010033526">Gunakan kod QR</translation> <translation id="8151638057146502721">Konfigurasi</translation> <translation id="8154790740888707867">Tiada fail</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb index 69157c7..039fa90 100644 --- a/chrome/app/resources/generated_resources_my.xtb +++ b/chrome/app/resources/generated_resources_my.xtb
@@ -1140,7 +1140,6 @@ <translation id="1862311223300693744">သင့်တွင် အထူး VPN၊ ပရောက်စီ၊ firewall သို့မဟုတ် NAS ဆော့ဖ်ဝဲ ထည့်သွင်းထားသလား။</translation> <translation id="1863047423483329595">ခြေရာခံခြင်း ကာကွယ်မှုကို ယာယီမရနိုင်ပါ။ Chrome သည် ဤဝန်ဆောင်မှုကို အပ်ဒိတ်လုပ်နေစဉ် ပြင်ပကုမ္ပဏီ၏ကွတ်ကီးများကို သင်ပိတ်မထားပါက ဝဘ်ဆိုက်များသည် ၎င်းတို့ကို ယာယီသုံးနိုင်သည်။ <ph name="BEGIN_LINK" />ပိုမိုလေ့လာရန်<ph name="END_LINK" /></translation> <translation id="1863182668524159459">အစဉ်လိုက်ပို့တ်များ မရှိပါ</translation> -<translation id="1863207472175483351">ထည့်သွင်းနေသည်…</translation> <translation id="1864111464094315414">အကောင့်ထဲဝင်ခြင်း</translation> <translation id="1864400682872660285">ပိုအေးသည့် အရောင်</translation> <translation id="1864454756846565995">USB-C ကိရိယာ (နောက်ဘက် ပို့တ်)</translation> @@ -5128,7 +5127,6 @@ <translation id="4988526792673242964">စာမျက်နှာများ</translation> <translation id="49896407730300355">ရေတွက်စက်ကို လက်ဝဲ&ရစ် လှည့်ပေးရန်</translation> <translation id="4989966318180235467">နောက်ခံ စာမျက်နှာကို &စစ်ဆေးပါ</translation> -<translation id="4990949771467040994">စောင့်နေသည်…</translation> <translation id="4991420928586866460">ထိပ်တန်း ကီးများကို လုပ်ကိုင်မှု ကီးများအဖြစ် သဘောထားရန်</translation> <translation id="4992458225095111526">Powerwash အား အတည်ပြုရန်</translation> <translation id="4992473555164495036">စီမံခန့်ခွဲသူက ရရှိနိုင်သော လက်ကွက်များကို ကန့်သတ်ထားသည်။</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb index f2a3264..468eeed 100644 --- a/chrome/app/resources/generated_resources_ne.xtb +++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">तपाईंले कुनै पनि विशेष VPN, प्रोक्सी, फायरवाल वा NAS सफ्टवेयर इन्स्टल गर्नुभएको छ?</translation> <translation id="1863047423483329595">ट्र्याकिङबाट सुरक्षित राख्ने सुविधा हाल उपलब्ध छैन। तपाईंले तेस्रो पक्षीय कुकीहरू ब्लक गर्नुभएको छैन भने Chrome ले यो सुविधा अपडेट गरिरहेका बेला साइटहरूले केही समयका लागि तेस्रो पक्षीय कुकीहरू प्रयोग गर्न सक्छन्। <ph name="BEGIN_LINK" />थप जान्नुहोस्<ph name="END_LINK" /></translation> <translation id="1863182668524159459">कुनै पनि सिरियल पोर्ट फेला परेन</translation> -<translation id="1863207472175483351">इन्स्टल गरिँदै छ...</translation> <translation id="1864111464094315414">लगइन</translation> <translation id="1864400682872660285">अझ शीतल</translation> <translation id="1864454756846565995">USB-C यन्त्र (पछाडिको पोर्ट)</translation> @@ -2674,6 +2673,7 @@ <translation id="3021065318976393105">ब्याट्री प्रयोग भइरहेका बेला</translation> <translation id="3021066826692793094">पुतली</translation> <translation id="3021678814754966447">फ्रेम स्रोत &हेर्नुहोस्</translation> +<translation id="3021902017511220299">स्क्यान गर्न सकिएन। तपाईंका एड्मिनले यो कारबाही गर्न रोक लगाउनुभएको छ।</translation> <translation id="3022361196600037287">यो Chromebook बाट <ph name="DEVICE" /> हटाइने छ र उक्त डिभाइस अब <ph name="PRIMARY_EMAIL" /> मा सेभ गरिने छैन।</translation> <translation id="3022978424994383087">मैले बुझिनँ।</translation> <translation id="3023464535986383522">सेलेक्ट टु स्पिक सुविधा</translation> @@ -5112,7 +5112,6 @@ <translation id="4988526792673242964">पृष्ठहरू</translation> <translation id="49896407730300355">घडिको उल्टो दिशा&तिर घुमाउनुहोस्</translation> <translation id="4989966318180235467">निरीक्षण र पृष्ठभूमि पृष्ठ</translation> -<translation id="4990949771467040994">प्रतीक्षा गरिँदै छ...</translation> <translation id="4991420928586866460">शीर्ष पङ्क्तिका कुञ्जीहरूलाई प्रकार्य कुञ्जीहरूको रूपमा व्यवहार गर्नुहोस्</translation> <translation id="4992458225095111526">Powerwash पुष्टि गर्नुहोस्</translation> <translation id="4992473555164495036">तपाईंको प्रशासकले उपलब्ध इनपुट विधिहरूलाई सीमित गर्नुभएको छ।</translation> @@ -9041,6 +9040,7 @@ <translation id="811994229154425014">दुई पटक स्पेस थिच्दा पूर्ण विराम टाइप हुने पारियोस्</translation> <translation id="8120505434908124087">eSIM प्रोफाइल इन्स्टल गर्नुहोस्</translation> <translation id="8121750884985440809">तपाईं अहिले आफ्नो स्क्रिन कास्ट गर्दै हुनुहुन्छ</translation> +<translation id="8122898034710982882">फोन हब, <ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">पहेँलो र सेतो फुल</translation> <translation id="8123975449645947908">पछाडितिर स्क्रोल गर्नुहोस्</translation> <translation id="8124313775439841391">व्यवस्थित ONC</translation> @@ -9076,6 +9076,7 @@ <translation id="8148760431881541277">साइन इन गर्ने सीमा तोक्नुहोस्</translation> <translation id="8149564499626272569">USB केबलमार्फत आफ्नो फोन कनेक्ट गरेर पहिचान पुष्टि गर्नुहोस्</translation> <translation id="8149870652370242480">आफ्नो फोनमा सेभ गरिएका पासवर्डहरू प्रयोग गर्न Chrome को iOS संस्करण डाउनलोड गर्नुहोस् र आफ्नो Google खातामा साइन इन गर्नुहोस्।</translation> +<translation id="8151057139207656239">बिल्डसम्बन्धी विवरणहरू कपी गरिएका छन्</translation> <translation id="815114315010033526">बरु QR कोड प्रयोग गर्नुहोस्</translation> <translation id="8151638057146502721">विन्यास गर्नुहोस्</translation> <translation id="8154790740888707867">कुनै फाइल छैन</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index f833aa6..474e87d 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Heb je speciale VPN-, proxy-, firewall- of NAS-software geïnstalleerd?</translation> <translation id="1863047423483329595">Trackingbeveiliging is tijdelijk niet beschikbaar. Terwijl Chrome deze functie updatet, kunnen sites tijdelijk cookies van derden gebruiken, tenzij je deze blokkeert. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Geen seriële poorten gevonden</translation> -<translation id="1863207472175483351">installeren...</translation> <translation id="1864111464094315414">Aanmelden</translation> <translation id="1864400682872660285">Koeler</translation> <translation id="1864454756846565995">USB-C-apparaat (poort aan achterkant)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">Pagina's</translation> <translation id="49896407730300355">Linksom &draaien</translation> <translation id="4989966318180235467">&Achtergrondpagina controleren</translation> -<translation id="4990949771467040994">wachten…</translation> <translation id="4991420928586866460">Toetsen op de bovenste rij behandelen als functietoetsen</translation> <translation id="4992458225095111526">Powerwash bevestigen</translation> <translation id="4992473555164495036">Je beheerder heeft de beschikbare invoermethoden beperkt.</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index 0732c5a..092ef705 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -1136,7 +1136,6 @@ <translation id="1862311223300693744">Har du noen spesialprogramvare for VPN, proxy-tjener, brannmur eller NAS installert?</translation> <translation id="1863047423483329595">Sporingsbeskyttelse er midlertidig utilgjengelig. Mens Chrome oppdaterer denne funksjonen, kan nettsteder midlertidig bruke informasjonskapsler fra tredjeparter med mindre du blokkerer dem. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Fant ingen serielle porter</translation> -<translation id="1863207472175483351">installerer …</translation> <translation id="1864111464094315414">Pålogging</translation> <translation id="1864400682872660285">Kaldere</translation> <translation id="1864454756846565995">USB-C-enhet (porten på baksiden)</translation> @@ -5123,7 +5122,6 @@ <translation id="4988526792673242964">Sider</translation> <translation id="49896407730300355">Rotér m&ot klokken</translation> <translation id="4989966318180235467">Inspeksjons- og bakgrunnsside</translation> -<translation id="4990949771467040994">Venter …</translation> <translation id="4991420928586866460">Behandle taster på øverste rad som funksjonstaster</translation> <translation id="4992458225095111526">Bekreft Powerwash</translation> <translation id="4992473555164495036">Administratoren har begrenset de tilgjengelige inndatametodene.</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb index 82f35aa..5cec123 100644 --- a/chrome/app/resources/generated_resources_or.xtb +++ b/chrome/app/resources/generated_resources_or.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">ଆପଣ କୌଣସି ବିଶେଷ VPN, ପ୍ରକ୍ସି, ଫାୟାରୱାଲ୍ କିମ୍ବା NAS ସଫ୍ଟୱେର୍ ଇନଷ୍ଟଲ୍ କରିଛନ୍ତି କି?</translation> <translation id="1863047423483329595">ଟ୍ରାକିଂ ସୁରକ୍ଷା ଅସ୍ଥାୟୀ ଭାବେ ଉପଲବ୍ଧ ନାହିଁ। Chrome ଏହି ଫିଚରକୁ ଅପଡେଟ କରିବା ସମୟରେ ଆପଣ ତୃତୀୟ-ପକ୍ଷ କୁକୀଗୁଡ଼ିକୁ ବନ୍ଦ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ସାଇଟଗୁଡ଼ିକ ଅସ୍ଥାୟୀ ଭାବେ ସେଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ। <ph name="BEGIN_LINK" />ଅଧିକ ଜାଣନ୍ତୁ<ph name="END_LINK" /></translation> <translation id="1863182668524159459">କୌଣସି କ୍ରମିକ ପୋର୍ଟଗୁଡ଼ିକ ମିଳିଲା ନାହିଁ</translation> -<translation id="1863207472175483351">ଇନଷ୍ଟଲ ହେଉଛି...</translation> <translation id="1864111464094315414">ଲଗ୍ଇନ୍</translation> <translation id="1864400682872660285">ଶୀତଳ</translation> <translation id="1864454756846565995">USB-C ଡିଭାଇସ୍ (ପଛ ପୋର୍ଟ)</translation> @@ -5114,7 +5113,6 @@ <translation id="4988526792673242964">ପୃଷ୍ଠାଗୁଡ଼ିକ</translation> <translation id="49896407730300355">c&ounterclockwise ଘୂରାନ୍ତୁ</translation> <translation id="4989966318180235467">&ପୃଷ୍ଠପଟ ପୃଷ୍ଠା ନିରୀକ୍ଷଣ କରନ୍ତୁ</translation> -<translation id="4990949771467040994">ଅପେକ୍ଷା କରାଯାଉଛି…</translation> <translation id="4991420928586866460">ଶୀର୍ଷ-ଧାଡ଼ିର କୀଗୁଡ଼ିକୁ ଫଙ୍କସନ୍ କୀ ଭାବରେ ବିବେଚନା କରନ୍ତୁ</translation> <translation id="4992458225095111526">ପାୱାର୍ୱାସ୍କୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁ</translation> <translation id="4992473555164495036">ଆପଣଙ୍କର ବ୍ୟବସ୍ଥାପକ ଉପଲବ୍ଧ ଇନ୍ପୁଟ୍ ପଦ୍ଧତିଗୁଡ଼ିକୁ ସୀମିତ କରିଛନ୍ତି।</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb index 51581c6..fd65593 100644 --- a/chrome/app/resources/generated_resources_pa.xtb +++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -1143,13 +1143,12 @@ ਸਥਾਪਤ ਕੀਤਾ ਹੈ?</translation> <translation id="1863047423483329595">ਟਰੈਕਿੰਗ ਸੰਬੰਧੀ ਸੁਰੱਖਿਆ ਕੁਝ ਸਮੇਂ ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ। Chrome ਵੱਲੋਂ ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਦੌਰਾਨ, ਸਾਈਟਾਂ ਕੁਝ ਸਮੇਂ ਲਈ ਤੀਜੀ-ਧਿਰ ਦੀਆਂ ਕੁਕੀਜ਼ ਦੀ ਵਰਤੋਂ ਉਦੋਂ ਤੱਕ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਨ੍ਹਾਂ ਨੂੰ ਬਲਾਕ ਨਹੀਂ ਕਰਦੇ ਹੋ। <ph name="BEGIN_LINK" />ਹੋਰ ਜਾਣੋ<ph name="END_LINK" /></translation> <translation id="1863182668524159459">ਕੋਈ ਸੀਰੀਅਲ ਪੋਰਟ ਨਹੀਂ ਮਿਲੇ</translation> -<translation id="1863207472175483351">ਸਥਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...</translation> <translation id="1864111464094315414">ਲੌਗ-ਇਨ ਕਰੋ</translation> <translation id="1864400682872660285">ਵਧੇਰੇ ਹਲਕਾ</translation> <translation id="1864454756846565995">USB-C ਡੀਵਾਈਸ (ਪਿਛਲਾ ਪੋਰਟ)</translation> <translation id="1865769994591826607">ਸਿਰਫ਼ ਸਮਰੂਪ-ਸਾਈਟ ਕਨੈਕਸ਼ਨ</translation> <translation id="186594096341696655">ਸੈਂਪਲ ਰੇਟ ਘਟਾਓ</translation> -<translation id="186612162884103683">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡਿਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਅਤੇ ਲਿਖ ਸਕਦਾ ਹੈ।</translation> +<translation id="186612162884103683">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡੀਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਅਤੇ ਲਿਖ ਸਕਦਾ ਹੈ।</translation> <translation id="1867780286110144690"><ph name="PRODUCT_NAME" /> ਆਪਣੀ ਇੰਸਟੌਲੇਸ਼ਨ ਪੂਰੀ ਕਰਨ ਲਈ ਤਿਆਰ ਹੈ</translation> <translation id="1868553836791672080">Chromium ਵਿੱਚ ਪਾਸਵਰਡ ਜਾਂਚ ਉਪਲਬਧ ਨਹੀਂ ਹੈ</translation> <translation id="1868617395637139709">Android ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ ਟਿਕਾਣੇ ਦੀ ਵਰਤੋਂ ਕਰੋ।</translation> @@ -3590,7 +3589,7 @@ <translation id="3767835232661747729">ਫ਼ਿਲਹਾਲ, ਤੁਸੀਂ ਸਿਰਫ਼ ਪਰਿਵਾਰਕ ਮੈਂਬਰਾਂ ਨਾਲ ਹੀ ਪਾਸਵਰਡਾਂ ਨੂੰ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ। ਆਪਣੇ ਗਰੁੱਪ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਣ ਲਈ <ph name="BEGIN_LINK" />ਪਰਿਵਾਰਕ ਮੈਂਬਰਾਂ ਨੂੰ ਸੱਦਾ ਦਿਓ<ph name="END_LINK" /> ਅਤੇ Google 'ਤੇ ਆਪਣੇ ਉਤਪਾਦਾਂ ਅਤੇ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਦਾ ਹੋਰ ਲਾਹਾ ਲਓ।</translation> <translation id="377050016711188788">ਆਈਸਕ੍ਰੀਮ</translation> <translation id="3771290962915251154">ਮਾਪਿਆਂ ਦੇ ਕੰਟਰੋਲ ਚਾਲੂ ਹੋਣ ਕਰਕੇ ਇਹ ਸੈਟਿੰਗ ਬੰਦ ਹੈ</translation> -<translation id="3771294271822695279">ਵੀਡਿਓ ਫਾਈਲਾਂ</translation> +<translation id="3771294271822695279">ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ</translation> <translation id="3771851622616482156">ਖੁੱਲ੍ਹੀਆਂ ਟੈਬਾਂ ਸਮੇਤ, ਤੁਹਾਨੂੰ ਇਸ ਸਾਈਟ ਤੋਂ ਸਾਈਨ-ਆਊਟ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ</translation> <translation id="3772046291955677288">ਮੈਂ <ph name="BEGIN_LINK1" />Google ਦੇ ਸੇਵਾ ਦੇ ਨਿਯਮਾਂ<ph name="END_LINK1" /> ਅਤੇ <ph name="BEGIN_LINK2" />Chrome ਅਤੇ ChromeOS ਦੇ ਵਧੀਕ ਸੇਵਾ ਦੇ ਨਿਯਮਾਂ<ph name="END_LINK2" /> ਨੂੰ ਪੜ੍ਹ ਲਿਆ ਹੈ ਅਤੇ ਉਨ੍ਹਾਂ ਨਾਲ ਸਹਿਮਤ ਹਾਂ।</translation> <translation id="3774059845329307709">ਸੀਰੀਅਲ ਨੰਬਰ</translation> @@ -4695,7 +4694,7 @@ <translation id="4639390152280993480">ਇਸ ਪੰਨੇ ਦਾ ਸਰਲੀਕਿਰਤ ਦ੍ਰਿਸ਼ ਦੇਖਣ ਲਈ, ਹੋਰ ਟੂਲ > ਪੜ੍ਹਨ ਸੰਬੰਧੀ ਮੋਡ 'ਤੇ ਜਾਓ</translation> <translation id="4641539339823703554">Chrome ਸਿਸਟਮ ਸਮਾਂ ਸੈੱਟ ਨਹੀਂ ਕਰ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਹੇਠਾਂ ਦਿੱਤਾ ਸਮਾਂ ਦੇਖੋ ਅਤੇ ਜੇਕਰ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸਨੂੰ ਠੀਕ ਕਰੋ।</translation> <translation id="4642587497923912728">Steam for Chromebook (ਬੀਟਾ) ਸਿਰਫ਼ ਉਨ੍ਹਾਂ ਖਾਤਿਆਂ ਲਈ ਹੀ ਉਪਲਬਧ ਹੈ, ਜਿਨ੍ਹਾਂ ਨਾਲ ਪਹਿਲਾਂ ਇਸ Chromebook 'ਤੇ ਸਾਈਨ-ਇਨ ਕੀਤਾ ਗਿਆ ਹੈ।</translation> -<translation id="4643612240819915418">&ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਵੀਡਿਓ ਖੋਲ੍ਹੋ</translation> +<translation id="4643612240819915418">&ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਵੀਡੀਓ ਖੋਲ੍ਹੋ</translation> <translation id="4643833688073835173">ਤੁਹਾਡੀ Chromebook ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਸਾਹਮਣੇ ਮੌਜੂਦ ਲੋਕਾਂ ਦਾ ਪਤਾ ਲਗਾਉਣ ਲਈ ਬਿਲਟ-ਇਨ ਸੈਂਸਰ ਦੀ ਵਰਤੋਂ ਕਰਦੀ ਹੈ। ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਵਿਚਲੇ ਸਾਰੇ ਡਾਟੇ 'ਤੇ ਤੁਰੰਤ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਫਿਰ ਇਸਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ। ਸੈਂਸਰ ਡਾਟਾ ਕਦੇ ਵੀ Google ਨੂੰ ਨਹੀਂ ਭੇਜਿਆ ਜਾਂਦਾ।</translation> <translation id="4644205769234414680">ਇਨਕੋਗਨਿਟੋ ਵਿੱਚ ਆਗਿਆ ਦਿਓ</translation> <translation id="4645575059429386691">ਤੁਹਾਡੇ ਮਾਤਾ ਜਾਂ ਪਿਤਾ ਵੱਲੋਂ ਵਿਵਸਥਿਤ</translation> @@ -4940,7 +4939,7 @@ <translation id="4838836835474292213">ਕਲਿੱਪਬੋਰਡ ਪੜ੍ਹਨ ਦੀ ਪਹੁੰਚ ਦਿੱਤੀ ਗਈ</translation> <translation id="4838907349371614303">ਪਾਸਵਰਡ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ</translation> <translation id="4838958829619609362">ਚੋਣ <ph name="LANGUAGE" /> ਵਿੱਚ ਉਪਲਬਧ ਨਹੀਂ ਹੈ</translation> -<translation id="4839303808932127586">ਦੇ ਤੌਰ 'ਤੇ ਵੀਡਿਓ ਰੱ&ਖਿਅਤ ਕਰੋ...</translation> +<translation id="4839303808932127586">...ਦੇ ਤੌਰ 'ਤੇ ਵੀਡੀਓ ਰੱਖਿਅਤ ਕਰੋ</translation> <translation id="4839910546484524995">ਆਪਣੇ ਡੀਵਾਈਸ ਦੀ ਜਾਂਚ ਕਰੋ</translation> <translation id="4840096453115567876">ਕੀ ਫਿਰ ਵੀ ਇਨਕੋਗਨਿਟੋ ਮੋਡ ਛੱਡਣਾ ਹੈ?</translation> <translation id="4841741146571978176">ਲੋੜੀਂਦੀ ਆਭਾਸੀ ਮਸ਼ੀਨ ਮੌਜੂਦ ਨਹੀਂ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਕਿਰਪਾ ਕਰਕੇ <ph name="VM_TYPE" /> ਦਾ ਸੈੱਟਅੱਪ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">ਸਫ਼ੇ</translation> <translation id="49896407730300355">ਕਾ&ਊਂਟਰਕਲੌਕਵਾਈਜ ਰੋਟੇਟ ਕਰੋ</translation> <translation id="4989966318180235467">ਜਾਂਚੋ&ਪਿਛੋਕੜ ਸਫ਼ਾ</translation> -<translation id="4990949771467040994">ਉਡੀਕ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...</translation> <translation id="4991420928586866460">ਉੱਪਰਲੀ-ਕਤਾਰ ਦੀਆਂ ਕੁੰਜੀਆਂ ਨਾਲ ਫੰਕਸ਼ਨ ਕੁੰਜੀਆਂ ਦੇ ਤੌਰ ਤੇ ਵਿਵਹਾਰ ਕਰੋ</translation> <translation id="4992458225095111526">ਪਾਵਰਵਾਸ਼ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ</translation> <translation id="4992473555164495036">ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਉਪਲਬਧ ਇਨਪੁੱਟ ਵਿਧੀਆਂ ਨੂੰ ਸੀਮਤ ਕਰ ਦਿੱਤਾ ਹੈ।</translation> @@ -7813,7 +7811,7 @@ <translation id="7160182524506337403">ਤੁਸੀਂ ਹੁਣ ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦੇਖ ਸਕਦੇ ਹੋ</translation> <translation id="7163202347044721291">ਕਿਰਿਆਸ਼ੀਲ ਕਰਨ ਲਈ ਕੋਡ ਦੀ ਪੁਸ਼ਟੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...</translation> <translation id="7165263843655074092">ਤੁਸੀਂ ਇਸ ਡੀਵਾਈਸ 'ਤੇ ਮਿਆਰੀ ਸੁਰੱਖਿਆ ਪ੍ਰਾਪਤ ਕਰ ਰਹੇ ਹੋ</translation> -<translation id="716640248772308851">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡਿਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਸਕਦਾ ਹੈ।</translation> +<translation id="716640248772308851">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡੀਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਸਕਦਾ ਹੈ।</translation> <translation id="7166815366658507447">ਹੌਟਸਪੌਟ ਚਾਲੂ ਹੈ</translation> <translation id="7167327771183668296">ਸਵੈ ਕਲਿੱਕਾਂ</translation> <translation id="7167486101654761064">&ਹਮੇਸ਼ਾਂ ਇਸ ਪ੍ਰਕਾਰ ਦੀਆਂ ਫਾਈਲਾਂ ਖੋਲ੍ਹੋ</translation> @@ -9132,7 +9130,7 @@ <translation id="8179976553408161302">ਦਰਜ ਕਰੋ</translation> <translation id="8180295062887074137"><ph name="PRINTER_NAME" /> <ph name="PRINTER_STATUS" />। <ph name="NUM_PRINTERS" /> ਵਿੱਚੋਂ <ph name="ITEM_POSITION" /> ਪ੍ਰਿੰਟਰ।</translation> <translation id="8180785270975217276">ਊਰਜਾ ਸੇਵਰ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ</translation> -<translation id="8180786512391440389">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡਿਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਸਕਦਾ ਹੈ।</translation> +<translation id="8180786512391440389">"<ph name="EXTENSION" />" ਸਹੀ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਏ ਹੋਏ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਵਿੱਚ ਚਿੱਤਰ, ਵੀਡੀਓ ਅਤੇ ਅਵਾਜ਼ ਫਾਈਲਾਂ ਪੜ੍ਹ ਸਕਦਾ ਹੈ।</translation> <translation id="8181215761849004992">ਡੋਮੇਨ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਇਹ ਦੇਖਣ ਲਈ ਆਪਣੇ ਖਾਤੇ ਦੀ ਜਾਂਚ ਕਰੋ ਕਿ ਤੁਹਾਡੇ ਕੋਲ ਡੀਵਾਈਸਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਦੇ ਵਿਸ਼ੇਸ਼-ਅਧਿਕਾਰ ਹਨ।</translation> <translation id="8182105986296479640">ਐਪਲੀਕੇਸ਼ਨ ਪ੍ਰਤੀਕਿਰਿਆ ਨਹੀਂ ਦੇ ਰਹੀ ਹੈ।</translation> <translation id="8182412589359523143">ਇਸ <ph name="DEVICE_TYPE" /> ਵਿੱਚੋਂ ਸਾਰਾ ਡਾਟਾ ਮਿਟਾਉਣ ਲਈ, <ph name="BEGIN_LINK" />ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ<ph name="END_LINK" />।</translation> @@ -9629,7 +9627,7 @@ <translation id="8577052309681449949">ਸਵੈਚਲਿਤ ਕਲਿੱਕਾਂ, ਕਰਸਰ ਦਾ ਆਕਾਰ, ਕਰਸਰ ਦਾ ਰੰਗ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ</translation> <translation id="8578639784464423491">99 ਤੋਂ ਜ਼ਿਆਦਾ ਅੱਖਰ ਨਹੀਂ ਹੋ ਸਕਦੇ</translation> <translation id="8581809080475256101">ਇਤਿਹਾਸ ਦੇਖਣ ਲਈ ਅੱਗੇ ਜਾਓ, ਸੰਦਰਭੀ ਮੀਨੂ ਦਬਾਓ</translation> -<translation id="8584280235376696778">&ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਵੀਡਿਓ ਖੋਲ੍ਹੋ</translation> +<translation id="8584280235376696778">&ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਵੀਡੀਓ ਖੋਲ੍ਹੋ</translation> <translation id="858451212965845553">ਆਪਣੇ ਡੀ&ਵਾਈਸਾਂ 'ਤੇ ਭੇਜੋ</translation> <translation id="8584843865238667486">ਵਰਤੋਂ ਪੰਨੇ <ph name="USAGE_PAGE" /> ਤੋਂ <ph name="USAGE" /> ਵਰਤੋਂ ਵਾਲੇ HID ਡੀਵਾਈਸ</translation> <translation id="8585480574870650651">Crostini ਹਟਾਓ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index 1cd8399d..16ab25b 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -1128,7 +1128,6 @@ <translation id="1862311223300693744">Czy masz zainstalowane jakieś specjalne oprogramowanie VPN, serwera proxy, zapory sieciowej lub NAS?</translation> <translation id="1863047423483329595">Ochrona przed śledzeniem jest chwilowo niedostępna. Kiedy Chrome aktualizuje tę funkcję, strony mogą tymczasowo używać plików cookie innych firm, chyba że je zablokujesz. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nie znaleziono portów szeregowych</translation> -<translation id="1863207472175483351">instaluję…</translation> <translation id="1864111464094315414">Zaloguj się</translation> <translation id="1864400682872660285">Chłodniejsze</translation> <translation id="1864454756846565995">Urządzenie USB-C (tylny port)</translation> @@ -5099,7 +5098,6 @@ <translation id="4988526792673242964">Strony</translation> <translation id="49896407730300355">&Obróć w lewo</translation> <translation id="4989966318180235467">Sprawdź &stronę tła</translation> -<translation id="4990949771467040994">czekam…</translation> <translation id="4991420928586866460">Traktuj klawisze z górnego rzędu jak klawisze funkcyjne</translation> <translation id="4992458225095111526">Potwierdzanie Powerwash</translation> <translation id="4992473555164495036">Administrator ograniczył dostępne metody wprowadzania.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index 45d3ca9..5b0e9dee 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -1143,7 +1143,6 @@ instalado?</translation> <translation id="1863047423483329595">A "Proteção antirrastreamento" está temporariamente indisponível. Enquanto o Chrome atualiza esse recurso, os sites podem usar cookies de terceiros temporariamente, a menos que você os bloqueie. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nenhuma porta serial encontrada</translation> -<translation id="1863207472175483351">instalando…</translation> <translation id="1864111464094315414">Login</translation> <translation id="1864400682872660285">Mais frias</translation> <translation id="1864454756846565995">Dispositivo USB-C (porta traseira)</translation> @@ -5132,7 +5131,6 @@ <translation id="4988526792673242964">Páginas</translation> <translation id="49896407730300355">Girar no s&entido anti-horário</translation> <translation id="4989966318180235467">Inspecionar página de &fundo</translation> -<translation id="4990949771467040994">aguardando…</translation> <translation id="4991420928586866460">Tratar teclas de linha superior como teclas de função</translation> <translation id="4992458225095111526">Confirmar powerwash</translation> <translation id="4992473555164495036">O administrador limitou os métodos de entrada disponíveis.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index ff8aa77..eaca1439 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Tem alguma VPN, proxy, firewall ou software NAS especial instalado?</translation> <translation id="1863047423483329595">A Proteção Antirrastreio está temporariamente indisponível Enquanto o Chrome estiver a atualizar esta funcionalidade, os sites podem usar temporariamente cookies de terceiros, a menos que os bloqueie. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nenhuma porta de série encontrada.</translation> -<translation id="1863207472175483351">a instalar…</translation> <translation id="1864111464094315414">Início de sessão</translation> <translation id="1864400682872660285">Mais frio</translation> <translation id="1864454756846565995">Dispositivo USB-C (porta traseira)</translation> @@ -5117,7 +5116,6 @@ <translation id="4988526792673242964">Páginas </translation> <translation id="49896407730300355">Rodar para a &esquerda</translation> <translation id="4989966318180235467">Inspecionar página de fundo</translation> -<translation id="4990949771467040994">a aguardar…</translation> <translation id="4991420928586866460">Tratar as teclas da linha superior como teclas de função</translation> <translation id="4992458225095111526">Confirmar Powerwash</translation> <translation id="4992473555164495036">O administrador limitou os métodos de introdução disponíveis.</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index 11f4135f..2fa60d479 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -1131,7 +1131,6 @@ <translation id="1862311223300693744">Ai un software special de VPN, proxy, firewall sau NAS instalat?</translation> <translation id="1863047423483329595">Protecția împotriva urmăririi este indisponibilă temporar. În timp ce Chrome actualizează această funcție, site-urile pot folosi temporar cookie-uri terță parte, cu excepția cazului în care le blochezi. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nu s-a găsit niciun port serial</translation> -<translation id="1863207472175483351">Se instalează...</translation> <translation id="1864111464094315414">Conectați-vă</translation> <translation id="1864400682872660285">Mai rece</translation> <translation id="1864454756846565995">Dispozitiv USB-C (portul din spate)</translation> @@ -1845,6 +1844,7 @@ <translation id="2402226831639195063">Tonuri</translation> <translation id="2405887402346713222">Numere de serie ale dispozitivului și ale componentelor</translation> <translation id="2406153734066939945">Ștergi profilul și datele asociate?</translation> +<translation id="2407671304279211586">Selectează furnizorul DNS</translation> <translation id="2408018932941436077">Se salvează cardul</translation> <translation id="2408955596600435184">Introdu codul PIN</translation> <translation id="2409268599591722235">Să începem</translation> @@ -5115,7 +5115,6 @@ <translation id="4988526792673242964">Pagini</translation> <translation id="49896407730300355">Rotiți în sens &invers acelor de ceasornic</translation> <translation id="4989966318180235467">Inspectați pagina de fun&dal</translation> -<translation id="4990949771467040994">Se așteaptă…</translation> <translation id="4991420928586866460">Tastele din rândul de sus sunt considerate taste pentru funcții</translation> <translation id="4992458225095111526">Confirmă Powerwash</translation> <translation id="4992473555164495036">Administratorul a limitat metodele de introducere a textului disponibile.</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index 3b65907..48af2641 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">На вашем компьютере установлено специализированное ПО, например VPN-клиент, прокси-сервер, брандмауэр или NAS?</translation> <translation id="1863047423483329595">Защита от слежения временно недоступна. Пока эта функция в Chrome обновляется, сайтам временно разрешено использовать сторонние файлы cookie, если вы не отключили такую возможность. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Последовательные порты не найдены.</translation> -<translation id="1863207472175483351">Установка…</translation> <translation id="1864111464094315414">Вход</translation> <translation id="1864400682872660285">Холоднее</translation> <translation id="1864454756846565995">Устройство USB-C (порт сзади)</translation> @@ -1846,6 +1845,7 @@ <translation id="2402226831639195063">Тональные символы</translation> <translation id="2405887402346713222">Серийные номера устройства и компонентов</translation> <translation id="2406153734066939945">Удалить профиль и все его данные?</translation> +<translation id="2407671304279211586">Выбрать поставщика услуг DNS</translation> <translation id="2408018932941436077">Сохранение карты</translation> <translation id="2408955596600435184">Введите PIN-код</translation> <translation id="2409268599591722235">Начать</translation> @@ -5116,7 +5116,6 @@ <translation id="4988526792673242964">Страницы</translation> <translation id="49896407730300355">Повернуть п&ротив часовой стрелки</translation> <translation id="4989966318180235467">Исследовать &фоновую страницу</translation> -<translation id="4990949771467040994">Ожидание…</translation> <translation id="4991420928586866460">Использовать клавиши верхнего ряда как функциональные</translation> <translation id="4992458225095111526">Подтверждение Powerwash</translation> <translation id="4992473555164495036">Администратор запретил некоторые способы ввода.</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb index cd9fece..ed10d68 100644 --- a/chrome/app/resources/generated_resources_si.xtb +++ b/chrome/app/resources/generated_resources_si.xtb
@@ -1131,7 +1131,6 @@ ස්ථාපනය කර තිබේද?</translation> <translation id="1863047423483329595">ලුහුබැඳීමේ ආරක්ෂාව තාවකාලිකව නොමැත. Chrome මෙම විශේෂාංගය යාවත්කාලීන කරන අතරතුර, ඔබ ඒවා අවහිර නොකරන්නේ නම් අඩවිවලට තාවකාලිකව තෙවන පාර්ශ්ව කුකී භාවිත කළ හැක. <ph name="BEGIN_LINK" />තව දැන ගන්න<ph name="END_LINK" /></translation> <translation id="1863182668524159459">අනුක්රමික තොට කිසිවක් හමු නොවිය</translation> -<translation id="1863207472175483351">ස්ථාපනය කරමින්...</translation> <translation id="1864111464094315414">පිවිසෙන්න</translation> <translation id="1864400682872660285">ශ්රීතකය</translation> <translation id="1864454756846565995">USB-C උපාංගය (පසුපස තොට)</translation> @@ -5120,7 +5119,6 @@ <translation id="4988526792673242964">පිටු</translation> <translation id="49896407730300355">වාමාවර්තව කරකවන්න (&o)</translation> <translation id="4989966318180235467">පසුබිම් පිටුව විමර්ශනය (&b)</translation> -<translation id="4990949771467040994">රැඳෙමින්...</translation> <translation id="4991420928586866460">ඉහළ පේලියේ යතුරු කාර්ය යතුරු ලෙස භාවිතා කරන්න</translation> <translation id="4992458225095111526">Powerwash තහවුරු කරන්න</translation> <translation id="4992473555164495036">ඔබේ පරිපාලක ලබා ගත හැකි ආදාන ක්රම සීමා කර ඇත.</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index b6a5add..ec53145 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -1132,7 +1132,6 @@ <translation id="1862311223300693744">Máte nainštalované nejaké špeciálne pripojenie VPN, server proxy, bránu firewall alebo softvér NAS?</translation> <translation id="1863047423483329595">Ochrana pred sledovaním je dočasne nedostupná. Počas aktualizácie tejto funkcie Chromom môžu weby dočasne používať súbory cookie tretej strany, pokiaľ ich nezablokujete. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nenašli sa žiadne sériové porty</translation> -<translation id="1863207472175483351">inštaluje sa...</translation> <translation id="1864111464094315414">Prihlásiť sa</translation> <translation id="1864400682872660285">Chladnejšie</translation> <translation id="1864454756846565995">Zariadenie USB-C (port vzadu)</translation> @@ -5116,7 +5115,6 @@ <translation id="4988526792673242964">Stránky</translation> <translation id="49896407730300355">Otočiť &proti smeru hodinových ručičiek</translation> <translation id="4989966318180235467">Skontrolovať &stránku na pozadí</translation> -<translation id="4990949771467040994">čaká sa…</translation> <translation id="4991420928586866460">Považovať klávesy v hornom riadku za funkčné klávesy</translation> <translation id="4992458225095111526">Potvrdenia obnovenia Powerwash</translation> <translation id="4992473555164495036">Správca obmedzil dostupné metódy vstupu.</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index e810725..037b9c35 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -1145,7 +1145,6 @@ programsko opremo NAS?</translation> <translation id="1863047423483329595">Zaščita pred sledenjem trenutno ni na voljo. Medtem ko Chrome posodablja to funkcijo, lahko spletna mesta začasno uporabljajo piškotke tretjih oseb, razen če jih blokirate. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Ni serijskih vrat</translation> -<translation id="1863207472175483351">nameščanje …</translation> <translation id="1864111464094315414">Prijava</translation> <translation id="1864400682872660285">Hladneje</translation> <translation id="1864454756846565995">Naprava USB-C (vrata zadaj)</translation> @@ -5134,7 +5133,6 @@ <translation id="4988526792673242964">Strani</translation> <translation id="49896407730300355">Zasukaj v o&bratni smeri urinega kazalca</translation> <translation id="4989966318180235467">Preglej stran v ozadju</translation> -<translation id="4990949771467040994">čakanje …</translation> <translation id="4991420928586866460">Obravnavaj tipke v zgornji vrstici kot funkcijske tipke</translation> <translation id="4992458225095111526">Potrdite Powerwash</translation> <translation id="4992473555164495036">Skrbnik je omejil razpoložljive načine vnosa.</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb index b9ffef6..541cfb3 100644 --- a/chrome/app/resources/generated_resources_sq.xtb +++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -1127,7 +1127,6 @@ <translation id="1862311223300693744">A ke VPN të veçantë, proxy, mur mbrojtës apo softuer NAS të instaluar?</translation> <translation id="1863047423483329595">"Mbrojtja nga gjurmimi" nuk ofrohet përkohësisht. Ndërkohë që Chrome po përditëson këtë veçori, sajtet mund të përdorin përkohësisht kukit e palëve të treta, përveçse nëse ti i bllokon ato. <ph name="BEGIN_LINK" />Mëso më shumë<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nuk u gjet asnjë portë seriale</translation> -<translation id="1863207472175483351">po instalohet...</translation> <translation id="1864111464094315414">Identifikimi</translation> <translation id="1864400682872660285">Më freskët</translation> <translation id="1864454756846565995">Pajisja USB-C (porta prapa)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">Faqet</translation> <translation id="49896407730300355">Rrotullo k&undër akrepave të orës</translation> <translation id="4989966318180235467">Inspekto &faqen e sfondit</translation> -<translation id="4990949771467040994">në pritje...</translation> <translation id="4991420928586866460">Trajtoji tastet e rreshtit të sipërm si taste të funksioneve</translation> <translation id="4992458225095111526">Konfirmo Powerwash</translation> <translation id="4992473555164495036">Administratori yt ka kufizuar mënyrat e mundshme të shkrimit.</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb index b0431b5..a64ee35 100644 --- a/chrome/app/resources/generated_resources_sr-Latn.xtb +++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -1129,7 +1129,6 @@ <translation id="1862311223300693744">Da li ste instalirali bilo kakav poseban softver za VPN, proksi, zaštitni zid ili NAS?</translation> <translation id="1863047423483329595">Zaštita od praćenja je privremeno nedostupna. Dok Chrome ažurira ovu funkciju, sajtovi mogu privremeno da koriste kolačiće treće strane ako ih ne blokirate. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Nismo pronašli nijedan serijski port</translation> -<translation id="1863207472175483351">instalira se...</translation> <translation id="1864111464094315414">Prijavljivanje</translation> <translation id="1864400682872660285">Hladnije</translation> <translation id="1864454756846565995">Uređaj sa USB priključkom tipa C (zadnji port)</translation> @@ -5113,7 +5112,6 @@ <translation id="4988526792673242964">Stranice</translation> <translation id="49896407730300355">Okreći u s&meru suprotnom od kretanja kazaljke na satu</translation> <translation id="4989966318180235467">Proveri stranicu &pozadine</translation> -<translation id="4990949771467040994">čeka se…</translation> <translation id="4991420928586866460">Tretiraj tastere iz gornjeg reda kao funkcijske tastere</translation> <translation id="4992458225095111526">Potvrđivanje Powerwash-a</translation> <translation id="4992473555164495036">Administrator je ograničio dostupne metode unosa.</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 9774b4b..cf8b013b 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -1129,7 +1129,6 @@ <translation id="1862311223300693744">Да ли сте инсталирали било какав посебан софтвер за VPN, прокси, заштитни зид или NAS?</translation> <translation id="1863047423483329595">Заштита од праћења је привремено недоступна. Док Chrome ажурира ову функцију, сајтови могу привремено да користе колачиће треће стране ако их не блокирате. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Нисмо пронашли ниједан серијски порт</translation> -<translation id="1863207472175483351">инсталира се...</translation> <translation id="1864111464094315414">Пријављивање</translation> <translation id="1864400682872660285">Хладније</translation> <translation id="1864454756846565995">Уређај са USB прикључком типа C (задњи порт)</translation> @@ -5113,7 +5112,6 @@ <translation id="4988526792673242964">Странице</translation> <translation id="49896407730300355">Окрећи у с&меру супротном од кретања казаљке на сату</translation> <translation id="4989966318180235467">Провери страницу &позадине</translation> -<translation id="4990949771467040994">чека се…</translation> <translation id="4991420928586866460">Третирај тастере из горњег реда као функцијске тастере</translation> <translation id="4992458225095111526">Потврђивање Powerwash-а</translation> <translation id="4992473555164495036">Администратор је ограничио доступне методе уноса.</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index 5191318..edff4ad 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -1142,7 +1142,6 @@ installerats?</translation> <translation id="1863047423483329595">Spårningsskydd är inte tillgängligt för tillfället. Medan Chrome uppdaterar den här funktionen kan webbplatser tillfälligt använda tredjepartscookies om du inte blockerar dem. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Ingen serieport hittades.</translation> -<translation id="1863207472175483351">Installeras …</translation> <translation id="1864111464094315414">Inloggning</translation> <translation id="1864400682872660285">Kallare</translation> <translation id="1864454756846565995">USB-C-enhet (bakre port)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">Sidor</translation> <translation id="49896407730300355">Rotera m&oturs</translation> <translation id="4989966318180235467">Kontrollera &bakgrundssida</translation> -<translation id="4990949771467040994">väntar …</translation> <translation id="4991420928586866460">Använd tangenterna på översta raden som funktionstangenter</translation> <translation id="4992458225095111526">Bekräfta återställning med Powerwash</translation> <translation id="4992473555164495036">Administratören har begränsat vilka inmatningsmetoder som är tillgängliga.</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index 09c480c..e88065a 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -1138,7 +1138,6 @@ <translation id="1862311223300693744">Je, umesakinisha programu yoyote maalum ya VPN, seva mbadala, kinga mtandao au NAS?</translation> <translation id="1863047423483329595">Kipengele cha Ulinzi dhidi ya Ufuatiliaji hakipatikani kwa muda. Chrome inaposasisha kipengele hiki, tovuti zinaweza kutumia vidakuzi vya washirika wengine isipokuwa ukivizuia. <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Haikupata milango yoyote ya kuingiza</translation> -<translation id="1863207472175483351">inasakinisha...</translation> <translation id="1864111464094315414">Ingia</translation> <translation id="1864400682872660285">Isiyo angavu</translation> <translation id="1864454756846565995">Kifaa cha USB-C (mlango wa nyuma)</translation> @@ -5126,7 +5125,6 @@ <translation id="4988526792673242964">Kurasa</translation> <translation id="49896407730300355">Zungusha kinyume saa</translation> <translation id="4989966318180235467">Ukaguzi na ukurasa wa mandharinyuma</translation> -<translation id="4990949771467040994">inasubiri...</translation> <translation id="4991420928586866460">Chukulia vitufe vya safu mlalo ya juu kama vitufe vya chaguo za kukokotoa</translation> <translation id="4992458225095111526">Thibitisha Powerwash</translation> <translation id="4992473555164495036">Msimamizi wako amedhibiti njia zilizopo za kuweka data.</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index 8d45e81..588f819 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -1142,7 +1142,6 @@ நிறுவியுள்ளீர்களா?</translation> <translation id="1863047423483329595">'கண்காணிப்புத் தடுப்பு' தற்காலிகமாகக் கிடைக்கவில்லை. மூன்றாம் தரப்புக் குக்கீகளைத் தடுக்கவில்லை என்றால் Chrome இந்த அம்சத்தைப் புதுப்பிக்கும் வரை தளங்கள் அவற்றைத் தற்காலிகமாகப் பயன்படுத்தலாம். <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" /></translation> <translation id="1863182668524159459">சீரியல் போர்ட்டுகள் இல்லை</translation> -<translation id="1863207472175483351">நிறுவுகிறது...</translation> <translation id="1864111464094315414">உள்நுழைவு</translation> <translation id="1864400682872660285">அதிக நீலம்</translation> <translation id="1864454756846565995">USB-C சாதனம் (பின்பக்கப் போர்ட்)</translation> @@ -5130,7 +5129,6 @@ <translation id="4988526792673242964">பக்கங்கள்</translation> <translation id="49896407730300355">இ&டஞ்சுழியாகச் சுற்று</translation> <translation id="4989966318180235467">&பின்புலப் பக்கத்தை ஆய்வுசெய்</translation> -<translation id="4990949771467040994">காத்திருக்கிறது...</translation> <translation id="4991420928586866460">முதன்மை வரிசை விசைகளைச் செயல்பாட்டு விசைகளாக பயன்படுத்து</translation> <translation id="4992458225095111526">பவர்வாஷை உறுதிப்படுத்தவும்</translation> <translation id="4992473555164495036">பயன்படுத்தக்கூடிய உள்ளீட்டு முறைகளை உங்கள் நிர்வாகி கட்டுப்படுத்தியுள்ளார்.</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index ef1ab7d..7210659 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -1140,7 +1140,6 @@ ఇన్స్టాల్ చేశారా?</translation> <translation id="1863047423483329595">ట్రాకింగ్ నుండి రక్షణ తాత్కాలికంగా అందుబాటులో లేదు. Chrome ఈ ఫీచర్ను అప్డేట్ చేస్తున్నప్పుడు, మీరు థర్డ్-పార్టీ కుక్కీలను బ్లాక్ చేయనంత వరకు సైట్లు తాత్కాలికంగా వాటిని ఉపయోగించగలవు. <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" /></translation> <translation id="1863182668524159459">సీరియల్ పోర్ట్లు కనుగొనబడలేదు</translation> -<translation id="1863207472175483351">ఇన్స్టాల్ అవుతోంది...</translation> <translation id="1864111464094315414">లాగిన్</translation> <translation id="1864400682872660285">చల్లని</translation> <translation id="1864454756846565995">USB-C పరికరం (వెనుకవైపు పోర్ట్)</translation> @@ -5129,7 +5128,6 @@ <translation id="4988526792673242964">పేజీలు</translation> <translation id="49896407730300355">అ&పసవ్యదిశలో తిప్పు</translation> <translation id="4989966318180235467">&నేపథ్య పేజీని పర్యవేక్షించు</translation> -<translation id="4990949771467040994">వేచి ఉంది…</translation> <translation id="4991420928586866460">ఎగువ-అడ్డు వరుస కీలను ఫంక్షన్ కీల లాగా పరిగణించు</translation> <translation id="4992458225095111526">పవర్వాష్ను నిర్ధారించండి</translation> <translation id="4992473555164495036">మీ నిర్వాహకుడు మీకు అందుబాటులో ఉండే ఇన్పుట్ పద్ధతులను పరిమితం చేశారు.</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index 370ea35..6a28c5c 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -681,6 +681,7 @@ <translation id="1536754031901697553">กำลังยกเลิกการเชื่อมต่อ...</translation> <translation id="1537254971476575106">แว่นขยายทั้งหน้าจอ</translation> <translation id="15373452373711364">เคอร์เซอร์เมาส์ขนาดใหญ่</translation> +<translation id="1539727654733007771">ไม่ได้ตั้งค่าเครือข่ายมือถือไว้ ดาวน์โหลด<ph name="BEGIN_LINK" />โปรไฟล์<ph name="END_LINK" />ใหม่</translation> <translation id="1540265419569299117">บริการแอป ChromeOS</translation> <translation id="1540605929960647700">เปิดใช้โหมดสาธิต</translation> <translation id="1541346352678737112">ไม่พบเครือข่าย</translation> @@ -1130,7 +1131,6 @@ <translation id="1862311223300693744">คุณได้ติดตั้ง VPN, พร็อกซี, ไฟร์วอลล์ หรือซอฟต์แวร์ NAS พิเศษไว้ไหม</translation> <translation id="1863047423483329595">การป้องกันการติดตามไม่พร้อมใช้งานชั่วคราว ในระหว่างที่ Chrome กำลังอัปเดตฟีเจอร์นี้ เว็บไซต์จะใช้คุกกี้ของบุคคลที่สามได้ชั่วคราว เว้นแต่คุณจะบล็อกคุกกี้ของบุคคลที่สาม <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> <translation id="1863182668524159459">ไม่พบพอร์ตอนุกรม</translation> -<translation id="1863207472175483351">กำลังติดตั้ง...</translation> <translation id="1864111464094315414">ลงชื่อเข้าใช้</translation> <translation id="1864400682872660285">เย็น</translation> <translation id="1864454756846565995">อุปกรณ์ USB-C (พอร์ตด้านหลัง)</translation> @@ -1251,6 +1251,7 @@ <translation id="1951012854035635156">ผู้ช่วย</translation> <translation id="1954597385941141174">เว็บไซต์ขอเชื่อมต่อกับอุปกรณ์ USB ได้</translation> <translation id="1954813140452229842">เกิดข้อผิดพลาดขณะต่อเชื่อมพื้นที่แชร์ โปรดตรวจสอบข้อมูลรับรองแล้วลองอีกครั้ง</translation> +<translation id="1955313993396968525">ค้นหาเฟรมวิดีโอด้วย <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="1956050014111002555">ไฟล์มีใบรับรองหลายใบ แต่ไม่มีการนำเข้าใบรับรอง:</translation> <translation id="1956167375087861299">ไม่อนุญาตให้ใช้ตัวระบุเพื่อเล่นเนื้อหาที่มีการคุ้มครอง</translation> <translation id="1956390763342388273">การดำเนินการนี้จะอัปโหลดไฟล์ทั้งหมดจาก "<ph name="FOLDER_PATH" />" ดำเนินการนี้เฉพาะในกรณีที่คุณเชื่อถือเว็บไซต์ดังกล่าวเท่านั้น</translation> @@ -1821,6 +1822,7 @@ <translation id="237828693408258535">แปลหน้านี้ไหม</translation> <translation id="2378982052244864789">เลือกไดเรกทอรีของส่วนขยาย</translation> <translation id="2379281330731083556">พิมพ์โดยใช้ช่องโต้ตอบของระบบ... <ph name="SHORTCUT_KEY" /></translation> +<translation id="2381461748765773292">ซึ่งอาจทำให้เครือข่ายมือถือของคุณยกเลิกการเชื่อมต่อสักครู่หนึ่ง</translation> <translation id="2381499968174336913">ตัวอย่างแท็บที่แชร์</translation> <translation id="2382875860893882175">การแคสต์หยุดอยู่ชั่วคราวในขณะนี้ คุณแคสต์ต่อหรือหยุดการแคสต์ได้ทุกเมื่อ</translation> <translation id="2383825469508278924">เปลี่ยนการแมปแป้นบนแป้นพิมพ์ แป้นฟังก์ชัน และอื่นๆ</translation> @@ -5116,7 +5118,6 @@ <translation id="4988526792673242964">หน้า</translation> <translation id="49896407730300355">หมุน&ทวนเข็มนาฬิกา</translation> <translation id="4989966318180235467">ตรวจสอบ&หน้าพื้นหลัง</translation> -<translation id="4990949771467040994">กำลังรอ…</translation> <translation id="4991420928586866460">ใช้แป้นแถวบนสุดเป็นแป้นฟังก์ชัน</translation> <translation id="4992458225095111526">ยืนยัน Powerwash</translation> <translation id="4992473555164495036">ผู้ดูแลระบบจำกัดวิธีการป้อนข้อมูลที่ใช้ได้เอาไว้</translation> @@ -6780,6 +6781,7 @@ <translation id="6344576354370880196">เครื่องพิมพ์ที่บันทึกไว้</translation> <translation id="6344608411615208519">ผู้ปกครองของคุณเป็นผู้<ph name="BEGIN_LINK" />จัดการเบราว์เซอร์<ph name="END_LINK" /></translation> <translation id="6344622098450209924">การป้องกันการติดตาม</translation> +<translation id="6345203628032613660">ค้นหาเฟรมวิดีโอด้วย <ph name="VISUAL_SEARCH_PROVIDER" /></translation> <translation id="6345418402353744910">ชื่อผู้ใช้และรหัสผ่านของคุณจำเป็นสำหรับพร็อกซี <ph name="PROXY" /> เพื่อให้ผู้ดูแลระบบกำหนดค่าเครือข่ายได้</translation> <translation id="6345566021391290381">มีรหัสผ่านที่แชร์กับคุณสำหรับ <ph name="WEBSITE_NAME" /> คุณสามารถใช้รหัสผ่านเหล่านั้นในแบบฟอร์มลงชื่อเข้าใช้ได้</translation> <translation id="6345878117466430440">ทำเครื่องหมายว่าอ่านแล้ว</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index e1d7031..9232aa1c 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">Herhangi bir özel VPN, proxy, güvenlik duvarı veya NAS yazılımı yüklü mü?</translation> <translation id="1863047423483329595">İzlemeye Karşı Koruma özelliği geçici olarak kullanılamıyor. Chrome bu özelliği güncellerken siteler, engellemediğiniz sürece üçüncü taraf çerezlerini geçici olarak kullanabilir. <ph name="BEGIN_LINK" />Daha fazla bilgi<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Seri bağlantı noktası bulunamadı</translation> -<translation id="1863207472175483351">yükleniyor...</translation> <translation id="1864111464094315414">Oturum Aç</translation> <translation id="1864400682872660285">Daha Soğuk</translation> <translation id="1864454756846565995">USB-C cihaz (arka bağlantı noktası)</translation> @@ -5112,7 +5111,6 @@ <translation id="4988526792673242964">Sayfalar</translation> <translation id="49896407730300355">Saat yönünün &tersine döndür</translation> <translation id="4989966318180235467">&Arka plan sayfasını incele</translation> -<translation id="4990949771467040994">bekliyor...</translation> <translation id="4991420928586866460">Üst satırdaki tuşları işlev tuşları olarak kullan</translation> <translation id="4992458225095111526">Powerwash'ı onaylayın</translation> <translation id="4992473555164495036">Yöneticiniz kullanılıabilir giriş yöntemlerini sınırladı.</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index acfaccb7..e20c2cdb 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -1145,7 +1145,6 @@ або NAS?</translation> <translation id="1863047423483329595">Функція "Захист від відстеження" тимчасово недоступна. Поки Chrome оновлює цю функцію, сайти можуть тимчасово використовувати сторонні файли cookie, якщо ви їх не заблокуєте. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Немає послідовних портів</translation> -<translation id="1863207472175483351">встановлення…</translation> <translation id="1864111464094315414">Вхід</translation> <translation id="1864400682872660285">Холод</translation> <translation id="1864454756846565995">Пристрій із портом USB типу C (на задній панелі)</translation> @@ -5133,7 +5132,6 @@ <translation id="4988526792673242964">Сторінки</translation> <translation id="49896407730300355">Повернути п&роти годинникової стрілки</translation> <translation id="4989966318180235467">Перевірити &фонову сторінку</translation> -<translation id="4990949771467040994">очікування…</translation> <translation id="4991420928586866460">Використовувати клавіші вгорі клавіатури як функціональні клавіші</translation> <translation id="4992458225095111526">Підтвердити відновлення заводських налаштувань</translation> <translation id="4992473555164495036">Адміністратор обмежив доступні методи введення.</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb index 693fa4ff..cfcb2e03 100644 --- a/chrome/app/resources/generated_resources_ur.xtb +++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">کیا آپ نے کوئی خصوصی VPN، پراکسی، فائروال یا NAS سافٹ ویئر انسٹال کیا ہوا ہے؟</translation> <translation id="1863047423483329595">ٹریکنگ تحفظ عارضی طور پر دستیاب نہیں ہے۔ جب Chrome اس خصوصیت کو اپ ڈیٹ کر رہا ہے تو سائٹس عارضی طور پر فریق ثالث کوکیز استعمال کر سکتی ہیں جب تک کہ آپ انہیں مسدود نہ کر دیں۔ <ph name="BEGIN_LINK" />مزید جانیں<ph name="END_LINK" /></translation> <translation id="1863182668524159459">کوئی سیریل پورٹ نہیں ملا</translation> -<translation id="1863207472175483351">انسٹال ہو رہی ہے...</translation> <translation id="1864111464094315414">لاگ ان</translation> <translation id="1864400682872660285">کولر</translation> <translation id="1864454756846565995">USB-C آلہ (پیچھے کا پورٹ)</translation> @@ -1846,6 +1845,7 @@ <translation id="2402226831639195063">ٹونز</translation> <translation id="2405887402346713222">آلہ اور اجزا کے نمبر شمار</translation> <translation id="2406153734066939945">اس پروفائل اور اس کے ڈیٹا کو حذف کریں؟</translation> +<translation id="2407671304279211586">DNS فراہم کنندہ کو منتخب کریں</translation> <translation id="2408018932941436077">کارڈ محفوظ ہو رہا ہے</translation> <translation id="2408955596600435184">اپنا PIN درج کریں</translation> <translation id="2409268599591722235">آئیے شروع کریں</translation> @@ -5116,7 +5116,6 @@ <translation id="4988526792673242964">صفحات</translation> <translation id="49896407730300355">گ&ھڑی کی مخالف سمت میں گھمائیں</translation> <translation id="4989966318180235467">&پس منظر کے صفحہ کا معائنہ کریں</translation> -<translation id="4990949771467040994">منتظر ہے...</translation> <translation id="4991420928586866460">سر فہرست قطار کی کلیدوں کو فنکشن کلیدوں کے بطور خیال کریں</translation> <translation id="4992458225095111526">پاور واش کی توثیق کریں</translation> <translation id="4992473555164495036">آپ کے منتظم نے اندراج کے دستیاب طریقوں کو محدود کیا ہوا ہے۔</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb index c07c056..04f559a 100644 --- a/chrome/app/resources/generated_resources_uz.xtb +++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -1129,7 +1129,6 @@ oʻrnatilganmi?</translation> <translation id="1863047423483329595">Kuzatuvdan himoya vaqtincha ishlamayapti Chrome bu funksiyani yangilayotganda saytlar vaqtincha tashqi cookie fayllardan foydalanishi mumkin (agar bloklanmagan boʻlsa). <ph name="BEGIN_LINK" />Batafsil<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Hech qanday ketma-ket port topilmadi</translation> -<translation id="1863207472175483351">oʻrnatilmoqda...</translation> <translation id="1864111464094315414">Kirish</translation> <translation id="1864400682872660285">Salqinroq</translation> <translation id="1864454756846565995">USB-C qurilma (orqa port)</translation> @@ -5118,7 +5117,6 @@ <translation id="4988526792673242964">Sahifalar</translation> <translation id="49896407730300355">Soat miliga teskari yo‘nalishda burish</translation> <translation id="4989966318180235467">&Orqa fon sahifasini ko‘rib chiqish</translation> -<translation id="4990949771467040994">kutilmoqda…</translation> <translation id="4991420928586866460">Yuqori qatordagi tugmalardan funksiya tugmalari sifatida foydalanish</translation> <translation id="4992458225095111526">Powerwash ishlatishni tasdiqlash</translation> <translation id="4992473555164495036">Ba’zi kiritish usullari administrator tomonidan cheklangan.</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index 74396ab5..0edcbd8 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -1142,7 +1142,6 @@ nào không?</translation> <translation id="1863047423483329595">Tính năng Chống theo dõi tạm thời không hoạt động. Trong khi Chrome đang cập nhật tính năng này, các trang web có thể tạm thời dùng cookie của bên thứ ba, trừ phi bạn chặn các cookie này. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Không tìm thấy cổng nối tiếp nào</translation> -<translation id="1863207472175483351">đang cài đặt...</translation> <translation id="1864111464094315414">Đăng nhập</translation> <translation id="1864400682872660285">Mát hơn</translation> <translation id="1864454756846565995">Thiết bị USB-C (cổng phía sau)</translation> @@ -5131,7 +5130,6 @@ <translation id="4988526792673242964">Trang</translation> <translation id="49896407730300355">Xoay &ngược chiều kim đồng hồ</translation> <translation id="4989966318180235467">Kiểm tra trang &nền</translation> -<translation id="4990949771467040994">đang chờ…</translation> <translation id="4991420928586866460">Coi các phím ở hàng trên cùng là phím chức năng</translation> <translation id="4992458225095111526">Xác nhận Powerwash</translation> <translation id="4992473555164495036">Quản trị viên của bạn đã giới hạn các phương thức nhập có sẵn.</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index f714b8de..1400e4a0c0 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -1123,7 +1123,6 @@ <translation id="1862311223300693744">您安装了任何特殊的 VPN、代理、防火墙或 NAS 软件吗?</translation> <translation id="1863047423483329595">暂时无法使用“跟踪保护”功能。在 Chrome 更新此功能期间,网站可暂时使用第三方 Cookie,除非您屏蔽了这类 Cookie。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation> <translation id="1863182668524159459">未发现串行端口</translation> -<translation id="1863207472175483351">正在安装…</translation> <translation id="1864111464094315414">登录</translation> <translation id="1864400682872660285">冷色调</translation> <translation id="1864454756846565995">USB-C 设备(背面端口)</translation> @@ -5106,7 +5105,6 @@ <translation id="4988526792673242964">页面</translation> <translation id="49896407730300355">逆时针旋转(&O)</translation> <translation id="4989966318180235467">检查背景页(&B)</translation> -<translation id="4990949771467040994">正在等待安装…</translation> <translation id="4991420928586866460">将顶行键设置为功能键</translation> <translation id="4992458225095111526">确认 Powerwash 操作</translation> <translation id="4992473555164495036">您的管理员限制了可用的输入法。</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb index 5742066..944dfca6 100644 --- a/chrome/app/resources/generated_resources_zh-HK.xtb +++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -1142,7 +1142,6 @@ 嗎?</translation> <translation id="1863047423483329595">「追蹤保護」功能暫時無法使用。Chrome 更新此功能時,網站可能會暫時使用第三方 Cookie,除非你封鎖這類 Cookie。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> <translation id="1863182668524159459">找不到序列連接埠</translation> -<translation id="1863207472175483351">正在安裝…</translation> <translation id="1864111464094315414">登入</translation> <translation id="1864400682872660285">冷色調</translation> <translation id="1864454756846565995">USB-C 裝置 (後方連接埠)</translation> @@ -2691,6 +2690,7 @@ <translation id="3021065318976393105">使用電池時</translation> <translation id="3021066826692793094">蝴蝶</translation> <translation id="3021678814754966447">檢視頁框原始碼(&V)</translation> +<translation id="3021902017511220299">掃描失敗。系統管理員已禁止這項操作。</translation> <translation id="3022361196600037287"><ph name="DEVICE" /> 將會從此 Chromebook 移除,且不會儲存至 <ph name="PRIMARY_EMAIL" />。</translation> <translation id="3022978424994383087">無法辨識語音。</translation> <translation id="3023464535986383522">揀選朗讀內容</translation> @@ -5127,7 +5127,6 @@ <translation id="4988526792673242964">網頁</translation> <translation id="49896407730300355">逆時針旋轉(&O)</translation> <translation id="4989966318180235467">檢查背景頁面(&B)</translation> -<translation id="4990949771467040994">正在等候…</translation> <translation id="4991420928586866460">使用最上方一排按鍵作為功能鍵</translation> <translation id="4992458225095111526">確認執行 Powerwash</translation> <translation id="4992473555164495036">您的管理員已限制可用的輸入方法。</translation> @@ -9056,6 +9055,7 @@ <translation id="811994229154425014">按空白鍵兩下插入句號</translation> <translation id="8120505434908124087">安裝 eSIM 卡設定檔</translation> <translation id="8121750884985440809">您目前正在投放螢幕畫面</translation> +<translation id="8122898034710982882">Phone Hub、<ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">黃色和白色的花</translation> <translation id="8123975449645947908">向後捲動</translation> <translation id="8124313775439841391">管理 ONC</translation> @@ -9091,6 +9091,7 @@ <translation id="8148760431881541277">限制登入</translation> <translation id="8149564499626272569">透過連接 USB 連接線的手機進行驗證</translation> <translation id="8149870652370242480">如要在手機上使用儲存的密碼,請下載 Chrome iOS 版,然後登入 Google 帳戶。</translation> +<translation id="8151057139207656239">已複製版本詳細資料</translation> <translation id="815114315010033526">改用 QR 碼</translation> <translation id="8151638057146502721">設定</translation> <translation id="8154790740888707867">沒有檔案</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index 6bb6fb9e..84ad66f 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -1130,7 +1130,6 @@ <translation id="1862311223300693744">你是否安裝了任何特殊的 VPN、Proxy、防火牆或網路附加儲存 (NAS) 軟體?</translation> <translation id="1863047423483329595">追蹤保護功能暫時無法使用。Chrome 更新這項功能時,網站可能會暫時使用第三方 Cookie (除非你封鎖這類 Cookie)。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> <translation id="1863182668524159459">找不到序列埠</translation> -<translation id="1863207472175483351">安裝中...</translation> <translation id="1864111464094315414">登入</translation> <translation id="1864400682872660285">冷色調</translation> <translation id="1864454756846565995">USB-C 裝置 (背面連接埠)</translation> @@ -2676,6 +2675,7 @@ <translation id="3021065318976393105">使用電池時</translation> <translation id="3021066826692793094">蝴蝶</translation> <translation id="3021678814754966447">檢視頁框原始碼(&V)</translation> +<translation id="3021902017511220299">掃描失敗。系統管理員已禁止這項操作。</translation> <translation id="3022361196600037287"><ph name="DEVICE" /> 將從這部 Chromebook 中移除,且不會儲存至 <ph name="PRIMARY_EMAIL" />。</translation> <translation id="3022978424994383087">無法辨識語音內容。</translation> <translation id="3023464535986383522">隨選朗讀</translation> @@ -5114,7 +5114,6 @@ <translation id="4988526792673242964">網頁</translation> <translation id="49896407730300355">逆時針旋轉(&O)</translation> <translation id="4989966318180235467">檢查背景頁面(&B)</translation> -<translation id="4990949771467040994">等待中…</translation> <translation id="4991420928586866460">使用最上方一排按鍵做為功能鍵</translation> <translation id="4992458225095111526">確認執行 Powerwash</translation> <translation id="4992473555164495036">你的管理員對可用的輸入法設定了限制。</translation> @@ -9042,6 +9041,7 @@ <translation id="811994229154425014">按兩下空格鍵可輸入句號</translation> <translation id="8120505434908124087">安裝 eSIM 卡設定檔</translation> <translation id="8121750884985440809">你目前正在投放螢幕畫面</translation> +<translation id="8122898034710982882">Phone Hub、<ph name="FEATURE_NAME" /></translation> <translation id="81238879832906896">黃色和白色花朵</translation> <translation id="8123975449645947908">向後捲動</translation> <translation id="8124313775439841391">管理化 ONC</translation> @@ -9077,6 +9077,7 @@ <translation id="8148760431881541277">限制登入</translation> <translation id="8149564499626272569">透過接上 USB 傳輸線的手機進行驗證</translation> <translation id="8149870652370242480">如要在手機上使用儲存的密碼,請下載 Chrome iOS 版,然後登入 Google 帳戶。</translation> +<translation id="8151057139207656239">已複製版本詳細資料</translation> <translation id="815114315010033526">改用 QR 圖碼</translation> <translation id="8151638057146502721">設定</translation> <translation id="8154790740888707867">沒有檔案</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb index 2373f89..ffc91ac 100644 --- a/chrome/app/resources/generated_resources_zu.xtb +++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -1141,7 +1141,6 @@ efakiwe?</translation> <translation id="1863047423483329595">Ukuvikela ukulandelela akutholakali okwamanje. Ngenkathi i-Chrome ibuyekeza lesi sakhi, amasayithi angasebenzisa okwesikhashana amakhukhi ngaphandle uma uwavimba. <ph name="BEGIN_LINK" />Funda kabanzi<ph name="END_LINK" /></translation> <translation id="1863182668524159459">Azikho izimbobo ze-serial ezitholiwe</translation> -<translation id="1863207472175483351">iyafaka...</translation> <translation id="1864111464094315414">Ngena ngemvume</translation> <translation id="1864400682872660285">Kupholile</translation> <translation id="1864454756846565995">Idivayisi ye-USB-C (imbobo esemuva)</translation> @@ -5130,7 +5129,6 @@ <translation id="4988526792673242964">Amakhasi</translation> <translation id="49896407730300355">Jikisa n&gokuphikisana newashi</translation> <translation id="4989966318180235467">Hlola ikhasi elisemuva</translation> -<translation id="4990949771467040994">isalindile…</translation> <translation id="4991420928586866460">Phatha okhiye berowu elingaphezulu njengokhiye bokusebenza</translation> <translation id="4992458225095111526">Qinisekisa i-Powerwash</translation> <translation id="4992473555164495036">Umqondisi wakho ukhawulele izindlela zokufaka.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_en-GB.xtb b/chrome/app/resources/google_chrome_strings_en-GB.xtb index f97dbe9f..67f371b 100644 --- a/chrome/app/resources/google_chrome_strings_en-GB.xtb +++ b/chrome/app/resources/google_chrome_strings_en-GB.xtb
@@ -26,6 +26,7 @@ <translation id="139993653570221430">You can change your mind at any time in Chrome settings. The trials run alongside the current way that ads get served, so you won’t see changes right away.</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome is done updating. You can use the latest version as soon as you relaunch. Your current tabs will then reopen.}=1{Chrome is done updating. You can use the latest version as soon as you relaunch. Your current tabs will then reopen. Your incognito window won't reopen.}other{Chrome is done updating. You can use the latest version as soon as you relaunch. Your current tabs will then reopen. Your # incognito windows won't reopen.}}</translation> <translation id="1434626383986940139">Chrome Canary Apps</translation> +<translation id="146866447420868597">Sign in to Chrome?</translation> <translation id="1492280395845991349">Relaunch to finish Chrome update</translation> <translation id="1497802159252041924">Install error: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">Customise your new Chrome profile</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ja.xtb b/chrome/app/resources/google_chrome_strings_ja.xtb index c5344fac..8c7ddbb 100644 --- a/chrome/app/resources/google_chrome_strings_ja.xtb +++ b/chrome/app/resources/google_chrome_strings_ja.xtb
@@ -24,6 +24,7 @@ <translation id="139993653570221430">この設定は Chrome の設定でいつでも変更できます。テストは、現在の方法での広告配信と並行して実施されるため、すぐに変化が現れるわけではありません。</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome の更新が完了しました。再起動すると最新バージョンをすぐに使用できます。その後、現在のタブが再度開きます。}=1{Chrome の更新が完了しました。再起動すると最新バージョンをすぐに使用できます。その後、現在のタブが再度開きます。シークレット ウィンドウは、再起動後は自動的には開きません。}other{Chrome の更新が完了しました。再起動すると最新バージョンをすぐに使用できます。その後、現在のタブが再度開きます。現在開いている # 個のシークレット ウィンドウは、再起動後は自動的には開きません。}}</translation> <translation id="1434626383986940139">Chrome Canary アプリ</translation> +<translation id="146866447420868597">Chrome にログインしますか?</translation> <translation id="1492280395845991349">Chrome の更新を完了するには再起動してください</translation> <translation id="1497802159252041924">インストール エラー: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">新しい Chrome プロフィールをカスタマイズ</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lt.xtb b/chrome/app/resources/google_chrome_strings_lt.xtb index acb2f97b..d8eecf8c 100644 --- a/chrome/app/resources/google_chrome_strings_lt.xtb +++ b/chrome/app/resources/google_chrome_strings_lt.xtb
@@ -26,6 +26,7 @@ <translation id="139993653570221430">Bet kada galite persigalvoti ir tai pakeisti „Chrome“ nustatymuose. Bandomuoju laikotarpiu skelbimai taip pat pateikiami esamu būdu, todėl pokyčių galite pastebėti ne iš karto.</translation> <translation id="1425903838053942728">{COUNT,plural, =0{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo.}=1{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo. Inkognito langas nebus atidarytas iš naujo.}one{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo. # inkognito langas nebus atidarytas iš naujo.}few{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo. # inkognito langai nebus atidaryti iš naujo.}many{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo. # inkognito lango nebus atidaryta iš naujo.}other{„Chrome“ atnaujinta. Naujausią versiją galite naudoti iš karto, kai paleidžiama iš naujo. Dabartiniai skirtukai bus atidaryti iš naujo. # inkognito langų nebus atidaryta iš naujo.}}</translation> <translation id="1434626383986940139">„Chrome“ programos („Canary“)</translation> +<translation id="146866447420868597">Prisijungti prie „Chrome“?</translation> <translation id="1492280395845991349">Paleiskite iš naujo, kad užbaigtumėte „Chrome“ atnaujinimą</translation> <translation id="1497802159252041924">Diegimo klaida: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">Tinkinkite naująjį „Chrome“ profilį</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb index 4631228..9469f78 100644 --- a/chrome/app/resources/google_chrome_strings_ms.xtb +++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -24,6 +24,7 @@ <translation id="139993653570221430">Anda boleh mengubah fikiran anda pada bila-bila masa dalam tetapan Chrome. Percubaan ini dijalankan di samping cara semasa iklan disiarkan, oleh itu anda tidak akan melihat perubahan dengan serta-merta.</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome sudah selesai membuat pengemaskinian. Anda boleh menggunakan versi terkini setelah anda membuat pelancaran semula. Selepas itu, tab semasa anda akan dibuka semula.}=1{Chrome sudah selesai membuat pengemaskinian. Anda boleh menggunakan versi terkini setelah anda membuat pelancaran semula. Selepas itu, tab semasa anda akan dibuka semula. Tetingkap Inkognito anda tidak akan dibuka semula.}other{Chrome sudah selesai membuat pengemaskinian. Anda boleh menggunakan versi terkini setelah anda membuat pelancaran semula. Selepas itu, tab semasa anda akan dibuka semula. # tetingkap Inkognito anda tidak akan dibuka semula.}}</translation> <translation id="1434626383986940139">Apl Chrome Canary</translation> +<translation id="146866447420868597">Log masuk ke Chrome?</translation> <translation id="1492280395845991349">Lancarkan semula untuk menyelesaikan pengemaskinian Chrome</translation> <translation id="1497802159252041924">Ralat pemasangan: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">Sesuaikan profil Chrome baharu anda</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ne.xtb b/chrome/app/resources/google_chrome_strings_ne.xtb index 2d6a87b..a6f82fd 100644 --- a/chrome/app/resources/google_chrome_strings_ne.xtb +++ b/chrome/app/resources/google_chrome_strings_ne.xtb
@@ -26,6 +26,7 @@ <translation id="139993653570221430">तपाईं जुनसुकै बेला Chrome का सेटिङमा गई आफ्नो सहमति फिर्ता लिन सक्नुहुन्छ। यी ट्रायलहरूमा विज्ञापन देखाउने हालको तरिका नै अपनाइने भएकाले तपाईंले गर्नुभएका परिवर्तनहरू तुरुन्तै लागू हुँदैनन्।</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome अपडेट भएको छ। तपाईं रिलन्च गर्ने बित्तिकै नवीनतम संस्करण प्रयोग गर्न सक्नुहुन्छ। त्यसपछि तपाईंका ट्याबहरू फेरि खुल्ने छन्।}=1{Chrome अपडेट भएको छ। तपाईं रिलन्च गर्ने बित्तिकै नवीनतम संस्करण प्रयोग गर्न सक्नुहुन्छ। त्यसपछि तपाईंका ट्याबहरू फेरि खुल्ने छन्। तपाईंको इन्कोग्निटो विन्डो फेरि खुल्ने छैन।}other{Chrome अपडेट भएको छ। तपाईं रिलन्च गर्ने बित्तिकै नवीनतम संस्करण प्रयोग गर्न सक्नुहुन्छ। त्यसपछि तपाईंका ट्याबहरू फेरि खुल्ने छन्। तपाईंका # वटा इन्कोग्निटो विन्डो फेरि खुल्ने छैनन्।}}</translation> <translation id="1434626383986940139">Chrome क्यानरी एप्स</translation> +<translation id="146866447420868597">Chrome मा साइन इन गर्ने हो?</translation> <translation id="1492280395845991349">Chrome अपडेट गर्ने प्रक्रिया पूरा गर्न रिलन्च गर्नुहोस्</translation> <translation id="1497802159252041924">इन्स्टल गर्ने क्रममा त्रुटि भयो: <ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">आफ्नो नयाँ Chrome प्रोफाइल आफूले चाहे जस्तो बनाउनुहोस्</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-HK.xtb b/chrome/app/resources/google_chrome_strings_zh-HK.xtb index f32c275..50a69f8 100644 --- a/chrome/app/resources/google_chrome_strings_zh-HK.xtb +++ b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
@@ -26,6 +26,7 @@ <translation id="139993653570221430">您可於 Chrome 設定中隨時改變主意。系統會同時執行試用功能和目前放送廣告的方式,因此您不會立即看到變化。</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟您目前的分頁。}=1{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟您目前的分頁,但您的無痕式視窗不會重新開啟。}other{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟您目前的分頁,但有 # 個無痕式視窗不會重新開啟。}}</translation> <translation id="1434626383986940139">Chrome Canary 應用程式</translation> +<translation id="146866447420868597">要登入 Chrome 嗎?</translation> <translation id="1492280395845991349">重新啟動即可完成 Chrome 更新</translation> <translation id="1497802159252041924">安裝錯誤:<ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">自訂您的新 Chrome 設定檔</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-TW.xtb b/chrome/app/resources/google_chrome_strings_zh-TW.xtb index 2f32da1..3528c0a 100644 --- a/chrome/app/resources/google_chrome_strings_zh-TW.xtb +++ b/chrome/app/resources/google_chrome_strings_zh-TW.xtb
@@ -24,6 +24,7 @@ <translation id="139993653570221430">你隨時可以前往 Chrome 設定變更這個選項。系統會同時執行試用功能和目前放送廣告的方式,因此你不會立即看到變化。</translation> <translation id="1425903838053942728">{COUNT,plural, =0{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟你目前的分頁。}=1{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟你目前的分頁,但無痕式視窗不會重新開啟。}other{Chrome 已完成更新。重新啟動後即可立即使用最新版本。屆時會重新開啟你目前的分頁,但有 # 個無痕式視窗不會重新開啟。}}</translation> <translation id="1434626383986940139">Chrome Canary 應用程式</translation> +<translation id="146866447420868597">要登入 Chrome 嗎?</translation> <translation id="1492280395845991349">重新啟動即可完成 Chrome 更新程序</translation> <translation id="1497802159252041924">安裝錯誤:<ph name="INSTALL_ERROR" /></translation> <translation id="1507198376417198979">自訂新的 Chrome 設定檔</translation>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 7056e4db..62e757a 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -123,6 +123,7 @@ "keyboard_arrow_up_chrome_refresh.icon", "laptop.icon", "leading_scroll.icon", + "left_panel_close.icon", "link_chrome_refresh.icon", "media_controls_arrow_drop_down.icon", "media_controls_arrow_drop_up.icon", @@ -190,6 +191,7 @@ "request_mobile_site_checked.icon", "request_mobile_site_unchecked.icon", "resize_handle.icon", + "right_panel_close.icon", "sad_tab.icon", "safety_check.icon", "save_group.icon",
diff --git a/chrome/app/vector_icons/left_panel_close.icon b/chrome/app/vector_icons/left_panel_close.icon new file mode 100644 index 0000000..3660718 --- /dev/null +++ b/chrome/app/vector_icons/left_panel_close.icon
@@ -0,0 +1,37 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +FLIPS_IN_RTL, +MOVE_TO, 13.5f, 13.25f, +V_LINE_TO, 6.75f, +LINE_TO, 10, 10, +LINE_TO, 13.5f, 13.25f, +CLOSE, +MOVE_TO, 4.4f, 17, +CUBIC_TO, 4.01f, 17, 3.68f, 16.86f, 3.41f, 16.59f, +CUBIC_TO, 3.14f, 16.32f, 3, 15.99f, 3, 15.6f, +V_LINE_TO, 4.4f, +CUBIC_TO, 3, 4.01f, 3.14f, 3.68f, 3.41f, 3.41f, +CUBIC_TO, 3.68f, 3.14f, 4.01f, 3, 4.4f, 3, +H_LINE_TO, 15.6f, +CUBIC_TO, 15.99f, 3, 16.32f, 3.14f, 16.59f, 3.41f, +CUBIC_TO, 16.86f, 3.68f, 17, 4.01f, 17, 4.4f, +V_LINE_TO, 15.6f, +CUBIC_TO, 17, 15.99f, 16.86f, 16.32f, 16.59f, 16.59f, +CUBIC_TO, 16.32f, 16.86f, 15.99f, 17, 15.6f, 17, +H_LINE_TO, 4.4f, +CLOSE, +MOVE_TO, 7, 15.5f, +V_LINE_TO, 4.5f, +H_LINE_TO, 4.5f, +V_LINE_TO, 15.5f, +H_LINE_TO, 7, +CLOSE, +MOVE_TO, 8.5f, 15.5f, +H_LINE_TO, 15.5f, +V_LINE_TO, 4.5f, +H_LINE_TO, 8.5f, +V_LINE_TO, 15.5f, +CLOSE \ No newline at end of file
diff --git a/chrome/app/vector_icons/right_panel_close.icon b/chrome/app/vector_icons/right_panel_close.icon new file mode 100644 index 0000000..141b89c --- /dev/null +++ b/chrome/app/vector_icons/right_panel_close.icon
@@ -0,0 +1,37 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +FLIPS_IN_RTL, +MOVE_TO, 6.5f, 6.75f, +V_LINE_TO, 13.25f, +LINE_TO, 10, 10, +LINE_TO, 6.5f, 6.75f, +CLOSE, +MOVE_TO, 4.4f, 17, +CUBIC_TO, 4.01f, 17, 3.68f, 16.86f, 3.41f, 16.59f, +CUBIC_TO, 3.14f, 16.32f, 3, 15.99f, 3, 15.6f, +V_LINE_TO, 4.4f, +CUBIC_TO, 3, 4.01f, 3.14f, 3.68f, 3.41f, 3.41f, +CUBIC_TO, 3.68f, 3.14f, 4.01f, 3, 4.4f, 3, +H_LINE_TO, 15.6f, +CUBIC_TO, 15.99f, 3, 16.32f, 3.14f, 16.59f, 3.41f, +CUBIC_TO, 16.86f, 3.68f, 17, 4.01f, 17, 4.4f, +V_LINE_TO, 15.6f, +CUBIC_TO, 17, 15.99f, 16.86f, 16.32f, 16.59f, 16.59f, +CUBIC_TO, 16.32f, 16.86f, 15.99f, 17, 15.6f, 17, +H_LINE_TO, 4.4f, +CLOSE, +MOVE_TO, 13, 15.5f, +H_LINE_TO, 15.5f, +V_LINE_TO, 4.5f, +H_LINE_TO, 13, +V_LINE_TO, 15.5f, +CLOSE, +MOVE_TO, 11.5f, 15.5f, +V_LINE_TO, 4.5f, +H_LINE_TO, 4.5f, +V_LINE_TO, 15.5f, +H_LINE_TO, 11.5f, +CLOSE \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7585866..8bc9072 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -11280,15 +11280,6 @@ kOsDesktop, FEATURE_VALUE_TYPE(blink::features::kPasswordStrongLabel)}, #endif -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) - {"attach-logs-to-autofill-rater-extentsion-report", - flag_descriptions::kAttachLogsToAutofillRaterExtensionReportName, - flag_descriptions::kAttachLogsToAutofillRaterExtensionReportDescription, - kOsMac | kOsWin | kOsLinux, - FEATURE_VALUE_TYPE(password_manager::features:: - kAttachLogsToAutofillRaterExtensionReport)}, -#endif - #if !BUILDFLAG(IS_ANDROID) {"trusted-vault-frequent-degraded-recoverability-polling", flag_descriptions::kTrustedVaultFrequentDegradedRecoverabilityPollingName,
diff --git a/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier_unittest.cc b/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier_unittest.cc index f0c5daa9..60bec217 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier_unittest.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier_unittest.cc
@@ -54,9 +54,14 @@ new LiveCaptionUnavailabilityNotifier(*main_rfh(), std::move(receiver)); } + void TearDown() override { + notifier_ = nullptr; + ChromeRenderViewHostTestHarness::TearDown(); + } + private: mojo::Remote<media::mojom::MediaFoundationRendererNotifier> remote_; - raw_ptr<LiveCaptionUnavailabilityNotifier, DanglingUntriaged> notifier_; + raw_ptr<LiveCaptionUnavailabilityNotifier> notifier_ = nullptr; }; TEST_F(LiveCaptionUnavailabilityNotifierTest, MediaFoundationRendererCreated) {
diff --git a/chrome/browser/android/cookies/cookies_fetcher_util.cc b/chrome/browser/android/cookies/cookies_fetcher_util.cc index edde285..3e4b80b 100644 --- a/chrome/browser/android/cookies/cookies_fetcher_util.cc +++ b/chrome/browser/android/cookies/cookies_fetcher_util.cc
@@ -55,7 +55,7 @@ i->LastAccessDate().ToDeltaSinceWindowsEpoch().InMicroseconds(), i->LastUpdateDate().ToDeltaSinceWindowsEpoch().InMicroseconds(), i->IsSecure(), i->IsHttpOnly(), static_cast<int>(i->SameSite()), - i->Priority(), i->IsSameParty(), + i->Priority(), /*sameParty=*/false, base::android::ConvertUTF8ToJavaString(env, pk), static_cast<int>(i->SourceScheme()), i->SourcePort()); env->SetObjectArrayElement(joa.obj(), index++, java_cookie.obj());
diff --git a/chrome/browser/android/preferences/shared_preferences_migrator_android.cc b/chrome/browser/android/preferences/shared_preferences_migrator_android.cc index 1b7c4bf..28dee603 100644 --- a/chrome/browser/android/preferences/shared_preferences_migrator_android.cc +++ b/chrome/browser/android/preferences/shared_preferences_migrator_android.cc
@@ -40,8 +40,7 @@ return absl::nullopt; } - bool result = - shared_prefs.ReadInt(shared_preference_key, /*default_value=*/0); + int result = shared_prefs.ReadInt(shared_preference_key, /*default_value=*/0); shared_prefs.RemoveKey(shared_preference_key); return result; }
diff --git a/chrome/browser/apps/app_service/file_utils_unittest.cc b/chrome/browser/apps/app_service/file_utils_unittest.cc index 7ac73d6..66de567 100644 --- a/chrome/browser/apps/app_service/file_utils_unittest.cc +++ b/chrome/browser/apps/app_service/file_utils_unittest.cc
@@ -54,8 +54,8 @@ ASSERT_TRUE( storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( mount_name_)); - profile_manager_->DeleteAllTestingProfiles(); profile_ = nullptr; + profile_manager_->DeleteAllTestingProfiles(); profile_manager_.reset(); } @@ -91,7 +91,7 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfileManager> profile_manager_; base::ScopedTempDir scoped_temp_dir_; - raw_ptr<TestingProfile, DanglingUntriaged | ExperimentalAsh> profile_; + raw_ptr<TestingProfile, ExperimentalAsh> profile_ = nullptr; }; TEST_F(FileUtilsTest, GetFileSystemURL) {
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 74bd178..8b20a18 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -4082,6 +4082,7 @@ "//chromeos/ash/components/dbus/update_engine:proto", "//chromeos/ash/components/dbus/upstart", "//chromeos/ash/components/dbus/virtual_file_provider", + "//chromeos/ash/components/demo_mode", "//chromeos/ash/components/early_prefs:reader", "//chromeos/ash/components/early_prefs:writer", "//chromeos/ash/components/fwupd",
diff --git a/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc index d7311818..d8121e7 100644 --- a/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc +++ b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc
@@ -373,7 +373,8 @@ EXPECT_FALSE(IsLauncherSearchIphViewVisible()); } -IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig, ClickAssistant) { +IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig, + ClickAssistantInIph) { OpenAppListAndWaitForIphView(); EXPECT_TRUE(IsLauncherSearchIphViewVisible()); @@ -410,6 +411,42 @@ } IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig, + ClickAssistantInSearchBox) { + OpenAppListAndWaitForIphView(); + + EXPECT_TRUE(IsLauncherSearchIphViewVisible()); + if (IsClamshellModeTest()) { + // Confirm that a background is installed as we check that this gets removed + // if IPH is not shown below. + EXPECT_TRUE(search_box_view()->assistant_button()->GetBackground()); + } + + // Confirm that assistant event is recorded. Make sure that the initial count + // is 0 to distinguish this from other events. + base::UserActionTester user_action_tester; + ASSERT_EQ(0, user_action_tester.GetActionCount(kNotifyEventUserActionName)); + views::ImageButton* assistant_button = search_box_view()->assistant_button(); + ASSERT_TRUE(assistant_button); + Click(assistant_button); + EXPECT_EQ(1, user_action_tester.GetActionCount(kNotifyEventUserActionName)); + + EXPECT_TRUE(IsAssistantPageActive()); + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); + + // Dismiss the app list and show it again. IPH won't be shown this time. Note + // that this behavior is coming from the IPH test config. + DismissAppList(); + OpenAppListForSearch(); + EXPECT_FALSE(IsLauncherSearchIphViewVisible()); + + if (IsClamshellModeTest()) { + // Launcher search iph installs a background to an assistant button in the + // search box. It should be removed if the iph gets dismissed. + EXPECT_FALSE(search_box_view()->assistant_button()->GetBackground()); + } +} + +IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig, NoIphWithoutAssistant) { // `AssistantTestApiImpl::SetAssistantEnabled` asserts that the value has // taken effect, i.e. we are sure that Assistant gets disabled after this
diff --git a/chrome/browser/ash/floating_workspace/floating_workspace_util.cc b/chrome/browser/ash/floating_workspace/floating_workspace_util.cc index 01f33df..706a5ebd 100644 --- a/chrome/browser/ash/floating_workspace/floating_workspace_util.cc +++ b/chrome/browser/ash/floating_workspace/floating_workspace_util.cc
@@ -11,8 +11,8 @@ #include "base/command_line.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h" #include "chromeos/ash/components/network/network_handler.h" #include "chromeos/ash/components/network/network_state_handler.h" #include "chromeos/ash/components/network/network_type_pattern.h" @@ -26,9 +26,14 @@ PrefService* GetActiveUserPrefService() { auto* active_user = user_manager::UserManager::Get()->GetActiveUser(); - return active_user - ? ProfileHelper::Get()->GetProfileByUser(active_user)->GetPrefs() - : nullptr; + if (active_user) { + auto* browser_context = + ash::BrowserContextHelper::Get()->GetBrowserContextByUser(active_user); + if (browser_context) { + return Profile::FromBrowserContext(browser_context)->GetPrefs(); + } + } + return nullptr; } } // namespace
diff --git a/chrome/browser/ash/login/demo_mode/demo_setup_controller.cc b/chrome/browser/ash/login/demo_mode/demo_setup_controller.cc index 1189852b..d973bcce 100644 --- a/chrome/browser/ash/login/demo_mode/demo_setup_controller.cc +++ b/chrome/browser/ash/login/demo_mode/demo_setup_controller.cc
@@ -31,15 +31,13 @@ #include "chrome/browser/browser_process.h" #include "chrome/grit/generated_resources.h" #include "chromeos/ash/components/dbus/dbus_thread_manager.h" +#include "chromeos/ash/components/demo_mode/utils/dimensions_utils.h" #include "chromeos/ash/components/install_attributes/install_attributes.h" #include "chromeos/constants/chromeos_features.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "google_apis/gaia/google_service_auth_error.h" -#include "third_party/abseil-cpp/absl/strings/ascii.h" -#include "third_party/icu/source/common/unicode/bytestream.h" -#include "third_party/icu/source/common/unicode/casemap.h" #include "ui/base/l10n/l10n_util.h" namespace ash { @@ -491,16 +489,7 @@ void DemoSetupController::SetAndCanonicalizeRetailerName( const std::string& retailer_name) { - icu::StringByteSink<std::string> byte_sink(&retailer_name_); - UErrorCode error_code = U_ZERO_ERROR; - icu::CaseMap::utf8Fold(/* options= */ 0, retailer_name, byte_sink, - /* edits= */ nullptr, error_code); - retailer_name_.erase( - std::remove_if(retailer_name_.begin(), retailer_name_.end(), - [](unsigned char c) { - return absl::ascii_ispunct(c) || absl::ascii_isspace(c); - }), - retailer_name_.end()); + retailer_name_ = ash::demo_mode::CanonicalizeDimension(retailer_name); } void DemoSetupController::Enroll(
diff --git a/chrome/browser/ash/login/oobe_interactive_ui_test.cc b/chrome/browser/ash/login/oobe_interactive_ui_test.cc index 18234403..134a9142 100644 --- a/chrome/browser/ash/login/oobe_interactive_ui_test.cc +++ b/chrome/browser/ash/login/oobe_interactive_ui_test.cc
@@ -68,6 +68,7 @@ #include "chrome/browser/ui/webui/ash/login/terms_of_service_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/theme_selection_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/touchpad_scroll_screen_handler.h" +#include "chrome/browser/ui/webui/ash/login/tpm_error_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/fake_gaia_mixin.h" @@ -77,6 +78,7 @@ #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h" #include "chromeos/ash/components/system/fake_statistics_provider.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/dbus/power/fake_power_manager_client.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -1140,4 +1142,108 @@ testing::Values(ArcState::kNotAvailable, ArcState::kAcceptTerms))); +class OobeFlexInteractiveUITest + : public OobeBaseTest, + public ::testing::WithParamInterface<::tpm_manager::TpmManagerStatus> { + public: + OobeFlexInteractiveUITest() = default; + OobeFlexInteractiveUITest(const OobeFlexInteractiveUITest&) = delete; + OobeFlexInteractiveUITest& operator=(const OobeFlexInteractiveUITest&) = + delete; + + ~OobeFlexInteractiveUITest() override = default; + + // EnrollmentScreenTest: + void SetUpOnMainThread() override { + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); + original_tpm_check_callback_ = + enrollment_screen->get_tpm_ownership_callback_for_testing(); + enrollment_screen->set_tpm_ownership_callback_for_testing(base::BindOnce( + &OobeFlexInteractiveUITest::HandleTakeTPMOwnershipResponse, + base::Unretained(this))); + + OobeBaseTest::SetUpOnMainThread(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(switches::kTpmIsDynamic); + OobeBaseTest::SetUpCommandLine(command_line); + } + + test::EnrollmentUIMixin enrollment_ui_{&mixin_host_}; + + private: + void HandleTakeTPMOwnershipResponse( + const ::tpm_manager::TakeOwnershipReply& reply) { + EXPECT_FALSE(tpm_reply_.has_value()); + tpm_reply_ = reply; + // Here we substitute fake reply with status that we want to test. + tpm_reply_.value().set_status(GetParam()); + + if (original_tpm_check_callback_) { + std::move(original_tpm_check_callback_).Run(tpm_reply_.value()); + } + } + + EnrollmentScreen::TpmStatusCallback original_tpm_check_callback_; + absl::optional<::tpm_manager::TakeOwnershipReply> tpm_reply_; +}; + +// Verify that ChromeOS Flex behaves as expected on devices with different TPM +// configurations. +IN_PROC_BROWSER_TEST_P(OobeFlexInteractiveUITest, SmokeEnroll) { + LoginDisplayHost::default_host()->GetWizardContext()->is_branded_build = true; + test::WaitForWelcomeScreen(); + RunWelcomeScreenChecks(); + test::TapWelcomeNext(); + + test::WaitForNetworkSelectionScreen(); + RunNetworkSelectionScreenChecks(); + test::TapNetworkSelectionNext(); + + test::WaitForUpdateScreen(); + test::ExitUpdateScreenNoUpdate(); + + LoginDisplayHost* host = LoginDisplayHost::default_host(); + host->HandleAccelerator(LoginAcceleratorAction::kStartEnrollment); + + test::WaitForEnrollmentScreen(); + switch (GetParam()) { + case ::tpm_manager::STATUS_SUCCESS: + case ::tpm_manager::STATUS_NOT_AVAILABLE: + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSignin); + return; + case ::tpm_manager::STATUS_DBUS_ERROR: { + OobeScreenExitWaiter(TpmErrorView::kScreenId).Wait(); + test::OobeJS().ExpectVisiblePath({"tpm-error-message", "restartButton"}); + ash::test::TapOnPathAndWaitForOobeToBeDestroyed( + {"tpm-error-message", "restartButton"}); + + EXPECT_EQ( + chromeos::FakePowerManagerClient::Get()->num_request_restart_calls(), + 1); + return; + } + + case ::tpm_manager::STATUS_DEVICE_ERROR: { + OobeScreenExitWaiter(TpmErrorView::kScreenId).Wait(); + test::OobeJS().ExpectVisiblePath({"tpm-error-message", "restartButton"}); + ash::test::TapOnPathAndWaitForOobeToBeDestroyed( + {"tpm-error-message", "restartButton"}); + EXPECT_EQ( + chromeos::FakePowerManagerClient::Get()->num_request_restart_calls(), + 1); + return; + } + } +} + +INSTANTIATE_TEST_SUITE_P(All, + OobeFlexInteractiveUITest, + ::testing::Values(::tpm_manager::STATUS_SUCCESS, + ::tpm_manager::STATUS_DEVICE_ERROR, + ::tpm_manager::STATUS_NOT_AVAILABLE, + ::tpm_manager::STATUS_DBUS_ERROR)); + } // namespace ash
diff --git a/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.cc b/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.cc index 1c4bc2bb..1037b276 100644 --- a/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.cc +++ b/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.cc
@@ -11,11 +11,14 @@ #include "base/check_op.h" #include "base/logging.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "base/values.h" #include "chrome/browser/ash/login/screens/base_screen.h" #include "chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h" #include "chrome/browser/ash/login/wizard_context.h" #include "chrome/browser/ui/webui/ash/login/osauth/factor_setup_success_screen_handler.h" +#include "chromeos/ash/components/login/auth/public/user_context.h" #include "chromeos/ash/components/osauth/public/auth_session_storage.h" #include "chromeos/ash/components/osauth/public/common_types.h" @@ -53,6 +56,8 @@ } // LINT.ThenChange(/chrome/browser/resources/chromeos/login/screens/osauth/factor_setup_success.js) +const base::TimeDelta kTimeoutDiff = base::Seconds(10); + } // namespace // static @@ -62,14 +67,16 @@ return BaseScreen::kNotApplicable; case Result::kProceed: return "Proceed"; + case Result::kTimedOut: + return "TimedOut"; } } FactorSetupSuccessScreen::FactorSetupSuccessScreen( base::WeakPtr<FactorSetupSuccessScreenView> view, ScreenExitCallback exit_callback) - : BaseScreen(FactorSetupSuccessScreenView::kScreenId, - OobeScreenPriority::DEFAULT), + : BaseOSAuthSetupScreen(FactorSetupSuccessScreenView::kScreenId, + OobeScreenPriority::DEFAULT), view_(std::move(view)), exit_callback_(std::move(exit_callback)) {} @@ -87,12 +94,42 @@ return false; } -void FactorSetupSuccessScreen::HideImpl() {} +void FactorSetupSuccessScreen::HideImpl() { + expiration_timer_.reset(); + BaseOSAuthSetupScreen::HideImpl(); +} void FactorSetupSuccessScreen::ShowImpl() { if (!view_) { return; } + InspectContextAndContinue( + base::BindOnce(&FactorSetupSuccessScreen::InspectContext, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&FactorSetupSuccessScreen::DoShow, + weak_ptr_factory_.GetWeakPtr())); +} + +void FactorSetupSuccessScreen::InspectContext(UserContext* user_context) { + if (!user_context) { + return; + } + base::Time valid_until = user_context->GetSessionLifetime(); + if (valid_until.is_null()) { + return; + } + base::Time timeout = valid_until - kTimeoutDiff; + base::TimeDelta delta = timeout - base::Time::Now(); + if (delta.is_negative()) { + delta = base::Seconds(0); + } + + expiration_timer_ = std::make_unique<base::OneShotTimer>(); + expiration_timer_->Start(FROM_HERE, delta, this, + &FactorSetupSuccessScreen::OnTimeout); +} + +void FactorSetupSuccessScreen::DoShow() { base::Value::Dict params; params.Set("modifiedFactors", GetModifiedFactorsString( @@ -113,4 +150,8 @@ BaseScreen::OnUserAction(args); } +void FactorSetupSuccessScreen::OnTimeout() { + exit_callback_.Run(Result::kTimedOut); +} + } // namespace ash
diff --git a/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.h b/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.h index a12f1c9..65c42e6 100644 --- a/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.h +++ b/chrome/browser/ash/login/screens/osauth/factor_setup_success_screen.h
@@ -9,6 +9,7 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" #include "base/values.h" #include "chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h" @@ -19,12 +20,13 @@ // Screen to inform the user that their authentication factors were // successfully updated during prior operations. -class FactorSetupSuccessScreen : public BaseScreen { +class FactorSetupSuccessScreen : public BaseOSAuthSetupScreen { public: using TView = FactorSetupSuccessScreenView; enum class Result { kNotApplicable, kProceed, + kTimedOut, }; static std::string GetResultString(Result result); @@ -38,12 +40,17 @@ FactorSetupSuccessScreen& operator=(const FactorSetupSuccessScreen&) = delete; private: - // BaseScreen: + // BaseOauthSetupScreen: bool MaybeSkip(WizardContext& context) override; void ShowImpl() override; void HideImpl() override; void OnUserAction(const base::Value::List& args) override; + void InspectContext(UserContext* user_context); + void DoShow(); + void OnTimeout(); + + std::unique_ptr<base::OneShotTimer> expiration_timer_; base::WeakPtr<FactorSetupSuccessScreenView> view_ = nullptr; ScreenExitCallback exit_callback_; base::WeakPtrFactory<FactorSetupSuccessScreen> weak_ptr_factory_{this};
diff --git a/chrome/browser/ash/login/screens/osauth/password_selection_screen.cc b/chrome/browser/ash/login/screens/osauth/password_selection_screen.cc index 93210c99..6424350 100644 --- a/chrome/browser/ash/login/screens/osauth/password_selection_screen.cc +++ b/chrome/browser/ash/login/screens/osauth/password_selection_screen.cc
@@ -19,6 +19,7 @@ #include "chromeos/ash/components/login/auth/auth_factor_editor.h" #include "chromeos/ash/components/login/auth/public/user_context.h" #include "chromeos/ash/services/auth_factor_config/auth_factor_config.h" +#include "chromeos/ash/services/auth_factor_config/auth_factor_config_utils.h" #include "chromeos/ash/services/auth_factor_config/in_process_instances.h" #include "chromeos/ash/services/auth_factor_config/password_factor_editor.h" @@ -126,6 +127,25 @@ return; } + // If user is going through recovery, detect which password need to be updated + // and return immediately. + if (context()->knowledge_factor_setup.auth_setup_flow == + WizardContext::AuthChangeFlow::kRecovery) { + CHECK(auth_factors_config_.HasConfiguredFactor( + cryptohome::AuthFactorType::kPassword)) + << "User need to have a password that should be updated"; + if (auth::IsLocalPassword(*auth_factors_config_.FindFactorByType( + cryptohome::AuthFactorType::kPassword))) { + exit_callback_.Run(Result::LOCAL_PASSWORD_FORCED); + return; + } else { + CHECK(auth::IsGaiaPassword(*auth_factors_config_.FindFactorByType( + cryptohome::AuthFactorType::kPassword))); + exit_callback_.Run(Result::GAIA_PASSWORD_FALLBACK); + return; + } + } + if (context()->skip_post_login_screens_for_tests) { LOG(WARNING) << "Skipping post-login screens, assuming that user has " "online password";
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index 8669acf8..3ff20fd 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -2287,6 +2287,10 @@ case FactorSetupSuccessScreen::Result::kNotApplicable: case FactorSetupSuccessScreen::Result::kProceed: ShowFingerprintSetupScreen(); + break; + case FactorSetupSuccessScreen::Result::kTimedOut: + ShowLoginScreen(); + return; } }
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc index 49cddcfe..26403d02 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash.cc
@@ -122,6 +122,8 @@ std::unique_ptr<DeviceCloudPolicyValidator> validator( CreateValidator(policy)); validator->ValidateInitialKey(install_attributes_->GetDomain()); + validator->ValidateDeviceId(install_attributes_->GetDeviceId(), + CloudPolicyValidatorBase::DEVICE_ID_REQUIRED); DeviceCloudPolicyValidator::StartValidation( std::move(validator), base::BindOnce(&DeviceCloudPolicyStoreAsh::OnPolicyToStoreValidated,
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc index 8c80bf4..55af84c 100644 --- a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc +++ b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc
@@ -345,6 +345,24 @@ EXPECT_EQ(std::string(), store_->policy_signature_public_key()); } +TEST_F(DeviceCloudPolicyStoreAshTest, InstallInitialPolicyBadDomain) { + PrepareNewSigningKey(); + device_policy_->policy_data().set_username("bad_owner@bad_domain.com"); + device_policy_->Build(); + store_->InstallInitialPolicy(device_policy_->policy()); + FlushDeviceSettings(); + ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); +} + +TEST_F(DeviceCloudPolicyStoreAshTest, InstallInitialPolicyBadDeviceId) { + PrepareNewSigningKey(); + device_policy_->policy_data().set_device_id("bad_device_id"); + device_policy_->Build(); + store_->InstallInitialPolicy(device_policy_->policy()); + FlushDeviceSettings(); + ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); +} + TEST_F(DeviceCloudPolicyStoreAshTest, StoreDeviceBlockDevmodeAllowed) { PrepareExistingPolicy(); device_policy_->payload().mutable_system_settings()->set_block_devmode(true);
diff --git a/chrome/browser/ash/printing/printer_setup_util.cc b/chrome/browser/ash/printing/printer_setup_util.cc index e5dc918..a82fce9 100644 --- a/chrome/browser/ash/printing/printer_setup_util.cc +++ b/chrome/browser/ash/printing/printer_setup_util.cc
@@ -28,6 +28,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #endif @@ -166,8 +167,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (base::FeatureList::IsEnabled( - ::printing::features::kEnableOopPrintDrivers)) { + if (::printing::IsOopPrintingEnabled()) { VLOG(1) << "Fetching printer capabilities via service"; ::printing::PrintBackendServiceManager& service_mgr = ::printing::PrintBackendServiceManager::GetInstance();
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.cc index 03eca072..4f196b8 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.cc
@@ -78,6 +78,16 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } +void PersonalizationAppSeaPenProviderImpl::SelectRecentSeaPenImage( + const base::FilePath& path, + SelectRecentSeaPenImageCallback callback) { + auto* wallpaper_controller = ash::WallpaperController::Get(); + DCHECK(wallpaper_controller); + + wallpaper_controller->SetSeaPenWallpaperFromFile(GetAccountId(profile_), path, + std::move(callback)); +} + wallpaper_handlers::SeaPenFetcher* PersonalizationAppSeaPenProviderImpl::GetOrCreateSeaPenFetcher() { if (!sea_pen_fetcher_) {
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.h b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.h index f33a592..24e34048 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.h +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_sea_pen_provider_impl.h
@@ -53,6 +53,10 @@ void SelectSeaPenThumbnail(uint32_t id, SelectSeaPenThumbnailCallback callback) override; + void SelectRecentSeaPenImage( + const base::FilePath& path, + SelectRecentSeaPenImageCallback callback) override; + private: wallpaper_handlers::SeaPenFetcher* GetOrCreateSeaPenFetcher();
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc index 34c9d85..6e86c451 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -424,12 +424,21 @@ } case ash::WallpaperType::kSeaPen: { // TODO(b/307757290) send a unique key and set description content. - const std::string key = base::UnguessableToken::Create().ToString(); + const std::string key = info->user_file_path; NotifyWallpaperChanged( ash::personalization_app::mojom::CurrentWallpaper::New( info->layout, info->type, key, /*description_title=*/std::string(), /*description_content=*/std::string())); + // Do not show file extension in user-visible selected details text. + const std::string file_name = base::FilePath(info->user_file_path) + .BaseName() + .RemoveExtension() + .value(); + std::vector<std::string> attribution = {file_name}; + NotifyAttributionChanged( + ash::personalization_app::mojom::CurrentAttribution::New( + std::move(attribution), key)); return; } case ash::WallpaperType::kCount:
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc index 5247e96..baab892 100644 --- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc +++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -392,6 +392,21 @@ EXPECT_EQ(std::string(), current->description_title); } +TEST_F(PersonalizationAppWallpaperProviderImplTest, + SendsSeaPenWallpaperFromFile) { + SetWallpaperObserver(); + + test_wallpaper_controller()->SetSeaPenWallpaperFromFile( + GetTestAccountId(), base::FilePath("/sea_pen/111.jpg"), + base::DoNothing()); + + ash::personalization_app::mojom::CurrentWallpaper* current = + current_wallpaper(); + EXPECT_EQ(ash::WallpaperType::kSeaPen, current->type); + EXPECT_EQ(std::string(), current->description_content); + EXPECT_EQ(std::string(), current->description_title); +} + TEST_F(PersonalizationAppWallpaperProviderImplTest, SetCurrentWallpaperLayout) { auto* ctrl = test_wallpaper_controller();
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index db82bd6c..f22e31e 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/functional/callback.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" @@ -990,7 +991,10 @@ true, }, }; - for (const auto& test_case : test_cases) { + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + const auto& test_case = test_cases[i]; + password_manager::features_util::OptInToAccountStorage(prefs, &sync_service);
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 05b83b1..043697c 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -22,6 +22,7 @@ #include "base/memory/weak_ptr.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" @@ -3128,6 +3129,9 @@ content::BrowsingDataRemover::DATA_TYPE_COOKIES, constants::DATA_TYPE_HISTORY, constants::DATA_TYPE_PASSWORDS}; for (content::BrowsingDataRemover::DataType test_data_type : test_cases) { + SCOPED_TRACE(base::StringPrintf("Test data type %d", + static_cast<int>(test_data_type))); + { FederatedIdentityPermissionContext federated_context(GetProfile());
diff --git a/chrome/browser/browsing_data/counters/autofill_counter_browsertest.cc b/chrome/browser/browsing_data/counters/autofill_counter_browsertest.cc index 4b31834d..31a3455c 100644 --- a/chrome/browser/browsing_data/counters/autofill_counter_browsertest.cc +++ b/chrome/browser/browsing_data/counters/autofill_counter_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/functional/bind.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/platform_thread.h" @@ -386,7 +387,9 @@ base::BindRepeating(&AutofillCounterTest::Callback, base::Unretained(this))); - for (const TestCase& test_case : test_cases) { + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + const auto& test_case = test_cases[i]; counter.SetPeriodStartForTesting(test_case.period_start); counter.Restart(); WaitForCounting();
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index aa82c52..da7a4936 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -847,23 +847,6 @@ is_ssl_error_override_allowed_for_origin); } -enum AppLoadedInTabSource { - // A platform app page tried to load one of its own URLs in a tab. - APP_LOADED_IN_TAB_SOURCE_APP = 0, - - // A platform app background page tried to load one of its own URLs in a tab. - APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE, - - // An extension or app tried to load a resource of a different platform app in - // a tab. - APP_LOADED_IN_TAB_SOURCE_OTHER_EXTENSION, - - // A non-app and non-extension page tried to load a platform app in a tab. - APP_LOADED_IN_TAB_SOURCE_OTHER, - - APP_LOADED_IN_TAB_SOURCE_MAX -}; - // Cached version of the locale so we can return the locale on the I/O // thread. std::string& GetIOThreadApplicationLocale() { @@ -1103,31 +1086,6 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) -AppLoadedInTabSource ClassifyAppLoadedInTabSource( - const GURL& opener_url, - const extensions::Extension* target_platform_app) { - if (!opener_url.SchemeIs(extensions::kExtensionScheme)) { - // The forbidden app URL was being opened by a non-extension page (e.g. - // http). - return APP_LOADED_IN_TAB_SOURCE_OTHER; - } - - if (opener_url.host_piece() != target_platform_app->id()) { - // The forbidden app URL was being opened by a different app or extension. - return APP_LOADED_IN_TAB_SOURCE_OTHER_EXTENSION; - } - - // This platform app was trying to window.open() one of its own URLs. - if (opener_url == - extensions::BackgroundInfo::GetBackgroundURL(target_platform_app)) { - // Source was the background page. - return APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE; - } - - // Source was a different page inside the app. - return APP_LOADED_IN_TAB_SOURCE_APP; -} - // Returns true if there is is an extension matching `url` in // `render_process_id` with `permission`. // @@ -3998,11 +3956,6 @@ const Extension* extension = registry->enabled_extensions().GetExtensionOrAppByURL(target_url); if (extension && extension->is_platform_app()) { - UMA_HISTOGRAM_ENUMERATION( - "Extensions.AppLoadedInTab", - ClassifyAppLoadedInTabSource(opener_url, extension), - APP_LOADED_IN_TAB_SOURCE_MAX); - // window.open() may not be used to load v2 apps in a regular tab. return false; }
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/common/api_guard_delegate_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/common/api_guard_delegate_unittest.cc index 6f9981f..0ac7098 100644 --- a/chrome/browser/chromeos/extensions/telemetry/api/common/api_guard_delegate_unittest.cc +++ b/chrome/browser/chromeos/extensions/telemetry/api/common/api_guard_delegate_unittest.cc
@@ -562,10 +562,7 @@ WebContentsCloseWaiter(const WebContentsCloseWaiter&) = delete; WebContentsCloseWaiter& operator=(const WebContentsCloseWaiter&) = delete; - void Wait() { - // TODO: handle return value. - std::ignore = future_.Wait(); - } + void Wait() { ASSERT_TRUE(future_.Wait()) << "Web contents did not close."; } private: // content::WebContentsObserver overrides.
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc index 6115393..08a6a37 100644 --- a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc +++ b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
@@ -8,11 +8,13 @@ #include <utility> #include <vector> +#include "base/base64.h" #include "base/command_line.h" #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/component_updater/pki_metadata_component_installer.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/common/chrome_switches.h" @@ -25,7 +27,10 @@ #include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_util.h" #include "content/public/test/browser_test.h" +#include "crypto/ec_private_key.h" +#include "crypto/sha2.h" #include "mojo/public/cpp/bindings/sync_call_restrictions.h" +#include "net/dns/mock_host_resolver.h" #include "net/net_buildflags.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "services/network/public/mojom/network_service.mojom.h" @@ -33,14 +38,12 @@ #include "testing/gtest/include/gtest/gtest.h" #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -#include "base/threading/thread_restrictions.h" #include "chrome/browser/ssl/ssl_browsertest_util.h" #include "net/base/features.h" #include "net/cert/internal/trust_store_chrome.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" -#include "net/dns/mock_host_resolver.h" #include "net/test/cert_builder.h" #include "net/test/cert_test_util.h" #endif @@ -76,6 +79,7 @@ SystemNetworkContextManager::SetEnableCertificateTransparencyForTesting( true); ASSERT_TRUE(component_dir_.CreateUniqueTempDir()); + host_resolver()->AddRule("*", "127.0.0.1"); // Set up a configuration that will enable or disable CT enforcement // depending on the test parameter. @@ -113,6 +117,10 @@ run_loop.Run(); } + const base::FilePath& GetComponentDirPath() const { + return component_dir_.GetPath(); + } + private: void OnCTLogListConfigured() override { ++pki_metadata_configured_times_; @@ -177,6 +185,170 @@ } } +IN_PROC_BROWSER_TEST_P(PKIMetadataComponentUpdaterTest, TestCTUpdate) { + const std::string kLog1OperatorName = "log operator 1"; + std::unique_ptr<crypto::ECPrivateKey> log1_private_key = + crypto::ECPrivateKey::Create(); + std::vector<uint8_t> log1_spki; + ASSERT_TRUE(log1_private_key->ExportPublicKey(&log1_spki)); + const std::string log1_spki_base64 = base::Base64Encode(log1_spki); + const std::string log1_id = + crypto::SHA256HashString(std::string(log1_spki.begin(), log1_spki.end())); + const std::string log1_id_base64 = base::Base64Encode(log1_id); + + const std::string kLog2OperatorName = "log operator 2"; + std::unique_ptr<crypto::ECPrivateKey> log2_private_key = + crypto::ECPrivateKey::Create(); + std::vector<uint8_t> log2_spki; + ASSERT_TRUE(log2_private_key->ExportPublicKey(&log2_spki)); + const std::string log2_spki_base64 = base::Base64Encode(log2_spki); + const std::string log2_id = + crypto::SHA256HashString(std::string(log2_spki.begin(), log2_spki.end())); + const std::string log2_id_base64 = base::Base64Encode(log2_id); + + const int64_t kLogStart = + (base::Time::Now() - base::Days(1) - base::Time::UnixEpoch()).InSeconds(); + const int64_t kLogEnd = + (base::Time::Now() + base::Days(1) - base::Time::UnixEpoch()).InSeconds(); + + // CT enforcement is disabled by default on tests. Override this behaviour. + SetRequireCTForTesting(); + WaitForPKIConfiguration(1); + + // Start a test server that uses a certificate with SCTs for the above test + // logs. + net::EmbeddedTestServer https_server_ok(net::EmbeddedTestServer::TYPE_HTTPS); + net::EmbeddedTestServer::ServerCertificateConfig server_config; + // TODO(https://crbug.com/1211074): Need to use a separate hostname for each + // request since the current code does not flush verifier caches on CT log + // updates. When log updates switch to the new path, change the test to use + // the same hostname for each request to test that caches are cleared as + // expected. + server_config.dns_names = {"*.example.com"}; + server_config.embedded_scts.emplace_back( + log1_id, bssl::UpRef(log1_private_key->key()), base::Time::Now()); + server_config.embedded_scts.emplace_back( + log2_id, bssl::UpRef(log2_private_key->key()), base::Time::Now()); + https_server_ok.SetSSLConfig(server_config); + + https_server_ok.ServeFilesFromSourceDirectory("chrome/test/data"); + ASSERT_TRUE(https_server_ok.Start()); + + // Check that the page is blocked depending on CT enforcement. + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_ok.GetURL("a.example.com", "/simple.html"))); + content::WebContents* tab = chrome_test_utils::GetActiveWebContents(this); + ASSERT_TRUE(WaitForRenderFrameReady(tab->GetPrimaryMainFrame())); + if (GetParam() == CTEnforcement::kEnabled) { + EXPECT_NE(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle()); + } else { + EXPECT_EQ(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle()); + } + + // Update with a CT configuration that trusts log1 and log2 + // + // Set up a configuration that will enable or disable CT enforcement + // depending on the test parameter. + chrome_browser_certificate_transparency::CTConfig ct_config; + ct_config.set_disable_ct_enforcement(GetParam() == CTEnforcement::kDisabled); + ct_config.mutable_log_list()->mutable_timestamp()->set_seconds( + (base::Time::Now() - base::Time::UnixEpoch()).InSeconds()); + { + chrome_browser_certificate_transparency::CTLog* log = + ct_config.mutable_log_list()->add_logs(); + log->set_log_id(log1_id_base64); + log->set_key(log1_spki_base64); + log->set_purpose(chrome_browser_certificate_transparency::CTLog::PROD); + log->mutable_temporal_interval()->mutable_start()->set_seconds(kLogStart); + log->mutable_temporal_interval()->mutable_end()->set_seconds(kLogEnd); + chrome_browser_certificate_transparency::CTLog_State* log_state = + log->add_state(); + log_state->set_current_state( + chrome_browser_certificate_transparency::CTLog::USABLE); + log_state->mutable_state_start()->set_seconds(kLogStart); + chrome_browser_certificate_transparency::CTLog_OperatorChange* + operator_history = log->add_operator_history(); + operator_history->set_name(kLog1OperatorName); + operator_history->mutable_operator_start()->set_seconds(kLogStart); + } + { + chrome_browser_certificate_transparency::CTLog* log = + ct_config.mutable_log_list()->add_logs(); + log->set_log_id(log2_id_base64); + log->set_key(log2_spki_base64); + log->set_purpose(chrome_browser_certificate_transparency::CTLog::PROD); + log->mutable_temporal_interval()->mutable_start()->set_seconds(kLogStart); + log->mutable_temporal_interval()->mutable_end()->set_seconds(kLogEnd); + chrome_browser_certificate_transparency::CTLog_State* log_state = + log->add_state(); + log_state->set_current_state( + chrome_browser_certificate_transparency::CTLog::USABLE); + log_state->mutable_state_start()->set_seconds(kLogStart); + chrome_browser_certificate_transparency::CTLog_OperatorChange* + operator_history = log->add_operator_history(); + operator_history->set_name(kLog2OperatorName); + operator_history->mutable_operator_start()->set_seconds(kLogStart); + } + { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(PKIMetadataComponentInstallerService::GetInstance() + ->WriteCTDataForTesting(GetComponentDirPath(), + ct_config.SerializeAsString())); + } + + // Should be trusted now. + PKIMetadataComponentInstallerService::GetInstance() + ->ReconfigureAfterNetworkRestart(); + WaitForPKIConfiguration(2); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_ok.GetURL("b.example.com", "/simple.html"))); + EXPECT_EQ(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle()); + + // Update CT configuration again with the same CT logs but mark the 1st log + // as retired. + { + chrome_browser_certificate_transparency::CTLog* log = + ct_config.mutable_log_list()->mutable_logs(0); + log->clear_state(); + // Log states are in reverse chronological order, so the most recent state + // comes first. + { + chrome_browser_certificate_transparency::CTLog_State* log_state = + log->add_state(); + log_state->set_current_state( + chrome_browser_certificate_transparency::CTLog::RETIRED); + log_state->mutable_state_start()->set_seconds(kLogStart + 1); + } + { + chrome_browser_certificate_transparency::CTLog_State* log_state = + log->add_state(); + log_state->set_current_state( + chrome_browser_certificate_transparency::CTLog::USABLE); + log_state->mutable_state_start()->set_seconds(kLogStart); + } + } + { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(PKIMetadataComponentInstallerService::GetInstance() + ->WriteCTDataForTesting(GetComponentDirPath(), + ct_config.SerializeAsString())); + } + + // Should be untrusted again since 2 logs are required for diversity. Both + // SCTs should verify successfully but only one of them is accepted as the + // other has a timestamp after the log retirement state change timestamp. + PKIMetadataComponentInstallerService::GetInstance() + ->ReconfigureAfterNetworkRestart(); + WaitForPKIConfiguration(3); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), https_server_ok.GetURL("c.example.com", "/simple.html"))); + if (GetParam() == CTEnforcement::kEnabled) { + EXPECT_NE(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle()); + } else { + EXPECT_EQ(u"OK", chrome_test_utils::GetActiveWebContents(this)->GetTitle()); + } +} + INSTANTIATE_TEST_SUITE_P(PKIMetadataComponentUpdater, PKIMetadataComponentUpdaterTest, testing::Values(CTEnforcement::kEnabled,
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc index fdbc3e4..d1aa90d 100644 --- a/chrome/browser/download/download_prefs.cc +++ b/chrome/browser/download/download_prefs.cc
@@ -147,13 +147,11 @@ prefs::kDownloadDefaultDirectory}; for (const char* path_pref : kPathPrefs) { const PrefService::Preference* pref = prefs->FindPreference(path_pref); - const base::FilePath current = prefs->GetFilePath(path_pref); - base::FilePath migrated; // Update the download directory if the pref is from user pref store or // default pref. - LOG(ERROR) << "DownloadPrefs::DownloadPrefs" << pref->IsUserControlled() - << "," << pref->IsDefaultValue() << "," << current.value(); if (pref->IsUserControlled()) { + const base::FilePath current = prefs->GetFilePath(path_pref); + base::FilePath migrated; if (!current.empty() && file_manager::util::MigratePathFromOldFormat( profile_, GetDefaultDownloadDirectory(), current, &migrated)) {
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java index ca51c75..9102e1d 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeatures.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.feed; +import androidx.annotation.NonNull; + import org.chromium.base.CommandLine; import org.chromium.base.ResettersForTesting; import org.chromium.chrome.browser.feed.componentinterfaces.SurfaceCoordinator.StreamTabId; @@ -40,17 +42,34 @@ } /** - * @return Whether the WebFeed UI should be enabled. Checks for the WEB_FEED flag, if - * the user is signed in and confirms it's not a child profile. + * Deprecated. Use {@link #isWebFeedUIEnabled(Profile profile)} instead. TODO(1410601): Migrate + * clank test `FeedFirstRunDialogIntegrationTest` and remove this method. + * + * @return Whether the feed is allowed to be used. Returns false if the feed is disabled due to + * enterprise policy, or by flag. The value returned should not be cached as it may change. */ public static boolean isWebFeedUIEnabled() { + return isWebFeedUIEnabled(Profile.getLastUsedRegularProfile()); + } + + /** + * @param profile the profile of the current user. + * @return Whether the WebFeed UI should be enabled. Checks for the WEB_FEED flag, if the user + * is signed in and confirms it's not a child profile. + */ + public static boolean isWebFeedUIEnabled(@NonNull Profile profile) { // TODO(b/197354832, b/188188861): change consent check to SIGNIN. + boolean isPrimaryAccountSignedIn = false; + if (IdentityServicesProvider.get().getSigninManager(profile) != null) { + isPrimaryAccountSignedIn = + IdentityServicesProvider.get() + .getSigninManager(profile) + .getIdentityManager() + .hasPrimaryAccount(ConsentLevel.SIGNIN); + } return ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_FEED) - && IdentityServicesProvider.get() - .getSigninManager(Profile.getLastUsedRegularProfile()) - .getIdentityManager() - .hasPrimaryAccount(ConsentLevel.SIGNIN) - && !Profile.getLastUsedRegularProfile().isChild() + && isPrimaryAccountSignedIn + && !profile.isChild() && isFeedEnabledByDSE(); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 1782a1e..727a8237 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -450,11 +450,6 @@ "expiry_milestone": 123 }, { - "name": "attach-logs-to-autofill-rater-extentsion-report", - "owners": [ "theocristea@google.com", "vasilii@chromium.org" ], - "expiry_milestone": 130 - }, - { "name": "attribution-reporting-debug-mode", "owners": [ "//content/browser/attribution_reporting/OWNERS" ], "expiry_milestone": 123 @@ -935,6 +930,16 @@ "expiry_milestone": 122 }, { + "name": "bottom-omnibox-promo-app-launch", + "owners": [ "christianxu@google.com", "bling-flags@google.com"], + "expiry_milestone": 127 + }, + { + "name": "bottom-omnibox-promo-fre", + "owners": [ "christianxu@google.com", "bling-flags@google.com"], + "expiry_milestone": 127 + }, + { "name": "bottom-omnibox-steady-state", "owners": [ "stkhapugin@chromium.org", "christianxu@google.com", "bling-flags@google.com"], "expiry_milestone": 122 @@ -1268,22 +1273,22 @@ { "name": "contextual-page-actions", "owners": [ "shaktisahu@google.com", "salg@google.com" ], - "expiry_milestone": 120 + "expiry_milestone": 125 }, { "name": "contextual-page-actions-reader-mode", "owners": [ "shaktisahu@google.com", "salg@google.com" ], - "expiry_milestone": 120 + "expiry_milestone": 125 }, { "name": "contextual-page-actions-share-model", "owners": [ "haileywang@google.com", "ssid@google.com" ], - "expiry_milestone": 120 + "expiry_milestone": 125 }, { "name": "contextual-page-actions-with-price-tracking", "owners": [ "shaktisahu@google.com", "salg@google.com" ], - "expiry_milestone": 120 + "expiry_milestone": 125 }, { "name": "contextual-search-debug", @@ -7618,6 +7623,11 @@ "expiry_milestone": 122 }, { + "name": "tab-grid-compositional-layout", + "owners": [ "lpromero@chromium.org", "bling-flags@google.com" ], + "expiry_milestone": 130 + }, + { "name": "tab-grid-new-transitions", "owners": [ "ewannpv@chromium.org", "bling-flags@google.com" ], "expiry_milestone": 125
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 79b4bbc5..71a9605 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -7827,14 +7827,6 @@ const char kDesktopPWAsUserLinkCapturingName[] = "Desktop PWA Link Capturing"; const char kDesktopPWAsUserLinkCapturingDescription[] = "Enables opening links from Chrome in an installed PWA"; - -const char kAttachLogsToAutofillRaterExtensionReportName[] = - "Attach logs to Autofill Rater Extension Report"; -const char kAttachLogsToAutofillRaterExtensionReportDescription[] = - "When a report is started via the Autofill Rater Extension, the logs which " - "are normally recorded in chrome://password-manager-internals and " - "chrome://autofill-internals will be recorded on files on the disk. At the " - "end of the report, these files will be attached to the report."; #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) #if BUILDFLAG(ENABLE_HLS_DEMUXER)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 7e121af..412921c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -4525,10 +4525,6 @@ extern const char kDesktopPWAsUserLinkCapturingName[]; extern const char kDesktopPWAsUserLinkCapturingDescription[]; - -extern const char kAttachLogsToAutofillRaterExtensionReportName[]; -extern const char kAttachLogsToAutofillRaterExtensionReportDescription[]; - #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) #if BUILDFLAG(ENABLE_HLS_DEMUXER)
diff --git a/chrome/browser/headless/headless_mode_protocol_browsertest.cc b/chrome/browser/headless/headless_mode_protocol_browsertest.cc index 87236d0e..09472541 100644 --- a/chrome/browser/headless/headless_mode_protocol_browsertest.cc +++ b/chrome/browser/headless/headless_mode_protocol_browsertest.cc
@@ -20,10 +20,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" -#if BUILDFLAG(IS_WIN) -#include "content/public/common/content_switches.h" -#endif - using testing::NotNull; namespace headless { @@ -268,8 +264,8 @@ #if BUILDFLAG(IS_WIN) // Screencast tests fail on Windows unless GPU compositing is disabled, - // see https://crbug.com/1411976 and https://crbug.com/1502651 . - command_line->AppendSwitch(::switches::kDisableGpuCompositing); + // see https://crbug.com/1411976 and https://crbug.com/1502651. + UseSoftwareCompositing(); #endif } };
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.cc b/chrome/browser/ip_protection/ip_protection_config_provider.cc index 3f91252..b471ace 100644 --- a/chrome/browser/ip_protection/ip_protection_config_provider.cc +++ b/chrome/browser/ip_protection/ip_protection_config_provider.cc
@@ -214,7 +214,7 @@ TryGetAuthTokensCallback callback) { auto bsa_get_tokens_start_time = base::TimeTicks::Now(); bsa_->GetTokens( - access_token_info.token, batch_size, + access_token_info.token, batch_size, quiche::ProxyLayer::kProxyA, [weak_ptr = weak_ptr_factory_.GetWeakPtr(), bsa_get_tokens_start_time, callback = std::move(callback)]( absl::StatusOr<absl::Span<quiche::BlindSignToken>> tokens) mutable {
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc index 45d54e009..42f8ae6 100644 --- a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc +++ b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
@@ -72,6 +72,7 @@ public: void GetTokens(std::string oauth_token, int num_tokens, + quiche::ProxyLayer proxy_layer, quiche::SignedTokenCallback callback) override { get_tokens_called_ = true; oauth_token_ = oauth_token;
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc index c2c7d86ed..48b66d1 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -163,6 +163,93 @@ base::FEATURE_ENABLED_BY_DEFAULT); #endif +content::DesktopMediaID::Type ConvertToDesktopMediaIDType( + DesktopMediaList::Type type) { + switch (type) { + case DesktopMediaList::Type::kScreen: + return content::DesktopMediaID::Type::TYPE_SCREEN; + case DesktopMediaList::Type::kWindow: + return content::DesktopMediaID::Type::TYPE_WINDOW; + case DesktopMediaList::Type::kWebContents: + case DesktopMediaList::Type::kCurrentTab: + case DesktopMediaList::Type::kNone: + break; + } + NOTREACHED_NORETURN(); +} + +content::DesktopMediaID::Id GetUpdatedWindowId( + const content::DesktopMediaID& desktop_media_id, + bool is_source_list_delegated) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // Use current value by default. + content::DesktopMediaID::Id window_id = desktop_media_id.window_id; + + // Update |window_id| if |desktop_media_id.id| corresponds to a + // viz::FrameSinkId. + // TODO(https://crbug.com/1366579): This lookup is fairly fragile and has + // now resulted in at least two patches to avoid it (though both are Wayland + // based problems). On top of that, the series of ifdefs is a bit confusing. + // We should try to simplify/abstract/cleanup this logic. + // The root cause is that the Ozone Wayland Window Manager does *not* use a + // platform handle/unique ID to back the AcceleratedWidget, but rather a + // monotonically increasing int. Thus, capturers on that platform that + // also (by default) use monotonically increasing ints as IDs (e.g. + // delegated source lists, the lacros capturer) can have source IDs that + // collide with known aura IDs. This causes us to mistakenly try to capture + // the non-aura windows as an aura window. The preview ultimately matches + // what is captured, but this is likely unexpected for the user and can + // result in multiple instances of a window appearing in the source list and + // also means that the collided non-aura window cannot be captured. +#if defined(USE_AURA) + if (!is_source_list_delegated) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // The lacros capturer is not delegated and can circumvent the collision + // described above because it receives additional information about each + // window from Ash-chrome; however, it is limited in how it can convey + // that information. |FormatSources|, above, will put the internal ID into + // the window_id slot; but this will not yet be a registered native + // window, as the capturer does not run on the UI thread. Thus, we still + // need to find and register this window here and then overwrite the + // window_id. If the window_id has not been set, we'll just fail to find a + // corresponding window and the state will remain unset. + DesktopMediaID::Id search_id = desktop_media_id.window_id; +#else + DesktopMediaID::Id search_id = desktop_media_id.id; +#endif + aura::WindowTreeHost* const host = + aura::WindowTreeHost::GetForAcceleratedWidget( + *reinterpret_cast<gfx::AcceleratedWidget*>(&search_id)); + aura::Window* const aura_window = host ? host->window() : nullptr; + if (aura_window) { + DesktopMediaID aura_id = DesktopMediaID::RegisterNativeWindow( + DesktopMediaID::TYPE_WINDOW, aura_window); + window_id = aura_id.window_id; + } else if (search_id != DesktopMediaID::kNullId) { + // This is expected for non-LaCrOS platforms, where we are searching all + // IDs (which include windows/screens that we don't own). However, on + // LaCrOS, if we set search_id, then that means we think we should know + // about the window. There are potential race conditions where this + // could happen, so don't throw an error, but do log it in case any + // issues pop up in the future so we can debug it. +#if BUILDFLAG(IS_CHROMEOS_LACROS) + LOG(ERROR) << __func__ << ": Could not find window but had window id"; + window_id = DesktopMediaID::kNullId; +#endif + } + } +#elif BUILDFLAG(IS_MAC) + if (base::FeatureList::IsEnabled(kWindowCaptureMacV2)) { + if (remote_cocoa::ScopedCGWindowID::Get(desktop_media_id.id)) { + window_id = desktop_media_id.id; + } + } +#endif + + return window_id; +} + } // namespace class NativeDesktopMediaList::Worker @@ -212,7 +299,7 @@ // which should be excluded from the list produced. static std::vector<SourceDescription> FormatSources( const webrtc::DesktopCapturer::SourceList& sources, - const DesktopMediaList::Type& list_type, + const DesktopMediaID::Type source_type, DesktopMediaID::Id excluded_window_id); #if BUILDFLAG(IS_WIN) @@ -243,7 +330,7 @@ base::WeakPtr<NativeDesktopMediaList> media_list_; - DesktopMediaList::Type type_; + DesktopMediaID::Type source_type_; const std::unique_ptr<ThumbnailCapturer> capturer_; const ThumbnailCapturer::FrameDeliveryMethod frame_delivery_method_; const bool add_current_process_windows_; @@ -280,13 +367,13 @@ bool add_current_process_windows) : task_runner_(task_runner), media_list_(media_list), - type_(type), + source_type_(ConvertToDesktopMediaIDType(type)), capturer_(std::move(capturer)), frame_delivery_method_(capturer_->GetFrameDeliveryMethod()), add_current_process_windows_(add_current_process_windows) { DCHECK(capturer_); - DCHECK(type_ == DesktopMediaList::Type::kWindow || + DCHECK(source_type_ == DesktopMediaID::Type::TYPE_WINDOW || !add_current_process_windows_); } @@ -328,14 +415,14 @@ } std::vector<SourceDescription> source_descriptions = - FormatSources(sources, type_, excluded_window_id_); + FormatSources(sources, source_type_, excluded_window_id_); #if BUILDFLAG(IS_WIN) // If |add_current_process_windows_| is set to false, |capturer_| will have // found the windows owned by the current process for us. Otherwise, we must // do this. if (add_current_process_windows_) { - DCHECK_EQ(type_, DesktopMediaList::Type::kWindow); + DCHECK_EQ(source_type_, DesktopMediaID::Type::TYPE_WINDOW); // WebRTC returns the windows in order of highest z-order to lowest, but // these additional windows will be out of order if we just append them. So // we sort the list according to the z-order of the windows. @@ -401,15 +488,13 @@ std::vector<DesktopMediaListBase::SourceDescription> NativeDesktopMediaList::Worker::FormatSources( const webrtc::DesktopCapturer::SourceList& sources, - const DesktopMediaList::Type& list_type, + const DesktopMediaID::Type source_type, DesktopMediaID::Id excluded_window_id) { std::vector<SourceDescription> source_descriptions; std::u16string title; for (size_t i = 0; i < sources.size(); ++i) { - DesktopMediaID::Type source_type = DesktopMediaID::Type::TYPE_NONE; - switch (list_type) { - case DesktopMediaList::Type::kScreen: - source_type = DesktopMediaID::Type::TYPE_SCREEN; + switch (source_type) { + case DesktopMediaID::Type::TYPE_SCREEN: // Just in case 'Screen' is inflected depending on the screen number, // use plural formatter. title = sources.size() > 1 @@ -420,8 +505,7 @@ IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME); break; - case DesktopMediaList::Type::kWindow: - source_type = DesktopMediaID::Type::TYPE_WINDOW; + case DesktopMediaID::Type::TYPE_WINDOW: // Skip the picker dialog window. if (sources[i].id == excluded_window_id) { continue; @@ -854,65 +938,8 @@ } #endif // BUILDFLAG(IS_WIN) - // Assign |source_it->id.window_id| if |source_it->id.id| corresponds to a - // viz::FrameSinkId. - // TODO(https://crbug.com/1366579): This lookup is fairly fragile and has - // now resulted in at least two patches to avoid it (though both are Wayland - // based problems). On top of that, the series of ifdefs is a bit confusing. - // We should try to simplify/abstract/cleanup this logic. - // The root cause is that the Ozone Wayland Window Manager does *not* use a - // platform handle/unique ID to back the AcceleratedWidget, but rather a - // monotonically increasing int. Thus, capturers on that platform that - // also (by default) use monotonically increasing ints as IDs (e.g. - // delegated source lists, the lacros capturer) can have source IDs that - // collide with known aura IDs. This causes us to mistakenly try to capture - // the non-aura windows as an aura window. The preview ultimately matches - // what is captured, but this is likely unexpected for the user and can - // result in multiple instances of a window appearing in the source list and - // also means that the collided non-aura window cannot be captured. -#if defined(USE_AURA) - if (!is_source_list_delegated_) { -#if BUILDFLAG(IS_CHROMEOS_LACROS) - // The lacros capturer is not delegated and can circumvent the collision - // described above because it receives additional information about each - // window from Ash-chrome; however, it is limited in how it can convey - // that information. |FormatSources|, above, will put the internal ID into - // the window_id slot; but this will not yet be a registered native - // window, as the capturer does not run on the UI thread. Thus, we still - // need to find and register this window here and then overwrite the - // window_id. If the window_id has not been set, we'll just fail to find a - // corresponding window and the state will remain unset. - DesktopMediaID::Id search_id = source_it->id.window_id; -#else - DesktopMediaID::Id search_id = source_it->id.id; -#endif - aura::WindowTreeHost* const host = - aura::WindowTreeHost::GetForAcceleratedWidget( - *reinterpret_cast<gfx::AcceleratedWidget*>(&search_id)); - aura::Window* const aura_window = host ? host->window() : nullptr; - if (aura_window) { - DesktopMediaID aura_id = DesktopMediaID::RegisterNativeWindow( - DesktopMediaID::TYPE_WINDOW, aura_window); - source_it->id.window_id = aura_id.window_id; - } else if (search_id != DesktopMediaID::kNullId) { - // This is expected for non-LaCrOS platforms, where we are searching all - // IDs (which include windows/screens that we don't own). However, on - // LaCrOS, if we set search_id, then that means we think we should know - // about the window. There are potential race conditions where this - // could happen, so don't throw an error, but do log it in case any - // issues pop up in the future so we can debug it. -#if BUILDFLAG(IS_CHROMEOS_LACROS) - LOG(ERROR) << __func__ << ": Could not find window but had window id"; - source_it->id.window_id = DesktopMediaID::kNullId; -#endif - } - } -#elif BUILDFLAG(IS_MAC) - if (base::FeatureList::IsEnabled(kWindowCaptureMacV2)) { - if (remote_cocoa::ScopedCGWindowID::Get(source_it->id.id)) - source_it->id.window_id = source_it->id.id; - } -#endif + source_it->id.window_id = + GetUpdatedWindowId(source_it->id, is_source_list_delegated_); ++source_it; }
diff --git a/chrome/browser/optimization_guide/model_execution/model_execution_browsertest.cc b/chrome/browser/optimization_guide/model_execution/model_execution_browsertest.cc index df70c13d..210f9bf 100644 --- a/chrome/browser/optimization_guide/model_execution/model_execution_browsertest.cc +++ b/chrome/browser/optimization_guide/model_execution/model_execution_browsertest.cc
@@ -17,6 +17,8 @@ #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_logger.h" #include "components/optimization_guide/core/optimization_guide_switches.h" +#include "components/optimization_guide/core/optimization_guide_util.h" +#include "components/optimization_guide/proto/model_quality_service.pb.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" @@ -32,19 +34,29 @@ kSuccessful = 0, kUnsuccessful = 1, kMalformed = 2, + kErrorFiltered = 3, + kUnsupportedLanguage = 4, }; -TestMessage BuildTestMessage(const std::string& test_message_str) { - TestMessage test_message; - test_message.set_test(test_message_str); - return test_message; -} - -proto::ExecuteResponse BuildTestExecuteResponse(const TestMessage& message) { +proto::ExecuteResponse BuildComposeResponse(const std::string& output) { + proto::ComposeResponse compose_response; + compose_response.set_output(output); proto::ExecuteResponse execute_response; proto::Any* any_metadata = execute_response.mutable_response_metadata(); - any_metadata->set_type_url("type.googleapis.com/" + message.GetTypeName()); - message.SerializeToString(any_metadata->mutable_value()); + any_metadata->set_type_url("type.googleapis.com/" + + compose_response.GetTypeName()); + compose_response.SerializeToString(any_metadata->mutable_value()); + auto response_data = + optimization_guide::ParsedAnyMetadata<proto::ComposeResponse>( + *any_metadata); + EXPECT_TRUE(response_data); + return execute_response; +} + +proto::ExecuteResponse BuildTestErrorExecuteResponse( + const proto::ErrorState& state) { + proto::ExecuteResponse execute_response; + execute_response.mutable_error_response()->set_error_state(state); return execute_response; } @@ -125,7 +137,7 @@ // Executes the model for the feature, waits until the response is received, // and returns the response. void ExecuteModel(proto::ModelExecutionFeature feature, - const TestMessage& request_metadata, + const google::protobuf::MessageLite& request_metadata, Profile* profile = nullptr) { if (!profile) { profile = browser()->profile(); @@ -152,7 +164,27 @@ base::OnceClosure on_model_execution_closure, OptimizationGuideModelExecutionResult result, std::unique_ptr<ModelQualityLogEntry> log_entry) { + if (result.has_value() || + result.error().error() == OptimizationGuideModelExecutionError:: + ModelExecutionError::kFiltered || + result.error().error() == + OptimizationGuideModelExecutionError::ModelExecutionError:: + kUnsupportedLanguage) { + EXPECT_TRUE(log_entry); + proto::LogAiDataRequest* log_ai_data_request = + log_entry.get()->log_ai_data_request(); + EXPECT_NE(log_ai_data_request, nullptr); + EXPECT_EQ(log_ai_data_request->feature_case(), + proto::LogAiDataRequest::FeatureCase::kCompose); + EXPECT_TRUE(log_ai_data_request->has_compose()); + EXPECT_TRUE(log_ai_data_request->mutable_compose()->has_request_data()); + } + if (result.has_value()) { + EXPECT_TRUE(log_entry.get() + ->log_ai_data_request() + ->mutable_compose() + ->has_response_data()); model_execution_result_ = base::ok(result.value()); } else { model_execution_result_ = base::unexpected(result.error()); @@ -177,7 +209,7 @@ if (response_type_ == ModelExecutionRemoteResponseType::kSuccessful) { std::string serialized_response; proto::ExecuteResponse execute_response = - BuildTestExecuteResponse(BuildTestMessage("foo response")); + BuildComposeResponse("foo response"); execute_response.SerializeToString(&serialized_response); response->set_code(net::HTTP_OK); response->set_content(serialized_response); @@ -187,6 +219,22 @@ } else if (response_type_ == ModelExecutionRemoteResponseType::kMalformed) { response->set_code(net::HTTP_OK); response->set_content("Not a proto"); + } else if (response_type_ == + ModelExecutionRemoteResponseType::kErrorFiltered) { + std::string serialized_response; + proto::ExecuteResponse execute_response = BuildTestErrorExecuteResponse( + proto::ErrorState::ERROR_STATE_FILTERED); + execute_response.SerializeToString(&serialized_response); + response->set_code(net::HTTP_OK); + response->set_content(serialized_response); + } else if (response_type_ == + ModelExecutionRemoteResponseType::kUnsupportedLanguage) { + std::string serialized_response; + proto::ExecuteResponse execute_response = BuildTestErrorExecuteResponse( + proto::ErrorState::ERROR_STATE_UNSUPPORTED_LANGUAGE); + execute_response.SerializeToString(&serialized_response); + response->set_code(net::HTTP_OK); + response->set_content(serialized_response); } else { NOTREACHED(); } @@ -230,7 +278,9 @@ IN_PROC_BROWSER_TEST_F(ModelExecutionDisabledBrowserTest, ModelExecutionDisabled) { - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_FALSE(model_execution_result_->has_value()); EXPECT_EQ(OptimizationGuideModelExecutionError::ModelExecutionError:: @@ -249,7 +299,9 @@ IN_PROC_BROWSER_TEST_F(ModelExecutionEnabledBrowserTest, ModelExecutionDisabledInIncognito) { Browser* otr_browser = CreateIncognitoBrowser(browser()->profile()); - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo"), + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request, otr_browser->profile()); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_FALSE(model_execution_result_->has_value()); @@ -261,7 +313,9 @@ IN_PROC_BROWSER_TEST_F(ModelExecutionEnabledBrowserTest, ModelExecutionFailsNoUserSignIn) { - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_FALSE(model_execution_result_->has_value()); EXPECT_EQ(OptimizationGuideModelExecutionError::ModelExecutionError:: @@ -275,12 +329,14 @@ EnableSignin(); SetExpectedBearerAccessToken("Bearer access_token"); - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_TRUE(model_execution_result_->has_value()); - EXPECT_EQ( - "foo response", - ParsedAnyMetadata<TestMessage>(model_execution_result_->value())->test()); + auto response = ParsedAnyMetadata<proto::ComposeResponse>( + model_execution_result_->value()); + EXPECT_EQ("foo response", response->output()); } IN_PROC_BROWSER_TEST_F(ModelExecutionEnabledBrowserTest, @@ -289,7 +345,9 @@ SetExpectedBearerAccessToken("Bearer access_token"); SetResponseType(ModelExecutionRemoteResponseType::kUnsuccessful); - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_FALSE(model_execution_result_->has_value()); EXPECT_EQ(OptimizationGuideModelExecutionError::ModelExecutionError:: @@ -304,7 +362,9 @@ SetExpectedBearerAccessToken("Bearer access_token"); SetResponseType(ModelExecutionRemoteResponseType::kMalformed); - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_FALSE(model_execution_result_->has_value()); EXPECT_EQ(OptimizationGuideModelExecutionError::ModelExecutionError:: @@ -313,6 +373,38 @@ EXPECT_TRUE(model_execution_result_->error().transient()); } +IN_PROC_BROWSER_TEST_F(ModelExecutionEnabledBrowserTest, + ModelExecutionFailsForErrorFilteredResponse) { + EnableSignin(); + SetExpectedBearerAccessToken("Bearer access_token"); + SetResponseType(ModelExecutionRemoteResponseType::kErrorFiltered); + + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); + EXPECT_TRUE(model_execution_result_.has_value()); + EXPECT_FALSE(model_execution_result_->has_value()); + EXPECT_EQ( + OptimizationGuideModelExecutionError::ModelExecutionError::kFiltered, + model_execution_result_->error().error()); +} + +IN_PROC_BROWSER_TEST_F(ModelExecutionEnabledBrowserTest, + ModelExecutionFailsForUnsupportedLanguageResponse) { + EnableSignin(); + SetExpectedBearerAccessToken("Bearer access_token"); + SetResponseType(ModelExecutionRemoteResponseType::kUnsupportedLanguage); + + proto::ComposeRequest request; + request.set_user_input("a user typed this"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); + EXPECT_TRUE(model_execution_result_.has_value()); + EXPECT_FALSE(model_execution_result_->has_value()); + EXPECT_EQ(OptimizationGuideModelExecutionError::ModelExecutionError:: + kUnsupportedLanguage, + model_execution_result_->error().error()); +} + class ModelExecutionInternalsPageBrowserTest : public ModelExecutionEnabledBrowserTest { public: @@ -335,7 +427,9 @@ EnableSignin(); SetExpectedBearerAccessToken("Bearer access_token"); - ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, BuildTestMessage("foo")); + proto::ComposeRequest request; + request.set_user_input("foo"); + ExecuteModel(proto::MODEL_EXECUTION_FEATURE_COMPOSE, request); EXPECT_TRUE(model_execution_result_.has_value()); EXPECT_TRUE(model_execution_result_->has_value()); CheckInternalsLog("ExecuteModel");
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 01c9da40..ae07159 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -39,15 +39,13 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/sync_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" -#include "chrome/browser/ui/autofill/chrome_autofill_client.h" #include "chrome/browser/ui/passwords/password_generation_popup_controller_impl.h" #include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h" #include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "chrome/browser/ui/passwords/ui_utils.h" #include "chrome/common/channel_info.h" #include "chrome/common/webui_url_constants.h" -#include "components/autofill/content/browser/content_autofill_driver.h" -#include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/autofill/content/browser/content_autofill_client.h" #include "components/autofill/content/browser/renderer_forms_with_server_predictions.h" #include "components/autofill/content/browser/scoped_autofill_managers_observation.h" #include "components/autofill/core/browser/logging/log_manager.h" @@ -785,15 +783,9 @@ autofill::AutofillDownloadManager* ChromePasswordManagerClient::GetAutofillDownloadManager() { - autofill::ContentAutofillDriverFactory* factory = - autofill::ContentAutofillDriverFactory::FromWebContents(web_contents()); - if (factory) { - autofill::ContentAutofillDriver* driver = - factory->DriverForFrame(web_contents()->GetPrimaryMainFrame()); - // |driver| can be NULL if the tab is being closed. - if (driver) { - return driver->GetAutofillManager().download_manager(); - } + if (auto* client = + autofill::ContentAutofillClient::FromWebContents(web_contents())) { + return client->GetDownloadManager(); } return nullptr; }
diff --git a/chrome/browser/pdf/pdf_extension_printing_test.cc b/chrome/browser/pdf/pdf_extension_printing_test.cc index 7ea7905..1d9fd63 100644 --- a/chrome/browser/pdf/pdf_extension_printing_test.cc +++ b/chrome/browser/pdf/pdf_extension_printing_test.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/pdf/pdf_extension_test_base.h" #include "chrome/browser/pdf/pdf_extension_test_util.h" #include "chrome/browser/printing/browser_printing_context_factory_for_test.h" -#include "chrome/browser/printing/print_backend_service_test_impl.h" #include "chrome/browser/printing/print_error_dialog.h" #include "chrome/browser/printing/print_job.h" #include "chrome/browser/printing/print_view_manager_base.h" @@ -37,6 +36,11 @@ #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" +#if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/print_backend_service_manager.h" +#include "chrome/browser/printing/print_backend_service_test_impl.h" +#endif + #if BUILDFLAG(ENABLE_PRINT_PREVIEW) #include "ui/base/ui_base_types.h" #endif @@ -116,11 +120,13 @@ // Avoid getting blocked by modal print error dialogs. Must be called after // the UI thread is up and running. SetShowPrintErrorDialogForTest(base::DoNothing()); +#if BUILDFLAG(ENABLE_OOP_PRINTING) if (UseService()) { print_backend_service_ = printing::PrintBackendServiceTestImpl::LaunchForTesting( test_remote_, test_print_backend_.get(), /*sandboxed=*/true); } +#endif PDFExtensionTestBase::SetUpOnMainThread(); } #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -152,7 +158,9 @@ #endif void TearDownOnMainThread() override { PDFExtensionTestBase::TearDownOnMainThread(); +#if BUILDFLAG(ENABLE_OOP_PRINTING) printing::PrintBackendServiceManager::ResetForTesting(); +#endif SetShowPrintErrorDialogForTest(base::NullCallback()); } void TearDown() override { @@ -161,16 +169,20 @@ printing::PrintBackend::SetPrintBackendForTesting(nullptr); } std::vector<base::test::FeatureRef> GetEnabledFeatures() const override { +#if BUILDFLAG(ENABLE_OOP_PRINTING) if (UseService()) { return {printing::features::kEnableOopPrintDrivers}; } +#endif return {}; } std::vector<base::test::FeatureRef> GetDisabledFeatures() const override { - if (UseService()) { - return {}; +#if BUILDFLAG(ENABLE_OOP_PRINTING) + if (!UseService()) { + return {printing::features::kEnableOopPrintDrivers}; } - return {printing::features::kEnableOopPrintDrivers}; +#endif + return {}; } void SetupPrintViewManagerForJobMonitoring(content::RenderFrameHost* frame) { @@ -227,8 +239,10 @@ scoped_refptr<printing::TestPrintBackend> test_print_backend_ = base::MakeRefCounted<printing::TestPrintBackend>(); printing::BrowserPrintingContextFactoryForTest test_printing_context_factory_; +#if BUILDFLAG(ENABLE_OOP_PRINTING) mojo::Remote<printing::mojom::PrintBackendService> test_remote_; std::unique_ptr<printing::PrintBackendServiceTestImpl> print_backend_service_; +#endif bool observing_print_job_ = false; bool print_job_destroyed_ = false; raw_ptr<base::RunLoop> run_loop_ = nullptr; @@ -377,7 +391,14 @@ } #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) -INSTANTIATE_TEST_SUITE_P(All, PDFExtensionPrintingTest, testing::Bool()); +INSTANTIATE_TEST_SUITE_P(All, + PDFExtensionPrintingTest, +#if BUILDFLAG(ENABLE_OOP_PRINTING) + testing::Bool() +#else + testing::Values(false) +#endif +); class PDFExtensionBasicPrintingTest : public PDFExtensionPrintingTest { public:
diff --git a/chrome/browser/permissions/permission_element_browsertest.cc b/chrome/browser/permissions/permission_element_browsertest.cc index 416671e..7d0e926 100644 --- a/chrome/browser/permissions/permission_element_browsertest.cc +++ b/chrome/browser/permissions/permission_element_browsertest.cc
@@ -9,9 +9,9 @@ #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_content_scrim_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/permissions/features.h" #include "components/permissions/test/permission_request_observer.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -53,8 +53,7 @@ class PermissionElementBrowserTest : public InProcessBrowserTest { public: PermissionElementBrowserTest() { - feature_list_.InitAndEnableFeature( - permissions::features::kPermissionElement); + feature_list_.InitAndEnableFeature(features::kPermissionElement); } PermissionElementBrowserTest(const PermissionElementBrowserTest&) = delete;
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 068dd47..1e8a871 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -302,6 +302,11 @@ prefs::kPrintingEnabled, base::Value::Type::BOOLEAN }, #endif // BUILDFLAG(ENABLE_PRINTING) +#if BUILDFLAG(ENABLE_OOP_PRINTING) + { key::kOopPrintDriversAllowed, + prefs::kOopPrintDriversAllowedByPolicy, + base::Value::Type::BOOLEAN }, +#endif { key::kSafeBrowsingEnabled, prefs::kSafeBrowsingEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 3c34e027..1d09064d 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1666,6 +1666,15 @@ SearchEngineChoiceService::RegisterLocalStatePrefs(registry); #endif + // Platform-specific and compile-time conditional individual preferences. + // If you have multiple preferences that should clearly be grouped together, + // please group them together into a helper function called above. Please + // keep this list alphabetized. + +#if BUILDFLAG(ENABLE_OOP_PRINTING) + registry->RegisterBooleanPref(prefs::kOopPrintDriversAllowedByPolicy, true); +#endif + // This is intentionally last. RegisterLocalStatePrefsForMigration(registry); }
diff --git a/chrome/browser/printing/prefs_util.cc b/chrome/browser/printing/prefs_util.cc index 27caaff..af731be 100644 --- a/chrome/browser/printing/prefs_util.cc +++ b/chrome/browser/printing/prefs_util.cc
@@ -11,11 +11,34 @@ #include "components/prefs/pref_service.h" #include "printing/backend/print_backend_utils.h" #include "printing/backend/printing_restrictions.h" +#include "printing/buildflags/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" +#if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "base/feature_list.h" +#include "chrome/browser/browser_process.h" +#include "components/prefs/pref_service.h" +#include "printing/printing_features.h" +#endif + namespace printing { +#if BUILDFLAG(ENABLE_OOP_PRINTING) +namespace { + +bool CheckOopPolicy() { + PrefService* local_state = g_browser_process->local_state(); + if (local_state && + local_state->HasPrefPath(prefs::kOopPrintDriversAllowedByPolicy)) { + return local_state->GetBoolean(prefs::kOopPrintDriversAllowedByPolicy); + } + return true; +} + +} // namespace +#endif // BUILDFLAG(ENABLE_OOP_PRINTING) + absl::optional<gfx::Size> ParsePaperSizeDefault(const PrefService& prefs) { if (!prefs.HasPrefPath(prefs::kPrintingPaperSizeDefault)) return absl::nullopt; @@ -38,4 +61,23 @@ return ParsePaperSize(*name); } +#if BUILDFLAG(ENABLE_OOP_PRINTING) +bool IsOopPrintingEnabled() { + // First check feature flag. + if (!base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + return false; + } + + // Check for policy override. Do no support dynamic refresh, cache and reuse + // the value from the first check. + static bool policy_override = CheckOopPolicy(); + return policy_override; +} + +bool ShouldPrintJobOop() { + return IsOopPrintingEnabled() && + features::kEnableOopPrintDriversJobPrint.Get(); +} +#endif // BUILDFLAG(ENABLE_OOP_PRINTING) + } // namespace printing
diff --git a/chrome/browser/printing/prefs_util.h b/chrome/browser/printing/prefs_util.h index 8220362..5da0f06 100644 --- a/chrome/browser/printing/prefs_util.h +++ b/chrome/browser/printing/prefs_util.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_PRINTING_PREFS_UTIL_H_ #define CHROME_BROWSER_PRINTING_PREFS_UTIL_H_ +#include "printing/buildflags/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" @@ -15,6 +16,14 @@ // Parse the printing.paper_size_default preference. absl::optional<gfx::Size> ParsePaperSizeDefault(const PrefService& prefs); +#if BUILDFLAG(ENABLE_OOP_PRINTING) +// Determine if out-of-process printing support is enabled. +bool IsOopPrintingEnabled(); + +// Determine if printing a job should be done out-of-process. +bool ShouldPrintJobOop(); +#endif + } // namespace printing #endif // CHROME_BROWSER_PRINTING_PREFS_UTIL_H_
diff --git a/chrome/browser/printing/print_job_worker_oop.cc b/chrome/browser/printing/print_job_worker_oop.cc index 6a61b18..e4b173c 100644 --- a/chrome/browser/printing/print_job_worker_oop.cc +++ b/chrome/browser/printing/print_job_worker_oop.cc
@@ -10,6 +10,7 @@ #include "base/notreached.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/printing/print_job.h" #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" @@ -20,7 +21,6 @@ #include "printing/buildflags/buildflags.h" #include "printing/metafile.h" #include "printing/printed_document.h" -#include "printing/printing_features.h" #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_WIN) @@ -415,7 +415,7 @@ void PrintJobWorkerOop::SendEstablishPrintingContext() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); @@ -439,7 +439,7 @@ void PrintJobWorkerOop::SendStartPrinting(const std::string& device_name, const std::u16string& document_name) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); // The device name is needed repeatedly for each call to the service, cache // that for this print job.
diff --git a/chrome/browser/printing/print_test_utils.cc b/chrome/browser/printing/print_test_utils.cc index 0347bfd3..3e59c39 100644 --- a/chrome/browser/printing/print_test_utils.cc +++ b/chrome/browser/printing/print_test_utils.cc
@@ -16,6 +16,7 @@ #include "printing/print_job_constants.h" #if BUILDFLAG(ENABLE_OOP_PRINTING_NO_OOP_BASIC_PRINT_DIALOG) +#include "chrome/browser/printing/prefs_util.h" #include "printing/printing_features.h" #endif @@ -117,7 +118,7 @@ MakeDefaultPrintSettings(printer_name); settings->set_copies(kPrintSettingsCopies + 1); #if BUILDFLAG(ENABLE_OOP_PRINTING_NO_OOP_BASIC_PRINT_DIALOG) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { // Supply fake data to mimic what might be collected from the system print // dialog. Platform-specific since the fake data still has to be able to // pass mojom data validation.
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index cddf5ea..c83df9a8 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc
@@ -26,9 +26,12 @@ #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "printing/buildflags/buildflags.h" -#include "printing/printing_features.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" +#endif + #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h" #endif @@ -118,7 +121,7 @@ } #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (printing::features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { // Register this worker so that the service persists as long as the user // keeps the system print dialog UI displayed. if (!RegisterSystemPrintClient())
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 0d6dc69d4..8ca3ebc 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -60,6 +60,7 @@ #endif #if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #endif @@ -201,7 +202,7 @@ // static void PrintViewManagerBase::DisableThirdPartyBlocking() { #if BUILDFLAG(ENABLE_OOP_PRINTING) && BUILDFLAG(ENABLE_OOP_BASIC_PRINT_DIALOG) - if (!features::ShouldPrintJobOop()) { + if (!ShouldPrintJobOop()) { ModuleDatabase::DisableThirdPartyBlocking(); } #else @@ -240,11 +241,13 @@ PrinterHandler::PrintCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +#if BUILDFLAG(ENABLE_OOP_PRINTING) || BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS) bool show_system_dialog = job_settings.FindBool(kSettingShowSystemDialog).value_or(false); +#endif #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop() && show_system_dialog) { + if (show_system_dialog && ShouldPrintJobOop()) { if (!RegisterSystemPrintClient()) { // Platform unable to support system print dialog at this time, treat // this as a cancel. @@ -384,7 +387,7 @@ // dialog is cancelled. if (printer_query->last_status() == mojom::ResultCode::kCanceled) { #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { UnregisterSystemPrintClient(); } #endif @@ -481,7 +484,7 @@ mojom::PrintParamsPtr params) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop() && !params) { + if (ShouldPrintJobOop() && !params) { // The attempt to use the default settings failed. There should be no // subsequent call to get settings from the user that would normally be // shared as part of this client registration. Immediately notify the @@ -505,7 +508,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { // Finished getting all settings (defaults and from user), no further need // to be registered as a system print client. UnregisterSystemPrintClient(); @@ -654,7 +657,7 @@ return; } #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop() && + if (ShouldPrintJobOop() && #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS) !analyzing_content_ && #endif @@ -815,7 +818,7 @@ return; } #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop() && !query_with_ui_client_id_.has_value()) { + if (ShouldPrintJobOop() && !query_with_ui_client_id_.has_value()) { // Renderer process has requested settings outside of the expected setup. std::move(callback).Run(nullptr); return; @@ -1088,7 +1091,7 @@ printing_rfh_ = nullptr; #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { // Ensure that any residual registration of printing client is released. // This might be necessary in some abnormal cases, such as the associated // render process having terminated. @@ -1236,7 +1239,7 @@ } #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { // Register this worker so that the service persists as long as the user // keeps the system print dialog UI displayed. if (!RegisterSystemPrintClient()) { @@ -1252,7 +1255,7 @@ #if BUILDFLAG(ENABLE_OOP_PRINTING) bool PrintViewManagerBase::RegisterSystemPrintClient() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); DCHECK(!query_with_ui_client_id_.has_value()); query_with_ui_client_id_ = PrintBackendServiceManager::GetInstance().RegisterQueryWithUiClient(); @@ -1268,7 +1271,7 @@ void PrintViewManagerBase::UnregisterSystemPrintClient() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); if (!query_with_ui_client_id_.has_value()) { return; }
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc index 7149a14..bdf440e 100644 --- a/chrome/browser/printing/printer_query.cc +++ b/chrome/browser/printing/printer_query.cc
@@ -33,8 +33,8 @@ #endif #if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/printer_query_oop.h" -#include "printing/printing_features.h" #endif #if BUILDFLAG(IS_WIN) @@ -47,7 +47,7 @@ PrintingContext::ProcessBehavior GetPrintingContextProcessBehavior() { #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { return PrintingContext::ProcessBehavior::kOopEnabledSkipSystemCalls; } #endif @@ -108,7 +108,7 @@ } #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (features::ShouldPrintJobOop()) { + if (ShouldPrintJobOop()) { return base::WrapUnique(new PrinterQueryOop(rfh_id)); } #endif
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc index c409749..c8ff65bb 100644 --- a/chrome/browser/printing/printer_query_oop.cc +++ b/chrome/browser/printing/printer_query_oop.cc
@@ -10,13 +10,13 @@ #include "base/check_op.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/printing/print_job_worker_oop.h" #include "components/device_event_log/device_event_log.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents.h" #include "printing/buildflags/buildflags.h" -#include "printing/printing_features.h" namespace printing { @@ -301,7 +301,7 @@ PrintBackendServiceManager::ClientId client_id, const std::string& printer_name) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); DVLOG(1) << "Establishing printing context for system print"; @@ -324,7 +324,7 @@ void PrinterQueryOop::SendUseDefaultSettings(SettingsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); CHECK(query_with_ui_client_id_.has_value()); PrintBackendServiceManager& service_mgr = @@ -342,7 +342,7 @@ bool is_scripted, SettingsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(features::ShouldPrintJobOop()); + DCHECK(ShouldPrintJobOop()); if (document_page_count > kMaxPageCount) { InvokeSettingsCallback(std::move(callback), mojom::ResultCode::kFailed);
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc index 3fef7a9..1065b09a 100644 --- a/chrome/browser/printing/system_access_process_print_browsertest.cc +++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -73,7 +73,7 @@ namespace { -#if !BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(ENABLE_OOP_PRINTING) && !BUILDFLAG(IS_CHROMEOS) constexpr gfx::SizeF kLetterPhysicalSize = gfx::SizeF(612, 792); constexpr gfx::RectF kLetterPrintableArea = gfx::RectF(5, 5, 602, 782); constexpr gfx::SizeF kLegalPhysicalSize = gfx::SizeF(612, 1008); @@ -84,7 +84,7 @@ // Letter, and similarly is 556 x 952 for Legal. constexpr gfx::SizeF kLetterExpectedContentSize = gfx::SizeF(556, 736); constexpr gfx::SizeF kLegalExpectedContentSize = gfx::SizeF(556, 952); -#endif // !BUILDFLAG(IS_CHROMEOS) +#endif // BUILDFLAG(ENABLE_OOP_PRINTING) && !BUILDFLAG(IS_CHROMEOS) #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS) constexpr char kFakeDmToken[] = "fake-dm-token"; @@ -118,6 +118,7 @@ base::RepeatingCallback<void(bool allowed)>; #endif // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS) +#if BUILDFLAG(ENABLE_OOP_PRINTING) void CancelPrintPreview(content::WebContents* preview_dialog) { // This script locates and clicks the Cancel button for a Print Preview // dialog. @@ -137,6 +138,7 @@ // as monitoring for the Print Preview to be done if that is needed. std::ignore = content::ExecJs(preview_dialog, kScript); } +#endif // BUILDFLAG(ENABLE_OOP_PRINTING) } // namespace @@ -471,6 +473,7 @@ disabled_features.push_back(features::kEnableCloudScanAfterPreview); } #endif +#if BUILDFLAG(ENABLE_OOP_PRINTING) if (UseService()) { enabled_features.push_back( {features::kEnableOopPrintDrivers, @@ -480,6 +483,7 @@ } else { disabled_features.push_back(features::kEnableOopPrintDrivers); } +#endif feature_list_.InitWithFeaturesAndParameters(enabled_features, disabled_features); } @@ -600,6 +604,7 @@ #endif } +#if BUILDFLAG(ENABLE_OOP_PRINTING) // `PrintBackendServiceTestImpl` does a debug check on shutdown that there // are no residual persistent printing contexts left in the service. For // tests which are known to break this (either by design, for test simplicity @@ -619,6 +624,7 @@ void OnRegisterSystemPrintClient(bool succeeded) override { system_print_registration_succeeded_ = succeeded; } +#endif void OnDidPrintDocument() override { ++did_print_document_count_; @@ -881,9 +887,11 @@ } #endif +#if BUILDFLAG(ENABLE_OOP_PRINTING) void SetCheckForPrintPreviewDone(bool check) { check_for_print_preview_done_ = check; } +#endif const absl::optional<bool> system_print_registration_succeeded() const { return system_print_registration_succeeded_; @@ -1164,7 +1172,7 @@ testing::Values(PrintBackendFeatureVariation::kOopSandboxedService, PrintBackendFeatureVariation::kOopUnsandboxedService)); -#endif +#endif // BUILDFLAG(ENABLE_OOP_PRINTING) class SystemAccessProcessInBrowserPrintBrowserTest : public SystemAccessProcessPrintBrowserTestBase { @@ -1179,6 +1187,8 @@ #endif }; +#if BUILDFLAG(ENABLE_OOP_PRINTING) + class SystemAccessProcessPrintBrowserTest : public SystemAccessProcessPrintBrowserTestBase, public testing::WithParamInterface<PrintBackendFeatureVariation> { @@ -1239,8 +1249,6 @@ #endif } -#if BUILDFLAG(ENABLE_OOP_PRINTING) - IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest, UpdatePrintSettingsPrintableArea) { AddPrinter("printer1");
diff --git a/chrome/browser/profiles/BUILD.gn b/chrome/browser/profiles/BUILD.gn index d2f6ef1..403b84b 100644 --- a/chrome/browser/profiles/BUILD.gn +++ b/chrome/browser/profiles/BUILD.gn
@@ -62,7 +62,9 @@ "//components/live_caption:constants", "//components/media_router/common", "//components/pref_registry", + "//components/prefs", "//components/profile_metrics", + "//components/search_engines", "//components/sync/service", "//components/variations", "//content/public/browser",
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 7c7c87c..b672915 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -28,7 +28,10 @@ #include "components/language/core/browser/pref_names.h" #include "components/live_caption/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_service.h" #include "components/profile_metrics/browser_profile_type.h" +#include "components/search_engines/search_engine_choice_utils.h" +#include "components/search_engines/search_engines_pref_names.h" #include "components/variations/variations.mojom.h" #include "components/variations/variations_client.h" #include "components/variations/variations_ids_provider.h" @@ -505,6 +508,14 @@ } void Profile::Wipe() { + // Clear the search engine choice prefs. + // TODO(b/312180262): Consider clearing other preferences as well. + if (search_engines::IsChoiceScreenFlagEnabled( + search_engines::ChoicePromo::kAny)) { + GetPrefs()->ClearPref( + prefs::kDefaultSearchProviderChoiceScreenCompletionTimestamp); + } + GetBrowsingDataRemover()->Remove( base::Time(), base::Time::Max(), chrome_browsing_data_remover::WIPE_PROFILE,
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index d397943..52a5f08 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -398,6 +398,9 @@ #if BUILDFLAG(ENABLE_PRINTING) registry->RegisterBooleanPref(prefs::kPrintingEnabled, true); #endif // BUILDFLAG(ENABLE_PRINTING) +#if BUILDFLAG(ENABLE_OOP_PRINTING) + registry->RegisterBooleanPref(prefs::kOopPrintDriversAllowedByPolicy, true); +#endif registry->RegisterBooleanPref(prefs::kPrintPreviewDisabled, false); registry->RegisterStringPref( prefs::kPrintPreviewDefaultDestinationSelectionRules, std::string());
diff --git a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_fil.xtb b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_fil.xtb index 64cccd78..05fe34b2 100644 --- a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_fil.xtb +++ b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_fil.xtb
@@ -3,6 +3,8 @@ <translationbundle lang="fil"> <translation id="1178581264944972037">I-pause</translation> <translation id="1921351128855867012">I-fast forward nang <ph name="NUMBER_OF_SECONDS" /> (na) segundo</translation> +<translation id="1984328900355667246">Hindi available ang pag-playback</translation> +<translation id="3023502830214299618">Sa kasamaang-palad, hindi available ang pag-playback para sa page na ito sa ngayon. Pakisubukan ulit sa ibang pagkakataon.</translation> <translation id="3807208219231826020">I-scrub ang Pag-playback</translation> <translation id="385051799172605136">Bumalik</translation> <translation id="4431240646217225907">Mag-highlight ng text at mag-auto scroll</translation>
diff --git a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_ms.xtb b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_ms.xtb index 93656ab..252293f8 100644 --- a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_ms.xtb +++ b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_ms.xtb
@@ -3,6 +3,8 @@ <translationbundle lang="ms"> <translation id="1178581264944972037">Jeda</translation> <translation id="1921351128855867012">Mundar laju <ph name="NUMBER_OF_SECONDS" /> saat</translation> +<translation id="1984328900355667246">Main balik tidak tersedia</translation> +<translation id="3023502830214299618">Dukacita dimaklumkan, main balik tidak tersedia untuk halaman ini pada masa ini. Sila cuba sebentar lagi.</translation> <translation id="3807208219231826020">Seret Main Balik</translation> <translation id="385051799172605136">Kembali</translation> <translation id="4431240646217225907">Serlahkan teks & penatalan automatik</translation>
diff --git a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_th.xtb b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_th.xtb index 6809742..8008dc1 100644 --- a/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_th.xtb +++ b/chrome/browser/readaloud/android/resources/translations/android_readaloud_strings_th.xtb
@@ -3,6 +3,8 @@ <translationbundle lang="th"> <translation id="1178581264944972037">หยุดชั่วคราว</translation> <translation id="1921351128855867012">กรอไปข้างหน้า <ph name="NUMBER_OF_SECONDS" /> วินาที</translation> +<translation id="1984328900355667246">เล่นเสียงไม่ได้</translation> +<translation id="3023502830214299618">ขออภัย ไม่สามารถเล่นเสียงสำหรับหน้านี้ได้ในขณะนี้ โปรดลองอีกครั้งภายหลัง</translation> <translation id="3807208219231826020">สครับการเล่น</translation> <translation id="385051799172605136">กลับ</translation> <translation id="4431240646217225907">ไฮไลต์ข้อความและการเลื่อนอัตโนมัติ</translation>
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index cd750959..15af2783 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -274,6 +274,7 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) #include "chrome/browser/supervised_user/supervised_user_service_factory.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" #endif @@ -3565,10 +3566,10 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) Profile* const profile = Profile::FromBrowserContext(browser_context_); - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile); - if (supervised_user_service && - supervised_user_service->IsURLFilteringEnabled()) { + CHECK(profile); + if (supervised_user::IsUrlFilteringEnabled(*profile->GetPrefs())) { + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForProfile(profile); supervised_user::SupervisedUserURLFilter* url_filter = supervised_user_service->GetURLFilter(); // Use the URL filter's synchronous call to check if a site has been @@ -3923,11 +3924,10 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) void RenderViewContextMenu::CheckSupervisedUserURLFilterAndSaveLinkAs() { Profile* const profile = Profile::FromBrowserContext(browser_context_); - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile); - - if (supervised_user_service && - supervised_user_service->IsURLFilteringEnabled()) { + CHECK(profile); + if (supervised_user::IsUrlFilteringEnabled(*profile->GetPrefs())) { + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForProfile(profile); supervised_user::SupervisedUserURLFilter* url_filter = supervised_user_service->GetURLFilter(); url_filter->GetFilteringBehaviorForURLWithAsyncChecks(
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 3d2c4d8..f361bae 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -144,6 +144,7 @@ #include "chrome/test/supervised_user/embedded_test_server_setup_mixin.h" #include "chrome/test/supervised_user/supervision_mixin.h" #include "components/supervised_user/core/browser/kids_chrome_management_client.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" #include "components/supervised_user/core/common/features.h" @@ -655,7 +656,8 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_SAVELINKAS)); // The entry is only disabled for platforms on which URL filtering is enabled. - if (GetSupervisedUserService()->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled( + *browser()->profile()->GetPrefs())) { EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SAVELINKAS)); } else { EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_SAVELINKAS)); @@ -669,7 +671,8 @@ base::RunLoop().RunUntilIdle(); - if (GetSupervisedUserService()->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled( + *browser()->profile()->GetPrefs())) { kids_management_api_mock().RestrictSubsequentClassifyUrl(); EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl) .Times(1); @@ -704,7 +707,8 @@ std::u16string suggested_filename = menu_observer.params().suggested_filename; // The save link as action is only blocked for platforms on which URL // filtering is enabled. - if (GetSupervisedUserService()->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled( + *browser()->profile()->GetPrefs())) { const std::string kSuggestedFilename(""); ASSERT_EQ(kSuggestedFilename, base::UTF16ToUTF8(suggested_filename).c_str()); @@ -720,7 +724,8 @@ SaveLinkAsEntryIsEnabledForUrlsAllowedByAsyncCheckerForChild) { ContextMenuWaiter menu_observer; - if (GetSupervisedUserService()->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled( + *browser()->profile()->GetPrefs())) { kids_management_api_mock().AllowSubsequentClassifyUrl(); EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl) .Times(1);
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_dropdown_item.html b/chrome/browser/resources/ash/settings/device_page/customize_button_dropdown_item.html index ecbebc4..2bbdc741 100644 --- a/chrome/browser/resources/ash/settings/device_page/customize_button_dropdown_item.html +++ b/chrome/browser/resources/ash/settings/device_page/customize_button_dropdown_item.html
@@ -10,7 +10,7 @@ background-color: var(--cros-highlight-color-hover); } </style> -<div id="container" hidden="[[option.hidden]]" +<div id="container" hidden="[[option.hidden]]" tabindex="-1" class="option-item" on-click="onDropdownItemSelected_"> [[option.name]] </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_select.html b/chrome/browser/resources/ash/settings/device_page/customize_button_select.html index d555ab0..3faa941 100644 --- a/chrome/browser/resources/ash/settings/device_page/customize_button_select.html +++ b/chrome/browser/resources/ash/settings/device_page/customize_button_select.html
@@ -16,6 +16,15 @@ height: 20px; } + .label-container { + display: flex; + } + + .label-container > span { + padding-inline-start: 3px; + padding-inline-end: 3px; + } + .md-select { background-position-x: 175px; padding: 8px 16px; @@ -23,9 +32,23 @@ } </style> <div tabindex="0" id="selectDropdown" - class="md-select" + class="md-select label-container" on-click="showDropdownMenu_"> + <template is="dom-if" if="[[remappedToKeyCombination_]]"> + <template is="dom-repeat" items="[[inputKeys_]]"> + <template is="dom-if" if="[[getIconIdForKey_(item)]]"> + <iron-icon icon="[[getIconIdForKey_(item)]]" + aria-hidden="true"> + </iron-icon> + </template> + <template is="dom-if" if="[[!getIconIdForKey_(item)]]"> + <span>[[item]]</span> + </template> + </template> + </template> + <template is="dom-if" if="[[!remappedToKeyCombination_]]"> [[label_]] + </template> </div> <iron-dropdown opened="[[shouldShowDropdownMenu_]]" no-cancel-on-outside-click>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts b/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts index b385851..4758d26 100644 --- a/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts +++ b/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts
@@ -5,11 +5,16 @@ import 'chrome://resources/cr_elements/md_select.css.js'; import 'chrome://resources/polymer/v3_0/iron-dropdown/iron-dropdown.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; +import 'chrome://resources/ash/common/shortcut_input_ui/shortcut_input_key.js'; +import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; +import 'chrome://resources/ash/common/shortcut_input_ui/icons.html.js'; import './input_device_settings_shared.css.js'; import './customize_button_dropdown_item.js'; import '../settings_shared.css.js'; import {DropdownMenuOptionList} from '/shared/settings/controls/settings_dropdown_menu.js'; +import {LWIN_KEY, META_KEY} from 'chrome://resources/ash/common/shortcut_input_ui/shortcut_input_key.js'; +import {KeyToIconNameMap} from 'chrome://resources/ash/common/shortcut_input_ui/shortcut_utils.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -56,24 +61,23 @@ [Modifier.META, 'meta'], ]); -function concateKeyString(firstStr: string, secondStr: string): string { - return firstStr.length === 0 ? secondStr : firstStr.concat(` + ${secondStr}`); -} - /** * Converts a keyEvent to a string representing all the modifiers and the vkey. */ -function getKeyCombinationLabel(keyEvent: KeyEvent): string { - let combinationLabel = ''; +function getInputKeys(keyEvent: KeyEvent): string[] { + const inputKeysArray: string[] = []; modifierBitMaskToString.forEach((modifierName: string, bitValue: number) => { if ((keyEvent.modifiers & bitValue) !== 0) { - combinationLabel = concateKeyString(combinationLabel, modifierName); + inputKeysArray.push(modifierName, '+'); } }); if (keyEvent.keyDisplay !== undefined && keyEvent.keyDisplay.length !== 0) { - combinationLabel = concateKeyString(combinationLabel, keyEvent.keyDisplay); + inputKeysArray.push(keyEvent.keyDisplay); + } else { + // If no regular key to display, remove the extra '+'. + inputKeysArray.splice(inputKeysArray.length - 1, 1); } - return combinationLabel; + return inputKeysArray; } /** @@ -138,6 +142,16 @@ type: String, computed: 'getSelectedLabel_(selectedValue, menu.*)', }, + + inputKeys_: { + type: Array, + value: [], + }, + + remappedToKeyCombination_: { + type: Boolean, + value: false, + }, }; } @@ -158,6 +172,8 @@ private shouldShowDropdownMenu_: boolean; private label_: string; private buttonRemapping_: ButtonRemapping; + private inputKeys_: string[]; + private remappedToKeyCombination_: boolean; override connectedCallback(): void { super.connectedCallback(); @@ -209,6 +225,9 @@ } else if (optionValue !== this.selectedValue) { this.set('selectedValue', optionValue); } + + // Close dropdown menu after selected. + this.shouldShowDropdownMenu_ = false; } private getSelectedLabel_(): string { @@ -294,6 +313,8 @@ } private initializeSelectedValue_(): void { + this.inputKeys_ = []; + this.remappedToKeyCombination_ = false; // For accelerator actions, the remappingAction.acceleratorAction value is // number. const acceleratorAction = @@ -310,14 +331,8 @@ this.setSelectedValue( ACCELERATOR_ACTION_PREFIX + acceleratorAction.toString()); } else if (keyEvent) { - const keyCombinationLabel = getKeyCombinationLabel(keyEvent) ?? - this.i18n('keyCombinationOptionLabel'); - - this.splice('menu', this.menu.length - 1, 1, { - value: KEY_COMBINATION_OPTION_VALUE, - name: keyCombinationLabel, - hidden: true, - }); + this.inputKeys_ = getInputKeys(keyEvent); + this.remappedToKeyCombination_ = !!this.inputKeys_; this.setSelectedValue(KEY_COMBINATION_OPTION_VALUE); } else if ( @@ -386,6 +401,14 @@ composed: true, })); } + + private getIconIdForKey_(key: string): string|null { + if (key === META_KEY || key === LWIN_KEY) { + return 'shortcut-input-keys:launcher'; + } + const iconName = KeyToIconNameMap[key]; + return iconName ? `shortcut-input-keys:${iconName}` : null; + } } declare global {
diff --git a/chrome/browser/resources/ash/settings/device_page/device_page.html b/chrome/browser/resources/ash/settings/device_page/device_page.html index 7e8c2f6..5413ff6 100644 --- a/chrome/browser/resources/ash/settings/device_page/device_page.html +++ b/chrome/browser/resources/ash/settings/device_page/device_page.html
@@ -9,6 +9,10 @@ --iron-icon-fill-color: currentColor; margin-inline-end: 8px; } + + :host-context(body.revamp-wayfinding-enabled) cr-link-row { + --cr-link-row-start-icon-color: var(--cros-sys-primary); + } </style> <os-settings-animated-pages id="pages" section="[[section_]]"> @@ -18,6 +22,7 @@ if="[[showPointersRow_(hasMouse_, hasPointingStick_, hasTouchpad_, isDeviceSettingsSplitEnabled_)]]"> <cr-link-row id="pointersRow" + start-icon="[[rowIcons_.pointingStick]]" label="[[getPointersTitle_(hasMouse_, hasPointingStick_, hasTouchpad_)]]" on-click="onPointersClick_" @@ -26,7 +31,8 @@ <template is="dom-if" if="[[showPerDeviceMouseRow_(mice, isDeviceSettingsSplitEnabled_)]]"> - <cr-link-row class="hr" id="perDeviceMouseRow" label="$i18n{mouseTitle}" + <cr-link-row class="hr" id="perDeviceMouseRow" + start-icon="[[rowIcons_.mouse]]" label="$i18n{mouseTitle}" on-click="onPerDeviceMouseClick_" aria-label="$i18n{mouseTitle}" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row> @@ -35,6 +41,7 @@ if="[[showPerDeviceTouchpadRow_(touchpads, isDeviceSettingsSplitEnabled_)]]"> <cr-link-row class="hr" id="perDeviceTouchpadRow" + start-icon="[[rowIcons_.touchpad]]" aria-label="$i18n{touchpadTitle}" label="$i18n{touchpadTitle}" on-click="onPerDeviceTouchpadClick_" role-description="$i18n{subpageArrowRoleDescription}"> @@ -44,6 +51,7 @@ if="[[showPerDevicePointingStickRow_(pointingSticks, isDeviceSettingsSplitEnabled_)]]"> <cr-link-row class="hr" id="perDevicePointingStickRow" + start-icon="[[rowIcons_.pointingStick]]" aria-label="$i18n{pointingStickTitle}" label="$i18n{pointingStickTitle}" on-click="onPerDevicePointingStickClick_" @@ -53,6 +61,7 @@ <template is="dom-if" if="[[isDeviceSettingsSplitEnabled_]]"> <cr-link-row id="perDeviceKeyboardRow" class="hr" + start-icon="[[rowIcons_.keyboardAndInputs]]" label="$i18n{keyboardTitle}" aria-label="$i18n{keyboardTitle}" sub-label="[[inputMethodDisplayName_]]" @@ -63,29 +72,34 @@ <template is="dom-if" if="[[!isDeviceSettingsSplitEnabled_]]"> <cr-link-row id="keyboardRow" class="hr" + start-icon="[[rowIcons_.keyboardAndInputs]]" label="$i18n{keyboardTitle}" sub-label="[[inputMethodDisplayName_]]" on-click="onKeyboardClick_" role-description="$i18n{subpageArrowRoleDescription}"></cr-link-row> </template> <template is="dom-if" if="[[hasStylus_]]"> - <cr-link-row class="hr" id="stylusRow" label="$i18n{stylusTitle}" + <cr-link-row class="hr" id="stylusRow" + start-icon="[[rowIcons_.stylus]]" + label="$i18n{stylusTitle}" on-click="onStylusClick_" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row> </template> <template is="dom-if" if="[[showGraphicsTabletRow_(graphicsTablets, isPeripheralCustomizationEnabled)]]"> - <cr-link-row class="hr" id="tabletRow" label="$i18n{tabletTitle}" + <cr-link-row class="hr" id="tabletRow" + start-icon="[[rowIcons_.tablet]]" label="$i18n{tabletTitle}" on-click="onGraphicsTabletClick" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row> </template> - <cr-link-row class="hr" id="displayRow" label="$i18n{displayTitle}" - on-click="onDisplayClick_" - role-description="$i18n{subpageArrowRoleDescription}"></cr-link-row> - <cr-link-row class="hr" id="audioRow" label="$i18n{audioTitle}" - on-click="onAudioClick_" + <cr-link-row class="hr" id="displayRow" start-icon="[[rowIcons_.display]]" + label="$i18n{displayTitle}" on-click="onDisplayClick_" + role-description="$i18n{subpageArrowRoleDescription}"> + </cr-link-row> + <cr-link-row class="hr" id="audioRow" start-icon="[[rowIcons_.audio]]" + label="$i18n{audioTitle}" on-click="onAudioClick_" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row> <template is="dom-if" if="[[!isRevampWayfindingEnabled_]]">
diff --git a/chrome/browser/resources/ash/settings/device_page/device_page.ts b/chrome/browser/resources/ash/settings/device_page/device_page.ts index 2b3bece..0d4dd3b 100644 --- a/chrome/browser/resources/ash/settings/device_page/device_page.ts +++ b/chrome/browser/resources/ash/settings/device_page/device_page.ts
@@ -199,6 +199,35 @@ computed: 'computeInputMethodDisplayName_(' + 'languages.inputMethods.currentId, languageHelper)', }, + + rowIcons_: { + type: Object, + value() { + if (isRevampWayfindingEnabled()) { + return { + mouse: 'os-settings:device-mouse', + touchpad: 'os-settings:device-touchpad', + pointingStick: 'os-settings:device-pointing-stick', + keyboardAndInputs: 'os-settings:device-keyboard', + stylus: 'os-settings:device-stylus', + tablet: 'os-settings:device-tablet', + display: 'os-settings:device-display', + audio: 'os-settings:device-audio', + }; + } + + return { + mouse: '', + touchpad: '', + pointingStick: '', + keyboardAndInputs: '', + stylus: '', + tablet: '', + display: '', + audio: '', + }; + }, + }, }; } @@ -239,6 +268,7 @@ private mouseSettingsObserverReceiver: MouseSettingsObserverReceiver; private graphicsTabletSettingsObserverReceiver: GraphicsTabletSettingsObserverReceiver; + private rowIcons_: Record<string, string>; private section_: Section; constructor() {
diff --git a/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.html b/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.html index 908c26b..400461e 100644 --- a/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.html +++ b/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.html
@@ -1,7 +1,13 @@ -<style include="settings-shared"></style> +<style include="settings-shared"> + :host-context(body.revamp-wayfinding-enabled) cr-link-row { + --cr-link-row-start-icon-color: var(--cros-sys-primary); + } +</style> <settings-card header-text="$i18n{printingPageTitle}"> - <cr-link-row id="cupsPrintersRow" label="$i18n{cupsPrintTitle}" + <cr-link-row id="cupsPrintersRow" + start-icon="[[rowIcons_.print]]" + label="$i18n{cupsPrintTitle}" sub-label="[[getCupsPrintDescription_()]]" on-click="onClickCupsPrint_" role-description="$i18n{subpageArrowRoleDescription}"> @@ -16,6 +22,7 @@ </cr-link-row> </template> <cr-link-row id="scanningApp" class="hr" + start-icon="[[rowIcons_.scan]]" on-click="onClickScanningApp_" label="$i18n{scanAppTitle}" sub-label="$i18n{scanAppSublabel}"
diff --git a/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.ts b/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.ts index a7290b8..194a0788 100644 --- a/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.ts +++ b/chrome/browser/resources/ash/settings/os_printing_page/printing_settings_card.ts
@@ -54,11 +54,29 @@ return isRevampWayfindingEnabled(); }, }, + + rowIcons_: { + type: Object, + value() { + if (isRevampWayfindingEnabled()) { + return { + print: 'os-settings:device-print', + scan: 'os-settings:device-scan', + }; + } + + return { + print: '', + scan: '', + }; + }, + }, }; } private browserProxy_: CupsPrintersBrowserProxy; private isRevampWayfindingEnabled_: boolean; + private rowIcons_: Record<string, string>; constructor() { super();
diff --git a/chrome/browser/resources/ash/settings/os_settings_icons.html b/chrome/browser/resources/ash/settings/os_settings_icons.html index a651131..d00c57e0f 100644 --- a/chrome/browser/resources/ash/settings/os_settings_icons.html +++ b/chrome/browser/resources/ash/settings/os_settings_icons.html
@@ -60,6 +60,52 @@ <path d="M0 0h24v24H0V0z" fill="none"></path><path d="M16 6l-1.41 1.41L19.17 12l-4.58 4.59L16 18l6-6zM8 18l1.41-1.41L4.83 12l4.58-4.59L8 6l-6 6z"></path> </g> + <!-- Device section --> + <g id="device-pointing-stick" width="20" height="20" viewBox="0 0 20 20"> + <g clip-path="url(#a)"> + <path fill-rule="evenodd" d="M10 11.625c-.444 0-.826-.16-1.146-.48-.32-.319-.479-.7-.479-1.145 0-.444.16-.826.48-1.146.319-.32.7-.479 1.145-.479.444 0 .826.16 1.146.48.32.319.479.7.479 1.145 0 .444-.16.826-.48 1.146-.319.32-.7.479-1.145.479Zm-.875-4.75v-5.02h1.75v5.02h-1.75Zm0 11.27v-5.02h1.75v5.02h-1.75Zm4-7.27v-1.75h5.02v1.75h-5.02Zm-11.27 0v-1.75h5.02v1.75h-5.02Z"></path> + </g> + <defs> + <clipPath id="a"> + <path fill="#fff" d="M0 0h20v20H0z"></path> + </clipPath> + </defs> + </g> + <g id="device-mouse" width="20" height="20" viewBox="0 0 20 20"> + <g clip-path="url(#a)"> + <path fill-rule="evenodd" d="M10 18.167c-1.708 0-3.167-.598-4.375-1.792C4.431 15.167 3.833 13.708 3.833 12V8c0-1.708.598-3.16 1.792-4.354C6.833 2.438 8.292 1.833 10 1.833c1.708 0 3.16.605 4.354 1.813C15.563 4.84 16.167 6.292 16.167 8v4c0 1.708-.605 3.167-1.813 4.375-1.194 1.194-2.646 1.792-4.354 1.792ZM10.75 7.5h3.646a4.316 4.316 0 0 0-1.167-2.542c-.666-.708-1.493-1.146-2.479-1.312V7.5Zm-5.146 0H9.25V3.646a4.14 4.14 0 0 0-2.48 1.312A4.316 4.316 0 0 0 5.605 7.5ZM10 16.438c1.222 0 2.264-.431 3.125-1.292.875-.875 1.313-1.924 1.313-3.146V9H5.563v3c0 1.222.43 2.27 1.291 3.146.875.86 1.924 1.291 3.146 1.291Z"></path> + </g> + <defs> + <clipPath id="a"> + <path fill="#fff" d="M0 0h20v20H0z"></path> + </clipPath> + </defs> + </g> + <g id="device-touchpad" width="18" height="16" viewBox="0 0 18 16"> + <path fill-rule="evenodd" d="M12.583 13.52c.82 0 1.514-.284 2.084-.853a2.88 2.88 0 0 0 .854-2.084V9.75H9.646v.833c0 .806.285 1.5.854 2.084a2.88 2.88 0 0 0 2.083.854ZM9.688 8.126h2.083V5.75a2.997 2.997 0 0 0-1.396.875 2.775 2.775 0 0 0-.687 1.5Zm3.708 0h2.083a2.906 2.906 0 0 0-.708-1.5 2.866 2.866 0 0 0-1.375-.875v2.375Zm-.813 7.042c-1.291 0-2.382-.438-3.27-1.313C8.437 12.965 8 11.875 8 10.584V8.645c0-1.292.438-2.375 1.313-3.25.888-.89 1.979-1.333 3.27-1.333 1.292 0 2.375.444 3.25 1.333.89.875 1.334 1.958 1.334 3.25v1.937c0 1.292-.445 2.382-1.334 3.271-.875.875-1.958 1.313-3.25 1.313Zm-10.02-3.73V2.563v8.874Zm0 1.73c-.487 0-.896-.167-1.23-.5a1.716 1.716 0 0 1-.5-1.23V2.563c0-.473.167-.876.5-1.209.334-.347.743-.52 1.23-.52h12.875c.486 0 .895.173 1.229.52.333.333.5.736.5 1.209v2.083a5.916 5.916 0 0 0-.813-.75 5.5 5.5 0 0 0-.916-.604v-.73H2.563v8.876h4c.027.305.083.604.166.895.083.292.195.57.333.834h-4.5Z"></path> + </g> + <g id="device-keyboard" width="18" height="12" viewBox="0 0 18 12"> + <path fill-rule="evenodd" d="M2.5 11.23c-.472 0-.882-.168-1.23-.5a1.716 1.716 0 0 1-.5-1.23v-7c0-.472.167-.875.5-1.208C1.619.944 2.029.77 2.5.77h13c.472 0 .875.173 1.208.52.348.334.521.737.521 1.209v7c0 .472-.173.882-.52 1.23-.334.332-.737.5-1.209.5h-13Zm0-1.73h13v-7h-13v7ZM6 9h6V7.5H6V9ZM4 6.5h1.5V5H4v1.5Zm2.125 0h1.5V5h-1.5v1.5Zm2.125 0h1.5V5h-1.5v1.5Zm2.125 0h1.5V5h-1.5v1.5Zm2.125 0H14V5h-1.5v1.5ZM4 4.5h1.5V3H4v1.5Zm2.125 0h1.5V3h-1.5v1.5Zm2.125 0h1.5V3h-1.5v1.5Zm2.125 0h1.5V3h-1.5v1.5Zm2.125 0H14V3h-1.5v1.5Zm-10 5v-7 7Z"></path> + </g> + <g id="device-stylus" width="16" height="16" viewBox="0 0 16 16"> + <path fill-rule="evenodd" d="M1.917 15.125a.83.83 0 0 1-.813-.23.952.952 0 0 1-.229-.832l.77-3.75 4.022 4.041-3.75.771Zm3.75-.77-4.021-4.043 8.958-8.937c.334-.333.736-.5 1.209-.5.472 0 .874.167 1.208.5l1.604 1.583c.333.334.5.743.5 1.23 0 .472-.167.875-.5 1.208l-8.958 8.958Zm6.146-11.75-8.021 8.04 1.562 1.563 8.042-8.02-1.584-1.584Z"></path> + </g> + <g id="device-tablet" width="20" height="14" viewBox="0 0 20 14"> + <path fill-rule="evenodd" d="M2.583 13.167a1.67 1.67 0 0 1-1.229-.5 1.716 1.716 0 0 1-.5-1.23V2.563c0-.487.167-.896.5-1.23a1.67 1.67 0 0 1 1.23-.5h14.833c.486 0 .895.174 1.229.521.333.333.5.736.5 1.209v8.875c0 .486-.167.895-.5 1.229a1.67 1.67 0 0 1-1.23.5H2.584Zm1-10.604h-1v8.875h1V2.563Zm1.5 8.875h9.834V2.563H5.083v8.875Zm11.334-8.875v8.875h1V2.563h-1Zm0 0h1-1Zm-12.834 0h-1 1Z"></path> + </g> + <g id="device-display" width="18" height="16" viewBox="0 0 18 16"> + <path fill-rule="evenodd" d="M5.917 15.167v-2H2.563c-.487 0-.896-.167-1.23-.5a1.671 1.671 0 0 1-.5-1.23V2.563c0-.487.167-.896.5-1.23a1.67 1.67 0 0 1 1.23-.5h12.875c.486 0 .895.167 1.229.5.333.334.5.743.5 1.23v8.875c0 .486-.167.895-.5 1.229-.334.333-.743.5-1.23.5h-3.354v2H5.917Zm-3.354-3.73h12.875V2.563H2.563v8.875Zm0 0V2.563v8.875Z"></path> + </g> + <g id="device-audio" width="12" height="17" viewBox="0 0 12 17"> + <path fill-rule="evenodd" d="M6 11.23c-.75 0-1.389-.258-1.917-.772a2.646 2.646 0 0 1-.77-1.916V3.583c0-.75.256-1.389.77-1.916A2.61 2.61 0 0 1 6 .875c.75 0 1.382.264 1.896.792a2.61 2.61 0 0 1 .792 1.916v4.959a2.61 2.61 0 0 1-.792 1.916c-.514.514-1.146.771-1.896.771Zm-.833 5.083v-2.084c-1.417-.194-2.59-.826-3.521-1.896C.716 11.25.25 9.986.25 8.542h1.646c0 1.139.396 2.11 1.187 2.916.806.792 1.778 1.188 2.917 1.188 1.139 0 2.104-.396 2.896-1.188.805-.805 1.208-1.777 1.208-2.916h1.646c0 1.444-.465 2.708-1.396 3.791-.93 1.07-2.104 1.702-3.52 1.896v2.084H5.166ZM6 9.5c.278 0 .507-.09.688-.27.18-.181.27-.41.27-.688V3.583a.931.931 0 0 0-.27-.687A.932.932 0 0 0 6 2.625a.932.932 0 0 0-.687.27.931.931 0 0 0-.271.688v4.959c0 .277.09.507.27.687.181.18.41.271.688.271Z"></path> + </g> + <g id="device-print" width="18" height="16" viewBox="0 0 18 16"> + <path fill-rule="evenodd" d="M14.167 3.833H3.833v-3h10.334v3Zm-.521 4.875c.222 0 .41-.076.562-.229a.756.756 0 0 0 .25-.583.79.79 0 0 0-.229-.583.757.757 0 0 0-.583-.25.823.823 0 0 0-.604.25.765.765 0 0 0-.23.562c0 .236.077.438.23.604.166.153.368.23.604.23Zm-1.209 4.855v-2.626H5.564v2.626h6.875Zm1.73 1.687H3.833v-3.104h-3V7c0-.597.209-1.104.625-1.52.417-.431.924-.647 1.521-.647h12.042c.597 0 1.104.216 1.52.646.417.417.626.924.626 1.521v5.146h-3v3.104Z"></path> + </g> + <g id="device-scan" width="16" height="13" viewBox="0 0 16 13"> + <path fill-rule="evenodd" d="M10.708 5.77 1.167 2.334 1.729.771l12.209 4.416c.43.14.756.382.979.73.236.333.354.701.354 1.104V10.5c0 .472-.174.882-.521 1.23-.333.332-.736.5-1.208.5H2.458c-.472 0-.882-.168-1.229-.5a1.716 1.716 0 0 1-.5-1.23v-3c0-.486.167-.896.5-1.23.347-.332.757-.5 1.23-.5h8.25Zm2.834 4.73v-3H2.458v3h11.084Zm-7.084-.75h6.084v-1.5H6.458v1.5Zm-2.25 0c.209 0 .382-.07.521-.208A.74.74 0 0 0 4.96 9a.707.707 0 0 0-.209-.52.698.698 0 0 0-.542-.23.74.74 0 0 0-.541.23.707.707 0 0 0-.209.52c0 .208.07.389.209.542a.779.779 0 0 0 .541.208Zm-1.75.75v-3 3Z"></path> + </g> + <!-- Files section --> <g id="folder-outline"><path d="M16 5h-4l-2-2H4c-1.1 0-1.99.9-1.99 2L2 15c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 10H4V7h12v8z"></path></g>
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js index a64635a..37b4526 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js
@@ -2370,8 +2370,9 @@ }); // Regression test that large text areas produce output. +// TODO(crbug.com/1503691): re-enable this test once its flakiness is resolved. AX_TEST_F( - 'ChromeVoxEditingTest', 'GiantTextAreaPerformance', + 'ChromeVoxEditingTest', 'DISABLED_GiantTextAreaPerformance', async function() { const mockFeedback = this.createMockFeedback(); const site = `
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js index bc29060..68562d5 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js
@@ -111,11 +111,9 @@ this.addListener_( EventType.LOAD_COMPLETE, event => this.onLoadComplete_(event)); - this.addListener_(EventType.FOCUS_AFTER_MENU_CLOSE, this.onMenuEnd); - this.addListener_(EventType.MENU_START, event => { - Output.forceModeForNextSpeechUtterance(QueueMode.CATEGORY_FLUSH); - this.onEventDefault(event); - }); + this.addListener_( + EventType.FOCUS_AFTER_MENU_CLOSE, event => this.onMenuEnd_(event)); + this.addListener_(EventType.MENU_START, event => this.onMenuStart_(event)); this.addListener_(EventType.RANGE_VALUE_CHANGED, this.onValueChanged); this.addListener_( EventType.SCROLL_POSITION_CHANGED, this.onScrollPositionChanged); @@ -734,8 +732,9 @@ /** * Provides all feedback once a menu end event fires. * @param {!ChromeVoxEvent} evt + * @private */ - onMenuEnd(evt) { + onMenuEnd_(evt) { // This is a work around for Chrome context menus not firing a focus event // after you close them. chrome.automation.getFocus(focus => { @@ -753,6 +752,15 @@ } /** + * @param {!ChromeVoxEvent} event + * @private + */ + onMenuStart_(event) { + Output.forceModeForNextSpeechUtterance(QueueMode.CATEGORY_FLUSH); + this.onEventDefault(event); + } + + /** * Provides all feedback once a scrolled to anchor event fires. * @param {!ChromeVoxEvent} evt */
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path.js index 3b3f44c..bd77e84d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/forced_action_path.js
@@ -408,10 +408,5 @@ () => ForcedActionPath.destroy()); BridgeHelper.registerHandler( BridgeConstants.ForcedActionPath.TARGET, - BridgeConstants.ForcedActionPath.Action.ON_KEY_DOWN, evt => { - if (!ForcedActionPath.instance) { - // Continue propagating. - return true; - } - return ForcedActionPath.instance.onKeyDown(evt); - }); + BridgeConstants.ForcedActionPath.Action.ON_KEY_DOWN, + evt => ForcedActionPath.instance?.onKeyDown(evt) ?? true);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js index 30951dd..90d4b16 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
@@ -422,9 +422,9 @@ .expectSpeech('Quick orientation') .call(doCmd('forceClickOnCurrentItem')) .expectSpeech(/Quick Orientation Tutorial, [0-9]+ Lessons/) - .call(doCmd('nextObject')) - .expectSpeech('Welcome to ChromeVox!') - .call(doCmd('forceClickOnCurrentItem')) + .call(() => { + tutorial.showFirstLesson_(); + }) .expectSpeech('Welcome to ChromeVox!') .expectSpeech( 'Welcome to the ChromeVox tutorial. To exit this tutorial at any ' +
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb index 5e4661f..f40a611 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb
@@ -428,7 +428,7 @@ <translation id="3783725005098956899">ਲੌਗ ਦਿਖਾਓ</translation> <translation id="3801735343383419236">ਸਵੈ-ਮੁਕੰਮਲ ਸੂਚੀ</translation> <translation id="3806327402890551732">ਅਗਲੀ ਜਾਂ ਪਿਛਲੀ ਆਈਟਮ 'ਤੇ ਜਾਓ</translation> -<translation id="3810838688059735925">ਵੀਡਿਓ</translation> +<translation id="3810838688059735925">ਵੀਡੀਓ</translation> <translation id="3813387282697781382">ਹਲਕਾ ਗਾਜਰ</translation> <translation id="3816633764618089385">ਅਗਲਾ ਮੀਡੀਆ</translation> <translation id="3821689185319271077">ਕੋਈ ਪੁਆਇੰਟਰ ਐਂਕਰ ਮੌਜੂਦ ਨਹੀਂ ਹੈ</translation> @@ -549,7 +549,7 @@ <translation id="4712898966495541134">ਚੋਣ ਦੀ ਸਮਾਪਤੀ</translation> <translation id="4740661827607246557">ਸਹਾਇਤਾ ਕਮਾਂਡਾਂ</translation> <translation id="4755857887974653209">ChromeVox ਨੂੰ ਬੰਦ ਕਰੋ</translation> -<translation id="4763480195061959176">ਵੀਡਿਓ</translation> +<translation id="4763480195061959176">ਵੀਡੀਓ</translation> <translation id="4764692524839457597">ਪੂਰਵ-ਨਿਰਧਾਰਤ</translation> <translation id="4772771694153161212">ਕੋਈ ਅੰਡਰਲਾਈਨ ਲਿਖਤ ਨਹੀਂ ਹੈ</translation> <translation id="4780458943471935919">ਅਗਲੇ ਪੰਨੇ 'ਤੇ ਸਕ੍ਰੋਲ ਕਰੋ</translation>
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index 29acc0bc..3a948ef 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -167,6 +167,7 @@ {name: 'Lexend Deca', css: '"Lexend Deca"'}, {name: 'EB Garamond', css: '"EB Garamond"'}, {name: 'STIX Two Text', css: '"STIX Two Text"'}, + {name: 'Andika', css: 'Andika'}, ]; // Maps a DOM node to the AXNodeID that was used to create it. DOM nodes and
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.html b/chrome/browser/resources/side_panel/read_anything/read_anything.html index fa377ff5..bc4239a97 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything.html +++ b/chrome/browser/resources/side_panel/read_anything/read_anything.html
@@ -8,7 +8,7 @@ <link rel="stylesheet" href="//resources/css/text_defaults_md.css"> <link rel="stylesheet" href="//theme/colors.css?sets=ui,chrome"> <link rel="stylesheet" href="//resources/css/md_colors.css"> - <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins|Comic+Neue|Lexend+Deca|EB+Garamond|STIX+Two+Text"> + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins|Comic+Neue|Lexend+Deca|EB+Garamond|STIX+Two+Text|Andika"> <style> html, body {
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc index d817594..e0ed6df 100644 --- a/chrome/browser/search/search.cc +++ b/chrome/browser/search/search.cc
@@ -8,6 +8,7 @@ #include <string> +#include "base/check_deref.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" @@ -31,6 +32,7 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) #include "chrome/browser/supervised_user/supervised_user_service_factory.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" // nogncheck #include "components/supervised_user/core/common/supervised_user_utils.h" @@ -139,15 +141,13 @@ IsMatchingServiceWorker(url, new_tab_url)); } -bool IsURLAllowedForSupervisedUser(const GURL& url, Profile* profile) { +bool IsURLAllowedForSupervisedUser(const GURL& url, Profile& profile) { #if BUILDFLAG(ENABLE_SUPERVISED_USERS) - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile); - if (!supervised_user_service || - !supervised_user_service->IsURLFilteringEnabled()) { + if (!supervised_user::IsUrlFilteringEnabled(*profile.GetPrefs())) { return true; } - + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForProfile(&profile); supervised_user::SupervisedUserURLFilter* url_filter = supervised_user_service->GetURLFilter(); if (url_filter->GetFilteringBehaviorForURL(url) == @@ -197,8 +197,10 @@ return NewTabURLDetails(local_url, NEW_TAB_URL_NOT_SET); if (!search_provider_url.SchemeIsCryptographic()) return NewTabURLDetails(local_url, NEW_TAB_URL_INSECURE); - if (!IsURLAllowedForSupervisedUser(search_provider_url, profile)) + if (!IsURLAllowedForSupervisedUser(search_provider_url, + CHECK_DEREF(profile))) { return NewTabURLDetails(local_url, NEW_TAB_URL_BLOCKED); + } return NewTabURLDetails(search_provider_url, NEW_TAB_URL_VALID); }
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc index 88dcb9e6..e16bb4ff 100644 --- a/chrome/browser/search/search_unittest.cc +++ b/chrome/browser/search/search_unittest.cc
@@ -38,6 +38,7 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) #include "base/test/scoped_feature_list.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" #include "components/supervised_user/core/common/features.h" @@ -378,7 +379,7 @@ hosts["foo.com"] = false; url_filter->SetManualHosts(std::move(hosts)); - if (supervised_user_service->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled(*profile()->GetPrefs())) { EXPECT_EQ(chrome::kChromeUINewTabPageThirdPartyURL, GetNewTabPageURL(profile())); GURL new_tab_url(chrome::kChromeUINewTabURL);
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_browsertest.cc b/chrome/browser/search_engine_choice/search_engine_choice_browsertest.cc index 3be85b19..dd4d41c 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_browsertest.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_browsertest.cc
@@ -698,3 +698,41 @@ search_engines::kSearchEngineChoiceScreenDefaultSearchEngineTypeHistogram, SearchEngineType::SEARCH_ENGINE_BING, 1); } + +#if !BUILDFLAG(IS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(SearchEngineChoiceBrowserTest, + DialogIsDisplayedOnEveryGuestSession) { + // Initial browser + EXPECT_EQ(BrowserList::GetInstance()->size(), 1u); + + Browser* first_guest_session = CreateGuestBrowser(); + EXPECT_EQ(BrowserList::GetInstance()->size(), 2u); + auto* first_service = static_cast<MockSearchEngineChoiceService*>( + SearchEngineChoiceServiceFactory::GetForProfile( + first_guest_session->profile())); + + // Navigate to a URL to display the dialog. + ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition( + first_guest_session, GURL(chrome::kChromeUINewTabPageURL), + WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)); + + EXPECT_TRUE(first_service->IsShowingDialog(first_guest_session)); + CloseBrowserSynchronously(first_guest_session); + EXPECT_EQ(BrowserList::GetInstance()->size(), 1u); + + Browser* second_guest_session = CreateGuestBrowser(); + auto* second_service = static_cast<MockSearchEngineChoiceService*>( + SearchEngineChoiceServiceFactory::GetForProfile( + second_guest_session->profile())); + EXPECT_EQ(BrowserList::GetInstance()->size(), 2u); + + // Navigate to a URL to display the dialog. + ASSERT_TRUE(ui_test_utils::NavigateToURLWithDisposition( + second_guest_session, GURL(chrome::kChromeUINewTabPageURL), + WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)); + + EXPECT_TRUE(second_service->IsShowingDialog(second_guest_session)); +} +#endif
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_service.cc b/chrome/browser/search_engine_choice/search_engine_choice_service.cc index a8376868..0b7167b 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_service.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_service.cc
@@ -92,7 +92,9 @@ TemplateURLPrepopulateData::GetPrepopulatedEngine(pref_service, prepopulate_id); CHECK(search_engine); - SetDefaultSearchProviderPrefValue(*pref_service, search_engine->sync_guid); + TemplateURL search_engine_template_url = TemplateURL(*search_engine); + template_url_service_->SetUserSelectedDefaultSearchProvider( + &search_engine_template_url); } else { // Make sure that the default search engine is a custom search engine. const TemplateURL* default_search_provider =
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_service_factory.cc b/chrome/browser/search_engine_choice/search_engine_choice_service_factory.cc index a5562b0..f52ecf4a 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_service_factory.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_service_factory.cc
@@ -6,24 +6,18 @@ #include "base/check_deref.h" #include "base/check_is_test.h" -#include "base/command_line.h" -#include "base/files/file_path.h" #include "build/branding_buildflags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_selections.h" #include "chrome/browser/search_engine_choice/search_engine_choice_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" -#include "components/prefs/pref_service.h" #include "components/search_engines/search_engine_choice_utils.h" -#include "components/search_engines/search_engines_pref_names.h" -#include "components/search_engines/search_engines_switches.h" #include "components/search_engines/template_url_service.h" #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/profiles/profiles_state.h" #include "chromeos/components/kiosk/kiosk_utils.h" -#include "chromeos/components/mgs/managed_guest_session_utils.h" #endif namespace { @@ -49,14 +43,11 @@ kProfileOutOfScope; } - bool is_regular_profile = profile.IsRegularProfile(); + bool is_regular_or_guest_profile = + profile.IsRegularProfile() || profile.IsGuestSession(); #if BUILDFLAG(IS_CHROMEOS) - is_regular_profile &= !chromeos::IsManagedGuestSession() && - !chromeos::IsKioskSession() && - !profiles::IsChromeAppKioskSession(); -#endif -#if BUILDFLAG(IS_CHROMEOS_LACROS) - is_regular_profile &= !profile.IsGuestSession(); + is_regular_or_guest_profile &= + !chromeos::IsKioskSession() && !profiles::IsChromeAppKioskSession(); #endif TemplateURLService* template_url_service = @@ -65,7 +56,7 @@ return search_engines::GetStaticChoiceScreenConditions( CHECK_DEREF(g_browser_process->policy_service()), /*profile_properties=*/ - {.is_regular_profile = is_regular_profile, + {.is_regular_profile = is_regular_or_guest_profile, .pref_service = profile.GetPrefs()}, CHECK_DEREF(template_url_service)); } @@ -85,7 +76,7 @@ ProfileSelections::Builder() .WithRegular(ProfileSelection::kOriginalOnly) .WithAshInternals(ProfileSelection::kNone) - .WithGuest(ProfileSelection::kNone) + .WithGuest(ProfileSelection::kOffTheRecordOnly) .Build()) { DependsOn(TemplateURLServiceFactory::GetInstance()); }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc index 7dbc480..47ca3de 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -264,7 +264,8 @@ std::unique_ptr<WebSigninInterceptor::Delegate> delegate) : profile_(profile), identity_manager_(IdentityManagerFactory::GetForProfile(profile)), - delegate_(std::move(delegate)) { + delegate_(std::move(delegate)), + state_(std::make_unique<ResetableState>()) { DCHECK(profile_); DCHECK(identity_manager_); DCHECK(delegate_); @@ -272,6 +273,9 @@ DiceWebSigninInterceptor::~DiceWebSigninInterceptor() = default; +DiceWebSigninInterceptor::ResetableState::ResetableState() = default; +DiceWebSigninInterceptor::ResetableState::~ResetableState() = default; + // static void DiceWebSigninInterceptor::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { @@ -358,7 +362,7 @@ signin::Tribool should_show_chrome_signin_bubble = MaybeShouldShowChromeSigninBubble(identity_manager_, email, - access_point_); + state_->access_point_); // If the access point is not set, it is unclear if we have to show the bubble // or not, so we must return nullopt. if (should_show_chrome_signin_bubble == signin::Tribool::kUnknown) { @@ -394,16 +398,16 @@ signin_metrics::AccessPoint access_point, bool is_new_account, bool is_sync_signin) { - if (is_interception_in_progress_) { + if (state_->is_interception_in_progress_) { // Multiple concurrent interceptions are not supported. RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome::kAbortInterceptInProgress); return; } - DCHECK_EQ(interception_start_time_, base::TimeTicks()); - interception_start_time_ = base::TimeTicks::Now(); - access_point_ = access_point; + DCHECK_EQ(state_->interception_start_time_, base::TimeTicks()); + state_->interception_start_time_ = base::TimeTicks::Now(); + state_->access_point_ = access_point; if (!web_contents) { // The tab has been closed (typically during the token exchange, which may @@ -452,10 +456,10 @@ absl::optional<SigninInterceptionHeuristicOutcome> heuristic_outcome = GetHeuristicOutcome(is_new_account, is_sync_signin, account_info.email, &entry); - account_id_ = account_id; - is_interception_in_progress_ = true; - new_account_interception_ = is_new_account; - web_contents_ = web_contents->GetWeakPtr(); + state_->account_id_ = account_id; + state_->is_interception_in_progress_ = true; + state_->new_account_interception_ = is_new_account; + state_->web_contents_ = web_contents->GetWeakPtr(); if (heuristic_outcome && !SigninInterceptionHeuristicOutcomeIsSuccess(*heuristic_outcome)) { @@ -465,11 +469,11 @@ } // Start a timeout for the async operations we're kicking off. - interception_info_available_timeout_.Reset( + state_->interception_info_available_timeout_.Reset( base::BindOnce(&DiceWebSigninInterceptor::OnInterceptionInfoFetchTimeout, base::Unretained(this))); base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( - FROM_HERE, interception_info_available_timeout_.callback(), + FROM_HERE, state_->interception_info_available_timeout_.callback(), base::Seconds(5)); // Process the interception (maybe kicking off async fetches). @@ -482,21 +486,22 @@ std::unique_ptr<ScopedWebSigninInterceptionBubbleHandle> bubble_handle, bool is_new_profile, WebSigninInterceptor::SigninInterceptionType interception_type) { - DCHECK(!session_startup_helper_); + DCHECK(!state_->session_startup_helper_); DCHECK(bubble_handle); - interception_bubble_handle_ = std::move(bubble_handle); - account_id_ = account_id; - interception_type_ = interception_type; - session_startup_helper_ = + state_->interception_bubble_handle_ = std::move(bubble_handle); + state_->account_id_ = account_id; + state_->interception_type_ = interception_type; + state_->session_startup_helper_ = std::make_unique<DiceInterceptedSessionStartupHelper>( profile_, is_new_profile, account_id, intercepted_contents); - session_startup_helper_->Startup( + state_->session_startup_helper_->Startup( base::BindOnce(&DiceWebSigninInterceptor::OnNewBrowserCreated, base::Unretained(this), is_new_profile)); } void DiceWebSigninInterceptor::Shutdown() { - if (is_interception_in_progress_ && !was_interception_ui_displayed_) { + if (state_->is_interception_in_progress_ && + !state_->was_interception_ui_displayed_) { RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome::kAbortShutdown); } @@ -504,20 +509,8 @@ } void DiceWebSigninInterceptor::Reset() { - web_contents_ = nullptr; - interception_info_available_timeout_.Cancel(); + state_ = std::make_unique<ResetableState>(); account_info_update_observation_.Reset(); - is_interception_in_progress_ = false; - account_id_ = CoreAccountId(); - new_account_interception_ = false; - intercepted_account_management_accepted_ = false; - interception_type_ = absl::nullopt; - dice_signed_in_profile_creator_.reset(); - interception_start_time_ = base::TimeTicks(); - was_interception_ui_displayed_ = false; - interception_bubble_handle_.reset(); - account_level_signin_restriction_policy_fetcher_.reset(); - intercepted_account_profile_separation_policies_.reset(); } const ProfileAttributesEntry* @@ -546,8 +539,9 @@ identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin); // In case of re-auth, do not show the enterprise separation dialog if the // user already consented to enterprise management. - if (!new_account_interception_ && primary_core_account_info.account_id == - intercepted_account_info.account_id) { + if (!state_->new_account_interception_ && + primary_core_account_info.account_id == + intercepted_account_info.account_id) { return !chrome::enterprise_util::UserAcceptedAccountManagement(profile_); } if (!signin_util::IsAccountExemptedFromEnterpriseProfileSeparation( @@ -558,12 +552,13 @@ if (!signin_util::IsProfileSeparationEnforcedByProfile( profile_, intercepted_account_info.email) && !signin_util::IsProfileSeparationEnforcedByPolicies( - intercepted_account_profile_separation_policies_.value_or( + state_->intercepted_account_profile_separation_policies_.value_or( policy::ProfileSeparationPolicies()))) { return false; } - return new_account_interception_ && intercepted_account_info.IsManaged(); + return state_->new_account_interception_ && + intercepted_account_info.IsManaged(); } bool DiceWebSigninInterceptor::ShouldShowEnterpriseDialog( @@ -575,7 +570,7 @@ return false; } - if (intercepted_account_profile_separation_policies_ + if (state_->intercepted_account_profile_separation_policies_ .value_or(policy::ProfileSeparationPolicies()) .profile_separation_settings() .value_or(policy::ProfileSeparationSettings::SUGGESTED) != @@ -646,10 +641,10 @@ void DiceWebSigninInterceptor::ShowSigninInterceptionBubble( const WebSigninInterceptor::Delegate::BubbleParameters& bubble_parameters, base::OnceCallback<void(SigninInterceptionResult)> callback) { - was_interception_ui_displayed_ = true; - interception_type_ = bubble_parameters.interception_type; - interception_bubble_handle_ = delegate_->ShowSigninInterceptionBubble( - web_contents_.get(), bubble_parameters, std::move(callback)); + state_->was_interception_ui_displayed_ = true; + state_->interception_type_ = bubble_parameters.interception_type; + state_->interception_bubble_handle_ = delegate_->ShowSigninInterceptionBubble( + state_->web_contents_.get(), bubble_parameters, std::move(callback)); } void DiceWebSigninInterceptor::EnsureObservingExtendedAccountInfo() { @@ -662,7 +657,7 @@ void DiceWebSigninInterceptor::ProcessInterceptionOrWait( const AccountInfo& info, bool timed_out) { - DCHECK_EQ(info.account_id, account_id_); + DCHECK_EQ(info.account_id, state_->account_id_); if (!IsRequiredExtendedAccountInfoAvailable(info)) { // We can't process the interception with the information currently @@ -691,8 +686,9 @@ IsFullExtendedAccountInfoAvailable(info); bool have_all_enterprise_info = EnterpriseSeparationMaybeRequired( - profile_, identity_manager_, info.email, new_account_interception_, - intercepted_account_profile_separation_policies_, + profile_, identity_manager_, info.email, + state_->new_account_interception_, + state_->intercepted_account_profile_separation_policies_, /*expects_intercepted_profile_separation_policies_for_testing=*/ intercepted_account_profile_separation_policies_response_for_testing_ .has_value()) @@ -717,7 +713,7 @@ if (have_all_extended_account_info && have_all_enterprise_info) { // We have all the information we need - process the interception. - interception_info_available_timeout_.Cancel(); + state_->interception_info_available_timeout_.Cancel(); OnInterceptionReadyToBeProcessed(info); return; } @@ -725,7 +721,7 @@ void DiceWebSigninInterceptor::OnInterceptionReadyToBeProcessed( const AccountInfo& info) { - DCHECK_EQ(info.account_id, account_id_); + DCHECK_EQ(info.account_id, state_->account_id_); DCHECK(IsRequiredExtendedAccountInfoAvailable(info)); absl::optional<WebSigninInterceptor::SigninInterceptionType> @@ -764,7 +760,7 @@ RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome:: kInterceptEnterpriseForcedProfileSwitch); - } else if (!new_account_interception_ && + } else if (!state_->new_account_interception_ && identity_manager_->GetPrimaryAccountId( signin::ConsentLevel::kSync) == info.account_id) { // In case of a reauth of an account that already had sync enabled, @@ -786,8 +782,8 @@ signin_util:: ProfileSeparationAllowsKeepingUnmanagedBrowsingDataInManagedProfile( profile_, - intercepted_account_profile_separation_policies_.value_or( - policy::ProfileSeparationPolicies())); + state_->intercepted_account_profile_separation_policies_ + .value_or(policy::ProfileSeparationPolicies())); RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome::kInterceptEnterpriseForced); } @@ -812,7 +808,7 @@ RecordSigninInterceptionHeuristicOutcome( SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch); } else if (ShouldShowChromeSigninBubble(identity_manager_, info.email, - access_point_)) { + state_->access_point_)) { interception_type = WebSigninInterceptor::SigninInterceptionType::kChromeSignin; RecordSigninInterceptionHeuristicOutcome( @@ -879,7 +875,7 @@ void DiceWebSigninInterceptor::OnExtendedAccountInfoUpdated( const AccountInfo& info) { - if (info.account_id != account_id_) { + if (info.account_id != state_->account_id_) { return; } ProcessInterceptionOrWait(info, false); @@ -887,7 +883,7 @@ void DiceWebSigninInterceptor::OnExtendedAccountInfoRemoved( const AccountInfo& info) { - if (info.account_id != account_id_) { + if (info.account_id != state_->account_id_) { return; } RecordSigninInterceptionHeuristicOutcome( @@ -897,13 +893,14 @@ void DiceWebSigninInterceptor::OnInterceptionInfoFetchTimeout() { account_info_update_observation_.Reset(); - if (!intercepted_account_profile_separation_policies_.has_value()) { - intercepted_account_profile_separation_policies_ = + if (!state_->intercepted_account_profile_separation_policies_.has_value()) { + state_->intercepted_account_profile_separation_policies_ = policy::ProfileSeparationPolicies(); } AccountInfo account_info = - identity_manager_->FindExtendedAccountInfoByAccountId(account_id_); + identity_manager_->FindExtendedAccountInfoByAccountId( + state_->account_id_); ProcessInterceptionOrWait(account_info, /*timed_out=*/true); } @@ -919,15 +916,15 @@ return; } - DCHECK(interception_bubble_handle_); + DCHECK(state_->interception_bubble_handle_); std::u16string profile_name = profiles::GetDefaultNameForNewSignedInProfile(account_info); - DCHECK(!dice_signed_in_profile_creator_); + DCHECK(!state_->dice_signed_in_profile_creator_); // Unretained is fine because the profile creator is owned by this. - dice_signed_in_profile_creator_ = + state_->dice_signed_in_profile_creator_ = std::make_unique<DiceSignedInProfileCreator>( - profile_, account_id_, profile_name, + profile_, state_->account_id_, profile_name, profiles::GetPlaceholderAvatarIndex(), base::BindOnce(&DiceWebSigninInterceptor::OnNewSignedInProfileCreated, base::Unretained(this), profile_color)); @@ -982,12 +979,12 @@ return; } - DCHECK(interception_bubble_handle_); - DCHECK(!dice_signed_in_profile_creator_); + DCHECK(state_->interception_bubble_handle_); + DCHECK(!state_->dice_signed_in_profile_creator_); // Unretained is fine because the profile creator is owned by this. - dice_signed_in_profile_creator_ = + state_->dice_signed_in_profile_creator_ = std::make_unique<DiceSignedInProfileCreator>( - profile_, account_id_, profile_path, + profile_, state_->account_id_, profile_path, base::BindOnce(&DiceWebSigninInterceptor::OnNewSignedInProfileCreated, base::Unretained(this), absl::nullopt)); } @@ -995,8 +992,8 @@ void DiceWebSigninInterceptor::OnNewSignedInProfileCreated( absl::optional<SkColor> profile_color, Profile* new_profile) { - DCHECK(dice_signed_in_profile_creator_); - dice_signed_in_profile_creator_.reset(); + DCHECK(state_->dice_signed_in_profile_creator_); + state_->dice_signed_in_profile_creator_.reset(); if (!new_profile) { Reset(); @@ -1027,28 +1024,28 @@ // TODO(crbug/1450011): Move this to DiceSignedInProfileCreator when // DisallowManagedProfileSignout is fully released. - if (intercepted_account_management_accepted_ && + if (state_->intercepted_account_management_accepted_ && base::FeatureList::IsEnabled(kDisallowManagedProfileSignout)) { auto* primary_account_mutator = IdentityManagerFactory::GetForProfile(new_profile) ->GetPrimaryAccountMutator(); primary_account_mutator->SetPrimaryAccount( - account_id_, signin::ConsentLevel::kSignin, + state_->account_id_, signin::ConsentLevel::kSignin, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN); } } chrome::enterprise_util::SetUserAcceptedAccountManagement( - new_profile, intercepted_account_management_accepted_); + new_profile, state_->intercepted_account_management_accepted_); // Work is done in this profile, the flow continues in the // DiceWebSigninInterceptor that is attached to the new profile. // We pass relevant parameters from this instance to the new one. DiceWebSigninInterceptorFactory::GetForProfile(new_profile) ->CreateBrowserAfterSigninInterception( - account_id_, web_contents_.get(), - std::move(interception_bubble_handle_), is_new_profile, - *interception_type_); + state_->account_id_, state_->web_contents_.get(), + std::move(state_->interception_bubble_handle_), is_new_profile, + *state_->interception_type_); Reset(); } @@ -1060,31 +1057,31 @@ /*enforced_by_policy=*/!signin_util::IsProfileSeparationEnforcedByProfile( profile_, account_info.email) && !signin_util::IsProfileSeparationEnforcedByPolicies( - intercepted_account_profile_separation_policies_.value_or( + state_->intercepted_account_profile_separation_policies_.value_or( policy::ProfileSeparationPolicies())), /*created=*/create == SigninInterceptionResult::kAccepted); // Make sure existing account is a non-signed in profile. if (create == SigninInterceptionResult::kAccepted) { - intercepted_account_management_accepted_ = true; + state_->intercepted_account_management_accepted_ = true; // In case of a reauth if there was no consent for management, do not create // a new profile. - if (!new_account_interception_ && + if (!state_->new_account_interception_ && GetPrimaryAccountInfo(identity_manager_).account_id == account_info.account_id) { chrome::enterprise_util::SetUserAcceptedAccountManagement( - profile_, intercepted_account_management_accepted_); + profile_, state_->intercepted_account_management_accepted_); Reset(); } else { OnProfileCreationChoice(account_info, profile_color, SigninInterceptionResult::kAccepted); } } else if (create == SigninInterceptionResult::kAcceptedWithExistingProfile) { - intercepted_account_management_accepted_ = true; + state_->intercepted_account_management_accepted_ = true; DCHECK_EQ(GetPrimaryAccountInfo(identity_manager_).account_id, account_info.account_id); chrome::enterprise_util::SetUserAcceptedAccountManagement( - profile_, intercepted_account_management_accepted_); + profile_, state_->intercepted_account_management_accepted_); Reset(); } else { DCHECK_EQ(SigninInterceptionResult::kDeclined, create) @@ -1100,9 +1097,9 @@ } void DiceWebSigninInterceptor::OnNewBrowserCreated(bool is_new_profile) { - DCHECK(interception_bubble_handle_); - interception_bubble_handle_.reset(); // Close the bubble now. - session_startup_helper_.reset(); + DCHECK(state_->interception_bubble_handle_); + state_->interception_bubble_handle_.reset(); // Close the bubble now. + state_->session_startup_helper_.reset(); // TODO(https://crbug.com/1225171): Remove |IsGuestSession| if Guest option is // no more supported. @@ -1112,8 +1109,8 @@ Browser* browser = chrome::FindBrowserWithProfile(profile_); DCHECK(browser); - delegate_->ShowFirstRunExperienceInNewProfile(browser, account_id_, - *interception_type_); + delegate_->ShowFirstRunExperienceInNewProfile(browser, state_->account_id_, + *state_->interception_type_); } // static @@ -1127,10 +1124,10 @@ void DiceWebSigninInterceptor::UpdateDiceWebSigninInterceptDeclinedPref( const std::string& email) { - CHECK(interception_type_.has_value()); + CHECK(state_->interception_type_.has_value()); const char* pref_name = - interception_type_.value() == + state_->interception_type_.value() == WebSigninInterceptor::SigninInterceptionType::kChromeSignin ? kChromeSigninInterceptionDeclinedPref : kProfileCreationInterceptionDeclinedPref; @@ -1174,9 +1171,9 @@ const AccountInfo& account_info, base::OnceCallback<void(const policy::ProfileSeparationPolicies&)> callback) { - if (account_level_signin_restriction_policy_fetcher_ != nullptr) { + if (state_->account_level_signin_restriction_policy_fetcher_ != nullptr) { // A fetch is already in progress, don't start a new one. - DCHECK_EQ(account_info.account_id, account_id_); + DCHECK_EQ(account_info.account_id, state_->account_id_); return; } @@ -1188,14 +1185,14 @@ return; } - DCHECK(!interception_info_available_timeout_.IsCancelled()); + DCHECK(!state_->interception_info_available_timeout_.IsCancelled()); - account_level_signin_restriction_policy_fetcher_ = + state_->account_level_signin_restriction_policy_fetcher_ = std::make_unique<policy::UserCloudSigninRestrictionPolicyFetcher>( g_browser_process->browser_policy_connector(), g_browser_process->system_network_context_manager() ->GetSharedURLLoaderFactory()); - account_level_signin_restriction_policy_fetcher_ + state_->account_level_signin_restriction_policy_fetcher_ ->GetManagedAccountsSigninRestriction( identity_manager_, account_info.account_id, std::move(callback), policy::utils::IsPolicyTestingEnabled(profile_->GetPrefs(), @@ -1211,7 +1208,7 @@ OnAccountLevelManagedAccountsSigninRestrictionReceived( const AccountInfo& account_info, const policy::ProfileSeparationPolicies& profile_separation_policies) { - intercepted_account_profile_separation_policies_ = + state_->intercepted_account_profile_separation_policies_ = profile_separation_policies; ProcessInterceptionOrWait(account_info, /*timed_out=*/false); } @@ -1223,7 +1220,7 @@ // Record the latency, except in the case where this is a duplicate request // for the same interception. - DCHECK_NE(interception_start_time_, base::TimeTicks()); + DCHECK_NE(state_->interception_start_time_, base::TimeTicks()); if (outcome == SigninInterceptionHeuristicOutcome::kAbortInterceptInProgress) { // This is a special-case where we immediately abort the intercept request @@ -1233,8 +1230,9 @@ base::UmaHistogramTimes("Signin.Intercept.HeuristicLatency", base::Milliseconds(0)); } else { - base::UmaHistogramTimes("Signin.Intercept.HeuristicLatency", - base::TimeTicks::Now() - interception_start_time_); + base::UmaHistogramTimes( + "Signin.Intercept.HeuristicLatency", + base::TimeTicks::Now() - state_->interception_start_time_); } }
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.h b/chrome/browser/signin/dice_web_signin_interceptor.h index 82a7be0..78b1b6e 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor.h +++ b/chrome/browser/signin/dice_web_signin_interceptor.h
@@ -121,7 +121,7 @@ // Returns true if the interception is in progress (running the heuristic or // showing on screen). bool is_interception_in_progress() const { - return is_interception_in_progress_; + return state_->is_interception_in_progress_; } void SetInterceptedAccountProfileSeparationPoliciesForTesting( @@ -162,6 +162,7 @@ FRIEND_TEST_ALL_PREFIXES( DiceWebSigninInterceptorTest, ForcedEnterpriseInterceptionTestNoForcedInterception); + FRIEND_TEST_ALL_PREFIXES(DiceWebSigninInterceptorTest, StateResetTest); // Cancels any current signin interception and resets the interceptor to its // initial state. @@ -282,51 +283,67 @@ bool IsFullExtendedAccountInfoAvailable( const AccountInfo& account_info) const; + // Struct to ease the resetting of the `DiceWebSigninInterceptor` class + // through the `DiceWebSigninInterceptor::Reset()` method. + // It should hold the data that are variable between different intereceptions. + struct ResetableState { + ResetableState(); + ~ResetableState(); + + // Used in the profile that was created after the interception succeeded. + std::unique_ptr<DiceInterceptedSessionStartupHelper> + session_startup_helper_; + + // Members below are related to the interception in progress. + base::WeakPtr<content::WebContents> web_contents_; + bool is_interception_in_progress_ = false; + CoreAccountId account_id_; + bool new_account_interception_ = false; + bool intercepted_account_management_accepted_ = false; + absl::optional<WebSigninInterceptor::SigninInterceptionType> + interception_type_; + signin_metrics::AccessPoint access_point_ = + signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN; + + // Timeout for waiting for full information to be available (see + // `ProcessInterceptionOrWait()`). + base::CancelableOnceCallback<void()> interception_info_available_timeout_; + + std::unique_ptr<DiceSignedInProfileCreator> dice_signed_in_profile_creator_; + // Used to retain the interception UI bubble until profile creation + // completes. + std::unique_ptr<ScopedWebSigninInterceptionBubbleHandle> + interception_bubble_handle_; + + // Used for metrics. + base::TimeTicks interception_start_time_; + bool was_interception_ui_displayed_ = false; + + // Used to fetch the cloud user level policy value of the profile separation + // policies. This can only fetch one policy value for one account at the + // time. + std::unique_ptr<policy::UserCloudSigninRestrictionPolicyFetcher> + account_level_signin_restriction_policy_fetcher_; + // Value of the profile separation policies for the intercepted account. If + // no value is set, then we have not yet received the policy value. + absl::optional<policy::ProfileSeparationPolicies> + intercepted_account_profile_separation_policies_; + }; + const raw_ptr<Profile, DanglingUntriaged> profile_; const raw_ptr<signin::IdentityManager, DanglingUntriaged> identity_manager_; std::unique_ptr<WebSigninInterceptor::Delegate> delegate_; - - // Used in the profile that was created after the interception succeeded. - std::unique_ptr<DiceInterceptedSessionStartupHelper> session_startup_helper_; - - // Members below are related to the interception in progress. - base::WeakPtr<content::WebContents> web_contents_; - bool is_interception_in_progress_ = false; - CoreAccountId account_id_; - bool new_account_interception_ = false; - bool intercepted_account_management_accepted_ = false; - absl::optional<WebSigninInterceptor::SigninInterceptionType> - interception_type_; base::ScopedObservation<signin::IdentityManager, signin::IdentityManager::Observer> account_info_update_observation_{this}; - signin_metrics::AccessPoint access_point_ = - signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN; - // Timeout for waiting for full information to be available (see - // `ProcessInterceptionOrWait()`). - base::CancelableOnceCallback<void()> interception_info_available_timeout_; + std::unique_ptr<ResetableState> state_; - std::unique_ptr<DiceSignedInProfileCreator> dice_signed_in_profile_creator_; - // Used to retain the interception UI bubble until profile creation completes. - std::unique_ptr<ScopedWebSigninInterceptionBubbleHandle> - interception_bubble_handle_; - - // Used for metrics. - base::TimeTicks interception_start_time_; - bool was_interception_ui_displayed_ = false; - - // Used to fetch the cloud user level policy value of the profile separation - // policies. This can only fetch one policy value for one account at the time. - std::unique_ptr<policy::UserCloudSigninRestrictionPolicyFetcher> - account_level_signin_restriction_policy_fetcher_; - // Value of the profile separation policies for the intercepted account. If - // no value is set, then we have not yet received the policy value. - absl::optional<policy::ProfileSeparationPolicies> - intercepted_account_profile_separation_policies_; // Value that should be return when trying to the value of the profile - // separation policies for the intercepted account. This should never be used - // in place of `intercepted_account_profile_separation_policies_`. + // separation policies for the intercepted account. This should never be + // used in place of `intercepted_account_profile_separation_policies_`. + // This field is excluded from `ResetableState` as tests do not expect to + // reset this value, it is expected to be sticky across tests. absl::optional<policy::ProfileSeparationPolicies> intercepted_account_profile_separation_policies_response_for_testing_; };
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc index c3b18ddd..bede03d 100644 --- a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc +++ b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
@@ -11,6 +11,7 @@ #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "build/buildflag.h" #include "build/chromeos_buildflags.h" @@ -108,8 +109,9 @@ void MakeValidAccountInfo( AccountInfo* info, const std::string& hosted_domain = kNoHostedDomainFound) { - if (info->IsValid()) + if (info->IsValid()) { return; + } info->full_name = "fullname"; info->given_name = "givenname"; info->hosted_domain = hosted_domain; @@ -399,7 +401,7 @@ ASSERT_EQ(identity_test_env()->identity_manager()->GetPrimaryAccountId( signin::ConsentLevel::kSignin), primary_account_info.account_id); - interceptor()->new_account_interception_ = true; + interceptor()->state_->new_account_interception_ = true; // Consumer account not intercepted. EXPECT_FALSE( interceptor()->ShouldEnforceEnterpriseProfileSeparation(account_info)); @@ -422,7 +424,7 @@ account_info_1.hosted_domain = "example.com"; identity_test_env()->UpdateAccountInfoForAccount(account_info_1); - interceptor()->new_account_interception_ = true; + interceptor()->state_->new_account_interception_ = true; // Primary account is not set. ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount( signin::ConsentLevel::kSignin)); @@ -1708,6 +1710,36 @@ SigninInterceptionHeuristicOutcome::kInterceptEnterpriseForced, 1); } +TEST_F(DiceWebSigninInterceptorTest, StateResetTest) { + // This is a simplification of the equality check. There is no need to + // implement a full exhaustive check for the test. + auto AreStatesEqual = + [](const DiceWebSigninInterceptor::ResetableState* state1, + const DiceWebSigninInterceptor::ResetableState* state2) { + return state1->is_interception_in_progress_ == + state2->is_interception_in_progress_; + }; + + // Create the default values to be compared to. + DiceWebSigninInterceptor::ResetableState default_values; + + DiceWebSigninInterceptor::ResetableState* state_ = + interceptor()->state_.get(); + // Ensure initial default values. + EXPECT_TRUE(AreStatesEqual(state_, &default_values)); + + // Simulate default state value modifications + state_->is_interception_in_progress_ = true; + + ASSERT_FALSE(AreStatesEqual(state_, &default_values)); + + // Reset and check the default values equality. + interceptor()->Reset(); + + // Values should be properly reset to default values. + EXPECT_TRUE(AreStatesEqual(interceptor()->state_.get(), &default_values)); +} + class DiceWebSigninInterceptorTestWithUnoEnabled : public DiceWebSigninInterceptorTest { public: @@ -1776,8 +1808,9 @@ ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount( signin::ConsentLevel::kSignin)); - // Unknown access point is treated as information not complete/compatible and - // should not show the bubble even if the rest of the information are valid. + // Unknown access point is treated as information not complete/compatible + // and should not show the bubble even if the rest of the information are + // valid. auto access_point = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN; EXPECT_CALL(*mock_delegate(), ShowSigninInterceptionBubble( web_contents(), testing::_, testing::_))
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc index 5420774..89c8562 100644 --- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -886,14 +886,14 @@ auto child2_input_coords = parse_points(result, iframe2_offset); // Helper to simulate a tab press and wait for a focus message. - auto press_tab_and_wait_for_message = [web_contents]( - content::RenderFrameHost* receiver, - bool reverse) { - SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, - ui::VKEY_TAB, false, reverse /* shift */, false, false); - LOG(INFO) << "Press tab"; - return EvalJs(receiver, "waitForFocusEvent()"); - }; + auto press_tab_and_wait_for_message = + [web_contents](content::RenderFrameHost* receiver, bool reverse) { + SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, + ui::VKEY_TAB, false, reverse /* shift */, false, + false); + LOG(INFO) << "Press tab"; + return EvalJs(receiver, "waitForFocusEvent()"); + }; auto click_element_and_wait_for_message = [web_contents](content::RenderFrameHost* receiver, @@ -1058,8 +1058,9 @@ } else if (response_params[0] == "resize") { resize_validated = true; } - if (remaining_events.empty() && resize_validated) + if (remaining_events.empty() && resize_validated) { break; + } } } @@ -1474,6 +1475,11 @@ ->CreateGuestViewManagerDelegate()); } + void TearDownOnMainThread() override { + test_guest_view_manager_ = nullptr; + SitePerProcessInteractiveBrowserTest::TearDownOnMainThread(); + } + protected: guest_view::TestGuestViewManager* test_guest_view_manager() const { return test_guest_view_manager_; @@ -1481,8 +1487,7 @@ private: guest_view::TestGuestViewManagerFactory factory_; - raw_ptr<guest_view::TestGuestViewManager, DanglingUntriaged> - test_guest_view_manager_; + raw_ptr<guest_view::TestGuestViewManager> test_guest_view_manager_ = nullptr; }; // This test loads a PDF inside an OOPIF and then verifies that context menu @@ -1896,12 +1901,14 @@ // will send a message, and the two messages can arrive in any order. std::string status; while (main_queue.WaitForMessage(&status)) { - if (status == "\"main-lost-focus\"") + if (status == "\"main-lost-focus\"") { break; + } } while (popup_queue.WaitForMessage(&status)) { - if (status == "\"popup-got-focus\"") + if (status == "\"popup-got-focus\"") { break; + } } // The popup should be focused now.
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_throttle.cc b/chrome/browser/supervised_user/supervised_user_navigation_throttle.cc index 289c15e4..88094f1 100644 --- a/chrome/browser/supervised_user/supervised_user_navigation_throttle.cc +++ b/chrome/browser/supervised_user/supervised_user_navigation_throttle.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "components/supervised_user/core/browser/supervised_user_interstitial.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" #include "components/supervised_user/core/common/supervised_user_utils.h" @@ -30,11 +31,8 @@ content::NavigationHandle* navigation_handle) { Profile* profile = Profile::FromBrowserContext( navigation_handle->GetWebContents()->GetBrowserContext()); - - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile); - if (!supervised_user_service || - !supervised_user_service->IsURLFilteringEnabled()) { + CHECK(profile); + if (!supervised_user::IsUrlFilteringEnabled(*profile->GetPrefs())) { return nullptr; }
diff --git a/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc b/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc index 503bd67..04a5898 100644 --- a/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc +++ b/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc
@@ -28,7 +28,7 @@ #include "components/supervised_user/core/browser/fetcher_config.h" #include "components/supervised_user/core/browser/kids_chrome_management_client.h" #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h" -#include "components/supervised_user/core/browser/supervised_user_service.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/common/features.h" #include "components/supervised_user/test_support/kids_management_api_server_mock.h" #include "components/variations/variations_switches.h" @@ -210,8 +210,8 @@ } bool IsUrlFilteringEnabled() const { - return SupervisedUserServiceFactory::GetForProfile(browser()->profile()) - ->IsURLFilteringEnabled(); + return supervised_user::IsUrlFilteringEnabled( + *browser()->profile()->GetPrefs()); } private:
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 14cd732..caa12ecc 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -65,6 +65,7 @@ private final boolean mIsSurfacePolishEnabled; private int mStatusIconAndUrlBarOffsetForSurfacePolish; private int mUrlActionContainerEndMargin; + private boolean mIsUrlFocusChangeInProgress; public LocationBarLayout(Context context, AttributeSet attrs) { this(context, attrs, R.layout.location_bar); @@ -231,15 +232,31 @@ if (childView.getVisibility() != GONE) { LayoutParams childLayoutParams = (LayoutParams) childView.getLayoutParams(); if (childView == mUrlBar) { + boolean urlBarLaidOutAtFocusedWidth; if (OmniboxFeatures.shouldAvoidRelayoutDuringFocusAnimation() && (mUrlFocusPercentage > 0.0f || mUrlBar.hasFocus())) { // Set a margin that places the url bar in its final, focused position. // During animation this will be compensated against using translation of // decreasing magnitude to avoid a jump. startMargin += getFocusedStatusViewSpacingDelta(); - mUrlBarLaidOutAtFocusedWidth = true; + urlBarLaidOutAtFocusedWidth = true; } else { - mUrlBarLaidOutAtFocusedWidth = false; + urlBarLaidOutAtFocusedWidth = false; + } + + // The behavior of setUrlFocusChangePercent() depends on the value of + // mUrlBarLaidOutAtFocusedWidth. We don't control the timing of external calls + // to setUrlFocusChangePercent() since it's driven by an animation. To avoid + // getting into a stale state, we call setUrlFocusChangePercent() again whenever + // the value of mUrlBarLaidOutAtFocusedWidth changes. + if (mNativeInitialized && + urlBarLaidOutAtFocusedWidth != mUrlBarLaidOutAtFocusedWidth) { + mUrlBarLaidOutAtFocusedWidth = urlBarLaidOutAtFocusedWidth; + setUrlFocusChangePercent( + mUrlFocusPercentage, + mUrlFocusPercentage, + mUrlFocusPercentage, + mIsUrlFocusChangeInProgress); } MarginLayoutParamsCompat.setMarginStart(childLayoutParams, startMargin); @@ -395,6 +412,7 @@ float startSurfaceScrollFraction, float urlFocusChangeFraction, boolean isUrlFocusChangeInProgress) { + mIsUrlFocusChangeInProgress = isUrlFocusChangeInProgress; mUrlFocusPercentage = getMaxValue( ntpSearchBoxScrollFraction,
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java index 1f2f79e..79c69674 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -717,10 +717,7 @@ if (mIsTablet) { float urlFocusChangeFraction = showExpandedState ? 1.0f : 0.0f; mLocationBarLayout.setUrlFocusChangePercent( - urlFocusChangeFraction, - urlFocusChangeFraction, - urlFocusChangeFraction, - mIsUrlFocusChangeInProgress); + urlFocusChangeFraction, urlFocusChangeFraction, urlFocusChangeFraction, false); mLocationBarLayout.updateLayoutParams( MeasureSpec.makeMeasureSpec( mLocationBarLayout.getMeasuredWidth(), MeasureSpec.EXACTLY));
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb index 17bcb86..f2d914d0 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
@@ -517,7 +517,7 @@ <translation id="3777796259512476958">ਤੁਹਾਨੂੰ ਜ਼ਿਆਦਾਤਰ ਸਾਈਟਾਂ ਤੋਂ ਸਾਈਨ-ਆਊਟ ਕਰ ਦਿੱਤਾ ਜਾਵੇਗਾ</translation> <translation id="3791957072666773229">{TAB_COUNT,plural, =1{1 ਟੈਬ}one{# ਟੈਬ}other{# ਟੈਬਾਂ}}</translation> <translation id="3795154175078851242">ਲਿੰਕ ਦੇ ਨਾਲ ਚਿੱਤਰ ਨੂੰ ਕਾਪੀ ਕਰੋ</translation> -<translation id="3810838688059735925">ਵੀਡਿਓ</translation> +<translation id="3810838688059735925">ਵੀਡੀਓ</translation> <translation id="3810973564298564668">ਵਿਵਸਥਿਤ ਕਰੋ</translation> <translation id="381861209280417772">ਪਾਸਵਰਡਾਂ ਨੂੰ ਮਿਟਾਓ</translation> <translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> ਡਾਊਨਲੋਡ ਮਿਟਾਏ ਗਏ</translation> @@ -699,7 +699,7 @@ <translation id="4750356170202299988">ਘੱਟ ਉਮਰ ਦੇ ਬੱਚਿਆਂ ਲਈ ਸਮੱਗਰੀ</translation> <translation id="4758061975920522644">ਸਿਰਫ਼ ਚਿੱਤਰ ਨੂੰ ਸਾਂਝਾ ਕਰੋ</translation> <translation id="4759238208242260848">ਡਾਊਨਲੋਡਸ</translation> -<translation id="4763480195061959176">ਵੀਡਿਓ</translation> +<translation id="4763480195061959176">ਵੀਡੀਓ</translation> <translation id="4766313118839197559">ਪਾਸਵਰਡ ਇਸ ਡੀਵਾਈਸ ਦੇ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ ਵਿੱਚ ਰੱਖਿਅਤ ਕੀਤੇ ਗਏ ਹਨ</translation> <translation id="4766678251456904326">ਡੀਵਾਈਸ ਵਿੱਚ ਖਾਤਾ ਸ਼ਾਮਲ ਕਰੋ</translation> <translation id="4767947714785277816">ਅਸੀਂ ਵਿਗਿਆਪਨ ਪਰਦੇਦਾਰੀ ਸੰਬੰਧੀ ਨਵੀਂ ਵਿਸ਼ੇਸ਼ਤਾ ਲਾਂਚ ਕਰ ਰਹੇ ਹਾਂ ਜਿਨ੍ਹਾਂ ਨੂੰ ਵਿਗਿਆਪਨ ਮਾਪ ਕਹਿੰਦੇ ਹਨ। Chrome ਸਾਈਟਾਂ ਅਤੇ ਐਪਾਂ ਵਿਚਕਾਰ ਬਹੁਤ ਹੀ ਸੀਮਤ ਜਾਣਕਾਰੀ ਨੂੰ ਸਾਂਝਾ ਕਰਦਾ ਹੈ, ਜਿਵੇਂ ਕਿ ਜਦੋਂ ਤੁਹਾਨੂੰ ਕੋਈ ਵਿਗਿਆਪਨ ਦਿਖਾਇਆ ਗਿਆ ਸੀ, ਤਾਂ ਜੋ ਵਿਗਿਆਪਨਾਂ ਦੀ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਮਾਪਨ ਵਿੱਚ ਮਦਦ ਕੀਤੀ ਜਾ ਸਕੇ।</translation>
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java index 2fd6a21..7fbf17a6 100644 --- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java +++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
@@ -126,9 +126,13 @@ // TODO(crbug.com/1295017): Consult UI team to determine the background color we // need to use here. RoundedIconGenerator roundedIconGenerator = - new RoundedIconGenerator(resources, avatarSize /* iconWidthDp */, - avatarSize /* iconHeightDp */, avatarSize / 2 /* cornerRadiusDp */, - Color.GRAY /* backgroundColor */, avatarMonogramTextSize); + new RoundedIconGenerator( + resources, + /* iconWidthDp= */ avatarSize, + /* iconHeightDp= */ avatarSize, + /* cornerRadiusDp= */ avatarSize / 2, + /* backgroundColor= */ Color.GRAY, + avatarMonogramTextSize); avatar = roundedIconGenerator.generateIconForText(avatarData.mName); } Drawable croppedAvatar = AvatarGenerator.makeRoundAvatar(resources, avatar, avatarSize);
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support.cc b/chrome/browser/ui/ash/multi_user/multi_profile_support.cc index cbe9a49..008efd8 100644 --- a/chrome/browser/ui/ash/multi_user/multi_profile_support.cc +++ b/chrome/browser/ui/ash/multi_user/multi_profile_support.cc
@@ -11,6 +11,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "chrome/browser/ash/app_restore/full_restore_service.h" +#include "chrome/browser/ash/floating_workspace/floating_workspace_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -172,10 +173,15 @@ Profile* profile = ProfileManager::GetActiveUserProfile(); full_restore::SetActiveProfilePath(profile->GetPath()); - auto* full_restore_service = - ash::full_restore::FullRestoreService::GetForProfile(profile); - if (full_restore_service) - full_restore_service->OnTransitionedToNewActiveUser(profile); + // Only init full restore when floating workspace is disabled or in safe mode. + // TODO(b/312233508): Add fws test coverage for this case. + if (!ash::floating_workspace_util::ShouldHandleRestartRestore()) { + auto* full_restore_service = + ash::full_restore::FullRestoreService::GetForProfile(profile); + if (full_restore_service) { + full_restore_service->OnTransitionedToNewActiveUser(profile); + } + } ChromeShelfController* chrome_shelf_controller = ChromeShelfController::instance();
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc index 469082fe..f80bb43 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.cc +++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -223,6 +223,16 @@ std::move(callback).Run(/*success=*/true); } +void TestWallpaperController::SetSeaPenWallpaperFromFile( + const AccountId& account_id, + const base::FilePath& sea_pen_file_path, + SetWallpaperCallback callback) { + ++sea_pen_wallpaper_count_; + wallpaper_info_ = ash::WallpaperInfo(); + wallpaper_info_->type = ash::WallpaperType::kSeaPen; + std::move(callback).Run(/*success=*/true); +} + void TestWallpaperController::ConfirmPreviewWallpaper() { NOTIMPLEMENTED(); }
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h index 6afb61ce..04a365d 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.h +++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -156,6 +156,9 @@ void SetSeaPenWallpaper(const AccountId& account_id, const ash::SeaPenImage& sea_pen_image, SetWallpaperCallback callback) override; + void SetSeaPenWallpaperFromFile(const AccountId& account_id, + const base::FilePath& sea_pen_file_path, + SetWallpaperCallback callback) override; void ConfirmPreviewWallpaper() override; void CancelPreviewWallpaper() override; void UpdateCurrentWallpaperLayout(const AccountId& account_id,
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index 2362372..decf9cf 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -34,6 +34,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/common/features.h" #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" #include "components/no_state_prefetch/common/prerender_origin.h" #include "components/omnibox/browser/location_bar_model.h" @@ -245,13 +246,9 @@ auth_map_["bar"] = AuthInfo("testuser", "barpassword"); auth_map_["testrealm"] = AuthInfo(username_basic_, password_); - if (GetParam() == SplitAuthCacheByNetworkIsolationKey::kFalse) { - scoped_feature_list_.InitAndDisableFeature( - network::features::kSplitAuthCacheByNetworkIsolationKey); - } else { - scoped_feature_list_.InitAndEnableFeature( - network::features::kSplitAuthCacheByNetworkIsolationKey); - } + scoped_feature_list_.InitWithFeatureStates( + {{network::features::kSplitAuthCacheByNetworkIsolationKey, + (GetParam() == SplitAuthCacheByNetworkIsolationKey::kTrue)}}); } void SetUpOnMainThread() override { @@ -331,6 +328,31 @@ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } +// There are tests that will fail with third party cookies blocked. To ensure +// that there is no regression in behavior when third party cookies are not +// blocked this test fixture has been added which turns off third party cookie +// blocking. +// crbug/1503201 - LoginPromptBrowserTest cases fail in 3PCD +class LoginPromptBrowserTestThirdPartyCookiesUnblocked + : public LoginPromptBrowserTest { + public: + LoginPromptBrowserTestThirdPartyCookiesUnblocked() { + scoped_feature_list_.InitWithFeatureStates( + {{network::features::kSplitAuthCacheByNetworkIsolationKey, + (GetParam() == SplitAuthCacheByNetworkIsolationKey::kTrue)}, + {content_settings::features::kTrackingProtection3pcd, false}}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + All, + LoginPromptBrowserTestThirdPartyCookiesUnblocked, + ::testing::Values(SplitAuthCacheByNetworkIsolationKey::kFalse, + SplitAuthCacheByNetworkIsolationKey::kTrue)); + const char kPrefetchAuthPage[] = "/login/prefetch.html"; const char kMultiRealmTestPage[] = "/login/multi_realm.html"; @@ -1130,7 +1152,7 @@ } // Allow crossdomain iframe login prompting despite the above. -IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTest, +IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTestThirdPartyCookiesUnblocked, AllowCrossdomainPromptForSubframes) { const char kTestPage[] = "/login/load_iframe_from_b.html"; @@ -1519,7 +1541,7 @@ // Test that the auth cache respects NetworkIsolationKeys when splitting the // cache based on the key is enabled. -IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTest, +IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTestThirdPartyCookiesUnblocked, AuthCacheAcrossNetworkIsolationKeys) { ASSERT_TRUE(embedded_test_server()->Start()); GURL test_page = embedded_test_server()->GetURL(kAuthBasicPage); @@ -1587,7 +1609,7 @@ "'YmFzaWN1c2VyOnNlY3JldA==') >= 0")); } -IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTest, +IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTestThirdPartyCookiesUnblocked, GloballyScopeHTTPAuthCacheEnabled) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -1844,7 +1866,7 @@ // interstitial. If this test becomes flaky, it's likely that the logic that // prevents the tested scenario from happening got broken, rather than the test // itself. -IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTest, +IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTestThirdPartyCookiesUnblocked, ShouldNotProceedExistingInterstitial) { net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); @@ -2052,7 +2074,8 @@ // Tests that when HTTP Auth committed interstitials are enabled, a prompt // triggered by a subframe can be cancelled. -IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTest, PromptFromSubframe) { +IN_PROC_BROWSER_TEST_P(LoginPromptBrowserTestThirdPartyCookiesUnblocked, + PromptFromSubframe) { ASSERT_TRUE(embedded_test_server()->Start()); content::WebContents* contents = @@ -2173,20 +2196,10 @@ public testing::WithParamInterface<SplitAuthCacheByNetworkIsolationKey> { public: LoginPromptExtensionBrowserTest() { - if (GetParam() == SplitAuthCacheByNetworkIsolationKey::kFalse) { - scoped_feature_list_.InitWithFeatures( - // enabled_features - {}, - // disabled_features - {network::features::kSplitAuthCacheByNetworkIsolationKey}); - } else { - scoped_feature_list_.InitWithFeatures( - // enabled_features - {network::features::kSplitAuthCacheByNetworkIsolationKey}, - // disabled_features - {}); + scoped_feature_list_.InitWithFeatureStates( + {{network::features::kSplitAuthCacheByNetworkIsolationKey, + (GetParam() == SplitAuthCacheByNetworkIsolationKey::kTrue)}}); } - } ~LoginPromptExtensionBrowserTest() override = default;
diff --git a/chrome/browser/ui/safety_hub/menu_notification_service.cc b/chrome/browser/ui/safety_hub/menu_notification_service.cc index db022ca..27138ba 100644 --- a/chrome/browser/ui/safety_hub/menu_notification_service.cc +++ b/chrome/browser/ui/safety_hub/menu_notification_service.cc
@@ -106,11 +106,13 @@ } std::list<SafetyHubMenuNotification*> notifications_to_be_shown; MenuNotificationPriority cur_highest_priority = MenuNotificationPriority::LOW; - for (auto const& item : result_map.value()) { - SafetyHubModuleInfoElement* info_element = + for (auto& item : result_map.value()) { + const SafetyHubModuleInfoElement* info_element = module_info_map_[item.first].get(); SafetyHubMenuNotification* notification = info_element->notification.get(); - notification->UpdateResult(std::move(result_map.value()[item.first])); + // The result in the ResultMap (item.second) is being moved away from and + // thus shouldn't be used again in this method. + notification->UpdateResult(std::move(item.second)); int max_all_time_impressions = item.first == safety_hub::SafetyHubModuleType::SAFE_BROWSING ? 3 : 0; if (notification->ShouldBeShown(info_element->interval, @@ -163,7 +165,7 @@ if (!result.has_value()) { return absl::nullopt; } - result_map[item.first] = std::move(result.value()); + result_map.try_emplace(item.first, std::move(result.value())); } return result_map; }
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc index 0b98f50..a879016 100644 --- a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc +++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc
@@ -193,7 +193,14 @@ permission_dict.Set(kSafetyHubOriginKey, permission.origin.ToString()); base::Value::List permission_types; for (ContentSettingsType cst : permission.permission_types) { - permission_types.Append(registry->Get(cst)->name()); + const content_settings::WebsiteSettingsInfo* website_info = + registry->Get(cst); + if (website_info) { + permission_types.Append(website_info->name()); + } + } + if (permission_types.empty()) { + continue; } permission_dict.Set(kUnusedSitePermissionsResultPermissionTypesKey, std::move(permission_types));
diff --git a/chrome/browser/ui/tabs/organization/trigger.cc b/chrome/browser/ui/tabs/organization/trigger.cc index bd501be2..7210e691 100644 --- a/chrome/browser/ui/tabs/organization/trigger.cc +++ b/chrome/browser/ui/tabs/organization/trigger.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/ui/tabs/organization/trigger_policies.h" #include "chrome/browser/ui/tabs/tab_group_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/ui_features.h" namespace { @@ -22,8 +23,6 @@ } return num_tabs_not_in_group; } - -constexpr int kMinTabCount = 7; } // namespace TabOrganizationTrigger::TabOrganizationTrigger( @@ -51,14 +50,16 @@ } float GetDefaultTriggerScoreThreshold() { - return kMinTabCount; + return features::kTabOrganizationTriggerThreshold.Get(); } std::unique_ptr<TriggerPolicy> GetDefaultTriggerPolicy( std::unique_ptr<BackoffLevelProvider> backoff_level_provider) { return std::make_unique<TargetFrequencyTriggerPolicy>( std::make_unique<UsageTickClock>(base::DefaultTickClock::GetInstance()), - base::Hours(6), 2.0f, std::move(backoff_level_provider)); + features::kTabOrganizationTriggerPeriod.Get(), + features::kTabOrganizationTriggerBackoffBase.Get(), + std::move(backoff_level_provider)); } std::unique_ptr<TabOrganizationTrigger> MakeMVPTrigger(
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index 098067a..6de7860d 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -144,6 +144,7 @@ kPasswordAndAutofillMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kPasswordManagerMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kShowSearchCompanion); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kPerformanceMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ToolsMenuModel, kPerformanceMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ToolsMenuModel, kChromeLabsMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ToolsMenuModel, kReadingModeMenuItem); @@ -710,9 +711,12 @@ if (!features::IsExtensionMenuInRootAppMenu()) { AddItemWithStringId(IDC_MANAGE_EXTENSIONS, IDS_SHOW_EXTENSIONS); } - AddItemWithStringId(IDC_PERFORMANCE, IDS_SHOW_PERFORMANCE); - SetElementIdentifierAt(GetIndexOfCommandId(IDC_PERFORMANCE).value(), - kPerformanceMenuItem); + if (!base::FeatureList::IsEnabled( + performance_manager::features::kPerformanceControlsSidePanel)) { + AddItemWithStringId(IDC_PERFORMANCE, IDS_SHOW_PERFORMANCE); + SetElementIdentifierAt(GetIndexOfCommandId(IDC_PERFORMANCE).value(), + kPerformanceMenuItem); + } if (chrome::CanOpenTaskManager()) AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -1698,6 +1702,13 @@ } } + if (base::FeatureList::IsEnabled( + performance_manager::features::kPerformanceControlsSidePanel)) { + AddItemWithStringId(IDC_PERFORMANCE, IDS_SHOW_PERFORMANCE); + SetElementIdentifierAt(GetIndexOfCommandId(IDC_PERFORMANCE).value(), + kPerformanceMenuItem); + } + AddItemWithStringId(IDC_SHOW_TRANSLATE, IDS_SHOW_TRANSLATE); CreateFindAndEditSubMenu(); @@ -1707,6 +1718,13 @@ AddSubMenuWithStringId(IDC_SAVE_AND_SHARE_MENU, IDS_SAVE_AND_SHARE_MENU, sub_menus_.back().get()); } else { + if (base::FeatureList::IsEnabled( + performance_manager::features::kPerformanceControlsSidePanel)) { + AddItemWithStringId(IDC_PERFORMANCE, IDS_SHOW_PERFORMANCE); + SetElementIdentifierAt(GetIndexOfCommandId(IDC_PERFORMANCE).value(), + kPerformanceMenuItem); + } + if (media_router::MediaRouterEnabled(browser()->profile())) { AddItemWithStringId(IDC_ROUTE_MEDIA, IDS_MEDIA_ROUTER_MENU_ITEM_TITLE); } @@ -1850,6 +1868,7 @@ kKeyOpenChromeRefreshIcon); SetCommandIcon(this, IDC_MORE_TOOLS_MENU, kMoreToolsMenuIcon); SetCommandIcon(this, IDC_OPTIONS, kSettingsMenuIcon); + SetCommandIcon(this, IDC_PERFORMANCE, kPerformanceIcon); #if BUILDFLAG(GOOGLE_CHROME_BRANDING) SetCommandIcon(this, IDC_HELP_MENU, kHelpMenuIcon); SetCommandIcon(this, IDC_SHOW_SEARCH_COMPANION,
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h index 3a9d150..55425f1 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.h +++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -172,6 +172,7 @@ DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kPasswordAndAutofillMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kPasswordManagerMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kShowSearchCompanion); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kPerformanceMenuItem); // Number of menus within the app menu with an arbitrarily high (variable) // number of menu items. For example, the number of bookmarks menu items
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc index 5a0f87f0..298f5e6 100644 --- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -367,11 +367,26 @@ AppMenuModel model(this, browser()); model.Init(); ToolsMenuModel toolModel(&model, browser()); + ASSERT_TRUE(toolModel.GetIndexOfCommandId(IDC_PERFORMANCE)); size_t performance_index = toolModel.GetIndexOfCommandId(IDC_PERFORMANCE).value(); EXPECT_TRUE(toolModel.IsEnabledAt(performance_index)); } +TEST_F(TestAppMenuModelCR2023, PerformanceItemElevated) { + feature_list_.Reset(); + feature_list_.InitWithFeatures( + /*enabled_features=*/{features::kChromeRefresh2023, + performance_manager::features:: + kPerformanceControlsSidePanel}, + /*disabled_features=*/{}); + AppMenuModel model(this, browser()); + model.Init(); + ASSERT_TRUE(model.GetIndexOfCommandId(IDC_PERFORMANCE)); + size_t performance_index = model.GetIndexOfCommandId(IDC_PERFORMANCE).value(); + EXPECT_TRUE(model.IsEnabledAt(performance_index)); +} + TEST_F(TestAppMenuModelCR2023, OrganizeTabsItem) { AppMenuModel model(this, browser()); model.Init();
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 5a87066..1ad79f1 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -238,6 +238,15 @@ base::FeatureList::IsEnabled(features::kTabOrganization); } +const base::FeatureParam<base::TimeDelta> kTabOrganizationTriggerPeriod{ + &kTabOrganization, "trigger_period", base::Hours(6)}; + +const base::FeatureParam<double> kTabOrganizationTriggerBackoffBase{ + &kTabOrganization, "backoff_base", 2.0}; + +const base::FeatureParam<double> kTabOrganizationTriggerThreshold{ + &kTabOrganization, "trigger_threshold", 7.0}; + BASE_FEATURE(kTabSearchChevronIcon, "TabSearchChevronIcon", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index acdf652..a125c68 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -129,6 +129,16 @@ BASE_DECLARE_FEATURE(kTabOrganization); bool IsTabOrganization(); +// The target (and minimum) interval between proactive nudge triggers. Measured +// against a clock that only runs while Chrome is in the foreground. +extern const base::FeatureParam<base::TimeDelta> kTabOrganizationTriggerPeriod; + +// The base to use for the trigger logic's exponential backoff. +extern const base::FeatureParam<double> kTabOrganizationTriggerBackoffBase; + +// The minimum score threshold for proactive nudge triggering to occur. +extern const base::FeatureParam<double> kTabOrganizationTriggerThreshold; + BASE_DECLARE_FEATURE(kTabSearchChevronIcon); BASE_DECLARE_FEATURE(kTabSearchFeedback);
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc index 5826094..c1198e6 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -13,14 +13,17 @@ #include "base/no_destructor.h" #include "base/ranges/algorithm.h" #include "build/build_config.h" +#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/extensions/extension_action_view_controller.h" #include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/side_panel/side_panel_ui.h" #include "chrome/browser/ui/toolbar/toolbar_action_hover_card_types.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.h" #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" @@ -32,6 +35,8 @@ #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_hover_card_controller.h" #include "chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h" +#include "chrome/common/pref_names.h" +#include "chrome/grit/generated_resources.h" #include "components/feature_engagement/public/event_constants.h" #include "content/public/browser/web_contents.h" #include "extensions/common/extension_features.h" @@ -39,6 +44,7 @@ #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/models/image_model.h" #include "ui/base/ui_base_features.h" @@ -186,6 +192,27 @@ AddMainItem(main_item); UpdateControlsVisibility(); + // Create close side panel button. + if (base::FeatureList::IsEnabled(features::kSidePanelPinning)) { + std::unique_ptr<ToolbarButton> close_side_panel_button = + std::make_unique<ToolbarButton>(base::BindRepeating( + &ExtensionsToolbarContainer::CloseSidePanelButtonPressed, + base::Unretained(this))); + close_side_panel_button->SetTooltipText(l10n_util::GetStringUTF16( + IDS_EXTENSIONS_SUBMENU_CLOSE_SIDE_PANEL_ITEM)); + close_side_panel_button->SetVisible(false); + close_side_panel_button->SetProperty(views::kFlexBehaviorKey, + views::FlexSpecification()); + close_side_panel_button_ = AddChildView(std::move(close_side_panel_button)); + UpdateCloseSidePanelButtonIcon(); + pref_change_registrar_.Init(browser_->profile()->GetPrefs()); + pref_change_registrar_.Add( + prefs::kSidePanelHorizontalAlignment, + base::BindRepeating( + &ExtensionsToolbarContainer::UpdateCloseSidePanelButtonIcon, + base::Unretained(this))); + } + CreateActions(); // TODO(pbos): Consider splitting out tab-strip observing into another class. @@ -199,6 +226,8 @@ // avoid events during teardown). action_hover_card_controller_.reset(); + close_side_panel_button_ = nullptr; + // The child views hold pointers to the |actions_|, and thus need to be // destroyed before them. RemoveAllChildViews(); @@ -222,6 +251,10 @@ for (const auto& action : actions_) action->UpdateState(); + + if (close_side_panel_button_) { + close_side_panel_button_->UpdateIcon(); + } } // TODO(emiliapaz): Move this method as an accessor in the header file once the @@ -664,8 +697,15 @@ if (drop_info_.get()) ReorderChildView(GetViewForId(drop_info_->action_id), drop_info_->index); - // The extension button is always last. - ReorderChildView(main_item(), children().size()); + // The extension button is always second to last if |close_side_panel_button_| + // exists, or last otherwise. + ReorderChildView(main_item(), close_side_panel_button_ ? children().size() - 1 + : children().size()); + + // The close side panel button is always last. + if (close_side_panel_button_) { + ReorderChildView(close_side_panel_button_, children().size()); + } } void ExtensionsToolbarContainer::CreateActions() { @@ -982,6 +1022,16 @@ .WithOrder(1)); } +void ExtensionsToolbarContainer::UpdateSidePanelState(bool is_active) { + close_side_panel_button_->SetVisible(is_active); + if (is_active) { + close_side_panel_button_anchor_higlight_ = + close_side_panel_button_->AddAnchorHighlight(); + } else { + close_side_panel_button_anchor_higlight_.reset(); + } +} + void ExtensionsToolbarContainer::MovePinnedAction( const ToolbarActionsModel::ActionId& action_id, size_t index, @@ -1050,6 +1100,10 @@ } } +void ExtensionsToolbarContainer::CloseSidePanelButtonPressed() { + SidePanelUI::GetSidePanelUIForBrowser(browser_)->Close(); +} + void ExtensionsToolbarContainer::UpdateToolbarActionHoverCard( ToolbarActionView* action_view, ToolbarActionHoverCardUpdateType update_type) { @@ -1082,5 +1136,12 @@ ToolbarActionHoverCardUpdateType::kHover); } +void ExtensionsToolbarContainer::UpdateCloseSidePanelButtonIcon() { + const bool is_right_aligned = browser_->profile()->GetPrefs()->GetBoolean( + prefs::kSidePanelHorizontalAlignment); + close_side_panel_button_->SetVectorIcon( + is_right_aligned ? kRightPanelCloseIcon : kLeftPanelCloseIcon); +} + BEGIN_METADATA(ExtensionsToolbarContainer, ToolbarIconContainerView) END_METADATA
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h index ac87e82c..270c9ae 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.h
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "chrome/browser/ui/views/extensions/extensions_toolbar_controls.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" +#include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h" #include "extensions/common/extension.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -124,6 +125,10 @@ int GetNumberOfActionsForTesting() { return actions_.size(); } + ToolbarButton* GetCloseSidePanelButtonForTesting() { + return close_side_panel_button_; + } + // Updates the flex layout rules for the extension toolbar container to have // views::MinimumFlexSizeRule::kPreferred when WindowControlsOverlay (WCO) is // toggled on for PWAs. Otherwise the extensions icon does not stay visible as @@ -131,6 +136,10 @@ // it's parent (in the case of WCO PWAs, WebAppFrameToolbarView). void WindowControlsOverlayEnabledChanged(bool enabled); + // Called when the side panel state has changed for an extensions side panel + // to pop out button reflecting the side panel being open. + void UpdateSidePanelState(bool is_active); + // ToolbarIconContainerView: void UpdateAllIcons() override; bool GetDropFormats(int* formats, @@ -260,6 +269,9 @@ // Maybe displays the In-Product-Help with a specific priority order. void MaybeShowIPH(); + // Triggers the side panel to close. + void CloseSidePanelButtonPressed(); + // TabStripModelObserver: void OnTabStripModelChanged( TabStripModel* tab_strip_model, @@ -305,6 +317,12 @@ void DragDropCleanup( const ToolbarActionsModel::ActionId& dragged_extension_id); + // Updates the vector icon used when the PrefChangeRegistrar listens to a + // change. When the side panel should open to the right side of the browser + // the default vector icon is used. When the side panel should open to the + // left side of the browser the flipped vector icon is used. + void UpdateCloseSidePanelButtonIcon(); + const raw_ptr<Browser> browser_; const raw_ptr<ToolbarActionsModel> model_; @@ -344,6 +362,11 @@ raw_ptr<ToolbarActionViewController> popup_owner_ = nullptr; // Extension with an open context menu, if any. absl::optional<extensions::ExtensionId> extension_with_open_context_menu_id_; + // View for closing the extension side panel. + raw_ptr<ToolbarButton> close_side_panel_button_ = nullptr; + // Used to ensure the button remains highlighted while active. + absl::optional<views::Button::ScopedAnchorHighlight> + close_side_panel_button_anchor_higlight_; // The widgets currently popped out and, for each, the extension it is // associated with. See AnchoredWidget. @@ -353,6 +376,9 @@ // there is none. std::unique_ptr<DropInfo> drop_info_; + // Observes and listens to side panel alignment changes. + PrefChangeRegistrar pref_change_registrar_; + base::WeakPtrFactory<ExtensionsToolbarContainer> weak_ptr_factory_{this}; base::WeakPtrFactory<ExtensionsToolbarContainer> drop_weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_pixel_test.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_pixel_test.cc index f353b9a4..9a31b84 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_pixel_test.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_pixel_test.cc
@@ -88,9 +88,11 @@ std::tuple<bool, std::string, CookieControlsEnforcement>> { public: CookieControlsBubbleViewPixelTest() { - scoped_feature_list_.InitAndEnableFeatureWithParameters( - content_settings::features::kUserBypassUI, - {{"expiration", std::get<1>(GetParam())}}); + scoped_feature_list_.InitWithFeaturesAndParameters( + {{content_settings::features::kUserBypassUI, + {{"expiration", std::get<1>(GetParam())}}}}, + // TODO(http://b/306151669): Add coverage for 3PCD state. + {content_settings::features::kTrackingProtection3pcd}); } void TearDownOnMainThread() override {
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 28cf5b07..67bf36d6 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -495,8 +495,9 @@ void ZoomBubbleView::OnExtensionIconImageChanged( extensions::IconImage* /* image */) { - image_button_->SetImage(views::Button::STATE_NORMAL, - &extension_info_.icon_image->image_skia()); + image_button_->SetImageModel( + views::Button::STATE_NORMAL, + ui::ImageModel::FromImageSkia(extension_info_.icon_image->image_skia())); image_button_->SchedulePaint(); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_header_view.cc b/chrome/browser/ui/views/omnibox/omnibox_header_view.cc index 631795e2..6f79528 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_header_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_header_view.cc
@@ -177,16 +177,17 @@ ? omnibox::kArrowDownChromeRefreshIcon : omnibox::kChevronIcon, dip_size, icon_color); - const gfx::ImageSkia arrow_up = + const ui::ImageModel arrow_up = OmniboxFieldTrial::IsChromeRefreshSuggestIconsEnabled() - ? gfx::CreateVectorIcon(omnibox::kArrowUpChromeRefreshIcon, dip_size, - icon_color) - : gfx::ImageSkiaOperations::CreateRotatedImage( - arrow_down, SkBitmapOperations::ROTATION_180_CW); + ? ui::ImageModel::FromVectorIcon(omnibox::kArrowUpChromeRefreshIcon, + icon_color, dip_size) + : ui::ImageModel::FromImageSkia( + gfx::ImageSkiaOperations::CreateRotatedImage( + arrow_down, SkBitmapOperations::ROTATION_180_CW)); // The "untoggled" button state corresponds with the group being shown. // The button's action is therefore to Hide the group, when clicked. - header_toggle_button_->SetImage(views::Button::STATE_NORMAL, arrow_up); + header_toggle_button_->SetImageModel(views::Button::STATE_NORMAL, arrow_up); header_toggle_button_->SetTooltipText( l10n_util::GetStringUTF16(IDS_TOOLTIP_HEADER_HIDE_SUGGESTIONS_BUTTON)); header_toggle_button_->SetAccessibleName(l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/views/overlay/resize_handle_button.cc b/chrome/browser/ui/views/overlay/resize_handle_button.cc index 1f684675..13a82caf 100644 --- a/chrome/browser/ui/views/overlay/resize_handle_button.cc +++ b/chrome/browser/ui/views/overlay/resize_handle_button.cc
@@ -127,7 +127,8 @@ break; } - SetImage(views::Button::STATE_NORMAL, icon); + SetImageModel(views::Button::STATE_NORMAL, + ui::ImageModel::FromImageSkia(icon)); } BEGIN_METADATA(ResizeHandleButton, views::ImageButton)
diff --git a/chrome/browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc b/chrome/browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc index 719e3f0..fb4d40c 100644 --- a/chrome/browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc +++ b/chrome/browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc
@@ -17,6 +17,7 @@ #include "components/content_settings/core/common/content_settings_types.h" #include "components/permissions/features.h" #include "components/permissions/permission_request_manager.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "net/dns/mock_host_resolver.h" #include "ui/base/interaction/element_identifier.h" @@ -34,7 +35,7 @@ EmbeddedPermissionPromptInteractiveTest() { https_server_ = std::make_unique<net::EmbeddedTestServer>( net::EmbeddedTestServer::TYPE_HTTPS); - feature_list_.InitWithFeatures({permissions::features::kPermissionElement, + feature_list_.InitWithFeatures({features::kPermissionElement, permissions::features::kOneTimePermission}, {}); ready_element_visible_.where = kReadyElementQuery;
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.cc b/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.cc index cd9727d2..6f3102bc 100644 --- a/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.cc +++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/containers/contains.h" +#include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/strings/string_util.h" #include "base/time/time.h" @@ -17,6 +18,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/color/chrome_color_id.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/url_identity.h" #include "chrome/browser/ui/views/bubble_anchor_util_views.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" @@ -129,6 +131,23 @@ } } +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_FUCHSIA) +std::optional<MediaCoordinator::ViewType> ComputePreviewType( + bool has_camera_request, + bool has_mic_request) { + if (has_camera_request && has_mic_request) { + return MediaCoordinator::ViewType::kBoth; + } + if (has_camera_request) { + return MediaCoordinator::ViewType::kCameraOnly; + } + if (has_mic_request) { + return MediaCoordinator::ViewType::kMicOnly; + } + return std::nullopt; +} +#endif + } // namespace PermissionPromptBubbleOneOriginView::PermissionPromptBubbleOneOriginView( @@ -149,16 +168,34 @@ PermissionPromptBaseView::GetUrlIdentity(browser, *delegate).name, GetVisibleRequests(*delegate.get())), GetExtraText(*delegate.get())) { + bool has_camera_request = false; + bool has_mic_request = false; std::vector<permissions::PermissionRequest*> visible_requests = GetVisibleRequests(*delegate.get()); for (std::size_t i = 0; i < visible_requests.size(); i++) { AddRequestLine(visible_requests[i], i); + if (visible_requests[i]->request_type() == + permissions::RequestType::kCameraStream) { + has_camera_request = true; + } else if (visible_requests[i]->request_type() == + permissions::RequestType::kMicStream) { + has_mic_request = true; + } } + MaybeAddMediaPreview(has_camera_request, has_mic_request, + visible_requests.size()); } PermissionPromptBubbleOneOriginView::~PermissionPromptBubbleOneOriginView() = default; +void PermissionPromptBubbleOneOriginView::ChildPreferredSizeChanged( + views::View* child) { + if (GetBubbleFrameView()) { + SizeToContents(); + } +} + void PermissionPromptBubbleOneOriginView::AddRequestLine( permissions::PermissionRequest* request, std::size_t index) { @@ -193,3 +230,22 @@ views::kMarginsKey, gfx::Insets().set_top(kPermissionBodyTopMargin)); } } + +void PermissionPromptBubbleOneOriginView::MaybeAddMediaPreview( + bool has_camera_request, + bool has_mic_request, + size_t index) { +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_FUCHSIA) + if (!base::FeatureList::IsEnabled(features::kCameraMicPreview)) { + return; + } + + auto view_type = ComputePreviewType(has_camera_request, has_mic_request); + if (!view_type) { + return; + } + + media_preview_coordinator_.emplace(view_type.value(), *this, index, + /*is_subsection=*/false); +#endif +}
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.h b/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.h index 9789123f..5cbc4a5 100644 --- a/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.h +++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble_one_origin_view.h
@@ -7,6 +7,10 @@ #include "chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.h" +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_FUCHSIA) +#include "chrome/browser/ui/views/media_preview/media_coordinator.h" +#endif + // Bubble that prompts the user to grant or deny a permission request from one // origin. // @@ -36,9 +40,20 @@ ~PermissionPromptBubbleOneOriginView() override; private: + void ChildPreferredSizeChanged(views::View* child) override; + // Add a line for the |request| at |index| of the view. void AddRequestLine(permissions::PermissionRequest* request, std::size_t index); + + // Adds Media (Camera / Mic) live preview feeds. + void MaybeAddMediaPreview(bool has_camera_request, + bool has_mic_request, + size_t index); + +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_FUCHSIA) + std::optional<MediaCoordinator> media_preview_coordinator_; +#endif }; #endif // CHROME_BROWSER_UI_VIEWS_PERMISSIONS_PERMISSION_PROMPT_BUBBLE_ONE_ORIGIN_VIEW_H_
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_factory.cc b/chrome/browser/ui/views/permissions/permission_prompt_factory.cc index bc44c36..3a4d21b 100644 --- a/chrome/browser/ui/views/permissions/permission_prompt_factory.cc +++ b/chrome/browser/ui/views/permissions/permission_prompt_factory.cc
@@ -15,11 +15,11 @@ #include "chrome/browser/ui/views/permissions/permission_prompt_quiet_icon.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/common/webui_url_constants.h" -#include "components/permissions/features.h" #include "components/permissions/permission_request.h" #include "components/permissions/permission_uma_util.h" #include "components/permissions/request_type.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" namespace { @@ -106,8 +106,7 @@ bool ShouldCurrentRequestUsePermissionElementSecondaryUI( permissions::PermissionPrompt::Delegate* delegate) { - if (!base::FeatureList::IsEnabled( - permissions::features::kPermissionElement)) { + if (!base::FeatureList::IsEnabled(features::kPermissionElement)) { return false; }
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc index 6c5dd57..54f2a18 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -349,6 +349,50 @@ void AvatarToolbarButton::HideSignInText() { delegate_->HideSignInText(); } + +void AvatarToolbarButton::DisabledStateHelper::Init( + bool previous_enable_state, + SkColor previous_disabled_text_color) { + CHECK(!init_); + + previous_enable_state_ = previous_enable_state; + previous_disabled_text_color_ = previous_disabled_text_color; + + init_ = true; +} + +bool AvatarToolbarButton::DisabledStateHelper::GetPreviousEnableState() const { + CHECK(init_); + return previous_enable_state_; +} + +SkColor AvatarToolbarButton::DisabledStateHelper::GetPreviousDisabledTextColor() + const { + CHECK(init_); + return previous_disabled_text_color_; +} + +void AvatarToolbarButton::DisableActionButton() { + SkColor active_text_color = GetCurrentTextColor(); + + // Disable the button and remember the disabled text color/state. + bool previous_enable_state = GetEnabled(); + SetEnabled(false); + disabled_state_helper_.Init(previous_enable_state, GetCurrentTextColor()); + + // Override the disable state color with the active text color. + SetTextColor(ButtonState::STATE_DISABLED, active_text_color); +} + +void AvatarToolbarButton::ResetActionButton() { + SetEnabled(disabled_state_helper_.GetPreviousEnableState()); + SetTextColor(ButtonState::STATE_DISABLED, + disabled_state_helper_.GetPreviousDisabledTextColor()); + + // Reset the helper instance. + disabled_state_helper_ = {}; +} + #endif void AvatarToolbarButton::AddObserver(Observer* observer) {
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h index 4548a6b..9204c9be 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
@@ -60,6 +60,9 @@ void ShowSignInText(); // Contracts the pill so that no text is shown. void HideSignInText(); + + void DisableActionButton(); + void ResetActionButton(); #endif void AddObserver(Observer* observer); @@ -94,6 +97,21 @@ FRIEND_TEST_ALL_PREFIXES(AvatarToolbarButtonTest, HighlightMeetsMinimumContrast); + // Struct to store the button state before overriding the disabled state. + class DisabledStateHelper { + public: + void Init(bool previous_enable_state, SkColor previous_disabled_text_color); + + bool GetPreviousEnableState() const; + SkColor GetPreviousDisabledTextColor() const; + + private: + bool init_ = false; + + bool previous_enable_state_ = true; + SkColor previous_disabled_text_color_; + }; + // ui::PropertyHandler: void AfterPropertyChange(const void* key, int64_t old_value) override; @@ -119,6 +137,8 @@ // separate animation. static base::TimeDelta g_iph_min_delay_after_creation; + DisabledStateHelper disabled_state_helper_; + base::ObserverList<Observer>::Unchecked observer_list_; base::WeakPtrFactory<AvatarToolbarButton> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc index 39ae1a1..9d88023 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
@@ -129,7 +129,9 @@ // avatar icon. if (bubble_parameters.interception_type == WebSigninInterceptor::SigninInterceptionType::kChromeSignin) { - GetAvatarToolbarButton(*browser)->ShowSignInText(); + AvatarToolbarButton* button = GetAvatarToolbarButton(*browser); + button->ShowSignInText(); + button->DisableActionButton(); } return handle; @@ -274,7 +276,9 @@ RecordInterceptionResult(bubble_parameters_, profile_, result); if (bubble_parameters_.interception_type == WebSigninInterceptor::SigninInterceptionType::kChromeSignin) { - GetAvatarToolbarButton(*browser_)->HideSignInText(); + AvatarToolbarButton* button = GetAvatarToolbarButton(*browser_); + button->HideSignInText(); + button->ResetActionButton(); } std::move(callback_).Run(result); if (!accepted_) {
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h index 8648898..54e670c0 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.h
@@ -97,6 +97,10 @@ ScopedHandle& operator=(const ScopedHandle&) = delete; ScopedHandle(const ScopedHandle&) = delete; + DiceWebSigninInterceptionBubbleView* GetBubbleViewForTesting() { + return bubble_.get(); + } + private: base::WeakPtr<DiceWebSigninInterceptionBubbleView> bubble_; };
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc index a09677e1..b471a64 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_browsertest.cc
@@ -519,17 +519,25 @@ base::HistogramTester histogram_tester; base::UserActionTester user_action_tester; - // `bubble` is owned by the view hierarchy. - DiceWebSigninInterceptionBubbleView* bubble = - new DiceWebSigninInterceptionBubbleView( + ASSERT_TRUE(GetAvatarButton()->GetEnabled()); + // Creating the bubble through the static function. + std::unique_ptr<ScopedWebSigninInterceptionBubbleHandle> handle = + DiceWebSigninInterceptionBubbleView::CreateBubble( browser(), GetAvatarButton(), GetTestChromeSigninBubbleParameters(), base::BindOnce(&DiceWebSigninInterceptionBubbleBrowserTest:: OnInterceptionComplete, base::Unretained(this))); - views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(bubble); + // `bubble` is owned by the view hierarchy. + DiceWebSigninInterceptionBubbleView* bubble = + static_cast<DiceWebSigninInterceptionBubbleView::ScopedHandle*>( + handle.get()) + ->GetBubbleViewForTesting(); + + views::Widget* widget = bubble->GetWidget(); // Equivalent to `kInterceptionBubbleBaseHeight` default. bubble->SetHeightAndShowWidget(/*height=*/500); EXPECT_FALSE(callback_result_.has_value()); + EXPECT_FALSE(GetAvatarButton()->GetEnabled()); // Take a handle on the bubble, to close it later. bubble_handle_ = bubble->GetHandle(); @@ -541,6 +549,7 @@ ASSERT_TRUE(callback_result_.has_value()); EXPECT_EQ(callback_result_, SigninInterceptionResult::kAccepted); EXPECT_TRUE(bubble->GetAccepted()); + EXPECT_TRUE(GetAvatarButton()->GetEnabled()); // Widget was not closed yet - the delegate then takes care of it through the // handle. @@ -571,17 +580,25 @@ base::HistogramTester histogram_tester; base::UserActionTester user_action_tester; - // `bubble` is owned by the view hierarchy. - DiceWebSigninInterceptionBubbleView* bubble = - new DiceWebSigninInterceptionBubbleView( + ASSERT_TRUE(GetAvatarButton()->GetEnabled()); + // Creating the bubble through the static function. + std::unique_ptr<ScopedWebSigninInterceptionBubbleHandle> handle = + DiceWebSigninInterceptionBubbleView::CreateBubble( browser(), GetAvatarButton(), GetTestChromeSigninBubbleParameters(), base::BindOnce(&DiceWebSigninInterceptionBubbleBrowserTest:: OnInterceptionComplete, base::Unretained(this))); - views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(bubble); + // `bubble` is owned by the view hierarchy. + DiceWebSigninInterceptionBubbleView* bubble = + static_cast<DiceWebSigninInterceptionBubbleView::ScopedHandle*>( + handle.get()) + ->GetBubbleViewForTesting(); + + views::Widget* widget = bubble->GetWidget(); // Equivalent to `kInterceptionBubbleBaseHeight` default. bubble->SetHeightAndShowWidget(/*height=*/500); EXPECT_FALSE(callback_result_.has_value()); + EXPECT_FALSE(GetAvatarButton()->GetEnabled()); views::test::WidgetDestroyedWaiter closing_observer(widget); EXPECT_FALSE(bubble->GetAccepted()); @@ -590,6 +607,7 @@ ASSERT_TRUE(callback_result_.has_value()); EXPECT_EQ(callback_result_, SigninInterceptionResult::kDeclined); EXPECT_FALSE(bubble->GetAccepted()); + EXPECT_TRUE(GetAvatarButton()->GetEnabled()); EXPECT_TRUE(widget->IsClosed()); // Widget will close now.
diff --git a/chrome/browser/ui/views/profiles/profile_menu_coordinator.cc b/chrome/browser/ui/views/profiles/profile_menu_coordinator.cc index 9410144..9945ca59 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_coordinator.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_coordinator.cc
@@ -35,10 +35,12 @@ ->toolbar_button_provider() ->GetAvatarToolbarButton(); - // Do not show avatar bubble if there is no avatar menu button or the bubble - // is already showing. - if (!avatar_toolbar_button || IsShowing()) + // Do not show avatar bubble if there is no avatar menu button, the button is + // disabled or the bubble is already showing. + if (!avatar_toolbar_button || !avatar_toolbar_button->GetEnabled() || + IsShowing()) { return; + } auto& browser = GetBrowser(); signin_ui_util::RecordProfileMenuViewShown(browser.profile());
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index 2937e79e..67603b5f 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -277,7 +277,9 @@ } gfx::ImageSkia image = ImageForMenu(*icon_, shortcutIconToImageRatio, icon_color); - SetImage(views::Button::STATE_NORMAL, SizeImage(image, button_size_)); + SetImageModel( + views::Button::STATE_NORMAL, + ui::ImageModel::FromImageSkia(SizeImage(image, button_size_))); views::InkDrop::Get(this)->SetBaseColor(icon_color); }
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc index 420f500..1ac27d7 100644 --- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
@@ -1321,6 +1321,55 @@ } } +IN_PROC_BROWSER_TEST_F(ExtensionSidePanelBrowserTest, + CloseSidePanelButtonVisibleWhenExtensionsSidePanelOpen) { + ExtensionTestMessageListener default_path_listener("default_path"); + + scoped_refptr<const extensions::Extension> extension = LoadExtension( + test_data_dir_.AppendASCII("api_test/side_panel/simple_default")); + ASSERT_TRUE(extension); + + // Check if ActionItem is created. + BrowserActions* browser_actions = BrowserActions::FromBrowser(browser()); + actions::ActionItem* action_item = + GetActionItemForExtension(extension.get(), browser_actions); + EXPECT_EQ(action_item->GetText(), base::UTF8ToUTF16(extension->short_name())); + EXPECT_FALSE(action_item->GetImage().IsEmpty()); + + SidePanelEntry::Key extension_key = GetKey(extension->id()); + SidePanelEntry* extension_entry = + global_registry()->GetEntryForKey(extension_key); + ASSERT_TRUE(extension_entry); + + // The key for the extension should be registered, but the side panel isn't + // shown yet and the close side panel button is not visible. + EXPECT_FALSE(side_panel_coordinator()->IsSidePanelShowing()); + EXPECT_FALSE(GetExtensionsToolbarContainer() + ->GetCloseSidePanelButtonForTesting() + ->GetVisible()); + + side_panel_coordinator()->Show(extension_key); + + // Wait until the view in the side panel is active by listening for the + // message sent from the view's script. Verify the close side panel button is + // visible. + ASSERT_TRUE(default_path_listener.WaitUntilSatisfied()); + EXPECT_TRUE(side_panel_coordinator()->IsSidePanelShowing()); + EXPECT_TRUE(GetExtensionsToolbarContainer() + ->GetCloseSidePanelButtonForTesting() + ->GetVisible()); + + // Now unload the extension. The key should no longer exist in the global + // registry and the side panel should close as a result and the close side + // panel button should not be visible. + UnloadExtension(extension->id()); + EXPECT_FALSE(global_registry()->GetEntryForKey(extension_key)); + EXPECT_FALSE(side_panel_coordinator()->IsSidePanelShowing()); + EXPECT_FALSE(GetExtensionsToolbarContainer() + ->GetCloseSidePanelButtonForTesting() + ->GetVisible()); +} + class ExtensionOpenSidePanelBrowserTest : public ExtensionSidePanelBrowserTest { public: ExtensionOpenSidePanelBrowserTest()
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc index 63c2e850..d249fe1 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
@@ -34,10 +34,7 @@ public: void SetUp() override { base::test::ScopedFeatureList features; - // TODO(b/310047213): Fix tests from failing when companion enabled. - scoped_feature_list_.InitWithFeatures( - {features::kReadAnything}, - {companion::features::internal::kSidePanelCompanion}); + scoped_feature_list_.InitWithFeatures({features::kReadAnything}, {}); TestWithBrowserView::SetUp(); side_panel_coordinator_ = @@ -47,14 +44,14 @@ // Ensure a kReadAnything entry is added to the contextual registry for the // first tab. - AddTab(browser_view()->browser(), GURL("http://foo1.com")); + AddTabToBrowser(GURL("http://foo1.com")); auto* tab_one_registry = SidePanelRegistry::Get(browser_view()->GetActiveWebContents()); contextual_registries_.push_back(tab_one_registry); // Ensure a kReadAnything entry is added to the contextual registry for the // second tab. - AddTab(browser_view()->browser(), GURL("http://foo2.com")); + AddTabToBrowser(GURL("http://foo2.com")); auto* tab_two_registry = SidePanelRegistry::Get(browser_view()->GetActiveWebContents()); contextual_registries_.push_back(tab_two_registry); @@ -104,6 +101,15 @@ read_anything_coordinator_->ActivePageNotDistillable(); } + void AddTabToBrowser(const GURL& tab_url) { + AddTab(browser_view()->browser(), tab_url); + // Remove the companion entry if it present. + auto* registry = + SidePanelRegistry::Get(browser_view()->GetActiveWebContents()); + registry->Deregister( + SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion)); + } + protected: raw_ptr<SidePanelCoordinator, DanglingUntriaged> side_panel_coordinator_ = nullptr;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc index 0a7c4de..e61306f4 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
@@ -210,6 +210,9 @@ if (base::Contains(kLanguagesSupportedByStixTwoText, lang)) { font_choices_.emplace_back(u"STIX Two Text"); } + if (base::Contains(kLanguagesSupportedByAndika, lang)) { + font_choices_.emplace_back(u"Andika"); + } font_choices_.shrink_to_fit(); }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc index a0c494f..f1773ce 100644 --- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc +++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
@@ -214,6 +214,7 @@ EXPECT_EQ("Lexend Deca", GetFontModel()->GetFontNameAt(4)); EXPECT_EQ("EB Garamond", GetFontModel()->GetFontNameAt(5)); EXPECT_EQ("STIX Two Text", GetFontModel()->GetFontNameAt(6)); + EXPECT_EQ("Andika", GetFontModel()->GetFontNameAt(7)); } TEST_F(ReadAnythingModelTest, FontModelGetFontNameChineseOptions) {
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc index 3552b95..320cf687 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -1138,7 +1138,7 @@ } IN_PROC_BROWSER_TEST_F(CompanionPageBrowserTest, - OpenCompanionPageWithVssEnabled) { + OpenCompanionPageWithVqsEnabled) { base::HistogramTester histogram_tester; OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()) ->OverrideTargetModelForTesting(
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc index 05e55b9..9ff0cc0 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" #include "chrome/browser/ui/views/frame/browser_actions.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h" @@ -1065,7 +1066,8 @@ CHECK(toolbar_container); if (key.id() == SidePanelEntryId::kExtension) { - // TODO(b/303064829): Handle extensions pop out and highlighting. + browser_view_->toolbar()->extensions_container()->UpdateSidePanelState( + is_active); } else { absl::optional<actions::ActionId> action_id = SidePanelEntryIdToActionId(key.id());
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc index ee34a946..e942b094 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
@@ -80,11 +80,10 @@ class SidePanelCoordinatorTest : public TestWithBrowserView { public: void SetUp() override { - SetUpFeatureList(); TestWithBrowserView::SetUp(); - AddTab(browser_view()->browser(), GURL("http://foo1.com")); - AddTab(browser_view()->browser(), GURL("http://foo2.com")); + AddTabToBrowser(GURL("http://foo1.com")); + AddTabToBrowser(GURL("http://foo2.com")); // Add a kSideSearch entry to the contextual registry for the first tab. browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); @@ -137,14 +136,6 @@ SidePanelEntry::Id::kSideSearch); } - virtual void SetUpFeatureList() { - // TODO(b/310047213): Fix tests from failing when companion enabled. - // Companion adds a contextual entry when the browser starts. Disable to - // prevent. - feature_list_.InitAndDisableFeature( - companion::features::internal::kSidePanelCompanion); - } - void VerifyEntryExistenceAndValue(absl::optional<SidePanelEntry*> entry, SidePanelEntry::Id id) { ASSERT_TRUE(entry.has_value()); @@ -175,6 +166,15 @@ return coordinator_->header_combobox_ != nullptr; } + void AddTabToBrowser(const GURL& tab_url) { + AddTab(browser_view()->browser(), tab_url); + // Remove the companion entry if it present. + auto* registry = + SidePanelRegistry::Get(browser_view()->GetActiveWebContents()); + registry->Deregister( + SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion)); + } + protected: base::test::ScopedFeatureList feature_list_; raw_ptr<SidePanelCoordinator, DanglingUntriaged> coordinator_; @@ -1763,6 +1763,7 @@ class SidePanelPinningCoordinatorTest : public SidePanelCoordinatorTest { public: void SetUp() override { + scoped_feature_list_.InitWithFeatures({features::kSidePanelPinning}, {}); SidePanelCoordinatorTest::SetUp(); content::WebContents* const web_contents = browser_view()->browser()->tab_strip_model()->GetWebContentsAt(0); @@ -1802,13 +1803,6 @@ return factories; } - void SetUpFeatureList() override { - // TODO(b/310047213): Fix tests from failing when companion enabled. - scoped_feature_list_.InitWithFeatures( - {features::kSidePanelPinning}, - {companion::features::internal::kSidePanelCompanion}); - } - static std::unique_ptr<KeyedService> BuildPinnedToolbarActionsModel( content::BrowserContext* context) { return std::make_unique<PinnedToolbarActionsModel>( @@ -1964,8 +1958,8 @@ void SetUp() override { TestWithBrowserView::SetUp(); - AddTab(browser_view()->browser(), GURL("http://foo1.com")); - AddTab(browser_view()->browser(), GURL("http://foo2.com")); + AddTabToBrowser(GURL("http://foo1.com")); + AddTabToBrowser(GURL("http://foo2.com")); coordinator_ = SidePanelUtil::GetSidePanelCoordinatorForBrowser(browser()); global_registry_ = SidePanelCoordinator::GetGlobalSidePanelRegistry(
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler.cc b/chrome/browser/ui/webui/history/browsing_history_handler.cc index 7fc51d4..2f45584a 100644 --- a/chrome/browser/ui/webui/history/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/history/browsing_history_handler.cc
@@ -9,6 +9,7 @@ #include <optional> #include <set> +#include "base/check_deref.h" #include "base/check_op.h" #include "base/feature_list.h" #include "base/functional/bind.h" @@ -60,6 +61,7 @@ #if BUILDFLAG(ENABLE_SUPERVISED_USERS) #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "components/supervised_user/core/browser/supervised_user_url_filter.h" #endif @@ -184,7 +186,7 @@ base::Value::Dict HistoryEntryToValue( const BrowsingHistoryService::HistoryEntry& entry, BookmarkModel* bookmark_model, - Profile* profile, + Profile& profile, const syncer::DeviceInfoTracker* tracker, base::Clock* clock) { base::Value::Dict result; @@ -193,7 +195,7 @@ // UrlIdentity holds a user-identifiable string for a URL. We will display // this string to the user. std::u16string domain = - UrlIdentity::CreateFromUrl(profile, entry.url, allowed_types, + UrlIdentity::CreateFromUrl(&profile, entry.url, allowed_types, url_identity_options) .name; @@ -260,10 +262,9 @@ result.Set("deviceType", device_type); #if BUILDFLAG(ENABLE_SUPERVISED_USERS) - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForProfile(profile); - if (supervised_user_service && - supervised_user_service->IsURLFilteringEnabled()) { + if (supervised_user::IsUrlFilteringEnabled(*profile.GetPrefs())) { + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForProfile(&profile); supervised_user::SupervisedUserURLFilter* url_filter = supervised_user_service->GetURLFilter(); supervised_user::FilteringBehavior filtering_behavior = @@ -514,6 +515,7 @@ base::OnceClosure continuation_closure) { query_history_continuation_ = std::move(continuation_closure); Profile* profile = Profile::FromWebUI(web_ui()); + CHECK(profile); BookmarkModel* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile); @@ -526,7 +528,7 @@ base::Value::List results_value; for (const BrowsingHistoryService::HistoryEntry& entry : results) { results_value.Append( - HistoryEntryToValue(entry, bookmark_model, profile, tracker, clock_)); + HistoryEntryToValue(entry, bookmark_model, *profile, tracker, clock_)); } base::Value::Dict results_info;
diff --git a/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc b/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc index 59de757..172835c0 100644 --- a/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc +++ b/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc
@@ -29,8 +29,7 @@ content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd( Profile::FromWebUI(web_ui), chrome::kChromeUIOmniboxPopupHost); - RealboxHandler::SetupDropdownWebUIDataSource(source, - Profile::FromWebUI(web_ui)); + RealboxHandler::SetupWebUIDataSource(source, Profile::FromWebUI(web_ui)); webui::SetupWebUIDataSource( source,
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc index dfd7c70..6196981 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
@@ -22,7 +22,6 @@ #include "content/public/browser/browser_thread.h" #include "printing/buildflags/buildflags.h" #include "printing/mojom/print.mojom.h" -#include "printing/printing_features.h" #if BUILDFLAG(IS_MAC) #include "chrome/common/printing/printer_capabilities_mac.h" @@ -33,6 +32,7 @@ #endif #if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #include "chrome/browser/ui/webui/print_preview/printer_handler.h" #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h" @@ -240,7 +240,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + if (IsOopPrintingEnabled()) { PRINTER_LOG(EVENT) << "Getting default printer via service"; PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); @@ -264,7 +264,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + if (IsOopPrintingEnabled()) { PRINTER_LOG(EVENT) << "Enumerate printers start via service"; PrintBackendServiceManager& service_mgr = PrintBackendServiceManager::GetInstance(); @@ -290,7 +290,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_OOP_PRINTING) - if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + if (IsOopPrintingEnabled()) { PRINTER_LOG(EVENT) << "Getting printer capabilities via service for " << device_name; PrintBackendServiceManager& service_mgr =
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index f1a9d46..e131015 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -91,6 +91,7 @@ #endif #if BUILDFLAG(ENABLE_OOP_PRINTING) +#include "chrome/browser/printing/prefs_util.h" #include "chrome/browser/printing/print_backend_service_manager.h" #include "printing/printing_features.h" #endif @@ -456,14 +457,14 @@ #if BUILDFLAG(ENABLE_OOP_PRINTING) void PrintPreviewUI::RegisterPrintBackendServiceManagerClient() { - if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + if (IsOopPrintingEnabled()) { service_manager_client_id_ = PrintBackendServiceManager::GetInstance().RegisterQueryClient(); } } void PrintPreviewUI::UnregisterPrintBackendServiceManagerClient() { - if (base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers)) { + if (IsOopPrintingEnabled()) { PrintBackendServiceManager::GetInstance().UnregisterClient( service_manager_client_id_); }
diff --git a/chrome/browser/ui/webui/realbox/realbox_handler.cc b/chrome/browser/ui/webui/realbox/realbox_handler.cc index 4b358d0..00582a264d 100644 --- a/chrome/browser/ui/webui/realbox/realbox_handler.cc +++ b/chrome/browser/ui/webui/realbox/realbox_handler.cc
@@ -616,13 +616,24 @@ // static void RealboxHandler::SetupWebUIDataSource(content::WebUIDataSource* source, Profile* profile) { - RealboxHandler::SetupDropdownWebUIDataSource(source, profile); - static constexpr webui::LocalizedString kStrings[] = { - {"searchBoxHint", IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD}}; + {"searchBoxHint", IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD}, + {"realboxSeparator", IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR}, + {"removeSuggestion", IDS_OMNIBOX_REMOVE_SUGGESTION}, + {"hideSuggestions", IDS_TOOLTIP_HEADER_HIDE_SUGGESTIONS_BUTTON}, + {"showSuggestions", IDS_TOOLTIP_HEADER_SHOW_SUGGESTIONS_BUTTON}}; source->AddLocalizedStrings(kStrings); source->AddBoolean( + "omniboxActionsUISimplification", + base::FeatureList::IsEnabled(omnibox::kOmniboxActionsUISimplification)); + source->AddBoolean( + "realboxCr23ExpandedStateIcons", + base::FeatureList::IsEnabled( + ntp_features::kRealboxCr23ExpandedStateIcons) || + base::FeatureList::IsEnabled(ntp_features::kRealboxCr23All)); + + source->AddBoolean( "realboxMatchSearchboxTheme", base::FeatureList::IsEnabled(ntp_features::kRealboxMatchSearchboxTheme)); @@ -666,21 +677,6 @@ void RealboxHandler::SetupDropdownWebUIDataSource( content::WebUIDataSource* source, Profile* profile) { - static constexpr webui::LocalizedString kStrings[] = { - {"realboxSeparator", IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR}, - {"removeSuggestion", IDS_OMNIBOX_REMOVE_SUGGESTION}, - {"hideSuggestions", IDS_TOOLTIP_HEADER_HIDE_SUGGESTIONS_BUTTON}, - {"showSuggestions", IDS_TOOLTIP_HEADER_SHOW_SUGGESTIONS_BUTTON}}; - source->AddLocalizedStrings(kStrings); - - source->AddBoolean( - "omniboxActionsUISimplification", - base::FeatureList::IsEnabled(omnibox::kOmniboxActionsUISimplification)); - source->AddBoolean( - "realboxCr23ExpandedStateIcons", - base::FeatureList::IsEnabled( - ntp_features::kRealboxCr23ExpandedStateIcons) || - base::FeatureList::IsEnabled(ntp_features::kRealboxCr23All)); } // static
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h index 096eb5a..541e9721 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.h +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -625,6 +625,10 @@ is_non_webauthn_request_ = is_non_webauthn_request; } + void set_is_enclave_authenticator_available(bool available) { + is_enclave_authenticator_available_ = available; + } + void set_cable_transport_info( absl::optional<bool> extension_is_v2, std::vector<std::unique_ptr<device::cablev2::Pairing>> paired_phones, @@ -799,6 +803,9 @@ // started_ records whether |StartFlow| has been called. bool started_ = false; + // True when the cloud enclave authenticator is available for use. + bool is_enclave_authenticator_available_ = false; + // pending_step_ holds requested steps until the UI is shown. The UI is only // shown once the TransportAvailabilityInfo is available, but authenticators // may request, e.g., PIN entry prior to that.
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index 6f16712..180579c 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -337,12 +337,18 @@ // Chrome disables platform authenticators is Guest sessions. They may be // available (behind an additional interstitial) in Incognito mode. - Profile* profile = - Profile::FromBrowserContext(render_frame_host->GetBrowserContext()); + auto* browser_context = render_frame_host->GetBrowserContext(); + Profile* profile = Profile::FromBrowserContext(browser_context); if (profile->IsGuestSession()) { return false; } + // The cloud enclave authenticator counts as a UVPA, regardless of what the + // underlying platform offers. + if (IsEnclaveAuthenticatorAvailable(browser_context)) { + return true; + } + return absl::nullopt; } @@ -398,6 +404,20 @@ } #endif // BUILDFLAG(IS_CHROMEOS) +bool ChromeWebAuthenticationDelegate::IsEnclaveAuthenticatorAvailable( + content::BrowserContext* browser_context) { + // `browser_context` is currently unused but will be needed to look up + // whether the current profile/device is registered with the authenticator. +#if BUILDFLAG(IS_CHROMEOS) + // Enclave service authenticators are not needed for Chrome OS. + return false; +#else + // TODO(https://crbug.com/1459620): This also has to be conditional on device + // registration with the enclave, when implemented. + return base::FeatureList::IsEnabled(device::kWebAuthnEnclaveAuthenticator); +#endif +} + // --------------------------------------------------------------------- // ChromeAuthenticatorRequestDelegate // --------------------------------------------------------------------- @@ -618,10 +638,15 @@ device::FidoRequestType request_type, absl::optional<device::ResidentKeyRequirement> resident_key_requirement, base::span<const device::CableDiscoveryData> pairings_from_extension, + bool is_enclave_authenticator_available, device::FidoDiscoveryFactory* discovery_factory) { DCHECK(request_type == device::FidoRequestType::kGetAssertion || resident_key_requirement.has_value()); + is_enclave_authenticator_available_ = is_enclave_authenticator_available; + dialog_model_->set_is_enclave_authenticator_available( + is_enclave_authenticator_available); + // Without the UI enabled, discoveries like caBLE, Android AOA, iCloud // keychain, and the enclave, don't make sense. if (base::FeatureList::IsEnabled( @@ -743,7 +768,7 @@ } if (non_extension_cablev2_enabled || cablev2_extension_provided || - base::FeatureList::IsEnabled(device::kWebAuthnEnclaveAuthenticator)) { + is_enclave_authenticator_available_) { if (SystemNetworkContextManager::GetInstance()) { discovery_factory->set_network_context( SystemNetworkContextManager::GetInstance()->GetContext()); @@ -790,7 +815,7 @@ } #endif - if (EnclaveAuthenticatorAvailable() && + if (is_enclave_authenticator_available_ && request_type == device::FidoRequestType::kGetAssertion) { ConfigureEnclaveDiscovery(rp_id, discovery_factory); } @@ -880,7 +905,7 @@ } if (base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials) && base::FeatureList::IsEnabled(device::kWebAuthnNewPasskeyUI) && - (can_use_synced_phone_passkeys_ || EnclaveAuthenticatorAvailable()) && + (can_use_synced_phone_passkeys_ || is_enclave_authenticator_available_) && !IsVirtualEnvironmentEnabled()) { GetPhoneContactableGpmPasskeysForRpId(&data.recognized_credentials); } @@ -1102,7 +1127,7 @@ PasskeyModelFactory::GetInstance()->GetForProfile( Profile::FromBrowserContext(GetBrowserContext())); CHECK(passkey_model); - device::AuthenticatorType type = EnclaveAuthenticatorAvailable() + device::AuthenticatorType type = is_enclave_authenticator_available_ ? device::AuthenticatorType::kEnclave : device::AuthenticatorType::kPhone; for (const sync_pb::WebauthnCredentialSpecifics& passkey : @@ -1132,17 +1157,6 @@ discovery_factory->SetEnclavePasskeys(std::move(passkeys)); } -bool ChromeAuthenticatorRequestDelegate::EnclaveAuthenticatorAvailable() { -#if BUILDFLAG(IS_CHROMEOS) - // Enclave service authenticators are not needed for Chrome OS. - return false; -#else - // TODO(https://crbug.com/1459620): This also has to be conditional on device - // registration with the enclave, when implemented. - return base::FeatureList::IsEnabled(device::kWebAuthnEnclaveAuthenticator); -#endif -} - #if BUILDFLAG(IS_MAC) // static absl::optional<int> ChromeAuthenticatorRequestDelegate::DaysSinceDate(
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h index 1912efc..1f05846 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -82,6 +82,8 @@ content::WebAuthenticationRequestProxy* MaybeGetRequestProxy( content::BrowserContext* browser_context, const url::Origin& caller_origin) override; + bool IsEnclaveAuthenticatorAvailable( + content::BrowserContext* browser_context) override; #if BUILDFLAG(IS_MAC) absl::optional<TouchIdAuthenticatorConfig> GetTouchIdAuthenticatorConfig( @@ -171,6 +173,7 @@ device::FidoRequestType request_type, absl::optional<device::ResidentKeyRequirement> resident_key_requirement, base::span<const device::CableDiscoveryData> pairings_from_extension, + bool is_enclave_authenticator_available, device::FidoDiscoveryFactory* discovery_factory) override; void SelectAccount( std::vector<device::AuthenticatorGetAssertionResponse> responses, @@ -254,8 +257,6 @@ const std::string& rp_id, device::FidoDiscoveryFactory* discovery_factory); - bool EnclaveAuthenticatorAvailable(); - #if BUILDFLAG(IS_MAC) // DaysSinceDate returns the number of days between `formatted_date` (in ISO // 8601 format) and `now`. It returns `nullopt` if `formatted_date` cannot be @@ -323,6 +324,9 @@ // available that can service requests for synced GPM passkeys. bool can_use_synced_phone_passkeys_ = false; + // True when the cloud enclave authenticator is available for use. + bool is_enclave_authenticator_available_ = false; + base::WeakPtrFactory<ChromeAuthenticatorRequestDelegate> weak_ptr_factory_{ this}; };
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc index 13e7225..bb7af4a8 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc
@@ -404,7 +404,7 @@ content::AuthenticatorRequestClientDelegate::RequestSource:: kWebAuthentication, test.request_type, test.resident_key_requirement, test.extensions, - &discovery_factory); + /*is_enclave_authenticator_available=*/false, &discovery_factory); switch (windows_has_hybrid == kWinHybridNoPasskeySyncing ? test.expected_result_with_system_hybrid @@ -459,12 +459,13 @@ delegate.DisableUI(); } MockCableDiscoveryFactory discovery_factory; - delegate.ConfigureDiscoveries(url::Origin::Create(GURL(origin)), origin, - content::AuthenticatorRequestClientDelegate:: - RequestSource::kWebAuthentication, - device::FidoRequestType::kMakeCredential, - device::ResidentKeyRequirement::kPreferred, - {}, &discovery_factory); + delegate.ConfigureDiscoveries( + url::Origin::Create(GURL(origin)), origin, + content::AuthenticatorRequestClientDelegate::RequestSource:: + kWebAuthentication, + device::FidoRequestType::kMakeCredential, + device::ResidentKeyRequirement::kPreferred, {}, + /*is_enclave_authenticator_available=*/false, &discovery_factory); EXPECT_EQ(discovery_factory.qr_key.has_value(), !disable_ui); EXPECT_EQ(discovery_factory.aoa_configured, !disable_ui); @@ -592,7 +593,7 @@ device::FidoRequestType::kGetAssertion, /*resident_key_requirement=*/absl::nullopt, /*pairings_from_extension=*/std::vector<device::CableDiscoveryData>(), - &discovery_factory); + /*is_enclave_authenticator_available=*/false, &discovery_factory); // Add a synced passkey for example.com and another for othersite.com. webauthn::PasskeyModel* passkey_model = @@ -654,7 +655,7 @@ device::FidoRequestType::kGetAssertion, /*resident_key_requirement=*/absl::nullopt, /*pairings_from_extension=*/std::vector<device::CableDiscoveryData>(), - &discovery_factory); + /*is_enclave_authenticator_available=*/false, &discovery_factory); // Add a synced passkey for example.com. webauthn::PasskeyModel* passkey_model = @@ -707,7 +708,7 @@ device::FidoRequestType::kGetAssertion, /*resident_key_requirement=*/absl::nullopt, /*pairings_from_extension=*/std::vector<device::CableDiscoveryData>(), - &discovery_factory); + /*is_enclave_authenticator_available=*/false, &discovery_factory); // Add a synced passkey for example.com and another that shadows it. webauthn::PasskeyModel* passkey_model =
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index c8d2a3b..450fe28 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1700481515-65aa7de54bfda6dd1c1c8ccaa010694885671eef.profdata +chrome-android32-main-1700502951-2736deaa9254004fe52631c9ba7f68c8d4ec02f0.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 92dd0b0..cf337c2 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1700481515-61b7d809905c4fe7048161ca37935eb847d66447.profdata +chrome-android64-main-1700502951-d3e14b35cff907babcda97c86111a890c6600432.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 8c5d2642..1223b1e 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1700459332-b9d9b3d8e973cad2e19ff1c1f7ea3e737a612e07.profdata +chrome-linux-main-1700502951-155ce6db151477b0d949f6e2b44d315457ad73c6.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 5d1939cb..f783c05 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1700459332-fc1ad09421901981da9f2593ace2ff42a7243d3e.profdata +chrome-mac-main-1700481515-d1c66873e16a8688d58d64d935a7525589205665.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 7d266ea4..65fa790 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1700481515-8dba4686d96c01903a2c11a3f0940a00857b0c81.profdata +chrome-win-arm64-main-1700502951-94a0a6e7a69ad39e95ed4d8498f6b78f9423a37c.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 731aab2..67224aa 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1700470769-74b9a98c3b707d47350cbba9df75acdda636e01f.profdata +chrome-win32-main-1700492136-f1824aa30de407f28bb843ab7162fee302abfc1c.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index b688109..e97cfc7 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1700470769-3528682c89cd6fc964424332d567ae34563b572b.profdata +chrome-win64-main-1700502951-655d22ef36762bdee4b6590e0cc2bb41cd0a1d18.profdata
diff --git a/chrome/common/accessibility/read_anything_constants.h b/chrome/common/accessibility/read_anything_constants.h index c253696..7bc7746 100644 --- a/chrome/common/accessibility/read_anything_constants.h +++ b/chrome/common/accessibility/read_anything_constants.h
@@ -91,6 +91,11 @@ "fr", "hr", "hu", "id", "it", "lt", "lv", "ms", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "sv", "sw", "tr", "uk", "vi"}; +const char* kLanguagesSupportedByAndika[] = { + "af", "bg", "ca", "cs", "da", "de", "en", "es", "et", "fi", "fil", "fr", + "hr", "hu", "id", "it", "kr", "lt", "lu", "lv", "ms", "nd", "nl", "nr", + "pl", "pt", "ro", "ru", "sk", "sl", "sr", "sv", "sw", "tr", "uk", "vi"}; + // Enum for logging when a text style setting is changed. // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused.
diff --git a/chrome/common/google_url_loader_throttle.cc b/chrome/common/google_url_loader_throttle.cc index ea83b33e..f5b7bd0d 100644 --- a/chrome/common/google_url_loader_throttle.cc +++ b/chrome/common/google_url_loader_throttle.cc
@@ -71,6 +71,43 @@ GoogleURLLoaderThrottle::~GoogleURLLoaderThrottle() = default; +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) +// static +bool GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + const GURL& request_url, + chrome::mojom::BoundSessionThrottlerParams* + bound_session_throttler_params) { + // No bound session. + if (!bound_session_throttler_params || + bound_session_throttler_params->domain.empty()) { + return false; + } + + // The feature must be on if throttler parameters exist. + CHECK(switches::IsBoundSessionCredentialsEnabled()); + + // Short lived Cookie fresh. + if (bound_session_throttler_params->cookie_expiry_date > base::Time::Now()) { + return false; + } + + // Short lived Cookie expired. + // Check if the request requires the short lived cookie. + if (!request_url.DomainIs(net::cookie_util::CookieDomainAsHost( + bound_session_throttler_params->domain))) { + return false; + } + + if (!bound_session_throttler_params->path.empty() && + !net::cookie_util::IsOnPath(bound_session_throttler_params->path, + request_url.path())) { + return false; + } + + return true; +} +#endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + void GoogleURLLoaderThrottle::DetachFromCurrentSequence() {} void GoogleURLLoaderThrottle::WillStartRequest( @@ -112,7 +149,9 @@ #endif #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) if (switches::IsBoundSessionCredentialsEnabled() && request->SendsCookies() && - ShouldDeferRequestForBoundSession(request->url)) { + ShouldDeferRequestForBoundSession( + request->url, + dynamic_params_->bound_session_throttler_params.get())) { CHECK(bound_session_request_throttled_handler_); *defer = true; CHECK(!bound_session_request_throttled_start_time_.has_value()); @@ -165,7 +204,9 @@ #endif #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) if (switches::IsBoundSessionCredentialsEnabled() && - ShouldDeferRequestForBoundSession(redirect_info->new_url)) { + ShouldDeferRequestForBoundSession( + redirect_info->new_url, + dynamic_params_->bound_session_throttler_params.get())) { CHECK(bound_session_request_throttled_handler_); *defer = true; CHECK(!bound_session_request_throttled_start_time_.has_value()); @@ -204,41 +245,6 @@ #endif #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) -bool GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( - const GURL& request_url) const { - CHECK(switches::IsBoundSessionCredentialsEnabled()); - const chrome::mojom::BoundSessionThrottlerParamsPtr& - bound_session_throttler_params = - dynamic_params_->bound_session_throttler_params; - - // No bound session. - if (bound_session_throttler_params.is_null() || - bound_session_throttler_params->domain.empty()) { - return false; - } - - // Short lived Cookie fresh. - if (bound_session_throttler_params->cookie_expiry_date > base::Time::Now()) { - return false; - } - - // Short lived Cookie expired. - // Check if the request requires the short lived cookie. - - if (!request_url.DomainIs(net::cookie_util::CookieDomainAsHost( - bound_session_throttler_params->domain))) { - return false; - } - - if (!bound_session_throttler_params->path.empty() && - !net::cookie_util::IsOnPath(bound_session_throttler_params->path, - request_url.path())) { - return false; - } - - return true; -} - void GoogleURLLoaderThrottle::OnDeferRequestForBoundSessionCompleted( BoundSessionRequestThrottledHandler::UnblockAction unblock_action) { // Use `PostTask` to avoid resuming the request before it has been deferred
diff --git a/chrome/common/google_url_loader_throttle.h b/chrome/common/google_url_loader_throttle.h index b9ac78a..2a5cd01 100644 --- a/chrome/common/google_url_loader_throttle.h +++ b/chrome/common/google_url_loader_throttle.h
@@ -40,6 +40,13 @@ static void UpdateCorsExemptHeader( network::mojom::NetworkContextParams* params); +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + static bool ShouldDeferRequestForBoundSession( + const GURL& request_url, + chrome::mojom::BoundSessionThrottlerParams* + bound_session_throttler_params); +#endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + // blink::URLLoaderThrottle: void DetachFromCurrentSequence() override; void WillStartRequest(network::ResourceRequest* request, @@ -58,7 +65,6 @@ #endif private: #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) - bool ShouldDeferRequestForBoundSession(const GURL& request_url) const; void OnDeferRequestForBoundSessionCompleted( BoundSessionRequestThrottledHandler::UnblockAction resume); void ResumeOrCancelRequest(
diff --git a/chrome/common/google_url_loader_throttle_unittest.cc b/chrome/common/google_url_loader_throttle_unittest.cc index 5281b9ca..b4ac2040 100644 --- a/chrome/common/google_url_loader_throttle_unittest.cc +++ b/chrome/common/google_url_loader_throttle_unittest.cc
@@ -170,6 +170,122 @@ std::make_unique<base::HistogramTester>(); }; +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionNullParams) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, nullptr)); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionEmptyParams) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, + chrome::mojom::BoundSessionThrottlerParams::New("", "", base::Time::Now()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionCookieFresh) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, + chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "/", base::Time::Now() + base::Minutes(10)) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionNotInBoundSession) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + GURL("https://youtube.com"), + chrome::mojom::BoundSessionThrottlerParams::New("google.com", "/", + base::Time::Min()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionCookieExpired) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "/", base::Time::Min()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionCookieExpiresNow) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "/", base::Time::Now()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionCookieExpiredDomainWithLeadingDot) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + ".google.com", "/", base::Time::Min()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionSubdomainUrl) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kGoogleSubdomainURL, chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "/", base::Time::Min()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionParentDomainUrl) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + "accounts.google.com", "/", base::Time::Min()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionUrlWithPath) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + GURL("https://google.com/foo/bar.html"), + chrome::mojom::BoundSessionThrottlerParams::New("google.com", "/", + base::Time::Now()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionPathEmpty) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "", base::Time::Now()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionUrlNotOnBoundSessionPath) { + EXPECT_FALSE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + kTestGoogleURL, chrome::mojom::BoundSessionThrottlerParams::New( + "google.com", "/test", base::Time::Now()) + .get())); +} + +TEST_F(GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionUrlWithPathOnBoundSessionPath) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + GURL("https://google.com/test/foo/bar.html"), + chrome::mojom::BoundSessionThrottlerParams::New("google.com", "/test", + base::Time::Now()) + .get())); +} + +TEST_F( + GoogleURLLoaderThrottleTest, + ShouldDeferRequestForBoundSessionSubdomainUrlWithPathOnBoundSessionPath) { + EXPECT_TRUE(GoogleURLLoaderThrottle::ShouldDeferRequestForBoundSession( + GURL("https://accounts.google.com/test/foo/bar.html"), + chrome::mojom::BoundSessionThrottlerParams::New("google.com", "/test", + base::Time::Now()) + .get())); +} + TEST_P(GoogleURLLoaderThrottleTest, NullBoundSessionThrottlerParams) { CallThrottleAndVerifyDeferExpectation( /*expect_defer=*/false, kTestGoogleURL); @@ -181,25 +297,6 @@ /*expect_defer=*/false, kGoogleSubdomainURL); } -TEST_P(GoogleURLLoaderThrottleTest, NoInterceptBoundSessionCookieFresh) { - ConfigureBoundSessionThrottlerParams("google.com", "/", - base::Time::Now() + base::Minutes(10)); - CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/false, kGoogleSubdomainURL); -} - -TEST_P(GoogleURLLoaderThrottleTest, NoInterceptDomainNotInBoundSession) { - ConfigureBoundSessionThrottlerParams("google.com", "/", base::Time::Min()); - CallThrottleAndVerifyDeferExpectation(/*expect_defer=*/false, - GURL("https://youtube.com")); -} - -TEST_P(GoogleURLLoaderThrottleTest, NoInterceptPathNotInBoundSession) { - ConfigureBoundSessionThrottlerParams("google.com", "/test", - base::Time::Min()); - CallThrottleAndVerifyDeferExpectation(/*expect_defer=*/false, kTestGoogleURL); -} - TEST_F(GoogleURLLoaderThrottleTest, NoInterceptRequestWithSendCookiesFalse) { ConfigureBoundSessionThrottlerParams("google.com", "/", base::Time::Min()); bool defer = false; @@ -220,60 +317,16 @@ BoundSessionRequestThrottledHandler::UnblockAction::kResume); } -TEST_P(GoogleURLLoaderThrottleTest, - InterceptBoundSessionCookieExpiredCookieDomainWithLeadingDot) { - ConfigureBoundSessionThrottlerParams(".google.com", "/", - base::Time::Now() - base::Minutes(10)); - CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/true, GURL("https://google.com/")); - UnblockRequestAndVerifyCallbackAction( - BoundSessionRequestThrottledHandler::UnblockAction::kResume); -} +TEST_P(GoogleURLLoaderThrottleTest, NoInterceptBoundSessionFeatureOff) { + base::test::ScopedFeatureList disable_feature; + disable_feature.InitAndDisableFeature( + switches::kEnableBoundSessionCredentials); -TEST_P(GoogleURLLoaderThrottleTest, - InterceptBoundSessionCookieExpiredCookieDomainWithoutLeadingDot) { ConfigureBoundSessionThrottlerParams("google.com", "/", base::Time::Now() - base::Minutes(10)); CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/true, GURL("https://google.com/")); - UnblockRequestAndVerifyCallbackAction( - BoundSessionRequestThrottledHandler::UnblockAction::kResume); -} - -TEST_P(GoogleURLLoaderThrottleTest, InterceptBoundSessionCookieExpiresNow) { - ConfigureBoundSessionThrottlerParams("google.com", "/", base::Time::Now()); - - CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/true, kGoogleSubdomainURL); - UnblockRequestAndVerifyCallbackAction( - BoundSessionRequestThrottledHandler::UnblockAction::kResume); -} - -TEST_P(GoogleURLLoaderThrottleTest, InterceptBoundSessionPathEmpty) { - ConfigureBoundSessionThrottlerParams("google.com", "", base::Time::Now()); - - CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/true, kGoogleSubdomainURL); - UnblockRequestAndVerifyCallbackAction( - BoundSessionRequestThrottledHandler::UnblockAction::kResume); -} - -TEST_P(GoogleURLLoaderThrottleTest, - NoInterceptRequestURLNotOnBoundSessionPath) { - ConfigureBoundSessionThrottlerParams("google.com", "/test", - base::Time::Now()); - CallThrottleAndVerifyDeferExpectation(/*expect_defer=*/false, kTestGoogleURL); -} - -TEST_P(GoogleURLLoaderThrottleTest, - InterceptRequestURLWithPrefixBoundSessionPath) { - ConfigureBoundSessionThrottlerParams("google.com", "/test", - base::Time::Now()); - CallThrottleAndVerifyDeferExpectation( - /*expect_defer=*/true, - GURL("https://accounts.google.com/test/foo/bar.html")); - UnblockRequestAndVerifyCallbackAction( - BoundSessionRequestThrottledHandler::UnblockAction::kResume); + /*expect_defer=*/false, + GURL("https://accounts.google.com/test/bar.html")); } TEST_P(GoogleURLLoaderThrottleTest, InterceptAndCancelRequest) {
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index fc5ce752..ccc1a6e9b 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -1568,6 +1568,14 @@ inline constexpr char kPrintingEnabled[] = "printing.enabled"; #endif // BUILDFLAG(ENABLE_PRINTING) +#if BUILDFLAG(ENABLE_OOP_PRINTING) +// Boolean controlling whether making platform printing calls from a +// PrintBackend service instead of from the browser process is allowed by +// policy. +inline constexpr char kOopPrintDriversAllowedByPolicy[] = + "printing.oop_print_drivers_allowed_by_policy"; +#endif + // Boolean controlling whether print preview is disabled. inline constexpr char kPrintPreviewDisabled[] = "printing.print_preview_disabled";
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index 83d15f4..9cc63fb 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -143,7 +143,7 @@ "//chrome/common/cart:mojo_bindings", "//chrome/common/net", "//chrome/common/search:mojo_bindings", - "//chrome/renderer/companion/visual_search", + "//chrome/renderer/companion/visual_query", "//chrome/services/speech/buildflags", "//components/autofill/content/renderer", "//components/autofill/core/common:features",
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc index ed1bdc3..0975cc1 100644 --- a/chrome/renderer/accessibility/read_anything_app_model.cc +++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -843,6 +843,8 @@ default_language_code())) { font_choices_.push_back("STIX Two Text"); } - + if (base::Contains(kLanguagesSupportedByAndika, default_language_code())) { + font_choices_.push_back("Andika"); + } return font_choices_; }
diff --git a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc index 7a927ae..1b61898 100644 --- a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc
@@ -1058,8 +1058,8 @@ // English SetLanguageCode("en"); std::vector<std::string> expectedFonts = { - "Poppins", "Sans-serif", "Serif", "Comic Neue", - "Lexend Deca", "EB Garamond", "STIX Two Text"}; + "Poppins", "Sans-serif", "Serif", "Comic Neue", + "Lexend Deca", "EB Garamond", "STIX Two Text", "Andika"}; std::vector<std::string> fonts = GetSupportedFonts(); EXPECT_EQ(fonts.size(), expectedFonts.size()); @@ -1069,7 +1069,8 @@ // Bulgarian SetLanguageCode("bg"); - expectedFonts = {"Sans-serif", "Serif", "EB Garamond", "STIX Two Text"}; + expectedFonts = {"Sans-serif", "Serif", "EB Garamond", "STIX Two Text", + "Andika"}; fonts = GetSupportedFonts(); EXPECT_EQ(fonts.size(), expectedFonts.size());
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index 9c062f4..28d3c9f4 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -29,7 +29,7 @@ #include "chrome/common/open_search_description_document_handler.mojom.h" #include "chrome/common/webui_url_constants.h" #include "chrome/renderer/chrome_content_settings_agent_delegate.h" -#include "chrome/renderer/companion/visual_search/visual_search_classifier_agent.h" +#include "chrome/renderer/companion/visual_query/visual_query_classifier_agent.h" #include "chrome/renderer/media/media_feeds.h" #include "components/crash/core/common/crash_key.h" #include "components/lens/lens_metadata.mojom.h" @@ -201,7 +201,7 @@ #endif #if !BUILDFLAG(IS_ANDROID) - SetVisualSearchClassifierAgent(); + SetVisualQueryClassifierAgent(); #endif translate_agent_ = new translate::TranslateAgent(render_frame, ISOLATED_WORLD_ID_TRANSLATE); @@ -581,10 +581,10 @@ #endif } -void ChromeRenderFrameObserver::SetVisualSearchClassifierAgent() { +void ChromeRenderFrameObserver::SetVisualQueryClassifierAgent() { #if !BUILDFLAG(IS_ANDROID) visual_classifier_ = - companion::visual_search::VisualSearchClassifierAgent::Create( + companion::visual_search::VisualQueryClassifierAgent::Create( render_frame()); #endif }
diff --git a/chrome/renderer/chrome_render_frame_observer.h b/chrome/renderer/chrome_render_frame_observer.h index 39d416e..73e1ecc 100644 --- a/chrome/renderer/chrome_render_frame_observer.h +++ b/chrome/renderer/chrome_render_frame_observer.h
@@ -11,7 +11,7 @@ #include "base/memory/raw_ptr.h" #include "build/build_config.h" #include "chrome/common/chrome_render_frame.mojom.h" -#include "chrome/renderer/companion/visual_search/visual_search_classifier_agent.h" +#include "chrome/renderer/companion/visual_query/visual_query_classifier_agent.h" #include "components/safe_browsing/buildflags.h" #include "content/public/renderer/render_frame_observer.h" #include "mojo/public/cpp/bindings/associated_receiver_set.h" @@ -111,8 +111,8 @@ // Initialize a |phishing_classifier_delegate_|. void SetClientSidePhishingDetection(); - // Initialize a |visual_search_classifier_agent_|. - void SetVisualSearchClassifierAgent(); + // Initialize a |visual_query_classifier_agent_|. + void SetVisualQueryClassifierAgent(); void OnRenderFrameObserverRequest( mojo::PendingAssociatedReceiver<chrome::mojom::ChromeRenderFrame> @@ -167,8 +167,8 @@ // Save the JavaScript to preload if ExecuteWebUIJavaScript is invoked. std::vector<std::u16string> webui_javascript_; - // Add visual search agent to suggest visually relevant items on the page. - raw_ptr<companion::visual_search::VisualSearchClassifierAgent, + // Add visual query agent to suggest visually relevant items on the page. + raw_ptr<companion::visual_search::VisualQueryClassifierAgent, ExperimentalRenderer> visual_classifier_ = nullptr; #endif
diff --git a/chrome/renderer/companion/visual_search/BUILD.gn b/chrome/renderer/companion/visual_query/BUILD.gn similarity index 79% rename from chrome/renderer/companion/visual_search/BUILD.gn rename to chrome/renderer/companion/visual_query/BUILD.gn index 24145fae..dd3e29e2 100644 --- a/chrome/renderer/companion/visual_search/BUILD.gn +++ b/chrome/renderer/companion/visual_query/BUILD.gn
@@ -4,14 +4,14 @@ import("//build/buildflag_header.gni") -source_set("visual_search") { +source_set("visual_query") { sources = [ - "visual_search_classification_and_eligibility.cc", - "visual_search_classification_and_eligibility.h", - "visual_search_classifier_agent.cc", - "visual_search_classifier_agent.h", - "visual_search_eligibility.cc", - "visual_search_eligibility.h", + "visual_query_classification_and_eligibility.cc", + "visual_query_classification_and_eligibility.h", + "visual_query_classifier_agent.cc", + "visual_query_classifier_agent.h", + "visual_query_eligibility.cc", + "visual_query_eligibility.h", ] deps = [ "//base", @@ -35,11 +35,11 @@ source_set("unit_tests") { testonly = true sources = [ - "visual_search_classification_and_eligibility_unittest.cc", - "visual_search_eligibility_unittest.cc", + "visual_query_classification_and_eligibility_unittest.cc", + "visual_query_eligibility_unittest.cc", ] deps = [ - ":visual_search", + ":visual_query", "//base", "//base/test:test_support", "//chrome/common/companion:mojo_bindings", @@ -60,9 +60,9 @@ source_set("browser_tests") { testonly = true - sources = [ "visual_search_classifier_agent_browsertest.cc" ] + sources = [ "visual_query_classifier_agent_browsertest.cc" ] deps = [ - ":visual_search", + ":visual_query", "//base", "//base/test:test_support", "//chrome/common",
diff --git a/chrome/renderer/companion/visual_search/DEPS b/chrome/renderer/companion/visual_query/DEPS similarity index 100% rename from chrome/renderer/companion/visual_search/DEPS rename to chrome/renderer/companion/visual_query/DEPS
diff --git a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.cc b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.cc similarity index 98% rename from chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.cc rename to chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.cc index 8584fd8a..0cbe465d 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.cc +++ b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h" #include "base/logging.h" #include "base/memory/ptr_util.h"
diff --git a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h similarity index 91% rename from chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h rename to chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h index 49c56fae..516edc9 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h +++ b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_CLASSIFICATION_AND_ELIGIBILITY_H_ -#define CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_CLASSIFICATION_AND_ELIGIBILITY_H_ +#ifndef CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_CLASSIFICATION_AND_ELIGIBILITY_H_ +#define CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_CLASSIFICATION_AND_ELIGIBILITY_H_ -#include "chrome/renderer/companion/visual_search/visual_search_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_eligibility.h" #include "components/optimization_guide/proto/visual_search_model_metadata.pb.h" #include "third_party/blink/public/web/web_element.h" #include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/vision/image_classifier.h"
diff --git a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility_unittest.cc b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility_unittest.cc similarity index 98% rename from chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility_unittest.cc rename to chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility_unittest.cc index 2a4fe9a8..91e95859 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility_unittest.cc +++ b/chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h" #include "base/files/file_util.h" #include "base/path_service.h"
diff --git a/chrome/renderer/companion/visual_search/visual_search_classifier_agent.cc b/chrome/renderer/companion/visual_query/visual_query_classifier_agent.cc similarity index 89% rename from chrome/renderer/companion/visual_search/visual_search_classifier_agent.cc rename to chrome/renderer/companion/visual_query/visual_query_classifier_agent.cc index f0bfc81..ca596ac 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classifier_agent.cc +++ b/chrome/renderer/companion/visual_query/visual_query_classifier_agent.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/companion/visual_search/visual_search_classifier_agent.h" +#include "chrome/renderer/companion/visual_query/visual_query_classifier_agent.h" #include "base/feature_list.h" #include "base/files/file.h" @@ -15,7 +15,7 @@ #include "base/task/thread_pool.h" #include "chrome/common/companion/visual_search.mojom.h" #include "chrome/common/companion/visual_search/features.h" -#include "chrome/renderer/companion/visual_search/visual_search_classification_and_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_classification_and_eligibility.h" #include "components/optimization_guide/proto/visual_search_model_metadata.pb.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" @@ -171,7 +171,7 @@ } // namespace -VisualSearchClassifierAgent::VisualSearchClassifierAgent( +VisualQueryClassifierAgent::VisualQueryClassifierAgent( content::RenderFrame* render_frame) : content::RenderFrameObserver(render_frame) { if (render_frame) { @@ -179,20 +179,20 @@ render_frame->GetAssociatedInterfaceRegistry() ->AddInterface<mojom::VisualSuggestionsRequestHandler>( base::BindRepeating( - &VisualSearchClassifierAgent::OnRendererAssociatedRequest, + &VisualQueryClassifierAgent::OnRendererAssociatedRequest, base::Unretained(this))); } } -VisualSearchClassifierAgent::~VisualSearchClassifierAgent() = default; +VisualQueryClassifierAgent::~VisualQueryClassifierAgent() = default; // static -VisualSearchClassifierAgent* VisualSearchClassifierAgent::Create( +VisualQueryClassifierAgent* VisualQueryClassifierAgent::Create( content::RenderFrame* render_frame) { - return new VisualSearchClassifierAgent(render_frame); + return new VisualQueryClassifierAgent(render_frame); } -void VisualSearchClassifierAgent::StartVisualClassification( +void VisualQueryClassifierAgent::StartVisualClassification( base::File visual_model, const std::string& config_proto, mojo::PendingRemote<mojom::VisualSuggestionsResultHandler> result_handler) { @@ -209,7 +209,7 @@ is_retrying_ = true; base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, - base::BindOnce(&VisualSearchClassifierAgent::StartVisualClassification, + base::BindOnce(&VisualQueryClassifierAgent::StartVisualClassification, weak_ptr_factory_.GetWeakPtr(), std::move(visual_model), std::move(config_proto), std::move(result_handler)), features::StartClassificationRetryDuration()); @@ -226,14 +226,14 @@ if (is_classifying_) { LOCAL_HISTOGRAM_BOOLEAN( - "Companion.VisualSearch.Agent.OngoingClassificationFailure", + "Companion.VisualQuery.Agent.OngoingClassificationFailure", is_classifying_); OnClassificationDone(std::move(empty_results)); return; } if (!visual_model.IsValid()) { - LOCAL_HISTOGRAM_BOOLEAN("Companion.VisualSearch.Agent.InvalidModelFailure", + LOCAL_HISTOGRAM_BOOLEAN("Companion.VisualQuery.Agent.InvalidModelFailure", !visual_model.IsValid()); OnClassificationDone(std::move(empty_results)); return; @@ -241,7 +241,7 @@ if (!visual_model_.IsValid() && !visual_model_.Initialize(std::move(visual_model))) { - LOCAL_HISTOGRAM_BOOLEAN("Companion.VisualSearch.Agent.InitModelFailure", + LOCAL_HISTOGRAM_BOOLEAN("Companion.VisualQuery.Agent.InitModelFailure", true); OnClassificationDone(std::move(empty_results)); return; @@ -261,11 +261,11 @@ base::BindOnce(&ClassifyImagesOnBackground, std::move(dom_images), std::move(model_data), std::move(config_proto), viewport_size), - base::BindOnce(&VisualSearchClassifierAgent::OnClassificationDone, + base::BindOnce(&VisualQueryClassifierAgent::OnClassificationDone, weak_ptr_factory_.GetWeakPtr())); } -void VisualSearchClassifierAgent::OnClassificationDone( +void VisualQueryClassifierAgent::OnClassificationDone( ClassificationResultsAndStats results) { is_classifying_ = false; is_retrying_ = false; @@ -290,14 +290,14 @@ results.first.size()); } -void VisualSearchClassifierAgent::OnRendererAssociatedRequest( +void VisualQueryClassifierAgent::OnRendererAssociatedRequest( mojo::PendingAssociatedReceiver<mojom::VisualSuggestionsRequestHandler> receiver) { receiver_.reset(); receiver_.Bind(std::move(receiver)); } -void VisualSearchClassifierAgent::DidFinishLoad() { +void VisualQueryClassifierAgent::DidFinishLoad() { if (!features::IsVisualSearchSuggestionsAgentEnabled()) { return; } @@ -311,14 +311,14 @@ if (model_provider_.is_bound()) { model_provider_->GetModelWithMetadata( - base::BindOnce(&VisualSearchClassifierAgent::HandleGetModelCallback, + base::BindOnce(&VisualQueryClassifierAgent::HandleGetModelCallback, weak_ptr_factory_.GetWeakPtr())); LOCAL_HISTOGRAM_BOOLEAN( "Companion.VisualQuery.Agent.ModelRequestSentSuccess", true); } } -void VisualSearchClassifierAgent::HandleGetModelCallback( +void VisualQueryClassifierAgent::HandleGetModelCallback( base::File file, const std::string& config) { // Now that we have the result, we can unbind and reset the receiver pipe. @@ -328,7 +328,7 @@ StartVisualClassification(std::move(file), config, std::move(result_handler)); } -void VisualSearchClassifierAgent::OnDestruct() { +void VisualQueryClassifierAgent::OnDestruct() { if (render_frame_) { render_frame_->GetAssociatedInterfaceRegistry()->RemoveInterface( mojom::VisualSuggestionsRequestHandler::Name_);
diff --git a/chrome/renderer/companion/visual_search/visual_search_classifier_agent.h b/chrome/renderer/companion/visual_query/visual_query_classifier_agent.h similarity index 80% rename from chrome/renderer/companion/visual_search/visual_search_classifier_agent.h rename to chrome/renderer/companion/visual_query/visual_query_classifier_agent.h index 4846fdc..c1cbdbe 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classifier_agent.h +++ b/chrome/renderer/companion/visual_query/visual_query_classifier_agent.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_CLASSIFIER_AGENT_H_ -#define CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_CLASSIFIER_AGENT_H_ +#ifndef CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_CLASSIFIER_AGENT_H_ +#define CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_CLASSIFIER_AGENT_H_ #include "base/files/file.h" #include "base/files/memory_mapped_file.h" @@ -11,7 +11,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/common/companion/visual_search.mojom.h" -#include "chrome/renderer/companion/visual_search/visual_search_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_eligibility.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "mojo/public/cpp/bindings/associated_receiver.h" @@ -24,17 +24,17 @@ std::pair<std::vector<SingleImageFeaturesAndBytes>, mojom::ClassificationStatsPtr>; -class VisualSearchClassifierAgent : public content::RenderFrameObserver, +class VisualQueryClassifierAgent : public content::RenderFrameObserver, mojom::VisualSuggestionsRequestHandler { public: - static VisualSearchClassifierAgent* Create( + static VisualQueryClassifierAgent* Create( content::RenderFrame* render_frame); - VisualSearchClassifierAgent(const VisualSearchClassifierAgent&) = delete; - VisualSearchClassifierAgent& operator=(const VisualSearchClassifierAgent&) = + VisualQueryClassifierAgent(const VisualQueryClassifierAgent&) = delete; + VisualQueryClassifierAgent& operator=(const VisualQueryClassifierAgent&) = delete; - ~VisualSearchClassifierAgent() override; + ~VisualQueryClassifierAgent() override; // RenderFrameObserver implementation: void OnDestruct() override; @@ -56,7 +56,7 @@ receiver); private: - explicit VisualSearchClassifierAgent(content::RenderFrame* render_frame); + explicit VisualQueryClassifierAgent(content::RenderFrame* render_frame); // Private method used to post result from long-running visual classification // tasks that runs in the background thread. This method should run in the @@ -91,9 +91,9 @@ mojo::Remote<mojom::VisualSuggestionsModelProvider> model_provider_; // Pointer factory necessary for scheduling tasks on different threads. - base::WeakPtrFactory<VisualSearchClassifierAgent> weak_ptr_factory_{this}; + base::WeakPtrFactory<VisualQueryClassifierAgent> weak_ptr_factory_{this}; }; } // namespace companion::visual_search -#endif // CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_CLASSIFIER_AGENT_H_ +#endif // CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_CLASSIFIER_AGENT_H_
diff --git a/chrome/renderer/companion/visual_search/visual_search_classifier_agent_browsertest.cc b/chrome/renderer/companion/visual_query/visual_query_classifier_agent_browsertest.cc similarity index 92% rename from chrome/renderer/companion/visual_search/visual_search_classifier_agent_browsertest.cc rename to chrome/renderer/companion/visual_query/visual_query_classifier_agent_browsertest.cc index f917a6ae..d9fc09f 100644 --- a/chrome/renderer/companion/visual_search/visual_search_classifier_agent_browsertest.cc +++ b/chrome/renderer/companion/visual_query/visual_query_classifier_agent_browsertest.cc
@@ -17,7 +17,7 @@ #include "base/test/test_timeouts.h" #include "chrome/common/companion/visual_search.mojom.h" #include "chrome/common/companion/visual_search/features.h" -#include "chrome/renderer/companion/visual_search/visual_search_classifier_agent.h" +#include "chrome/renderer/companion/visual_query/visual_query_classifier_agent.h" #include "chrome/test/base/chrome_render_view_test.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -102,16 +102,16 @@ mojo::ReceiverSet<mojom::VisualSuggestionsModelProvider> receivers_; }; -class VisualSearchClassifierAgentTest : public ChromeRenderViewTest { +class VisualQueryClassifierAgentTest : public ChromeRenderViewTest { public: - VisualSearchClassifierAgentTest() = default; + VisualQueryClassifierAgentTest() = default; void SetUp() override { ChromeRenderViewTest::SetUp(); content::RenderFrame* render_frame = GetMainRenderFrame(); render_frame->GetAssociatedInterfaceRegistry()->RemoveInterface( mojom::VisualSuggestionsRequestHandler::Name_); - agent_ = VisualSearchClassifierAgent::Create(render_frame); + agent_ = VisualQueryClassifierAgent::Create(render_frame); model_file_ = LoadModelFile(model_file_path()); base::DiscardableMemoryAllocator::SetInstance(&test_allocator_); render_frame->GetBrowserInterfaceBroker()->SetBinderForTesting( @@ -162,7 +162,7 @@ } protected: - raw_ptr<VisualSearchClassifierAgent, DanglingUntriaged> + raw_ptr<VisualQueryClassifierAgent, DanglingUntriaged> agent_; // Owned by RenderFrame base::HistogramTester histogram_tester_; TestVisualResultHandler test_handler_; @@ -172,7 +172,7 @@ FakeModelProvider fake_provider_; }; -TEST_F(VisualSearchClassifierAgentTest, +TEST_F(VisualQueryClassifierAgentTest, StartClassification_SingleImageNonShoppy) { LoadHtmlWithSingleImage(); agent_->StartVisualClassification(model_file_.Duplicate(), "", @@ -187,7 +187,7 @@ } } -TEST_F(VisualSearchClassifierAgentTest, +TEST_F(VisualQueryClassifierAgentTest, StartClassification_SingleImageNonShoppy_AgentEnabled) { SetUpFeatureList(); LoadHtmlWithSingleImage(); @@ -205,7 +205,7 @@ } } -TEST_F(VisualSearchClassifierAgentTest, StartClassification_NoImages) { +TEST_F(VisualQueryClassifierAgentTest, StartClassification_NoImages) { std::string html = "<html><body>dummy</body></html>"; LoadHTML(html.c_str()); agent_->StartVisualClassification(model_file_.Duplicate(), "", @@ -224,7 +224,7 @@ } } -TEST_F(VisualSearchClassifierAgentTest, StartClassification_InvalidModel) { +TEST_F(VisualQueryClassifierAgentTest, StartClassification_InvalidModel) { base::File file; LoadHtmlWithSingleImage(); agent_->StartVisualClassification(file.Duplicate(), "", @@ -232,6 +232,6 @@ base::RunLoop().RunUntilIdle(); EXPECT_CALL(test_handler_, HandleClassification(_, _)).Times(0); histogram_tester_.ExpectBucketCount( - "Companion.VisualSearch.Agent.InvalidModelFailure", true, 1); + "Companion.VisualQuery.Agent.InvalidModelFailure", true, 1); } } // namespace companion::visual_search
diff --git a/chrome/renderer/companion/visual_search/visual_search_eligibility.cc b/chrome/renderer/companion/visual_query/visual_query_eligibility.cc similarity index 99% rename from chrome/renderer/companion/visual_search/visual_search_eligibility.cc rename to chrome/renderer/companion/visual_query/visual_query_eligibility.cc index bf701877..8cdc06e 100644 --- a/chrome/renderer/companion/visual_search/visual_search_eligibility.cc +++ b/chrome/renderer/companion/visual_query/visual_query_eligibility.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/companion/visual_search/visual_search_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_eligibility.h" #include <algorithm> #include <cmath>
diff --git a/chrome/renderer/companion/visual_search/visual_search_eligibility.h b/chrome/renderer/companion/visual_query/visual_query_eligibility.h similarity index 97% rename from chrome/renderer/companion/visual_search/visual_search_eligibility.h rename to chrome/renderer/companion/visual_query/visual_query_eligibility.h index 8ee02b7e..a0e7b2d 100644 --- a/chrome/renderer/companion/visual_search/visual_search_eligibility.h +++ b/chrome/renderer/companion/visual_query/visual_query_eligibility.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_ELIGIBILITY_H_ -#define CHROME_RENDERER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_ELIGIBILITY_H_ +#ifndef CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_ELIGIBILITY_H_ +#define CHROME_RENDERER_COMPANION_VISUAL_QUERY_VISUAL_QUERY_ELIGIBILITY_H_ #include <algorithm> #include <limits>
diff --git a/chrome/renderer/companion/visual_search/visual_search_eligibility_unittest.cc b/chrome/renderer/companion/visual_query/visual_query_eligibility_unittest.cc similarity index 99% rename from chrome/renderer/companion/visual_search/visual_search_eligibility_unittest.cc rename to chrome/renderer/companion/visual_query/visual_query_eligibility_unittest.cc index 003964d3..186f339 100644 --- a/chrome/renderer/companion/visual_search/visual_search_eligibility_unittest.cc +++ b/chrome/renderer/companion/visual_query/visual_query_eligibility_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/companion/visual_search/visual_search_eligibility.h" +#include "chrome/renderer/companion/visual_query/visual_query_eligibility.h" #include "base/test/metrics/histogram_tester.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 3d2925c..0f7cd4c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1713,7 +1713,7 @@ "//chrome/common/companion/visual_search:flags", "//chrome/common/privacy_budget:test_support", "//chrome/renderer", - "//chrome/renderer/companion/visual_search:browser_tests", + "//chrome/renderer/companion/visual_query:browser_tests", "//chrome/services/qrcode_generator/public/cpp", "//chrome/services/qrcode_generator/public/mojom", "//chrome/services/removable_storage_writer:lib", @@ -3065,11 +3065,12 @@ if (enable_printing) { sources += [ "../browser/pdf/pdf_extension_printing_test.cc" ] - # TODO(crbug.com/1414651): All printToPdf tests consistenly fail on ChromeOS + # TODO(crbug.com/1414651): All printToPdf tests consistently fail on ChromeOS if (!is_chromeos) { sources += [ "../browser/devtools/protocol/devtools_printtopdf_browsertest.cc", ] + deps += [ "//components/printing/browser" ] } } } @@ -6734,7 +6735,7 @@ "//chrome/common/profiler:unit_tests", "//chrome/common/themes:autogenerated_theme_util", "//chrome/common/themes:unit_tests", - "//chrome/renderer/companion/visual_search:unit_tests", + "//chrome/renderer/companion/visual_query:unit_tests", "//chrome/services/file_util:unit_tests", "//chrome/services/qrcode_generator/public/cpp", "//components/account_id",
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_recent_wallpapers_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_recent_wallpapers_element_test.ts index 5900852..a42972ddf 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_recent_wallpapers_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_recent_wallpapers_element_test.ts
@@ -11,17 +11,17 @@ import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js'; import {TestPersonalizationStore} from './test_personalization_store.js'; -import {TestWallpaperProvider} from './test_wallpaper_interface_provider.js'; +import {TestSeaPenProvider} from './test_sea_pen_interface_provider.js'; suite('SeaPenRecentWallpapersElementTest', function() { let personalizationStore: TestPersonalizationStore; - let wallpaperProvider: TestWallpaperProvider; + let seaPenProvider: TestSeaPenProvider; let seaPenRecentWallpapersElement: SeaPenRecentWallpapersElement|null; setup(() => { const mocks = baseSetup(); personalizationStore = mocks.personalizationStore; - wallpaperProvider = mocks.wallpaperProvider; + seaPenProvider = mocks.seaPenProvider; }); teardown(async () => { @@ -31,7 +31,7 @@ test('displays recently used Sea Pen wallpapers', async () => { personalizationStore.data.wallpaper.seaPen.recentWallpapers = - wallpaperProvider.seaPenWallpapers; + seaPenProvider.seaPenWallpapers; // Initialize |seaPenRecentWallpapersElement|. seaPenRecentWallpapersElement = initElement(SeaPenRecentWallpapersElement); @@ -65,7 +65,7 @@ test('opens menu options for a Sea Pen wallpaper', async () => { personalizationStore.data.wallpaper.seaPen.recentWallpapers = - wallpaperProvider.seaPenWallpapers; + seaPenProvider.seaPenWallpapers; // Initialize |seaPenRecentWallpapersElement|. seaPenRecentWallpapersElement = initElement(SeaPenRecentWallpapersElement); @@ -105,7 +105,7 @@ 'selects Wallpaper Info menu option for a Sea Pen wallpaper', async () => { personalizationStore.data.wallpaper.seaPen.recentWallpapers = - wallpaperProvider.seaPenWallpapers; + seaPenProvider.seaPenWallpapers; // Initialize |seaPenRecentWallpapersElement|. seaPenRecentWallpapersElement = @@ -171,4 +171,27 @@ 'wallpaperInfoDialog'), 'no Wallpaper Info dialog after close button clicked'); }); + + test('clicks on a recent wallpaper to set wallpaper', async () => { + personalizationStore.data.wallpaper.seaPen.recentWallpapers = + seaPenProvider.seaPenWallpapers; + + // Initialize |seaPenRecentWallpapersElement|. + seaPenRecentWallpapersElement = initElement(SeaPenRecentWallpapersElement); + await waitAfterNextRender(seaPenRecentWallpapersElement); + + // Sea Pen wallpaper thumbnails should display. + const recentWallpapers = + seaPenRecentWallpapersElement.shadowRoot!.querySelectorAll( + 'div:not([hidden]) .recent-wallpaper'); + assertEquals(3, recentWallpapers!.length, 'should be 3 images available.'); + + // Click on the second image to set it as wallpaper. + (recentWallpapers[1] as HTMLElement)!.click(); + + const filePath = await seaPenProvider.whenCalled('selectRecentSeaPenImage'); + assertEquals( + seaPenProvider.seaPenWallpapers[1]!.file_path, filePath, + 'file_path sent for the second Sea Pen image'); + }); });
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_sea_pen_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_sea_pen_interface_provider.ts index 0ee7128..2d51602 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_sea_pen_interface_provider.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_sea_pen_interface_provider.ts
@@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {SeaPenProviderInterface, SeaPenThumbnail} from 'chrome://personalization/js/personalization_app.js'; +import {SeaPenProviderInterface, SeaPenThumbnail, SeaPenWallpaper} from 'chrome://personalization/js/personalization_app.js'; +import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; export class TestSeaPenProvider extends TestBrowserProxy implements @@ -26,10 +27,30 @@ }, ]; + seaPenWallpapers: SeaPenWallpaper[] = [ + { + query_info: 'a close up of a flower with water drops on it', + url: {url: 'https://images.googleusercontent.com/image_1.jpg'}, + file_path: {path: '/sea_pen/image_1.jpg'}, + }, + { + query_info: + 'a large white ball in the middle of a field with soap bubbles', + url: {url: 'https://images.googleusercontent.com/image_2.jpg'}, + file_path: {'path': '/sea_pen/image_2.jpg'}, + }, + { + query_info: 'a large rock sitting on top of a hill in the desert', + url: {url: 'https://images.googleusercontent.com/image_3.jpg'}, + file_path: {'path': '/sea_pen/image_3.jpg'}, + }, + ]; + constructor() { super([ 'searchWallpaper', 'selectSeaPenThumbnail', + 'selectRecentSeaPenImage', ]); } @@ -42,4 +63,9 @@ this.methodCalled('selectSeaPenThumbnail', id); return Promise.resolve({success: true}); } + + selectRecentSeaPenImage(filePath: FilePath) { + this.methodCalled('selectRecentSeaPenImage', filePath); + return Promise.resolve({success: true}); + } }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts index 690a4c7..27fd3c9 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CurrentAttribution, CurrentWallpaper, DefaultImageSymbol, GooglePhotosAlbum, GooglePhotosEnablementState, GooglePhotosPhoto, kDefaultImageSymbol, OnlineImageType, SeaPenWallpaper, WallpaperCollection, WallpaperImage, WallpaperLayout, WallpaperObserverInterface, WallpaperObserverRemote, WallpaperProviderInterface, WallpaperType} from 'chrome://personalization/js/personalization_app.js'; +import {CurrentAttribution, CurrentWallpaper, DefaultImageSymbol, GooglePhotosAlbum, GooglePhotosEnablementState, GooglePhotosPhoto, kDefaultImageSymbol, OnlineImageType, WallpaperCollection, WallpaperImage, WallpaperLayout, WallpaperObserverInterface, WallpaperObserverRemote, WallpaperProviderInterface, WallpaperType} from 'chrome://personalization/js/personalization_app.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; @@ -156,24 +156,6 @@ this.collectionId = this.collections_![0]!.id; this.timeOfDayCollectionId = this.collections_![3]!.id; - this.seaPenWallpapers = [ - { - query_info: 'a close up of a flower with water drops on it', - url: {url: 'https://images.googleusercontent.com/image_1.jpg'}, - file_path: {path: '/sea_pen/image_1.jpg'}, - }, - { - query_info: - 'a large white ball in the middle of a field with soap bubbles', - url: {url: 'https://images.googleusercontent.com/image_2.jpg'}, - file_path: {'path': '/sea_pen/image_2.jpg'}, - }, - { - query_info: 'a large rock sitting on top of a hill in the desert', - url: {url: 'https://images.googleusercontent.com/image_3.jpg'}, - file_path: {'path': '/sea_pen/image_3.jpg'}, - }, - ]; } private collections_: WallpaperCollection[]|null; @@ -200,7 +182,6 @@ collectionId: string; setDailyRefreshCollectionIdResponse = {success: false}; timeOfDayCollectionId: string; - seaPenWallpapers: SeaPenWallpaper[]; selectWallpaperResponse = true; selectGooglePhotosPhotoResponse = true; selectGooglePhotosAlbumResponse = true;
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/customize_button_select_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/customize_button_select_test.ts index 79eee90..d7bb42a 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/customize_button_select_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/customize_button_select_test.ts
@@ -93,7 +93,9 @@ await flushTasks(); assertEquals(getSelectedValue(), 'key combination'); - assertEquals(select.get('label_'), 'ctrl + z'); + assertTrue(select.get('remappedToKeyCombination_')); + assertEquals(select.get('label_'), 'Key combination'); + assertDeepEquals(select.get('inputKeys_'), ['ctrl', '+', 'z']); // Switch to another button remapping. select.set( @@ -103,7 +105,9 @@ await flushTasks(); assertEquals(getSelectedValue(), 'key combination'); - assertEquals(select.get('label_'), 'ctrl + v'); + assertTrue(select.get('remappedToKeyCombination_')); + assertEquals(select.get('label_'), 'Key combination'); + assertDeepEquals(select.get('inputKeys_'), ['ctrl', '+', 'v']); }); test('update dropdown will sent events', async () => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/supported_fonts.js b/chrome/test/data/webui/side_panel/read_anything/supported_fonts.js index 1804e3d..423eda9 100644 --- a/chrome/test/data/webui/side_panel/read_anything/supported_fonts.js +++ b/chrome/test/data/webui/side_panel/read_anything/supported_fonts.js
@@ -35,11 +35,11 @@ assertEquals(buttons.length, expected); }; - assertFontForLanguageCode('en', 7); - assertFontForLanguageCode('es', 7); + assertFontForLanguageCode('en', 8); + assertFontForLanguageCode('es', 8); assertFontForLanguageCode('zz', 2); assertFontForLanguageCode('hi', 3); - assertFontForLanguageCode('tr', 6); + assertFontForLanguageCode('tr', 7); return result; })();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js index 3ccf571..91aad415 100644 --- a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js +++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
@@ -52,5 +52,8 @@ chrome.readingMode.setThemeForTesting('STIX Two Text', 18.0, 0, 0, 1, 0); assertFontName('"STIX Two Text"'); + chrome.readingMode.setThemeForTesting('Andika', 18.0, 0, 0, 1, 0); + assertFontName('Andika'); + return result; })();
diff --git a/chrome/test/supervised_user/family_member.cc b/chrome/test/supervised_user/family_member.cc index 2874a2a..b2af66f9 100644 --- a/chrome/test/supervised_user/family_member.cc +++ b/chrome/test/supervised_user/family_member.cc
@@ -9,12 +9,14 @@ #include "base/containers/flat_map.h" #include "base/strings/strcat.h" #include "base/test/bind.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/e2e_tests/test_accounts_util.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "chrome/browser/ui/browser.h" #include "components/signin/public/base/consent_level.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" #include "google_apis/gaia/core_account_id.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -28,7 +30,7 @@ supervised_user::SupervisedUserService* supervised_user_service = SupervisedUserServiceFactory::GetForProfile(profile); CHECK(supervised_user_service) << "Incognito mode is not supported."; - CHECK(supervised_user_service->IsURLFilteringEnabled()) + CHECK(supervised_user::IsUrlFilteringEnabled(*profile->GetPrefs())) << "Blocklist control page is only available to user who have that " "feature enabled. Check if member is a subject to parental controls.";
diff --git a/chromeos/ash/components/demo_mode/BUILD.gn b/chromeos/ash/components/demo_mode/BUILD.gn new file mode 100644 index 0000000..ce71e9c --- /dev/null +++ b/chromeos/ash/components/demo_mode/BUILD.gn
@@ -0,0 +1,21 @@ +# 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. +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //ash") + +component("demo_mode") { + sources = [ + "utils/dimensions_utils.cc", + "utils/dimensions_utils.h", + ] + + deps = [ + "//base", + "//third_party/abseil-cpp:absl", + "//third_party/icu", + ] + + defines = [ "IS_CHROMEOS_ASH_COMPONENTS_DEMO_MODE_IMPL" ] +}
diff --git a/chromeos/ash/components/demo_mode/COMMON_METADATA b/chromeos/ash/components/demo_mode/COMMON_METADATA new file mode 100644 index 0000000..e8e28f5 --- /dev/null +++ b/chromeos/ash/components/demo_mode/COMMON_METADATA
@@ -0,0 +1,4 @@ +team_email: "cros-demo-mode-eng@google.com" +buganizer: { + component_id:812312 +} \ No newline at end of file
diff --git a/chromeos/ash/components/demo_mode/DEPS b/chromeos/ash/components/demo_mode/DEPS new file mode 100644 index 0000000..b201104 --- /dev/null +++ b/chromeos/ash/components/demo_mode/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+base", + "+third_party/icu", +] \ No newline at end of file
diff --git a/chromeos/ash/components/demo_mode/DIR_METADATA b/chromeos/ash/components/demo_mode/DIR_METADATA new file mode 100644 index 0000000..c6f72ef6 --- /dev/null +++ b/chromeos/ash/components/demo_mode/DIR_METADATA
@@ -0,0 +1 @@ +mixins: "//chromeos/ash/components/demo_mode/COMMON_METADATA" \ No newline at end of file
diff --git a/chromeos/ash/components/demo_mode/OWNERS b/chromeos/ash/components/demo_mode/OWNERS new file mode 100644 index 0000000..e7bdf3a --- /dev/null +++ b/chromeos/ash/components/demo_mode/OWNERS
@@ -0,0 +1,3 @@ +llin@chromium.org +xiqiruan@chromium.org +yilkal@chromium.org \ No newline at end of file
diff --git a/chromeos/ash/components/demo_mode/utils/dimensions_utils.cc b/chromeos/ash/components/demo_mode/utils/dimensions_utils.cc new file mode 100644 index 0000000..454f624d --- /dev/null +++ b/chromeos/ash/components/demo_mode/utils/dimensions_utils.cc
@@ -0,0 +1,29 @@ +// 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 "chromeos/ash/components/demo_mode/utils/dimensions_utils.h" + +#include "third_party/abseil-cpp/absl/strings/ascii.h" +#include "third_party/icu/source/common/unicode/bytestream.h" +#include "third_party/icu/source/common/unicode/casemap.h" + +namespace ash::demo_mode { + +std::string CanonicalizeDimension(const std::string& dimension_value) { + std::string canonicalized_value; + + icu::StringByteSink<std::string> byte_sink(&canonicalized_value); + UErrorCode error_code = U_ZERO_ERROR; + icu::CaseMap::utf8Fold(/* options= */ 0, dimension_value, byte_sink, + /* edits= */ nullptr, error_code); + canonicalized_value.erase( + std::remove_if(canonicalized_value.begin(), canonicalized_value.end(), + [](unsigned char c) { + return absl::ascii_ispunct(c) || absl::ascii_isspace(c); + }), + canonicalized_value.end()); + return canonicalized_value; +} + +} // namespace ash::demo_mode
diff --git a/chromeos/ash/components/demo_mode/utils/dimensions_utils.h b/chromeos/ash/components/demo_mode/utils/dimensions_utils.h new file mode 100644 index 0000000..d243c1a --- /dev/null +++ b/chromeos/ash/components/demo_mode/utils/dimensions_utils.h
@@ -0,0 +1,19 @@ +// 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 CHROMEOS_ASH_COMPONENTS_DEMO_MODE_UTILS_DIMENSIONS_UTILS_H_ +#define CHROMEOS_ASH_COMPONENTS_DEMO_MODE_UTILS_DIMENSIONS_UTILS_H_ + +#include <string> + +#include "base/component_export.h" + +namespace ash::demo_mode { + +COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_DEMO_MODE) +std::string CanonicalizeDimension(const std::string& dimension_value); + +} // namespace ash::demo_mode + +#endif // CHROMEOS_ASH_COMPONENTS_DEMO_MODE_UTILS_DIMENSIONS_UTILS_H_
diff --git a/chromeos/ash/components/growth/BUILD.gn b/chromeos/ash/components/growth/BUILD.gn index a733e53..a1f2866 100644 --- a/chromeos/ash/components/growth/BUILD.gn +++ b/chromeos/ash/components/growth/BUILD.gn
@@ -22,6 +22,7 @@ deps = [ "//ash/constants", "//base", + "//chromeos/ash/components/demo_mode", "//components/prefs", "//components/version_info", ]
diff --git a/chromeos/ash/components/growth/DEPS b/chromeos/ash/components/growth/DEPS index 75cc514..9ac60b8 100644 --- a/chromeos/ash/components/growth/DEPS +++ b/chromeos/ash/components/growth/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+ash/constants", "+base", + "+chromeos/ash/components/demo_mode", "+components/prefs", "+components/version_info", ] \ No newline at end of file
diff --git a/chromeos/ash/components/growth/campaigns_manager_unittest.cc b/chromeos/ash/components/growth/campaigns_manager_unittest.cc index b3d4888..ae24270 100644 --- a/chromeos/ash/components/growth/campaigns_manager_unittest.cc +++ b/chromeos/ash/components/growth/campaigns_manager_unittest.cc
@@ -371,6 +371,34 @@ ASSERT_EQ(nullptr, campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); } +TEST_F(CampaignsManagerTest, GetDemoModeCampaignCanonicalizedRetailerId) { + LoadComponentAndVerifyLoadComplete( + base::StringPrintf(kValidCampaignsFileTemplate, + R"( + "demoMode": { + "retailers": ["best-buy", "best_buy"], + "storeIds": ["2", "4", "6"], + "countries": ["US"], + "capability": { + "isCloudGamingDevice": true, + "isFeatureAwareDevice": true + } + } + )")); + + MockDemoMode( + /*in_demo_mode=*/true, + /*cloud_gaming_device=*/true, + /*feature_aware_device=*/true, + /*store_id=*/"2", + /*retailer_id=*/"bestbuy", + /*country=*/"US"); + + // Verify that the campaign is selected if there is not in demo mode. + VerifyDemoModePayload( + campaigns_manager_->GetCampaignBySlot(Slot::kDemoModeApp)); +} + TEST_F(CampaignsManagerTest, GetDemoModeCampaignCountryMismatch) { LoadComponentAndVerifyLoadComplete( base::StringPrintf(kValidCampaignsFileTemplate, kValidDemoModeTargeting));
diff --git a/chromeos/ash/components/growth/campaigns_matcher.cc b/chromeos/ash/components/growth/campaigns_matcher.cc index f48d052..ae0b009 100644 --- a/chromeos/ash/components/growth/campaigns_matcher.cc +++ b/chromeos/ash/components/growth/campaigns_matcher.cc
@@ -9,6 +9,7 @@ #include "base/containers/contains.h" #include "base/logging.h" #include "base/version.h" +#include "chromeos/ash/components/demo_mode/utils/dimensions_utils.h" #include "chromeos/ash/components/growth/campaigns_manager_client.h" #include "chromeos/ash/components/growth/campaigns_model.h" #include "chromeos/ash/components/growth/growth_metrics.h" @@ -131,6 +132,24 @@ return true; } +bool CampaignsMatcher::MatchRetailers( + const base::Value::List* retailers) const { + if (!retailers) { + return true; + } + + base::Value::List canonicalized_retailers; + for (auto& retailer : *retailers) { + if (retailer.is_string()) { + canonicalized_retailers.Append( + ash::demo_mode::CanonicalizeDimension(retailer.GetString())); + } + } + + return MatchPref(&canonicalized_retailers, ash::prefs::kDemoModeRetailerId, + local_state_); +} + bool CampaignsMatcher::MatchDemoModeAppVersion( const DemoModeTargeting& targeting) const { const auto* min_version = targeting.GetAppMinVersion(); @@ -178,9 +197,8 @@ return false; } - return MatchPref(targeting.GetStoreIds(), ash::prefs::kDemoModeStoreId, - local_state_) && - MatchPref(targeting.GetRetailers(), ash::prefs::kDemoModeRetailerId, + return MatchRetailers(targeting.GetRetailers()) && + MatchPref(targeting.GetStoreIds(), ash::prefs::kDemoModeStoreId, local_state_) && MatchPref(targeting.GetCountries(), ash::prefs::kDemoModeCountry, local_state_);
diff --git a/chromeos/ash/components/growth/campaigns_matcher.h b/chromeos/ash/components/growth/campaigns_matcher.h index 18d2a0d..3fc8f1ad 100644 --- a/chromeos/ash/components/growth/campaigns_matcher.h +++ b/chromeos/ash/components/growth/campaigns_matcher.h
@@ -33,6 +33,7 @@ private: bool MatchDemoModeTier(const DemoModeTargeting& targeting) const; bool MatchDemoModeAppVersion(const DemoModeTargeting& targeting) const; + bool MatchRetailers(const base::Value::List* retailers) const; bool MaybeMatchDemoModeTargeting(const DemoModeTargeting& targeting) const; bool MatchMilestone(const DeviceTargeting& targeting) const; bool MatchDeviceTargeting(const DeviceTargeting& targeting) const;
diff --git a/chromeos/ash/components/network/cellular_policy_handler.cc b/chromeos/ash/components/network/cellular_policy_handler.cc index 1c81fea4..d8d9bb54 100644 --- a/chromeos/ash/components/network/cellular_policy_handler.cc +++ b/chromeos/ash/components/network/cellular_policy_handler.cc
@@ -187,7 +187,6 @@ void CellularPolicyHandler::ProcessRequests() { if (remaining_install_requests_.empty()) { - need_refresh_profile_list_ = true; return; } @@ -294,6 +293,38 @@ return; } + PerformInstallESim(*euicc_path); +} + +void CellularPolicyHandler::PerformInstallESim( + const dbus::ObjectPath& euicc_path) { + base::Value::Dict new_shill_properties = GetNewShillProperties(); + // If iccid is found in policy onc, the installation will be skipped because + // it indicates that the eSIM profile has already been installed before using + // the same SM-DP+ or SM-DS. + const absl::optional<std::string> iccid = GetIccidFromPolicyONC(); + if (iccid) { + const absl::optional<dbus::ObjectPath> profile_path = + FindExistingMatchingESimProfile(*iccid); + if (profile_path) { + NET_LOG(EVENT) << "Found an existing installed profile that matches the " + << "policy eSIM installation request. Configuring a Shill " + << "service for the profile: " + << GetCurrentActivationCode().ToString(); + cellular_esim_installer_->ConfigureESimService( + std::move(new_shill_properties), euicc_path, *profile_path, + base::BindOnce(&CellularPolicyHandler::OnConfigureESimService, + weak_ptr_factory_.GetWeakPtr())); + return; + } + + NET_LOG(EVENT) << "Skip installation because iccid is found in the policy" + << " ONC, this indicates that the eSIM profile has already" + << " been installed."; + PopAndProcessRequests(); + return; + } + if (!HasNonCellularInternetConnectivity()) { NET_LOG(ERROR) << "Failed to install the policy eSIM profile due to missing a " @@ -307,36 +338,6 @@ return; } - if (need_refresh_profile_list_) { - // Profile list for current EUICC may not have been refreshed, so explicitly - // refresh profile list before processing installation requests. - cellular_esim_profile_handler_->RefreshProfileListAndRestoreSlot( - *euicc_path, - base::BindOnce(&CellularPolicyHandler::OnRefreshProfileList, - weak_ptr_factory_.GetWeakPtr(), *euicc_path)); - return; - } - - PerformInstallESim(*euicc_path); -} - -void CellularPolicyHandler::PerformInstallESim( - const dbus::ObjectPath& euicc_path) { - base::Value::Dict new_shill_properties = GetNewShillProperties(); - absl::optional<dbus::ObjectPath> profile_path = - FindExistingMatchingESimProfile(); - if (profile_path) { - NET_LOG(EVENT) << "Found an existing installed profile that matches the " - << "policy eSIM installation request. Configuring a Shill " - << "service for the profile: " - << GetCurrentActivationCode().ToString(); - cellular_esim_installer_->ConfigureESimService( - std::move(new_shill_properties), euicc_path, *profile_path, - base::BindOnce(&CellularPolicyHandler::OnConfigureESimService, - weak_ptr_factory_.GetWeakPtr())); - return; - } - NET_LOG(EVENT) << "Installing policy eSIM profile: " << GetCurrentActivationCode().ToString(); @@ -373,24 +374,6 @@ } } -void CellularPolicyHandler::OnRefreshProfileList( - const dbus::ObjectPath& euicc_path, - std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock) { - if (!inhibit_lock) { - NET_LOG(ERROR) << "Failed to refresh the profile list due to an inhibit " - << "error, path: " << euicc_path.value(); - PerformInstallESim(euicc_path); - return; - } - - need_refresh_profile_list_ = false; - - // Reset the |inhibit_lock| so that the device will be uninhibited - // automatically. - inhibit_lock.reset(); - PerformInstallESim(euicc_path); -} - void CellularPolicyHandler::OnConfigureESimService( absl::optional<dbus::ObjectPath> service_path) { DCHECK(is_installing_); @@ -671,16 +654,21 @@ return remaining_install_requests_.front()->activation_code; } -absl::optional<dbus::ObjectPath> -CellularPolicyHandler::FindExistingMatchingESimProfile() { +absl::optional<std::string> CellularPolicyHandler::GetIccidFromPolicyONC() { const std::string* iccid = policy_util::GetIccidFromONC( remaining_install_requests_.front()->onc_config); - if (!iccid) { + if (!iccid || iccid->empty()) { return absl::nullopt; } + return *iccid; +} + +absl::optional<dbus::ObjectPath> +CellularPolicyHandler::FindExistingMatchingESimProfile( + const std::string& iccid) { for (CellularESimProfile esim_profile : cellular_esim_profile_handler_->GetESimProfiles()) { - if (esim_profile.iccid() == *iccid) { + if (esim_profile.iccid() == iccid) { return esim_profile.path(); } }
diff --git a/chromeos/ash/components/network/cellular_policy_handler.h b/chromeos/ash/components/network/cellular_policy_handler.h index 7adfb0bc..bf90bc4 100644 --- a/chromeos/ash/components/network/cellular_policy_handler.h +++ b/chromeos/ash/components/network/cellular_policy_handler.h
@@ -167,9 +167,6 @@ // connectivity. void PerformInstallESim(const dbus::ObjectPath& euicc_path); - void OnRefreshProfileList( - const dbus::ObjectPath& euicc_path, - std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock); void OnConfigureESimService(absl::optional<dbus::ObjectPath> service_path); void OnInhibitedForRefreshSmdxProfiles( const dbus::ObjectPath& euicc_path, @@ -196,7 +193,10 @@ base::Value::Dict GetNewShillProperties(); const policy_util::SmdxActivationCode& GetCurrentActivationCode() const; - absl::optional<dbus::ObjectPath> FindExistingMatchingESimProfile(); + absl::optional<dbus::ObjectPath> FindExistingMatchingESimProfile( + const std::string& iccid); + // Return absl::nullopt if no or empty iccid is found in the policy ONC. + absl::optional<std::string> GetIccidFromPolicyONC(); bool HasNonCellularInternetConnectivity(); InstallRetryReason HermesResponseStatusToRetryReason( HermesResponseStatus status) const; @@ -220,11 +220,6 @@ bool is_installing_ = false; - // While Hermes is the source of truth for the EUICC state, Chrome maintains a - // cache of the installed eSIM profiles. To ensure we properly detect when a - // profile has already been installed for a particular request we force a - // refresh of the profile cache before each installation. - bool need_refresh_profile_list_ = true; base::circular_deque<std::unique_ptr<InstallPolicyESimRequest>> remaining_install_requests_;
diff --git a/chromeos/ash/components/network/cellular_policy_handler_legacy_unittest.cc b/chromeos/ash/components/network/cellular_policy_handler_legacy_unittest.cc index e597681..5f3a516 100644 --- a/chromeos/ash/components/network/cellular_policy_handler_legacy_unittest.cc +++ b/chromeos/ash/components/network/cellular_policy_handler_legacy_unittest.cc
@@ -219,7 +219,6 @@ chromeos::onc::ReadDictionaryFromJson(onc_json); ASSERT_TRUE(policy.has_value()); cellular_policy_handler_->InstallESim(activation_code, *policy); - FastForwardProfileRefreshDelay(); base::RunLoop().RunUntilIdle(); if (!expect_install_success) {
diff --git a/chromeos/ash/components/network/cellular_policy_handler_unittest.cc b/chromeos/ash/components/network/cellular_policy_handler_unittest.cc index 9d4fa75..7a8971b8 100644 --- a/chromeos/ash/components/network/cellular_policy_handler_unittest.cc +++ b/chromeos/ash/components/network/cellular_policy_handler_unittest.cc
@@ -222,8 +222,6 @@ void InstallProfile(const base::Value::Dict& onc_config) { cellular_policy_handler()->InstallESim(onc_config); base::RunLoop().RunUntilIdle(); - - FastForwardRefreshDelay(); } HermesProfileClient::Properties* FindProfileProperties( @@ -530,8 +528,6 @@ CompleteShillServiceAutoConnect(*onc_config); - EXPECT_EQ(InhibitReason::kRefreshingProfileList, - cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kRequestingAvailableProfiles, cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kInstallingProfile, @@ -594,8 +590,6 @@ CompleteShillServiceAutoConnect(*onc_config); - EXPECT_EQ(InhibitReason::kRefreshingProfileList, - cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kRequestingAvailableProfiles, cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kInstallingProfile, @@ -634,10 +628,6 @@ GenerateCellularPolicy(activation_code)); ASSERT_TRUE(onc_config.has_value()); - // Queue a success result for the call to refresh the profile list. - HermesEuiccClient::Get()->GetTestInterface()->QueueHermesErrorStatus( - HermesResponseStatus::kSuccess); - // Queue a failure result for the SM-DS scan itself. HermesEuiccClient::Get()->GetTestInterface()->QueueHermesErrorStatus( HermesResponseStatus::kErrorUnknown); @@ -684,8 +674,6 @@ CellularInhibitorObserver cellular_inhibitor_observer; InstallProfile(*onc_config); - EXPECT_EQ(InhibitReason::kRefreshingProfileList, - cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kRequestingAvailableProfiles, cellular_inhibitor_observer.PopInhibitReason()); EXPECT_EQ(InhibitReason::kInstallingProfile, @@ -980,9 +968,7 @@ const std::string* iccid = properties->FindString(shill::kIccidProperty); EXPECT_TRUE(iccid && *iccid == kTestProfileIccid0); - cellular_policy_handler()->InstallESim(*onc_config); - - FastForwardRefreshDelay(); + InstallProfile(*onc_config); CompleteShillServiceAutoConnect(*onc_config); @@ -1077,9 +1063,7 @@ base::StringPrintf(kCellularPolicyPattern, base::RandUint64(), "{}")); ASSERT_TRUE(onc_config.has_value()); - cellular_policy_handler()->InstallESim(*onc_config); - - FastForwardRefreshDelay(); + InstallProfile(*onc_config); CheckHistogramState(expected_state); }
diff --git a/chromeos/ash/services/libassistant/public/mojom/platform_delegate.mojom b/chromeos/ash/services/libassistant/public/mojom/platform_delegate.mojom index fe97767..5db3afd 100644 --- a/chromeos/ash/services/libassistant/public/mojom/platform_delegate.mojom +++ b/chromeos/ash/services/libassistant/public/mojom/platform_delegate.mojom
@@ -8,13 +8,16 @@ import "chromeos/ash/services/assistant/public/mojom/assistant_audio_decoder.mojom"; import "chromeos/services/network_config/public/mojom/cros_network_config.mojom"; import "media/mojo/mojom/audio_stream_factory.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "services/device/public/mojom/battery_monitor.mojom"; import "services/device/public/mojom/wake_lock_provider.mojom"; // Delegate that exposes methods to bind platform related functionality. +[RequireContext=sandbox.mojom.Context.kPrivilegedUtility] interface PlatformDelegate { // Requests an Audio Service AudioStreamFactory from the browser. + [AllowedContext=sandbox.mojom.Context.kPrivilegedUtility] BindAudioStreamFactory( pending_receiver<media.mojom.AudioStreamFactory> receiver);
diff --git a/chromeos/ash/services/libassistant/public/mojom/service.mojom b/chromeos/ash/services/libassistant/public/mojom/service.mojom index 0fede8c..2d686aa 100644 --- a/chromeos/ash/services/libassistant/public/mojom/service.mojom +++ b/chromeos/ash/services/libassistant/public/mojom/service.mojom
@@ -18,6 +18,7 @@ import "chromeos/ash/services/libassistant/public/mojom/speech_recognition_observer.mojom"; import "chromeos/ash/services/libassistant/public/mojom/timer_controller.mojom"; import "chromeos/ash/services/libassistant/public/mojom/notification_delegate.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; // Service is hosted in the browser process if libassistant is not available. @@ -38,6 +39,7 @@ interface LibassistantService { // Bind everything needed to start the service. + [AllowedContext=sandbox.mojom.Context.kBrowser] Bind( pending_receiver<AudioInputController> audio_input_controller, pending_receiver<ConversationController> conversation_controller,
diff --git a/chromeos/ash/services/recording/public/mojom/recording_service.mojom b/chromeos/ash/services/recording/public/mojom/recording_service.mojom index ce13a3d..8f41cc3 100644 --- a/chromeos/ash/services/recording/public/mojom/recording_service.mojom +++ b/chromeos/ash/services/recording/public/mojom/recording_service.mojom
@@ -7,6 +7,7 @@ import "media/mojo/mojom/audio_stream_factory.mojom"; import "mojo/public/mojom/base/big_string.mojom"; import "mojo/public/mojom/base/file_path.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; import "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom"; import "services/viz/public/mojom/compositing/frame_sink_id.mojom"; @@ -81,7 +82,8 @@ // video. // Note that a maximum of one screen recording can be done at any time. // TODO(https://crbug.com/1147991) Explore alternative sandboxing. -[ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox] +[ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox, + RequireContext=sandbox.mojom.Context.kBrowser] interface RecordingService { // All the below Record*() interfaces, take a pending remote to a client (e.g. // Ash) which will be notified when recording finishes and all the encoded @@ -134,6 +136,7 @@ // needed. This is desired in Fullscreen recording, as it makes it clear when // the recorded display changes its rotation. // |frame_sink_id| must be valid. + [AllowedContext=sandbox.mojom.Context.kBrowser] RecordFullscreen( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer, @@ -166,6 +169,7 @@ // OnFrameSinkSizeChanged() which will update the resolution constraints on // the capturer to avoid letterboxing, so the resulting video frames are sharp // and crisp, and their size match that of the window in pixels. + [AllowedContext=sandbox.mojom.Context.kBrowser] RecordWindow( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer, @@ -193,6 +197,7 @@ // generated video frame sizes, which results in the wrong region being shown // in the video. // |frame_sink_id| must be valid. + [AllowedContext=sandbox.mojom.Context.kBrowser] RecordRegion( pending_remote<RecordingServiceClient> client, pending_remote<viz.mojom.FrameSinkVideoCapturer> video_capturer,
diff --git a/chromeos/services/tts/public/mojom/tts_service.mojom b/chromeos/services/tts/public/mojom/tts_service.mojom index c8fa90b9..811ba26 100644 --- a/chromeos/services/tts/public/mojom/tts_service.mojom +++ b/chromeos/services/tts/public/mojom/tts_service.mojom
@@ -5,6 +5,7 @@ module chromeos.tts.mojom; import "media/mojo/mojom/audio_stream_factory.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; // Audio parameters used for PlaybackTtsStream. @@ -17,10 +18,12 @@ // tts-sandboxed process. TtsEngineExtensionObserver, the other end of this // interface, in the browser process, brokers a connection between TtsService // and two possible engine types, [Google|Playback]TtsStream. -[ServiceSandbox=sandbox.mojom.Sandbox.kTts] +[ServiceSandbox=sandbox.mojom.Sandbox.kTts, + RequireContext=sandbox.mojom.Context.kBrowswer] interface TtsService { // Binds a GoogleTtsStream received by this service. // The remote lives in the Google tts component extension. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindGoogleTtsStream( pending_receiver<GoogleTtsStream> receiver, pending_remote<media.mojom.AudioStreamFactory> stream_factory); @@ -29,6 +32,7 @@ // The remote lives in the Ash Chrome browser process. // The caller can request specific |sample_rate| and |buffer_size|. The actual // audio parameters for the output device are returned. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindPlaybackTtsStream( pending_receiver<PlaybackTtsStream> receiver, pending_remote<media.mojom.AudioStreamFactory> stream_factory,
diff --git a/chromeos/strings/chromeos_strings_fil.xtb b/chromeos/strings/chromeos_strings_fil.xtb index d570352a..bc47a43 100644 --- a/chromeos/strings/chromeos_strings_fil.xtb +++ b/chromeos/strings/chromeos_strings_fil.xtb
@@ -29,6 +29,7 @@ <translation id="1175697296044146566">Pinapamahalaan ng <ph name="MANAGER" /> ang <ph name="DEVICE_TYPE" /> na ito.</translation> <translation id="1175951029573070619">Katamtaman (<ph name="SIGNAL_STRENGTH" />)</translation> <translation id="1181037720776840403">Alisin</translation> +<translation id="1191518099344003522">Naka-enable ang APN.</translation> <translation id="1195447618553298278">Hindi kilalang error.</translation> <translation id="1195784767091936222">I-on ang awtomatikong dark mode</translation> <translation id="1196959502276349371">Bersyon <ph name="VERSION" /></translation> @@ -81,6 +82,7 @@ <translation id="1515129336378114413">home ng browser</translation> <translation id="1526389707933164996">Animation ng screen saver</translation> <translation id="152892567002884378">Lakasan ang volume</translation> +<translation id="1539242642795599947">Default at attach ang uri ng APN.</translation> <translation id="1555130319947370107">Asul</translation> <translation id="155865706765934889">Touchpad</translation> <translation id="1561927818299383735">kulay ng backlit</translation> @@ -440,6 +442,7 @@ <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> Larawan</translation> <translation id="4333390807948134856">Napindot ang key na <ph name="KEY_NAME" /></translation> <translation id="4354430579665871434">key</translation> +<translation id="4361257691546579041">Default ang uri ng APN.</translation> <translation id="437294888293595148">I-reset ang lahat ng shortcut</translation> <translation id="4378373042927530923">Hindi Tumakbo</translation> <translation id="4378551569595875038">Kumokonekta...</translation> @@ -660,6 +663,7 @@ <translation id="5946538341867151940">Hindi ka pa nakakonekta. Kung nagrerekomenda ang iyong mobile carrier ng custom na APN, ilagay ang impormasyon ng APN sa pamamagitan ng pagpili sa "+ Bagong APN"</translation> <translation id="5972388717451707488">Update Engine</translation> <translation id="5984145644188835034">Default na Wallpaper</translation> +<translation id="6001235009374883388">Attach ang uri ng APN.</translation> <translation id="6017514345406065928">Berde</translation> <translation id="6019566113895157499">Key Shortcuts</translation> <translation id="6034694447310538551">I-enable ang awtomatikong buwanang pag-reset</translation> @@ -827,6 +831,7 @@ <translation id="7180611975245234373">I-refresh</translation> <translation id="7180865173735832675">I-customize</translation> <translation id="7184043045742675738">Mag-click sa anumang key para i-customize ang iyong button. Baguhin ang posisyon ng key gamit ang mouse o mga arrow key.</translation> +<translation id="7212547870105584639">Pamahalaan ang mga setting ng APN ng network. Bumubuo ang mga APN ng koneksyon sa pagitan ng cellular network at internet. <ph name="BEGIN_LINK_LEARN_MORE" />Matuto pa<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="7212734716605298123">Mga update sa firmware para sa mga external na device</translation> <translation id="7216409898977639127">Cellular provider</translation> <translation id="725133483556299729">Pumili ng email</translation>
diff --git a/chromeos/strings/chromeos_strings_ms.xtb b/chromeos/strings/chromeos_strings_ms.xtb index c025238..9097bba1 100644 --- a/chromeos/strings/chromeos_strings_ms.xtb +++ b/chromeos/strings/chromeos_strings_ms.xtb
@@ -29,6 +29,7 @@ <translation id="1175697296044146566"><ph name="DEVICE_TYPE" /> ini diurus oleh <ph name="MANAGER" />.</translation> <translation id="1175951029573070619">Biasa (<ph name="SIGNAL_STRENGTH" />)</translation> <translation id="1181037720776840403">Alih keluar</translation> +<translation id="1191518099344003522">APN didayakan.</translation> <translation id="1195447618553298278">Ralat tidak diketahui.</translation> <translation id="1195784767091936222">Hidupkan mod gelap automatik</translation> <translation id="1196959502276349371">Versi <ph name="VERSION" /></translation> @@ -81,6 +82,7 @@ <translation id="1515129336378114413">laman utama penyemak imbas</translation> <translation id="1526389707933164996">Animasi penyelamat skrin</translation> <translation id="152892567002884378">Tambah kelantangan</translation> +<translation id="1539242642795599947">APN merupakan jenis lalai dan lampiran.</translation> <translation id="1555130319947370107">Biru</translation> <translation id="155865706765934889">Pad sentuh</translation> <translation id="1561927818299383735">warna cahaya belakang</translation> @@ -440,6 +442,7 @@ <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> Imej</translation> <translation id="4333390807948134856">Kekunci <ph name="KEY_NAME" /> ditekan</translation> <translation id="4354430579665871434">kekunci</translation> +<translation id="4361257691546579041">APN merupakan jenis lalai.</translation> <translation id="437294888293595148">Tetapkan semula semua pintasan</translation> <translation id="4378373042927530923">Tidak Berjalan</translation> <translation id="4378551569595875038">Menyambung...</translation> @@ -660,6 +663,7 @@ <translation id="5946538341867151940">Anda belum disambungkan lagi. Jika pembawa mudah alih anda mengesyorkan APN yang tersuai, masukkan maklumat APN dengan memilih "+ APN Baharu"</translation> <translation id="5972388717451707488">Enjin Kemaskinian</translation> <translation id="5984145644188835034">Kertas Dinding Lalai</translation> +<translation id="6001235009374883388">APN merupakan jenis lampiran.</translation> <translation id="6017514345406065928">Hijau</translation> <translation id="6019566113895157499">Pintasan Kekunci</translation> <translation id="6034694447310538551">Dayakan tetapan semula bulanan automatik</translation> @@ -827,6 +831,7 @@ <translation id="7180611975245234373">Muat semula</translation> <translation id="7180865173735832675">Peribadikan</translation> <translation id="7184043045742675738">Klik sebarang kekunci untuk menyesuaikan butang anda. Ubah kedudukan kekunci dengan tetikus atau kekunci anak panah.</translation> +<translation id="7212547870105584639">Urus tetapan APN rangkaian. APN mewujudkan sambungan antara rangkaian selular dengan Internet. <ph name="BEGIN_LINK_LEARN_MORE" />Ketahui lebih lanjut<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="7212734716605298123">Kemaskinian perisian tegar untuk peranti luaran</translation> <translation id="7216409898977639127">Penyedia selular</translation> <translation id="725133483556299729">Pilih e-mel</translation>
diff --git a/chromeos/strings/chromeos_strings_pa.xtb b/chromeos/strings/chromeos_strings_pa.xtb index d68d566f3..3bb770a 100644 --- a/chromeos/strings/chromeos_strings_pa.xtb +++ b/chromeos/strings/chromeos_strings_pa.xtb
@@ -360,7 +360,7 @@ <translation id="3748026146096797577">ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ</translation> <translation id="3749289110408117711">ਫਾਈਲ ਨਾਮ</translation> <translation id="3754384069690464321">ਇਸ ਵਾਲਪੇਪਰ ਦੇ ਬਿਹਤਰੀਨ ਨਤੀਜਿਆਂ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਸਵੈਚਲਿਤ-ਗੂੜ੍ਹਾ ਮੋਡ ਚਾਲੂ ਕਰੋ। ਤੁਸੀਂ ਇਸਨੂੰ ਕਿਸੇ ਵੀ ਸਮੇਂ ਐਪ ਵਿੱਚ ਵਾਪਸ ਬਦਲ ਸਕਦੇ ਹੋ।</translation> -<translation id="3771294271822695279">ਵੀਡਿਓ ਫਾਈਲਾਂ</translation> +<translation id="3771294271822695279">ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ</translation> <translation id="3784455785234192852">ਲਾਕ ਕਰੋ</translation> <translation id="380097101658023925">RGB ਕੰਟਰੋਲ</translation> <translation id="38114475217616659">ਸਾਰਾ ਇਤਿਹਾਸ ਕਲੀਅਰ ਕਰੋ</translation>
diff --git a/chromeos/strings/chromeos_strings_th.xtb b/chromeos/strings/chromeos_strings_th.xtb index c20c101..2996eb5 100644 --- a/chromeos/strings/chromeos_strings_th.xtb +++ b/chromeos/strings/chromeos_strings_th.xtb
@@ -29,6 +29,7 @@ <translation id="1175697296044146566"><ph name="DEVICE_TYPE" /> เครื่องนี้จัดการโดย <ph name="MANAGER" /></translation> <translation id="1175951029573070619">ปานกลาง (<ph name="SIGNAL_STRENGTH" />)</translation> <translation id="1181037720776840403">นำออก</translation> +<translation id="1191518099344003522">เปิดใช้ APN แล้ว</translation> <translation id="1195447618553298278">ข้อผิดพลาดที่ไม่รู้จัก</translation> <translation id="1195784767091936222">เปิดโหมดมืดอัตโนมัติ</translation> <translation id="1196959502276349371">เวอร์ชัน <ph name="VERSION" /></translation> @@ -81,6 +82,7 @@ <translation id="1515129336378114413">หน้าหลักของเบราว์เซอร์</translation> <translation id="1526389707933164996">ภาพเคลื่อนไหวของโปรแกรมรักษาหน้าจอ</translation> <translation id="152892567002884378">เพิ่มระดับเสียง</translation> +<translation id="1539242642795599947">APN เป็นแบบ Default และ Attach</translation> <translation id="1555130319947370107">สีน้ำเงิน</translation> <translation id="155865706765934889">ทัชแพด</translation> <translation id="1561927818299383735">สีเรืองแสง</translation> @@ -440,6 +442,7 @@ <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> ภาพ</translation> <translation id="4333390807948134856">กดปุ่ม <ph name="KEY_NAME" /> อยู่</translation> <translation id="4354430579665871434">แป้น</translation> +<translation id="4361257691546579041">APN เป็นแบบ Default</translation> <translation id="437294888293595148">รีเซ็ตทางลัดทั้งหมด</translation> <translation id="4378373042927530923">ไม่ทำงาน</translation> <translation id="4378551569595875038">กำลังเชื่อมต่อ</translation> @@ -660,6 +663,7 @@ <translation id="5946538341867151940">คุณยังไม่ได้เชื่อมต่อ หากผู้ให้บริการเครือข่ายมือถือของคุณแนะนำ APN ที่กําหนดเอง ให้ป้อนข้อมูล APN ดังกล่าวโดยเลือก "+ APN ใหม่"</translation> <translation id="5972388717451707488">อัปเดตเครื่องมือ</translation> <translation id="5984145644188835034">วอลเปเปอร์เริ่มต้น</translation> +<translation id="6001235009374883388">APN เป็นแบบ Attach</translation> <translation id="6017514345406065928">สีเขียว</translation> <translation id="6019566113895157499">แป้นพิมพ์ลัด</translation> <translation id="6034694447310538551">เปิดใช้การรีเซ็ตทุกเดือนโดยอัตโนมัติ</translation> @@ -827,6 +831,7 @@ <translation id="7180611975245234373">รีเฟรช</translation> <translation id="7180865173735832675">กำหนดค่า</translation> <translation id="7184043045742675738">คลิกแป้นใดก็ได้เพื่อปรับแต่งปุ่ม เปลี่ยนตำแหน่งแป้นด้วยเมาส์หรือแป้นลูกศร</translation> +<translation id="7212547870105584639">จัดการการตั้งค่า APN ของเครือข่าย APN จะเริ่มการเชื่อมต่อระหว่างเครือข่ายมือถือกับอินเทอร์เน็ต <ph name="BEGIN_LINK_LEARN_MORE" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="7212734716605298123">การอัปเดตเฟิร์มแวร์สำหรับอุปกรณ์ภายนอก</translation> <translation id="7216409898977639127">ผู้ให้บริการเครือข่ายมือถือ</translation> <translation id="725133483556299729">เลือกอีเมล</translation>
diff --git a/clank b/clank index 68949fa..f5a65a3 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 68949fa36ab0fb6ad6d4f07bfed5139ecc426c3b +Subproject commit f5a65a354e79fc3652b1f2ef7a54e15317abb85a
diff --git a/components/android_autofill/browser/autofill_provider_android.cc b/components/android_autofill/browser/autofill_provider_android.cc index d31e49f..da51414e 100644 --- a/components/android_autofill/browser/autofill_provider_android.cc +++ b/components/android_autofill/browser/autofill_provider_android.cc
@@ -129,7 +129,7 @@ // Focus or field value change will also trigger the query, so it should be // ignored if the form is same. - if (!IsCurrentlyLinkedForm(form)) { + if (!IsLinkedForm(form)) { StartNewSession(manager, form, field, bounding_box); } @@ -223,7 +223,7 @@ const gfx::RectF& bounding_box) { DCHECK_CURRENTLY_ON(BrowserThread::UI); FieldInfo field_info; - if (!IsCurrentlyLinkedForm(form) || + if (!IsLinkedForm(form) || !form_->GetSimilarFieldIndex(field, &field_info.index)) { return; } @@ -241,7 +241,7 @@ const FormData& form, const FormFieldData& field, const gfx::RectF& bounding_box) { - if (!IsCurrentlyLinkedForm(form)) { + if (!IsLinkedForm(form)) { StartNewSession(manager, form, field, bounding_box); // TODO(crbug.com/1478934): Return early at this point? } @@ -259,7 +259,9 @@ bool known_success, SubmissionSource source) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!IsCurrentlyLinkedManager(manager) || !form_) { + // TODO(b/297228856): Remove `!form_` check when + // `kAndroidAutofillFormSubmissionCheckById` launches. + if (!IsLinkedManager(manager) || !form_) { return; } @@ -269,14 +271,10 @@ // form submission, we want to inform `AutofillManager` about the submission. // Otherwise no saving prompt can be offered. if (base::FeatureList::IsEnabled( - features::kAndroidAutofillFormSubmissionCheckById)) { - if (form_->form().global_id() != form.global_id()) { - return; - } - } else { - if (!form_->SimilarFormAs(form)) { - return; - } + features::kAndroidAutofillFormSubmissionCheckById) + ? !IsIdOfLinkedForm(form.global_id()) + : !form_->SimilarFormAs(form)) { + return; } if (known_success || source == SubmissionSource::FORM_SUBMISSION) { @@ -292,7 +290,7 @@ AndroidAutofillManager* manager, bool had_interacted_form) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!IsCurrentlyLinkedManager(manager)) { + if (!IsLinkedManager(manager)) { return; } @@ -307,7 +305,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); FieldInfo field_info; - if (!IsCurrentlyLinkedForm(form) || + if (!IsLinkedForm(form) || !form_->GetSimilarFieldIndex(field, &field_info.index)) { return; } @@ -324,7 +322,7 @@ const gfx::RectF& bounding_box) { DCHECK_CURRENTLY_ON(BrowserThread::UI); FieldInfo field_info; - if (!IsCurrentlyLinkedForm(form) || + if (!IsLinkedForm(form) || !form_->GetSimilarFieldIndex(field, &field_info.index)) { return; } @@ -337,7 +335,7 @@ void AutofillProviderAndroid::MaybeFireFormFieldVisibilitiesDidChange( AndroidAutofillManager* manager, const FormData& form) { - if (!IsCurrentlyLinkedForm(form) || + if (!IsLinkedForm(form) || !base::FeatureList::IsEnabled( features::kAndroidAutofillSupportVisibilityChanges)) { return; @@ -356,12 +354,15 @@ const FormData& form, base::TimeTicks timestamp) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (manager != manager_.get() || !IsCurrentlyLinkedForm(form)) { + if (manager != manager_.get() || !IsIdOfLinkedForm(form.global_id())) { UMA_HISTOGRAM_BOOLEAN( "Autofill.WebView.OnDidFillAutofillFormDataEarlyReturnReason", manager == manager_.get()); return; } + // TODO(crbug.com/1198811): Investigate passing the actually filled fields, in + // case the passed fields to be filled are different from the fields that were + // actually filled. bridge_->OnDidFillAutofillFormData(); } @@ -378,7 +379,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); MaybeSendPrefillRequest(manager, form_id); - if (!form_ || form_->form().global_id() != form_id) { + if (!IsIdOfLinkedForm(form_id)) { return; } @@ -394,8 +395,9 @@ void AutofillProviderAndroid::OnServerQueryRequestError( AndroidAutofillManager* manager, FormSignature form_signature) { - if (!IsCurrentlyLinkedManager(manager) || !form_.get()) + if (!IsLinkedManager(manager) || !form_.get()) { return; + } if (auto* form_structure = manager_->FindCachedFormById(form_->form().global_id())) { @@ -410,7 +412,7 @@ void AutofillProviderAndroid::OnManagerResetOrDestroyed( AndroidAutofillManager* manager) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!IsCurrentlyLinkedManager(manager)) { + if (!IsLinkedManager(manager)) { return; } @@ -431,12 +433,16 @@ form_->form().fields[field_index].is_autofilled; } -bool AutofillProviderAndroid::IsCurrentlyLinkedManager( - AndroidAutofillManager* manager) { +bool AutofillProviderAndroid::IsLinkedManager( + AndroidAutofillManager* manager) const { return manager == manager_.get(); } -bool AutofillProviderAndroid::IsCurrentlyLinkedForm(const FormData& form) { +bool AutofillProviderAndroid::IsIdOfLinkedForm(FormGlobalId form_id) const { + return form_ && form_->form().global_id() == form_id; +} + +bool AutofillProviderAndroid::IsLinkedForm(const FormData& form) const { return form_ && form_->SimilarFormAs(form); }
diff --git a/components/android_autofill/browser/autofill_provider_android.h b/components/android_autofill/browser/autofill_provider_android.h index 89fa76d..0873a16 100644 --- a/components/android_autofill/browser/autofill_provider_android.h +++ b/components/android_autofill/browser/autofill_provider_android.h
@@ -113,9 +113,15 @@ void MaybeFireFormFieldVisibilitiesDidChange(AndroidAutofillManager* manager, const FormData& form); - bool IsCurrentlyLinkedManager(AndroidAutofillManager* manager); + bool IsLinkedManager(AndroidAutofillManager* manager) const; - bool IsCurrentlyLinkedForm(const FormData& form); + // Checks whether a `form_` is linked and whether it's the same form as + // `form`, having same identifier. + bool IsIdOfLinkedForm(FormGlobalId form_id) const; + + // Same as `IsLinkedForm`, but also checks that `form` and `form_` are + // similar, using form similarity checks. + bool IsLinkedForm(const FormData& form) const; gfx::RectF ToClientAreaBound(const gfx::RectF& bounding_box);
diff --git a/components/android_autofill/browser/form_data_android.h b/components/android_autofill/browser/form_data_android.h index 953354d1..d86fce2 100644 --- a/components/android_autofill/browser/form_data_android.h +++ b/components/android_autofill/browser/form_data_android.h
@@ -69,7 +69,7 @@ const FormData& form() const { return form_; } - const SessionId session_id() const { return session_id_; } + SessionId session_id() const { return session_id_; } private: // The session id of this form. It is used to generate virtual view ids for
diff --git a/components/attribution_reporting/constants.h b/components/attribution_reporting/constants.h index 7a65eda90..02594e0 100644 --- a/components/attribution_reporting/constants.h +++ b/components/attribution_reporting/constants.h
@@ -9,7 +9,6 @@ #include <stdint.h> #include "base/time/time.h" -#include "components/attribution_reporting/source_type.mojom.h" namespace attribution_reporting { @@ -35,16 +34,6 @@ static_assert(kMinReportWindow <= kMinSourceExpiry); -constexpr uint32_t DefaultTriggerDataCardinality( - mojom::SourceType source_type) { - switch (source_type) { - case mojom::SourceType::kNavigation: - return 8; - case mojom::SourceType::kEvent: - return 2; - } -} - } // namespace attribution_reporting #endif // COMPONENTS_ATTRIBUTION_REPORTING_CONSTANTS_H_
diff --git a/components/attribution_reporting/trigger_config.cc b/components/attribution_reporting/trigger_config.cc index 80079b4..3ef5325 100644 --- a/components/attribution_reporting/trigger_config.cc +++ b/components/attribution_reporting/trigger_config.cc
@@ -19,7 +19,6 @@ #include "base/types/expected.h" #include "base/types/expected_macros.h" #include "base/values.h" -#include "components/attribution_reporting/constants.h" #include "components/attribution_reporting/features.h" #include "components/attribution_reporting/source_registration_error.mojom.h" #include "components/attribution_reporting/source_type.mojom.h" @@ -44,6 +43,15 @@ // https://wicg.github.io/attribution-reporting-api/#max-distinct-trigger-data-per-source constexpr uint8_t kMaxTriggerDataPerSource = 32; +constexpr uint32_t DefaultTriggerDataCardinality(SourceType source_type) { + switch (source_type) { + case SourceType::kNavigation: + return 8; + case SourceType::kEvent: + return 2; + } +} + // If `dict` contains a valid "trigger_data" field, writes the resulting keys // into `trigger_data_indices` using `spec_index` as the value. // `trigger_data_indices` is also used to perform deduplication checks.
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 060b309..9ed10428 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -339,7 +339,7 @@ void AutofillAgent::DidCommitProvisionalLoad(ui::PageTransition transition) { // Navigation to a new page or a page refresh. - last_queried_element_.Reset(); + last_queried_element_ = {}; form_cache_ = unsafe_render_frame() ? std::make_unique<FormCache>(unsafe_render_frame()->GetWebFrame()) @@ -355,7 +355,8 @@ } void AutofillAgent::DidChangeScrollOffset() { - if (last_queried_element_.IsNull()) { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + if (last_queried_element.IsNull()) { return; } @@ -369,7 +370,7 @@ ->PostTask(FROM_HERE, base::BindOnce(&AutofillAgent::DidChangeScrollOffsetImpl, weak_ptr_factory_.GetWeakPtr(), - last_queried_element_)); + last_queried_element)); } } else { HidePopup(); @@ -378,7 +379,7 @@ void AutofillAgent::DidChangeScrollOffsetImpl( const WebFormControlElement& element) { - if (element != last_queried_element_ || element.IsNull() || + if (element != last_queried_element_.GetField() || element.IsNull() || focus_requires_scroll_ || !is_popup_possibly_visible_ || !element.Focused()) { return; @@ -403,11 +404,12 @@ void AutofillAgent::FocusedElementChanged(const WebElement& element) { HidePopup(); + WebFormElement last_interacted_form = last_interacted_form_.GetForm(); if (element.IsNull()) { // Focus moved away from the last interacted form (if any) to somewhere else // on the page. if (auto* autofill_driver = unsafe_autofill_driver()) { - autofill_driver->FocusNoLongerOnForm(!last_interacted_form_.IsNull()); + autofill_driver->FocusNoLongerOnForm(!last_interacted_form.IsNull()); } return; } @@ -416,9 +418,9 @@ element.DynamicTo<WebFormControlElement>(); bool focus_moved_to_new_form = false; - if (!last_interacted_form_.IsNull() && + if (!last_interacted_form.IsNull() && (form_control_element.IsNull() || - last_interacted_form_ != form_control_element.Form())) { + last_interacted_form != form_control_element.Form())) { // The focused element is not part of the last interacted form (could be // in a different form). if (auto* autofill_driver = unsafe_autofill_driver()) { @@ -447,21 +449,22 @@ /*focused_node_was_last_clicked=*/focused_node_was_last_clicked); } - if (focus_moved_to_new_form) + if (focus_moved_to_new_form) { return; + } if (form_control_element.IsNull() || !form_control_element.IsEnabled() || !form_util::IsTextAreaElementOrTextInput(form_control_element)) { return; } - last_queried_element_ = form_control_element; + last_queried_element_ = FieldRef(form_control_element); FormData form; FormFieldData field; if (!form_control_element.IsReadOnly() && FindFormAndFieldForFormControlElement( - last_queried_element_, field_data_manager(), + last_queried_element_.GetField(), field_data_manager(), MaybeExtractDatalist({ExtractOption::kBounds}), &form, &field)) { if (auto* autofill_driver = unsafe_autofill_driver()) { autofill_driver->FocusOnFormField(form, field, field.bounds); @@ -520,8 +523,9 @@ autofill_driver->DidEndTextFieldEditing(); } focus_state_notifier_.ResetFocus(); - if (password_generation_agent_) + if (password_generation_agent_) { password_generation_agent_->DidEndTextFieldEditing(element); + } SendPotentiallySubmittedFormToBrowser(); } @@ -558,7 +562,7 @@ if (!input_element.IsNull() && password_autofill_agent_->TextDidChangeInTextField(input_element)) { is_popup_possibly_visible_ = true; - last_queried_element_ = element; + last_queried_element_ = FieldRef(element); return; } @@ -611,8 +615,9 @@ return; } - if (datalist_option_change_batch_timer_.IsRunning()) + if (datalist_option_change_batch_timer_.IsRunning()) { datalist_option_change_batch_timer_.AbandonAndStop(); + } datalist_option_change_batch_timer_.Start( FROM_HERE, base::Milliseconds(kWaitTimeForOptionsChangesMs), @@ -622,8 +627,9 @@ void AutofillAgent::BatchDataListOptionChange( const blink::WebFormControlElement& element) { - if (element.GetDocument().IsNull()) + if (element.GetDocument().IsNull()) { return; + } OnProvisionallySaveForm(element.Form(), element, ElementChangeSource::TEXTFIELD_CHANGED); @@ -657,50 +663,53 @@ void AutofillAgent::ApplyFormAction(mojom::ActionType action_type, mojom::ActionPersistence action_persistence, const FormData& form) { - // If `element_` is null or not focused, Autofill was either triggered from - // another frame or the `element_` has been detached from the DOM or the focus - // was moved otherwise. - // If `element_` is from a different form than `form`, then Autofill was - // triggered from a different form in the same frame, and either this is a - // subframe and both forms should be filled, or focus has changed right after - // the user accepted the suggestions. + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + // If `last_queried_element_` is null or not focused, Autofill was either + // triggered from another frame or the `last_queried_element_` has been + // detached from the DOM or the focus was moved otherwise. // - // In these cases, we set `element_` to some form field as if Autofill had - // been triggered from that field. This is necessary because currently - // AutofillAgent relies on `element_` in many places. + // If `last_queried_element_` is from a different form than `form`, then + // Autofill was triggered from a different form in the same frame, and either + // this is a subframe and both forms should be filled, or focus has changed + // right after the user accepted the suggestions. + // + // In these cases, we set `last_queried_element_` to some form field as if + // Autofill had been triggered from that field. This is necessary because + // currently AutofillAgent relies on `last_queried_element_` in many places. if (!form.fields.empty() && - (last_queried_element_.IsNull() || !last_queried_element_.Focused() || + (last_queried_element.IsNull() || !last_queried_element.Focused() || form_util::GetFormRendererId(form_util::GetOwningForm( - last_queried_element_)) != form.unique_renderer_id)) { + last_queried_element)) != form.unique_renderer_id)) { if (!unsafe_render_frame()) { return; } WebDocument document = unsafe_render_frame()->GetWebFrame()->GetDocument(); - last_queried_element_ = form_util::FindFormControlByRendererId( - document, form.fields.front().unique_renderer_id); + last_queried_element_ = FieldRef(form_util::FindFormControlByRendererId( + document, form.fields.front().unique_renderer_id)); + last_queried_element = last_queried_element_.GetField(); } - if (last_queried_element_.IsNull()) { + if (last_queried_element.IsNull()) { return; } ClearPreviewedForm(); if (action_persistence == mojom::ActionPersistence::kPreview) { - query_node_autofill_state_ = last_queried_element_.GetAutofillState(); + query_node_autofill_state_ = last_queried_element.GetAutofillState(); previewed_elements_ = form_util::ApplyFormAction( - form.fields, last_queried_element_, action_type, action_persistence); + form.fields, last_queried_element, action_type, action_persistence); } else { was_last_action_fill_ = true; - query_node_autofill_state_ = last_queried_element_.GetAutofillState(); + query_node_autofill_state_ = last_queried_element.GetAutofillState(); bool filled_some_fields = - !form_util::ApplyFormAction(form.fields, last_queried_element_, + !form_util::ApplyFormAction(form.fields, last_queried_element, action_type, action_persistence) .empty(); - if (!last_queried_element_.Form().IsNull()) { - UpdateLastInteractedForm(last_queried_element_.Form()); + if (!last_queried_element.Form().IsNull()) { + UpdateLastInteractedForm(last_queried_element.Form()); } else { formless_elements_were_autofilled_ |= filled_some_fields; } @@ -733,32 +742,37 @@ } void AutofillAgent::ClearSection() { - if (last_queried_element_.IsNull() || !form_cache_) { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + if (last_queried_element.IsNull() || !form_cache_) { return; } - form_cache_->ClearSectionWithElement(last_queried_element_); + form_cache_->ClearSectionWithElement(last_queried_element); } void AutofillAgent::ClearPreviewedForm() { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); // TODO(crbug.com/816533): It is very rare, but it looks like the |element_| // can be null if a provisional load was committed immediately prior to // clearing the previewed form. - if (last_queried_element_.IsNull()) { + if (last_queried_element.IsNull()) { return; } // |password_generation_agent_| can be null in android_webview & weblayer. if (password_generation_agent_ && password_generation_agent_->DidClearGenerationSuggestion( - last_queried_element_)) { + last_queried_element)) { return; } - if (password_autofill_agent_->DidClearAutofillSelection( - last_queried_element_)) { + last_queried_element)) { return; } - form_util::ClearPreviewedElements(last_action_type_, previewed_elements_, - last_queried_element_, + std::vector<WebFormControlElement> previewed_elements; + for (const FieldRef& previewed_element : previewed_elements_) { + previewed_elements.push_back(previewed_element.GetField()); + } + form_util::ClearPreviewedElements(last_action_type_, previewed_elements, + last_queried_element, query_node_autofill_state_); previewed_elements_ = {}; } @@ -772,9 +786,12 @@ } WebDocument document = render_frame->GetWebFrame()->GetDocument(); last_queried_element_ = - form_util::FindFormControlByRendererId(document, field_id); - if (!last_queried_element_.IsNull()) { - ShowSuggestions(last_queried_element_, trigger_source); + FieldRef(form_util::FindFormControlByRendererId(document, field_id)); + + if (WebFormControlElement last_queried_element = + last_queried_element_.GetField(); + !last_queried_element.IsNull()) { + ShowSuggestions(last_queried_element, trigger_source); } } @@ -790,7 +807,7 @@ // TODO(crbug.com/1427131): Look up `field_id` rather than using // `last_queried_element_` once // blink::features::kAutofillUseDomNodeIdForRendererId is enabled. - WebFormControlElement form_control = last_queried_element_; + WebFormControlElement form_control = last_queried_element_.GetField(); if (!form_control.IsNull() && field_id == form_util::GetFieldRendererId(form_control) && form_util::IsTextAreaElementOrTextInput(form_control)) { @@ -809,7 +826,7 @@ form_util::PreviewSuggestion(form_control.SuggestedValue().Utf16(), form_control.Value().Utf16(), &form_control); - previewed_elements_.push_back(form_control); + previewed_elements_.emplace_back(last_queried_element_); break; } break; @@ -852,26 +869,28 @@ void AutofillAgent::SetSuggestionAvailability( FieldRendererId field_id, mojom::AutofillSuggestionAvailability suggestion_availability) { - if (last_queried_element_.IsNull() || - field_id != form_util::GetFieldRendererId(last_queried_element_)) { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + if (last_queried_element.IsNull() || + field_id != form_util::GetFieldRendererId(last_queried_element)) { return; } SetAutofillSuggestionAvailability( - last_queried_element_.DynamicTo<WebInputElement>(), + last_queried_element.DynamicTo<WebInputElement>(), suggestion_availability); } void AutofillAgent::AcceptDataListSuggestion( FieldRendererId field_id, const std::u16string& suggested_value) { - if (last_queried_element_.IsNull() || - field_id != form_util::GetFieldRendererId(last_queried_element_)) { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + if (last_queried_element.IsNull() || + field_id != form_util::GetFieldRendererId(last_queried_element)) { return; } WebInputElement input_element = - last_queried_element_.DynamicTo<WebInputElement>(); + last_queried_element.DynamicTo<WebInputElement>(); if (input_element.IsNull()) { // Early return for non-input fields such as textarea. return; @@ -899,18 +918,19 @@ new_value = base::JoinString(parts, u","); } - DoFillFieldWithValue(new_value, last_queried_element_, + DoFillFieldWithValue(new_value, last_queried_element, WebAutofillState::kNotFilled); } void AutofillAgent::PreviewPasswordSuggestion(const std::u16string& username, const std::u16string& password) { - if (last_queried_element_.IsNull()) { + WebFormControlElement last_queried_element = last_queried_element_.GetField(); + if (last_queried_element.IsNull()) { return; } bool handled = password_autofill_agent_->PreviewSuggestion( - last_queried_element_, blink::WebString::FromUTF16(username), + last_queried_element, blink::WebString::FromUTF16(username), blink::WebString::FromUTF16(password)); DCHECK(handled); } @@ -956,21 +976,26 @@ DCHECK(MaybeWasOwnedByFrame(element, unsafe_render_frame())); CHECK_NE(trigger_source, AutofillSuggestionTriggerSource::kUnspecified); - if (!element.IsEnabled() || element.IsReadOnly()) + if (!element.IsEnabled() || element.IsReadOnly()) { return; - if (!element.SuggestedValue().IsEmpty()) + } + if (!element.SuggestedValue().IsEmpty()) { return; + } const WebInputElement input_element = element.DynamicTo<WebInputElement>(); if (!input_element.IsNull()) { - if (!input_element.IsTextField()) + if (!input_element.IsTextField()) { return; - if (!input_element.SuggestedValue().IsEmpty()) + } + if (!input_element.SuggestedValue().IsEmpty()) { return; + } } else { DCHECK(form_util::IsTextAreaElement(element)); - if (!element.To<WebFormControlElement>().SuggestedValue().IsEmpty()) + if (!element.To<WebFormControlElement>().SuggestedValue().IsEmpty()) { return; + } } // Don't attempt to autofill with values that are too large or if filling @@ -988,7 +1013,7 @@ return; } - last_queried_element_ = element; + last_queried_element_ = FieldRef(element); if (form_util::IsAutofillableInputElement(input_element)) { if (password_generation_agent_ && password_generation_agent_->ShowPasswordGenerationSuggestions( @@ -1110,8 +1135,9 @@ WebInputElement input_element = element.DynamicTo<WebInputElement>(); // `input_element` can be null for textarea elements. - if (!input_element.IsNull()) + if (!input_element.IsNull()) { password_autofill_agent_->UpdateStateForTextChange(input_element); + } form_tracker_.set_ignore_control_changes(false); } @@ -1214,8 +1240,9 @@ is_popup_possibly_visible_ = false; // The keyboard accessory has a separate, more complex hiding logic. - if (IsKeyboardAccessoryEnabled()) + if (IsKeyboardAccessoryEnabled()) { return; + } if (auto* autofill_driver = unsafe_autofill_driver()) { autofill_driver->HidePopup(); @@ -1249,8 +1276,9 @@ } WebDocument doc = unsafe_render_frame()->GetWebFrame()->GetDocument(); WebElement focused_element; - if (!doc.IsNull()) + if (!doc.IsNull()) { focused_element = doc.FocusedElement(); + } if (!focused_element.IsNull()) { SendFocusedInputChangedNotificationToBrowser(focused_element); @@ -1292,7 +1320,7 @@ const blink::WebFormControlElement& element) { DCHECK(MaybeWasOwnedByFrame(element, unsafe_render_frame())); - if (!was_last_action_fill_ || last_queried_element_.IsNull()) { + if (!was_last_action_fill_ || last_queried_element_.GetField().IsNull()) { return; } @@ -1330,8 +1358,9 @@ const WebFormControlElement& element) { // Note: Consider supporting other autofill types in the future as well. #if BUILDFLAG(IS_ANDROID) - if (password_autofill_agent_->ShouldSuppressKeyboard()) + if (password_autofill_agent_->ShouldSuppressKeyboard()) { return true; + } #endif return false; } @@ -1358,8 +1387,9 @@ was_last_action_fill_ = false; const WebInputElement input_element = element.DynamicTo<WebInputElement>(); - if (input_element.IsNull() && !form_util::IsTextAreaElement(element)) + if (input_element.IsNull() && !form_util::IsTextAreaElement(element)) { return; + } #if BUILDFLAG(IS_ANDROID) if (!base::FeatureList::IsEnabled( @@ -1501,7 +1531,7 @@ // `last_interacted_form_` except when formless extraction fails, document // the reason if any, cleanup otherwise. if (provisionally_saved_form_) { - last_interacted_form_.Reset(); + last_interacted_form_ = {}; } }; @@ -1643,9 +1673,12 @@ // return either the extracted form or `provisionally_saved_form_` as a // fallback if extraction fails. The remaining logic deals with formless // fields. - if (!last_interacted_form_.IsNull()) { + // The reason why we check the ID and not the form is that we might've been + // caching a form that was removed, hence the form will be null but the ID + // won't. + if (last_interacted_form_.GetId()) { if (std::optional<FormData> form = form_util::ExtractFormData( - last_interacted_form_, field_data_manager())) { + last_interacted_form_.GetForm(), field_data_manager())) { return form; } return provisionally_saved_form_; @@ -1680,7 +1713,7 @@ } void AutofillAgent::ResetLastInteractedElements() { - last_interacted_form_.Reset(); + last_interacted_form_ = {}; last_clicked_form_control_element_for_testing_ = {}; formless_elements_user_edited_.clear(); formless_elements_were_autofilled_ = false; @@ -1691,9 +1724,9 @@ const blink::WebFormElement& form) { DCHECK(MaybeWasOwnedByFrame(form, unsafe_render_frame())); - last_interacted_form_ = form; - provisionally_saved_form_ = - form_util::ExtractFormData(last_interacted_form_, field_data_manager()); + last_interacted_form_ = FormRef(form); + provisionally_saved_form_ = form_util::ExtractFormData( + last_interacted_form_.GetForm(), field_data_manager()); } void AutofillAgent::OnFormNoLongerSubmittable() {
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h index e25c092..99251a8d 100644 --- a/components/autofill/content/renderer/autofill_agent.h +++ b/components/autofill/content/renderer/autofill_agent.h
@@ -176,8 +176,8 @@ bool IsPrerendering() const; - const blink::WebFormControlElement& focused_element() const { - return last_queried_element_; + blink::WebFormControlElement focused_element() const { + return last_queried_element_.GetField(); } FieldDataManager& field_data_manager() const { @@ -384,10 +384,10 @@ std::unique_ptr<PasswordGenerationAgent> password_generation_agent_; // The element corresponding to the last request sent for form field Autofill. - blink::WebFormControlElement last_queried_element_; + FieldRef last_queried_element_; // The elements that currently are being previewed. - std::vector<blink::WebFormControlElement> previewed_elements_; + std::vector<FieldRef> previewed_elements_; // Records the last autofill action (Fill or Undo) done by the agent. Used in // ClearPreviewedForm to get the default state of previewed fields @@ -395,7 +395,7 @@ mojom::ActionType last_action_type_ = mojom::ActionType::kFill; // Last form which was interacted with by the user. - blink::WebFormElement last_interacted_form_; + FormRef last_interacted_form_; // When dealing with an unowned form, we keep track of the unowned fields // the user has modified so we can determine when submission occurs.
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index 1972d3d..55e74e84 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1713,6 +1713,9 @@ std::optional<FormData> ExtractFormData( const WebFormElement& form_element, const FieldDataManager& field_data_manager) { + if (form_element.IsNull()) { + return std::nullopt; + } FormData extracted_form; // TODO(crbug.com/1007974): Make this function return std::optional too. bool extraction_successful = WebFormElementToFormData( @@ -2332,7 +2335,7 @@ return form; } -std::vector<WebFormControlElement> ApplyFormAction( +std::vector<FieldRef> ApplyFormAction( base::span<const FormFieldData> fields, const WebFormControlElement& initiating_element, mojom::ActionType action_type, @@ -2363,7 +2366,7 @@ std::vector<std::pair<WebFormControlElement*, const FormFieldData*>> autofillable_elements_index_pairs; - std::vector<WebFormControlElement> matching_fields; + std::vector<FieldRef> matching_fields; matching_fields.reserve(control_elements.size()); // Prepare for binary search. @@ -2412,7 +2415,7 @@ initially_focused_element = &element; } - matching_fields.push_back(element); + matching_fields.emplace_back(element); // In preview mode, only fill the field if it changes the fields value. // With this, the WebAutofillState is not changed from kAutofilled to // kPreviewed. This prevents the highlighting to change. @@ -2445,7 +2448,7 @@ // Autofill the non-initiating elements. for (const auto& [filled_element, field_data] : autofillable_elements_index_pairs) { - matching_fields.push_back(*filled_element); + matching_fields.emplace_back(*filled_element); fill_or_preview(*field_data, false, filled_element); }
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h index f41dc613..e53b64ad 100644 --- a/components/autofill/content/renderer/form_autofill_util.h +++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -13,6 +13,7 @@ #include "base/containers/flat_map.h" #include "base/i18n/rtl.h" +#include "components/autofill/content/renderer/form_tracker.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/dense_set.h" #include "components/autofill/core/common/form_data.h" @@ -351,8 +352,8 @@ // Fills or previews the fields represented by `fields`. // `initiating_element` is the element that initiated the autofill process. -// Returns the filled blink elements. -std::vector<blink::WebFormControlElement> ApplyFormAction( +// Returns the filled elements. +std::vector<FieldRef> ApplyFormAction( base::span<const FormFieldData> fields, const blink::WebFormControlElement& initiating_element, mojom::ActionType action_type,
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index cd59101..7bbfabfe4 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -247,7 +247,7 @@ // Check if the given element is a username input field. bool IsUsernameInputField(const blink::WebInputElement& input_element) const; - const blink::WebFormControlElement& focused_element() const { + blink::WebFormControlElement focused_element() const { CHECK(autofill_agent_); return autofill_agent_->focused_element(); }
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index 0294dac..c191b64 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -465,8 +465,27 @@ case PopupItemId::kFieldByFieldFilling: if (const AutofillField* autofill_trigger_field = GetQueriedAutofillField()) { - LogFillingMethodUsed(autofill_metrics::AutofillFillingMethodMetric:: - kFieldByFieldFilling); + autofill_metrics::LogFillingMethodUsed( + autofill_metrics::AutofillFillingMethodMetric:: + kFieldByFieldFilling); + CHECK(suggestion.field_by_field_filling_type_used); + // Only log the field-by-field filling type used if it was accepted from + // a suggestion in a subpopup. The root popup can have field-by-field + // suggestions after a field-by-field suggestion was accepted from a + // subpopup, this is done to keep the user in a certain filling + // granularity during their filling experience. However only the + // subpopups field-by-field-filling types are statically built, based on + // what we think is useful/handy (this will in the future vary per + // country, see crbug.com/1502162), while field-by-field filling + // suggestions in the root popup are dynamically built depending on the + // triggering field type, which means that selecting them is the only + // option users have in the first level. Therefore we only emit logs for + // subpopup acceptance to measure the efficiency of the types we chose + // and potentially remove/add new ones. + if (position.sub_popup_level > 0) { + autofill_metrics::LogFieldByFieldFillingFieldUsed( + *(suggestion.field_by_field_filling_type_used)); + } // We target only the triggering field type in the // PopupItemId::kFieldByFieldFilling case. last_field_types_to_fill_for_address_form_section_ @@ -489,7 +508,7 @@ query_form_, query_field_); break; case PopupItemId::kFillFullAddress: - LogFillingMethodUsed( + autofill_metrics::LogFillingMethodUsed( autofill_metrics::AutofillFillingMethodMetric::kGroupFillingAddress); FillAutofillFormData( suggestion.popup_item_id, @@ -499,7 +518,7 @@ .field_types_to_fill = GetAddressFieldsForGroupFilling()}); break; case PopupItemId::kFillFullName: - LogFillingMethodUsed( + autofill_metrics::LogFillingMethodUsed( autofill_metrics::AutofillFillingMethodMetric::kGroupFillingName); FillAutofillFormData( suggestion.popup_item_id, @@ -510,8 +529,9 @@ GetServerFieldTypesOfGroup(FieldTypeGroup::kName)}); break; case PopupItemId::kFillFullPhoneNumber: - LogFillingMethodUsed(autofill_metrics::AutofillFillingMethodMetric:: - kGroupFillingPhoneNumber); + autofill_metrics::LogFillingMethodUsed( + autofill_metrics::AutofillFillingMethodMetric:: + kGroupFillingPhoneNumber); FillAutofillFormData( suggestion.popup_item_id, suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false, @@ -521,7 +541,7 @@ GetServerFieldTypesOfGroup(FieldTypeGroup::kPhone)}); break; case PopupItemId::kFillFullEmail: - LogFillingMethodUsed( + autofill_metrics::LogFillingMethodUsed( autofill_metrics::AutofillFillingMethodMetric::kGroupFillingEmail); FillAutofillFormData( suggestion.popup_item_id, @@ -638,7 +658,7 @@ if (suggestion.popup_item_id == PopupItemId::kAddressEntry || suggestion.popup_item_id == PopupItemId::kFillEverythingFromAddressProfile) { - LogFillingMethodUsed( + autofill_metrics::LogFillingMethodUsed( autofill_metrics::AutofillFillingMethodMetric::kFullForm); } }
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index 316591d..dbc1a6b 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -1356,6 +1356,47 @@ suggestion, SuggestionPosition{.row = 1}, suggestion_source); } +// Tests that when the suggestion is of type +// `PopupItemId::kFieldByFieldFilling`, we emit the expected metric +// corresponding to which field type was used. +TEST_F(AutofillExternalDelegateUnitTest, + FieldByFieldFilling_SubPopup_EmitsTypeMetric) { + Suggestion suggestion = Suggestion(u"Jon", PopupItemId::kFieldByFieldFilling); + suggestion.field_by_field_filling_type_used = std::optional(NAME_FIRST); + IssueOnQuery(); + browser_autofill_manager_->OnFormsSeen({queried_form_}, {}); + // Wait until form is parsed. + task_environment_.RunUntilIdle(); + base::HistogramTester histogram_tester; + + external_delegate_->DidAcceptSuggestion( + suggestion, SuggestionPosition{.row = 0, .sub_popup_level = 1}, + AutofillSuggestionTriggerSource::kFormControlElementClicked); + + histogram_tester.ExpectUniqueSample( + "Autofill.FieldByFieldFilling.FieldTypeUsed", + autofill_metrics::AutofillFieldByFieldFillingTypes::kNameFirst, 1); +} + +TEST_F(AutofillExternalDelegateUnitTest, + FieldByFieldFilling_RootPopup_DoNotEmitTypeMetric) { + Suggestion suggestion = Suggestion(u"Jon", PopupItemId::kFieldByFieldFilling); + suggestion.field_by_field_filling_type_used = std::optional(NAME_FIRST); + IssueOnQuery(); + browser_autofill_manager_->OnFormsSeen({queried_form_}, {}); + // Wait until form is parsed. + task_environment_.RunUntilIdle(); + base::HistogramTester histogram_tester; + + external_delegate_->DidAcceptSuggestion( + suggestion, SuggestionPosition{.row = 0}, + AutofillSuggestionTriggerSource::kFormControlElementClicked); + + histogram_tester.ExpectUniqueSample( + "Autofill.FieldByFieldFilling.FieldTypeUsed", + autofill_metrics::AutofillFieldByFieldFillingTypes::kNameFirst, 0); +} + // Test parameter data for asserting that the expected set of field types // is stored in the delegate. struct GetLastServerTypesToFillForSectionTestParams {
diff --git a/components/autofill/core/browser/autofill_granular_filling_utils.cc b/components/autofill/core/browser/autofill_granular_filling_utils.cc index 8cdd06e..2d82638 100644 --- a/components/autofill/core/browser/autofill_granular_filling_utils.cc +++ b/components/autofill/core/browser/autofill_granular_filling_utils.cc
@@ -16,12 +16,13 @@ case FieldTypeGroup::kName: return GetServerFieldTypesOfGroup(FieldTypeGroup::kName); case FieldTypeGroup::kAddress: + case FieldTypeGroup::kCompany: return GetAddressFieldsForGroupFilling(); case FieldTypeGroup::kPhone: return GetServerFieldTypesOfGroup(FieldTypeGroup::kPhone); - case FieldTypeGroup::kNoGroup: case FieldTypeGroup::kEmail: - case FieldTypeGroup::kCompany: + return GetServerFieldTypesOfGroup(FieldTypeGroup::kEmail); + case FieldTypeGroup::kNoGroup: case FieldTypeGroup::kCreditCard: case FieldTypeGroup::kPasswordField: case FieldTypeGroup::kTransaction:
diff --git a/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc b/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc index 7716c9d1..1a9e8b2 100644 --- a/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc +++ b/components/autofill/core/browser/autofill_granular_filling_utils_unittest.cc
@@ -43,12 +43,38 @@ ServerFieldTypeSet({NAME_FIRST})); } +// The test below asserts that when the last targeted fields match +// `AutofillFillingMethod::kGroupFilling`, +// `GetTargetServerFieldsForTypeAndLastTargetedFields()` returns a set of fields +// that match the group of the triggering field. TEST( AutofillGranularFillingUtilsTest, - GetTargetServerFieldsForTypeAndLastTargetedFields_AddressFieldsGroup_ReturnsTriggeringFieldTypeGroup) { + GetTargetServerFieldsForTypeAndLastTargetedFields_GroupFilling_ReturnsTriggeringFieldTypeGroup) { + //`FieldTypeGroup::kName` triggering field. EXPECT_EQ(GetTargetServerFieldsForTypeAndLastTargetedFields( - GetAddressFieldsForGroupFilling(), NAME_FIRST), + GetAddressFieldsForGroupFilling(), + /*triggering_field_type=*/NAME_FIRST), GetServerFieldTypesOfGroup(FieldTypeGroup::kName)); + + //`FieldTypeGroup::kCompany` triggering field. + // Note that `FieldTypeGroup::kCompany` behaves the same as + // `FieldTypeGroup::kAddress`. + EXPECT_EQ(GetTargetServerFieldsForTypeAndLastTargetedFields( + GetServerFieldTypesOfGroup(FieldTypeGroup::kName), + /*triggering_field_type=*/COMPANY_NAME), + GetAddressFieldsForGroupFilling()); + + //`FieldTypeGroup::kAddress` triggering field. + EXPECT_EQ(GetTargetServerFieldsForTypeAndLastTargetedFields( + GetServerFieldTypesOfGroup(FieldTypeGroup::kName), + /*triggering_field_type=*/ADDRESS_HOME_LINE1), + GetAddressFieldsForGroupFilling()); + + //`FieldTypeGroup::kEmail` triggering field. + EXPECT_EQ(GetTargetServerFieldsForTypeAndLastTargetedFields( + GetAddressFieldsForGroupFilling(), + /*triggering_field_type=*/EMAIL_ADDRESS), + GetServerFieldTypesOfGroup(FieldTypeGroup::kEmail)); } TEST(
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index b541fc54a..e54aba04 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -420,9 +420,9 @@ LogAutofillTypePredictionsAvailable(log_manager_, queryable_forms); // Query the server if at least one of the forms was parsed. - if (!queryable_forms.empty() && download_manager()) { + if (!queryable_forms.empty() && client().GetDownloadManager()) { NotifyObservers(&Observer::OnBeforeLoadedServerPredictions); - if (!download_manager()->StartQueryRequest( + if (!client().GetDownloadManager()->StartQueryRequest( queryable_forms, driver().IsolationInfo(), GetWeakPtr())) { NotifyObservers(&Observer::OnAfterLoadedServerPredictions); }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 0e6f380..3b355035 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -370,10 +370,6 @@ AutofillDriver& driver() { return *driver_; } const AutofillDriver& driver() const { return *driver_; } - AutofillDownloadManager* download_manager() { - return client().GetDownloadManager(); - } - // The return value shouldn't be cached, retrieve it as needed. AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger() { return form_interactions_ukm_logger_.get();
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index 6bca076..19745bdd 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -848,10 +848,8 @@ // We add an icon to the address (profile) suggestion if there is more than // one profile related field in the form. if (contains_profile_related_fields) { - // TODO(crbug.com/1459990): Remove this hardcoding once the last filling - // granularity is available to this method. Filling granularies different - // than full form will not have an icon. - const bool fill_full_form = true; + const bool fill_full_form = + suggestions.back().popup_item_id == PopupItemId::kAddressEntry; if (base::FeatureList::IsEnabled( features::kAutofillGranularFillingAvailable)) { suggestions.back().icon = fill_full_form ? Suggestion::Icon::kLocation @@ -871,6 +869,8 @@ if (base::FeatureList::IsEnabled( features::kAutofillGranularFillingAvailable)) { + // TODO(crbug.com/1502162): Make the granular filling options vary + // depending on the locale. AddGranularFillingChildSuggestions(last_targeted_fields, trigger_field_type, *profile, suggestions.back());
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc index 81026aa..0e6c3047 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -89,6 +89,7 @@ Field(&Suggestion::main_text, Suggestion::Text(main_text, Suggestion::Text::IsPrimary(true))), Field(&Suggestion::payload, payload), + Field(&Suggestion::icon, Suggestion::Icon::kNoIcon), Field(&Suggestion::field_by_field_filling_type_used, std::optional(field_by_field_filling_type_used))); } @@ -1299,20 +1300,23 @@ std::vector<Suggestion> suggestions = CreateSuggestionWithChildrenFromProfile( profile(), absl::optional<ServerFieldTypeSet>(GetAddressFieldsForGroupFilling()), - NAME_FIRST); + NAME_FIRST, {NAME_FIRST, NAME_LAST}); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ(suggestions[0].popup_item_id, PopupItemId::kFillFullName); + EXPECT_EQ(suggestions[0].icon, Suggestion::Icon::kNoIcon); } +// Note that only full form filling has an icon. TEST_F( AutofillChildrenSuggestionsGenenarationTest, CreateSuggestionsFromProfiles_LastTargetedFieldsAreAllServerFields_FullForm) { std::vector<Suggestion> suggestions = CreateSuggestionWithChildrenFromProfile( - profile(), kAllServerFieldTypes, NAME_FIRST); + profile(), kAllServerFieldTypes, NAME_FIRST, {NAME_FIRST, NAME_LAST}); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ(suggestions[0].popup_item_id, PopupItemId::kAddressEntry); + EXPECT_EQ(suggestions[0].icon, Suggestion::Icon::kLocation); } // Fallback to full form (PopupItemId::kAddressEntry) when the last targeted
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 37528da..c3912ed 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -2139,8 +2139,9 @@ client().GetUkmRecorder(), source_id, *submitted_form, submission_time); } - if (!download_manager()) + if (!client().GetDownloadManager()) { return; + } // Check if the form is among the forms that were recently auto-filled. bool was_autofilled = base::Contains(autofilled_form_signatures_, @@ -2154,7 +2155,7 @@ non_empty_types.insert(CREDIT_CARD_VERIFICATION_CODE); } - download_manager()->StartUploadRequest( + client().GetDownloadManager()->StartUploadRequest( *submitted_form, was_autofilled, non_empty_types, /*login_form_signature=*/std::string(), observed_submission, client().GetPrefs(), GetWeakPtr());
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 5583e5570..65c28cb 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -409,35 +409,6 @@ return num_complete_profiles; } -bool FormDataImporter::LogAddressFormImportRequirementMetric( - const AutofillProfile& profile, - LogBuffer* import_log_buffer) { - base::flat_set<autofill_metrics::AddressProfileImportRequirementMetric> - autofill_profile_requirement_results = - GetAutofillProfileRequirementResult(profile, import_log_buffer); - - for (const auto& requirement_result : autofill_profile_requirement_results) { - autofill_metrics::LogAddressFormImportRequirementMetric(requirement_result); - } - - autofill_metrics::LogAddressFormImportCountrySpecificFieldRequirementsMetric( - autofill_profile_requirement_results.contains( - AddressImportRequirement::kZipRequirementViolated), - autofill_profile_requirement_results.contains( - AddressImportRequirement::kStateRequirementViolated), - autofill_profile_requirement_results.contains( - AddressImportRequirement::kCityRequirementViolated), - autofill_profile_requirement_results.contains( - AddressImportRequirement::kLine1RequirementViolated)); - - return !base::ranges::any_of( - kMinimumAddressRequirementViolations, - [&](AddressImportRequirement address_requirement_violation) { - return autofill_profile_requirement_results.contains( - address_requirement_violation); - }); -} - AutofillProfile FormDataImporter::ConstructProfileFromObservedValues( const base::flat_map<ServerFieldType, std::u16string>& observed_values, LogBuffer* import_log_buffer, @@ -628,9 +599,9 @@ bool finalized_import = candidate_profile.FinalizeAfterImport(); // Reject the profile if the validation requirements are not met. - // `IsValidLearnableProfile()` goes first to collect metrics. + // `ValidateNonEmptyValues()` goes first to collect metrics. bool has_invalid_information = - !IsValidLearnableProfile(candidate_profile, import_log_buffer) || + !ValidateNonEmptyValues(candidate_profile, import_log_buffer) || has_multiple_distinct_email_addresses || has_invalid_field_types; // Profiles with valid information qualify for multi-step imports. @@ -646,26 +617,24 @@ RemoveInaccessibleProfileValues(candidate_profile); // Do not import a profile if any of the requirements is violated. - bool all_fulfilled = LogAddressFormImportRequirementMetric( - candidate_profile, import_log_buffer) && + // `IsMinimumAddress()` goes first, since it logs to autofill-internals. + bool all_fulfilled = IsMinimumAddress(candidate_profile, import_log_buffer) && !has_invalid_information; // Collect metrics regarding the requirements for an address profile import. + autofill_metrics::LogAddressFormImportRequirementMetric(candidate_profile); autofill_metrics::LogAddressFormImportRequirementMetric( has_multiple_distinct_email_addresses ? AddressImportRequirement::kEmailAddressUniqueRequirementViolated : AddressImportRequirement::kEmailAddressUniqueRequirementFulfilled); - autofill_metrics::LogAddressFormImportRequirementMetric( has_invalid_field_types ? AddressImportRequirement::kNoInvalidFieldTypesRequirementViolated : AddressImportRequirement::kNoInvalidFieldTypesRequirementFulfilled); - autofill_metrics::LogAddressFormImportRequirementMetric( import_metadata.observed_invalid_country ? AddressImportRequirement::kCountryValidRequirementViolated : AddressImportRequirement::kCountryValidRequirementFulfilled); - autofill_metrics::LogAddressFormImportRequirementMetric( all_fulfilled ? AddressImportRequirement::kOverallRequirementFulfilled : AddressImportRequirement::kOverallRequirementViolated);
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index 9d0dcea3..c6956d4 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -244,12 +244,6 @@ std::vector<AddressProfileImportCandidate>* address_profile_import_candidates); - // Validates that the required fields in the `profile` have values, based on - // the requirements of the `profile`'s country. Accordingly, logs the form - // import requirement metrics. - bool LogAddressFormImportRequirementMetric(const AutofillProfile& profile, - LogBuffer* import_log_buffer); - // Helper method to construct an AutofillProfile out of observed values in the // form. Used during `ExtractAddressProfileFromSection()`. AutofillProfile ConstructProfileFromObservedValues(
diff --git a/components/autofill/core/browser/form_data_importer_utils.cc b/components/autofill/core/browser/form_data_importer_utils.cc index bfcbdf6..10daa36 100644 --- a/components/autofill/core/browser/form_data_importer_utils.cc +++ b/components/autofill/core/browser/form_data_importer_utils.cc
@@ -5,12 +5,8 @@ #include "components/autofill/core/browser/form_data_importer_utils.h" #include "base/containers/contains.h" -#include "base/feature_list.h" -#include "base/ranges/algorithm.h" -#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/geo/autofill_country.h" -#include "components/autofill/core/browser/metrics/profile_import_metrics.h" #include "components/autofill/core/browser/profile_requirement_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_internals/log_message.h" @@ -19,9 +15,6 @@ namespace { -using AddressImportRequirement = - autofill_metrics::AddressProfileImportRequirementMetric; - bool IsOriginPartOfDeletionInfo(const absl::optional<url::Origin>& origin, const history::DeletionInfo& deletion_info) { if (!origin) @@ -35,42 +28,6 @@ } // anonymous namespace -bool IsValidLearnableProfile(const AutofillProfile& profile, - LogBuffer* import_log_buffer) { - // Returns false if `profile` has invalid information for `type`. - auto ValidateAndLog = [&](ServerFieldType type, - AddressImportRequirement valid, - AddressImportRequirement invalid) { - if (profile.IsPresentButInvalid(type)) { - autofill_metrics::LogAddressFormImportRequirementMetric(invalid); - LOG_AF(import_log_buffer) - << LogMessage::kImportAddressProfileFromFormFailed << "Invalid " - << FieldTypeToStringView(type) << "." << CTag{}; - return false; - } else { - autofill_metrics::LogAddressFormImportRequirementMetric(valid); - return true; - } - }; - - // Reject profiles with invalid `EMAIL_ADDRESS`, `ADDRESS_HOME_STATE` or - // `ADDRESS_HOME_ZIP` entries and collect metrics on their validity. - bool all_requirements_satisfied = ValidateAndLog( - EMAIL_ADDRESS, AddressImportRequirement::kEmailValidRequirementFulfilled, - AddressImportRequirement::kEmailValidRequirementViolated); - - all_requirements_satisfied &= - ValidateAndLog(ADDRESS_HOME_STATE, - AddressImportRequirement::kStateValidRequirementFulfilled, - AddressImportRequirement::kStateValidRequirementViolated); - - all_requirements_satisfied &= ValidateAndLog( - ADDRESS_HOME_ZIP, AddressImportRequirement::kZipValidRequirementFulfilled, - AddressImportRequirement::kZipValidRequirementViolated); - - return all_requirements_satisfied; -} - std::string GetPredictedCountryCode( const AutofillProfile& profile, const GeoIpCountryCode& variation_country_code,
diff --git a/components/autofill/core/browser/form_data_importer_utils.h b/components/autofill/core/browser/form_data_importer_utils.h index d19fe86..f5e2679 100644 --- a/components/autofill/core/browser/form_data_importer_utils.h +++ b/components/autofill/core/browser/form_data_importer_utils.h
@@ -106,11 +106,6 @@ const size_t max_size_; }; -// Checks suitability of an an import candidate `profile` by validating some -// of the profiles values. -bool IsValidLearnableProfile(const AutofillProfile& profile, - LogBuffer* import_log_buffer); - // Tries to infer the country `profile` is from, which can be useful to // verify whether the data is sensible. Returns a two-letter ISO country code // by considering, in decreasing order of priority:
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.cc b/components/autofill/core/browser/metrics/autofill_metrics.cc index 5ab743b..21c6759 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics.cc
@@ -76,54 +76,53 @@ {ADDRESS_HOME_APT_NUM, "ApartmentNumber"}, {ADDRESS_HOME_SUBPREMISE, "SubPremise"}}); -// Note: if adding an enum value here, update the corresponding description for -// AutofillFieldPredictionQualityByFieldType in -// tools/metrics/histograms/enums.xml. +// Don't change the enum values because they are recorded in metrics. enum FieldTypeGroupForMetrics { GROUP_AMBIGUOUS = 0, - GROUP_NAME, - GROUP_COMPANY, - GROUP_ADDRESS_LINE_1, - GROUP_ADDRESS_LINE_2, - GROUP_ADDRESS_CITY, - GROUP_ADDRESS_STATE, - GROUP_ADDRESS_ZIP, - GROUP_ADDRESS_COUNTRY, - GROUP_ADDRESS_HOME_STREET_NAME, - GROUP_ADDRESS_HOME_HOUSE_NUMBER, - GROUP_ADDRESS_HOME_SUBPREMISE, - GROUP_PHONE, - GROUP_FAX, // Deprecated. - GROUP_EMAIL, - GROUP_CREDIT_CARD_NAME, - GROUP_CREDIT_CARD_NUMBER, - GROUP_CREDIT_CARD_DATE, - GROUP_CREDIT_CARD_TYPE, - GROUP_PASSWORD, - GROUP_ADDRESS_LINE_3, - GROUP_USERNAME, - GROUP_STREET_ADDRESS, - GROUP_CREDIT_CARD_VERIFICATION, - GROUP_UNFILLABLE, - GROUP_ADDRESS_HOME_APT_NUM, - GROUP_ADDRESS_HOME_SORTING_CODE, - GROUP_ADDRESS_HOME_DEPENDENT_LOCALITY, - GROUP_ADDRESS_HOME_OTHER_SUBUNIT, - GROUP_ADDRESS_HOME_ADDRESS, - GROUP_ADDRESS_HOME_ADDRESS_WITH_NAME, - GROUP_ADDRESS_HOME_FLOOR, - GROUP_UNKNOWN_TYPE, - GROUP_BIRTHDATE, - GROUP_IBAN, - GROUP_ADDRESS_HOME_LANDMARK, - GROUP_ADDRESS_HOME_BETWEEN_STREETS, - GROUP_ADDRESS_HOME_ADMIN_LEVEL2, - GROUP_ADDRESS_HOME_STREET_LOCATION, - GROUP_ADDRESS_HOME_OVERFLOW, - GROUP_DELIVERY_INSTRUCTIONS, - GROUP_ADDRESS_HOME_OVERFLOW_AND_LANDMARK, - GROUP_ADDRESS_HOME_BETWEEN_STREETS_OR_LANDMARK, - // Add new entries here and update enums.xml. + GROUP_NAME = 1, + GROUP_COMPANY = 2, + GROUP_ADDRESS_LINE_1 = 3, + GROUP_ADDRESS_LINE_2 = 4, + GROUP_ADDRESS_CITY = 5, + GROUP_ADDRESS_STATE = 6, + GROUP_ADDRESS_ZIP = 7, + GROUP_ADDRESS_COUNTRY = 8, + GROUP_ADDRESS_HOME_STREET_NAME = 9, + GROUP_ADDRESS_HOME_HOUSE_NUMBER = 10, + GROUP_ADDRESS_HOME_SUBPREMISE = 11, + GROUP_PHONE = 12, + GROUP_FAX = 13, // Deprecated. + GROUP_EMAIL = 14, + GROUP_CREDIT_CARD_NAME = 15, + GROUP_CREDIT_CARD_NUMBER = 16, + GROUP_CREDIT_CARD_DATE = 17, + GROUP_CREDIT_CARD_TYPE = 18, + GROUP_PASSWORD = 19, + GROUP_ADDRESS_LINE_3 = 20, + GROUP_USERNAME = 21, + GROUP_STREET_ADDRESS = 22, + GROUP_CREDIT_CARD_VERIFICATION = 23, + GROUP_UNFILLABLE = 24, + GROUP_ADDRESS_HOME_APT_NUM = 25, + GROUP_ADDRESS_HOME_SORTING_CODE = 26, + GROUP_ADDRESS_HOME_DEPENDENT_LOCALITY = 27, + GROUP_ADDRESS_HOME_OTHER_SUBUNIT = 28, + GROUP_ADDRESS_HOME_ADDRESS = 29, + GROUP_ADDRESS_HOME_ADDRESS_WITH_NAME = 30, + GROUP_ADDRESS_HOME_FLOOR = 31, + GROUP_UNKNOWN_TYPE = 32, + GROUP_BIRTHDATE = 33, + GROUP_IBAN = 34, + GROUP_ADDRESS_HOME_LANDMARK = 35, + GROUP_ADDRESS_HOME_BETWEEN_STREETS = 36, + GROUP_ADDRESS_HOME_ADMIN_LEVEL2 = 37, + GROUP_ADDRESS_HOME_STREET_LOCATION = 38, + GROUP_ADDRESS_HOME_OVERFLOW = 39, + GROUP_DELIVERY_INSTRUCTIONS = 40, + GROUP_ADDRESS_HOME_OVERFLOW_AND_LANDMARK = 41, + GROUP_ADDRESS_HOME_BETWEEN_STREETS_OR_LANDMARK = 42, + // Note: if adding an enum value here, run + // tools/metrics/histograms/update_autofill_enums.py NUM_FIELD_TYPE_GROUPS_FOR_METRICS };
diff --git a/components/autofill/core/browser/metrics/profile_import_metrics.cc b/components/autofill/core/browser/metrics/profile_import_metrics.cc index 7c2f37e..2f6eddf2 100644 --- a/components/autofill/core/browser/metrics/profile_import_metrics.cc +++ b/components/autofill/core/browser/metrics/profile_import_metrics.cc
@@ -4,9 +4,11 @@ #include "components/autofill/core/browser/metrics/profile_import_metrics.h" +#include "base/containers/contains.h" #include "base/metrics/histogram_functions.h" #include "base/strings/strcat.h" #include "components/autofill/core/browser/metrics/autofill_metrics_utils.h" +#include "components/autofill/core/browser/profile_requirement_utils.h" #include "services/metrics/public/cpp/ukm_builders.h" namespace autofill::autofill_metrics { @@ -70,11 +72,25 @@ metric); } -void LogAddressFormImportCountrySpecificFieldRequirementsMetric( - bool is_zip_missing, - bool is_state_missing, - bool is_city_missing, - bool is_line1_missing) { +void LogAddressFormImportRequirementMetric(const AutofillProfile& profile) { + std::vector<AddressProfileImportRequirementMetric> requirements = + ValidateProfileImportRequirements(profile); + for (AddressProfileImportRequirementMetric& requirement : requirements) { + LogAddressFormImportRequirementMetric(requirement); + } + + bool is_zip_missing = base::Contains( + requirements, + AddressProfileImportRequirementMetric::kZipRequirementViolated); + bool is_state_missing = base::Contains( + requirements, + AddressProfileImportRequirementMetric::kStateRequirementViolated); + bool is_city_missing = base::Contains( + requirements, + AddressProfileImportRequirementMetric::kCityRequirementViolated); + bool is_line1_missing = base::Contains( + requirements, + AddressProfileImportRequirementMetric::kLine1RequirementViolated); const auto metric = static_cast<AddressProfileImportCountrySpecificFieldRequirementsMetric>( (is_zip_missing ? 0b1 : 0) | (is_state_missing ? 0b10 : 0) |
diff --git a/components/autofill/core/browser/metrics/profile_import_metrics.h b/components/autofill/core/browser/metrics/profile_import_metrics.h index 1db900b9..b5c52a2b 100644 --- a/components/autofill/core/browser/metrics/profile_import_metrics.h +++ b/components/autofill/core/browser/metrics/profile_import_metrics.h
@@ -117,13 +117,9 @@ void LogAddressFormImportRequirementMetric( AddressProfileImportRequirementMetric metric); -// Logs the overall status of the country specific field requirements for -// importing an address profile from a submitted form. -void LogAddressFormImportCountrySpecificFieldRequirementsMetric( - bool is_zip_missing, - bool is_state_missing, - bool is_city_missing, - bool is_line1_missing); +// Validates the profile import requirements and emits all the results. +// Additionally, logs country-specific field requirement metrics. +void LogAddressFormImportRequirementMetric(const AutofillProfile& profile); // Logs the overall status of an address import upon form submission. void LogAddressFormImportStatusMetric(AddressProfileImportStatusMetric metric);
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 48c210c..891e537 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -2290,22 +2290,13 @@ EXPECT_EQ(0U, personal_data_->GetProfilesToSuggest().size()); } -// Test that local profiles are not added if |kAutofillProfileEnabled| is set to -// |false|. +// Test that profiles are not added if `kAutofillProfileEnabled` is set to +// false. TEST_F(PersonalDataManagerTest, GetProfilesToSuggest_NoProfilesAddedIfDisabled) { - // Disable Profile autofill. prefs::SetAutofillProfileEnabled(personal_data_->pref_service_, false); - - // Add a local profile. - AutofillProfile local_profile; - test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz", - "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", - "Orlando", "FL", "32801", "US", "19482937549"); - AddProfileToPersonalDataManager(local_profile); - - // Expect no profile values or suggestions were added. - EXPECT_EQ(0U, personal_data_->GetProfiles().size()); + AddProfileToPersonalDataManager(test::GetFullProfile()); + EXPECT_TRUE(personal_data_->GetProfiles().empty()); } TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) {
diff --git a/components/autofill/core/browser/profile_requirement_utils.cc b/components/autofill/core/browser/profile_requirement_utils.cc index 09a021d..282ae5d 100644 --- a/components/autofill/core/browser/profile_requirement_utils.cc +++ b/components/autofill/core/browser/profile_requirement_utils.cc
@@ -5,6 +5,7 @@ #include "components/autofill/core/browser/profile_requirement_utils.h" #include <string_view> +#include <vector> #include "base/containers/contains.h" #include "base/strings/utf_string_conversions.h" @@ -19,11 +20,22 @@ using AddressImportRequirement = autofill_metrics::AddressProfileImportRequirementMetric; +// Stores the collection of AddressImportRequirement that are violated. These +// violation prevents the import of a profile. +constexpr AddressImportRequirement kMinimumAddressRequirementViolations[] = { + AddressImportRequirement::kLine1RequirementViolated, + AddressImportRequirement::kCityRequirementViolated, + AddressImportRequirement::kStateRequirementViolated, + AddressImportRequirement::kZipRequirementViolated, + AddressImportRequirement::kZipOrStateRequirementViolated, + AddressImportRequirement::kLine1OrHouseNumberRequirementViolated, + AddressImportRequirement::kNameRequirementViolated}; + } // anonymous namespace -base::flat_set<autofill_metrics::AddressProfileImportRequirementMetric> -GetAutofillProfileRequirementResult(const AutofillProfile& profile, - LogBuffer* import_log_buffer) { +std::vector<autofill_metrics::AddressProfileImportRequirementMetric> +ValidateProfileImportRequirements(const AutofillProfile& profile, + LogBuffer* import_log_buffer) { CHECK(profile.HasInfo(ADDRESS_HOME_COUNTRY)); std::vector<AddressImportRequirement> address_import_requirements; @@ -66,58 +78,88 @@ country.requires_line1(), {ADDRESS_HOME_LINE1, ADDRESS_HOME_STREET_NAME}, AddressImportRequirement::kLine1RequirementFulfilled, AddressImportRequirement::kLine1RequirementViolated); - is_valid &= ValidateAndLog(country.requires_city(), {ADDRESS_HOME_CITY}, AddressImportRequirement::kCityRequirementFulfilled, AddressImportRequirement::kCityRequirementViolated); - is_valid &= ValidateAndLog(country.requires_state(), {ADDRESS_HOME_STATE}, AddressImportRequirement::kStateRequirementFulfilled, AddressImportRequirement::kStateRequirementViolated); - is_valid &= ValidateAndLog(country.requires_zip(), {ADDRESS_HOME_ZIP}, AddressImportRequirement::kZipRequirementFulfilled, AddressImportRequirement::kZipRequirementViolated); - is_valid &= ValidateAndLog( country.requires_zip_or_state(), {ADDRESS_HOME_ZIP, ADDRESS_HOME_STATE}, AddressImportRequirement::kZipOrStateRequirementFulfilled, AddressImportRequirement::kZipOrStateRequirementViolated); - is_valid &= ValidateAndLog( country.requires_line1_or_house_number(), {ADDRESS_HOME_LINE1, ADDRESS_HOME_HOUSE_NUMBER}, AddressImportRequirement::kLine1OrHouseNumberRequirementFulfilled, AddressImportRequirement::kLine1OrHouseNumberRequirementViolated); - - // TODO(crbug.com/1413205): Merge this into is_minimum_address. + // TODO(crbug.com/1413205): Only check for the full name if all other + // requirements are fulfilled. This is relevant for feature-enrolement. + // Remove `is_valid` and check in every case once the feature is launched. if (is_valid && country.requires_full_name()) { ValidateAndLog(/*required=*/true, {NAME_FULL}, AddressImportRequirement::kNameRequirementFulfilled, AddressImportRequirement::kNameRequirementViolated); } - return base::flat_set<AddressImportRequirement>( - std::move(address_import_requirements)); + return address_import_requirements; } -bool IsMinimumAddress(const AutofillProfile& profile) { +bool ValidateNonEmptyValues(const AutofillProfile& profile, + LogBuffer* log_buffer) { + // Returns false if `profile` has invalid information for `type`. + auto ValidateAndLog = [&](ServerFieldType type, + AddressImportRequirement valid, + AddressImportRequirement invalid) { + if (profile.IsPresentButInvalid(type)) { + autofill_metrics::LogAddressFormImportRequirementMetric(invalid); + LOG_AF(log_buffer) << LogMessage::kImportAddressProfileFromFormFailed + << "Invalid " << FieldTypeToStringView(type) << "." + << CTag{}; + return false; + } else { + autofill_metrics::LogAddressFormImportRequirementMetric(valid); + return true; + } + }; + + // Reject profiles with invalid `EMAIL_ADDRESS`, `ADDRESS_HOME_STATE` or + // `ADDRESS_HOME_ZIP` entries and collect metrics on their validity. + bool all_requirements_satisfied = ValidateAndLog( + EMAIL_ADDRESS, AddressImportRequirement::kEmailValidRequirementFulfilled, + AddressImportRequirement::kEmailValidRequirementViolated); + + all_requirements_satisfied &= + ValidateAndLog(ADDRESS_HOME_STATE, + AddressImportRequirement::kStateValidRequirementFulfilled, + AddressImportRequirement::kStateValidRequirementViolated); + + all_requirements_satisfied &= ValidateAndLog( + ADDRESS_HOME_ZIP, AddressImportRequirement::kZipValidRequirementFulfilled, + AddressImportRequirement::kZipValidRequirementViolated); + + return all_requirements_satisfied; +} + +bool IsMinimumAddress(const AutofillProfile& profile, LogBuffer* log_buffer) { const std::vector<std::string>& country_codes = autofill::CountryDataMap::GetInstance()->country_codes(); if (!base::Contains(country_codes, base::UTF16ToUTF8(profile.GetRawInfo( ADDRESS_HOME_COUNTRY)))) { return false; } - base::flat_set<AddressImportRequirement> address_import_requirements = - GetAutofillProfileRequirementResult(profile, - /*import_log_buffer=*/nullptr); + std::vector<AddressImportRequirement> address_requirements = + ValidateProfileImportRequirements(profile, log_buffer); return !base::ranges::any_of( kMinimumAddressRequirementViolations, [&](AddressImportRequirement address_requirement_violation) { - return address_import_requirements.contains( - address_requirement_violation); + return base::Contains(address_requirements, + address_requirement_violation); }); }
diff --git a/components/autofill/core/browser/profile_requirement_utils.h b/components/autofill/core/browser/profile_requirement_utils.h index 233e245..b2263d0 100644 --- a/components/autofill/core/browser/profile_requirement_utils.h +++ b/components/autofill/core/browser/profile_requirement_utils.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PROFILE_REQUIREMENT_UTILS_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_PROFILE_REQUIREMENT_UTILS_H_ +#include <vector> + #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/metrics/profile_import_metrics.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -12,42 +14,30 @@ namespace autofill { -// Stores the collection of AddressProfileImportRequirementMetric that are -// violated. These violation prevents the import of a profile. -constexpr autofill_metrics::AddressProfileImportRequirementMetric - kMinimumAddressRequirementViolations[] = { - autofill_metrics::AddressProfileImportRequirementMetric:: - kLine1RequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kCityRequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kStateRequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kZipRequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kZipOrStateRequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kLine1OrHouseNumberRequirementViolated, - autofill_metrics::AddressProfileImportRequirementMetric:: - kNameRequirementViolated}; +// Checks the country-specific import requirements of the `profile` by ensuring +// that certain types have a non-empty value. For each requirement the function +// returns either the fulfilled or violated enum entry. An address submitted via +// a form must have at least the fields required as determined by its country +// code. No verification of validity of the contents is performed. This is an +// existence check only. Assumes `profile` has been finalized. Introducing +// additional profile import checks should be complemented with adding to the +// violations list in `kMinimumAddressRequirementViolations`. If `log_buffer` is +// present, validation results are logged there. +std::vector<autofill_metrics::AddressProfileImportRequirementMetric> +ValidateProfileImportRequirements(const AutofillProfile& profile, + LogBuffer* log_buffer = nullptr); -// Does requirement checks on the `profile`. Either the requirements are -// fulfilled or they are violated. An address submitted via a form must have at -// least the fields required as determined by its country code. No verification -// of validity of the contents is performed. This is an existence check only. -// Assumes `profile` has been finalized. -// Introducing additional profile import checks should be complemented with -// adding to the violations list in -// `autofill_metrics::kMinimumAddressRequirementViolations`. -base::flat_set<autofill_metrics::AddressProfileImportRequirementMetric> -GetAutofillProfileRequirementResult(const AutofillProfile& profile, - LogBuffer* import_log_buffer); +// Validates non-empty values for certain types (e.g. is the email address +// an actual email address). Emits metrics for all violate (= non-empty and +// invalid) types. +// Returns true if all non-empty values are valid. +bool ValidateNonEmptyValues(const AutofillProfile& profile, + LogBuffer* log_buffer); -// Returns true if minimum requirements for import of a given `profile` have -// been met. -// Uses the country_code from `profile` to fetch the requirements and the run -// the validations. -bool IsMinimumAddress(const AutofillProfile& profile); +// Returns true if the minimum requirements to import the `profile` are met. +// If `log_buffer` is present, validation results are logged there. +bool IsMinimumAddress(const AutofillProfile& profile, + LogBuffer* log_buffer = nullptr); // Returns true if the profile can be migrated to the Account. Only sufficiently // complete profiles are migrated and this method does not check for the
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc index f612bd4..f2eccd1 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_sync_difference_tracker.cc
@@ -111,12 +111,11 @@ // deletion of A. In most cases the redundant deletion does not even // get sent as the processor already knows A got deleted remotely. // 2) Remote entity B got uploaded by another client through race - // condition (i.e. not knowing about A, yet). In practice, this only - // happens when two clients simultaneously convert a server profile - // into local profiles. If the other client goes offline before - // receiving A, this client is responsible for deleting A from the - // server and thus must issue a deletion. (In most cases, the other - // client does not go offline and thus both clients issue a deletion + // condition (i.e. not knowing about A, yet). If the other client + // goes offline before receiving A, this client is responsible for + // deleting A from the server and thus must issue a deletion. (In + // most cases, the other client does not go offline and thus both + // clients issue a deletion) // of A independently). // 3) (a paranoid case) Remote entity B got uploaded by another client // by an error, i.e. already as a duplicate given their local state.
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h index d5a305a..e50041f 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h +++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
@@ -114,18 +114,15 @@ const std::u16string& value, WebDatabase* db); - // Adds an Autofill profile to the web database. Valid only for local - // profiles. + // Adds an Autofill profile to the web database. WebDatabase::State AddAutofillProfile(const AutofillProfile& profile, WebDatabase* db); - // Updates an Autofill profile in the web database. Valid only for local - // profiles. + // Updates an Autofill profile in the web database. WebDatabase::State UpdateAutofillProfile(const AutofillProfile& profile, WebDatabase* db); - // Removes an Autofill profile from the web database. Valid only for local - // profiles. + // Removes an Autofill profile from the web database. WebDatabase::State RemoveAutofillProfile( const std::string& guid, AutofillProfile::Source profile_source, @@ -226,15 +223,15 @@ WebDatabase::State ClearAllServerData(WebDatabase* db); WebDatabase::State ClearAllLocalData(WebDatabase* db); - // Removes Autofill records from the database. Valid only for local - // cards/profiles. + // Removes Autofill records from the database. Valid only for local cards and + // kLocalOrSyncable profiles. WebDatabase::State RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end, WebDatabase* db); - // Removes origin URLs associated with Autofill profiles and credit cards - // from the database. Valid only for local cards/profiles. + // Removes origin URLs associated with local credit cards from the database. + // Autofill profiles don't store an origin, so this doesn't apply to them. WebDatabase::State RemoveOriginURLsModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end,
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 1925410..b57f3a0 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -336,7 +336,6 @@ // Replaces cached web elements in AutofillAgent and FormTracker by their // renderer ids. -// DONOTSUMBIT: Disable. BASE_FEATURE(kAutofillReplaceCachedWebElementsByRendererIds, "AutofillReplaceCachedWebElementsByRendererIds", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/autofill/ios/browser/autofill_util.h b/components/autofill/ios/browser/autofill_util.h index 41097ab..3b9d37a 100644 --- a/components/autofill/ios/browser/autofill_util.h +++ b/components/autofill/ios/browser/autofill_util.h
@@ -5,10 +5,11 @@ #ifndef COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_UTIL_H_ #define COMPONENTS_AUTOFILL_IOS_BROWSER_AUTOFILL_UTIL_H_ -#include <vector> +#import <optional> +#import <vector> -#include "base/values.h" - +#import "base/unguessable_token.h" +#import "base/values.h" #import "ios/web/public/js_messaging/web_frame.h" class GURL; @@ -23,6 +24,7 @@ struct FormData; struct FormFieldData; class FieldDataManager; +struct FrameTokenWithPredecessor; // Checks if current context is secure from an autofill standpoint. bool IsContextSecureForWebState(web::WebState* web_state); @@ -31,6 +33,12 @@ // unsuccessful. std::unique_ptr<base::Value> ParseJson(NSString* json_string); +// Local and remote frame IDs generated in JavaScript are equivalent to +// base::UnguessableToken (128 bits, cryptographically random). Returns a +// base::UnguessableToken equivalent to the given JS-generated ID. +std::optional<base::UnguessableToken> DeserializeJavaScriptFrameId( + const std::string& frame_id); + // Processes the JSON form data extracted from the page into the format expected // by BrowserAutofillManager and fills it in |forms_data|. // |forms_data| cannot be nil. @@ -65,6 +73,12 @@ const FieldDataManager& field_data_manager, FormFieldData* field_data); +// Extracts a single child frame's data from the JSON dictionary into a +// FrameTokenWithPredecessor object. Returns false if the data could not be +// extracted. +bool ExtractRemoteFrameToken(const base::Value::Dict& frame_data, + FrameTokenWithPredecessor* token_with_predecessor); + typedef base::OnceCallback<void(const base::Value*)> JavaScriptResultCallback; // Creates a callback for a string JS function return type.
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm index 386e15a1..068307d 100644 --- a/components/autofill/ios/browser/autofill_util.mm +++ b/components/autofill/ios/browser/autofill_util.mm
@@ -4,30 +4,31 @@ #import "components/autofill/ios/browser/autofill_util.h" -#include <utility> +#import <utility> -#include "base/apple/foundation_util.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/types/cxx23_to_underlying.h" -#include "base/values.h" -#include "components/autofill/core/browser/autofill_field.h" -#include "components/autofill/core/common/autocomplete_parsing_util.h" -#include "components/autofill/core/common/autofill_util.h" +#import "base/apple/foundation_util.h" +#import "base/functional/bind.h" +#import "base/functional/callback.h" +#import "base/json/json_reader.h" +#import "base/json/json_writer.h" +#import "base/strings/string_number_conversions.h" +#import "base/strings/sys_string_conversions.h" +#import "base/strings/utf_string_conversions.h" +#import "base/types/cxx23_to_underlying.h" +#import "base/values.h" +#import "components/autofill/core/browser/autofill_field.h" +#import "components/autofill/core/common/autocomplete_parsing_util.h" +#import "components/autofill/core/common/autofill_features.h" +#import "components/autofill/core/common/autofill_util.h" #import "components/autofill/core/common/field_data_manager.h" -#include "components/autofill/core/common/form_data.h" -#include "components/autofill/core/common/form_field_data.h" +#import "components/autofill/core/common/form_data.h" +#import "components/autofill/core/common/form_field_data.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" -#include "ios/web/public/security/ssl_status.h" +#import "ios/web/public/security/ssl_status.h" #import "ios/web/public/web_state.h" -#include "url/gurl.h" -#include "url/origin.h" +#import "url/gurl.h" +#import "url/origin.h" using autofill::FormControlType; using base::NumberToString; @@ -91,6 +92,26 @@ return base::Value::ToUniquePtrValue(std::move(*json_value)); } +std::optional<base::UnguessableToken> DeserializeJavaScriptFrameId( + const std::string& frame_id) { + // A valid ID is 128 bits, or 32 hex digits. + if (frame_id.length() != 32) { + return {}; + } + + // Break string into first and last 16 hex digits. + std::string high_hex = frame_id.substr(0, 16); + std::string low_hex = frame_id.substr(16); + + uint64_t high, low; + if (!base::HexStringToUInt64(high_hex, &high) || + !base::HexStringToUInt64(low_hex, &low)) { + return {}; + } + + return base::UnguessableToken::Deserialize(high, low); +} + bool ExtractFormsData(NSString* forms_json, bool filtered, const std::u16string& form_name, @@ -186,6 +207,21 @@ form_data->frame_id = *frame_id; } + if (base::FeatureList::IsEnabled( + autofill::features::kAutofillAcrossIframesIos)) { + // Child frame tokens, optional. + if (const base::Value::List* child_frames_list = + form.FindList("child_frames")) { + for (const auto& frame_dict : *child_frames_list) { + autofill::FrameTokenWithPredecessor token; + if (frame_dict.is_dict() && + ExtractRemoteFrameToken(frame_dict.GetDict(), &token)) { + form_data->child_frames.push_back(std::move(token)); + } + } + } + } + // Field list (mandatory) is extracted. const base::Value::List* fields_list = form.FindList("fields"); if (!fields_list) { @@ -317,6 +353,31 @@ return true; } +bool ExtractRemoteFrameToken( + const base::Value::Dict& frame_data, + FrameTokenWithPredecessor* token_with_predecessor) { + const std::string* frame_id = frame_data.FindString("token"); + if (!frame_id) { + return false; + } + + std::optional<base::UnguessableToken> token = + DeserializeJavaScriptFrameId(*frame_id); + if (!token) { + return false; + } + + const std::optional<double> predecessor = + frame_data.FindDouble("predecessor"); + if (!predecessor) { + return false; + } + + token_with_predecessor->token = RemoteFrameToken(*token); + token_with_predecessor->predecessor = *predecessor; + return true; +} + JavaScriptResultCallback CreateStringCallback( void (^completionHandler)(NSString*)) { return CreateStringCallback(base::BindOnce(completionHandler));
diff --git a/components/autofill/ios/browser/autofill_util_unittests.mm b/components/autofill/ios/browser/autofill_util_unittests.mm index 425edb6..ee4467e 100644 --- a/components/autofill/ios/browser/autofill_util_unittests.mm +++ b/components/autofill/ios/browser/autofill_util_unittests.mm
@@ -5,12 +5,13 @@ #import "components/autofill/ios/browser/autofill_util.h" #import "base/memory/scoped_refptr.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" +#import "base/strings/utf_string_conversions.h" +#import "base/values.h" #import "components/autofill/core/common/field_data_manager.h" +#import "components/autofill/core/common/form_data.h" #import "components/autofill/core/common/form_field_data.h" #import "components/autofill/core/common/unique_ids.h" -#include "testing/platform_test.h" +#import "testing/platform_test.h" using AutofillUtilTest = PlatformTest; @@ -81,3 +82,56 @@ EXPECT_EQ(autofill::FieldPropertiesFlags::kUserTyped, field_data.properties_mask); } + +// Tests various aspects of converting hex IDs equivalent to those generated by +// JavaScript into UnguessableTokens. +TEST_F(AutofillUtilTest, DeserializeTokens) { + // Should work with a 32-character (128-bit) hex string. Also test that + // hex conversion is robust to upper/lower case. + auto token = autofill::DeserializeJavaScriptFrameId( + "0123456789abcdef0123456789ABCDEF"); + ASSERT_TRUE(token.has_value()); + EXPECT_EQ("0123456789abcdef0123456789abcdef", + base::ToLowerASCII(token->ToString())); + + // Should fail if the string has the wrong length + token = autofill::DeserializeJavaScriptFrameId(std::string(4, '1')); + EXPECT_FALSE(token.has_value()); + token = autofill::DeserializeJavaScriptFrameId(std::string(34, 'f')); + EXPECT_FALSE(token.has_value()); + + // Should fail if the string isn't hex + token = autofill::DeserializeJavaScriptFrameId(std::string(32, '?')); + EXPECT_FALSE(token.has_value()); +} + +// Test that the properties mask is extracted from the form field data. +TEST_F(AutofillUtilTest, ExtractRemoteFrameToken) { + base::Value::Dict remote_frame_token_dict; + remote_frame_token_dict.Set("token", + base::Value("beefbeefbeefbeefcafecafecafecafe")); + remote_frame_token_dict.Set("predecessor", base::Value(64)); + + autofill::FrameTokenWithPredecessor token_with_predecessor; + + ASSERT_TRUE(ExtractRemoteFrameToken(remote_frame_token_dict, + &token_with_predecessor)); + EXPECT_EQ(base::ToLowerASCII(absl::get<autofill::RemoteFrameToken>( + token_with_predecessor.token) + .ToString()), + "beefbeefbeefbeefcafecafecafecafe"); + EXPECT_EQ(token_with_predecessor.predecessor, 64); + + base::Value::Dict malformed1; + malformed1.Set("garbage", base::Value("garbage")); + EXPECT_FALSE(ExtractRemoteFrameToken(malformed1, &token_with_predecessor)); + + base::Value::Dict malformed2; + malformed2.Set("token", base::Value("garbage")); + EXPECT_FALSE(ExtractRemoteFrameToken(malformed2, &token_with_predecessor)); + + base::Value::Dict malformed3; + malformed3.Set("token", base::Value("beefbeefbeefbeefcafecafecafecafe")); + malformed3.Set("predecessor", base::Value("garbage")); + EXPECT_FALSE(ExtractRemoteFrameToken(malformed3, &token_with_predecessor)); +}
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb index 038d2f5c..03185bd5 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ar.xtb
@@ -192,6 +192,7 @@ <translation id="4278390842282768270">مسموح به</translation> <translation id="429312253194641664">تفعيل موقع إلكتروني للوسائط</translation> <translation id="42981349822642051">توسيع</translation> +<translation id="4336566011000459927">سيعيد Chrome فرض قيود على ملفات تعريف الارتباط اليوم.</translation> <translation id="4338831206024587507">جميع المواقع الإلكترونية ضمن <ph name="DOMAIN" /></translation> <translation id="4402755511846832236">منع المواقع الإلكترونية من رصد استخدامك النشط لهذا الجهاز</translation> <translation id="4412992751769744546">السماح بملفات تعريف الارتباط التابعة لجهات خارجية</translation> @@ -294,6 +295,7 @@ <translation id="6177128806592000436">إن اتصالك بهذا الموقع غير آمن</translation> <translation id="6181444274883918285">إضافة موقع إلكتروني إلى قائمة الاستثناءات</translation> <translation id="6192792657125177640">الاستثناءات</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{سيعيد Chrome حظر ملفات تعريف الارتباط غدًا.}zero{يتبقى # يوم إلى أن يتم حظر ملفات تعريف الارتباط مرة أخرى.}two{يتبقى يومان إلى أن يتم حظر ملفات تعريف الارتباط مرة أخرى.}few{تتبقى # أيام إلى أن يتم حظر ملفات تعريف الارتباط مرة أخرى.}many{يتبقى # يومًا إلى أن يتم حظر ملفات تعريف الارتباط مرة أخرى.}other{يتبقى # يوم إلى أن يتم حظر ملفات تعريف الارتباط مرة أخرى.}}</translation> <translation id="6195163219142236913">ملفات تعريف الارتباط التابعة لجهات خارجية محدودة</translation> <translation id="6196640612572343990">حظر ملفات تعريف الارتباط التابعة لجهات خارجية</translation> <translation id="6205314730813004066">الخصوصية في عرض الإعلانات</translation> @@ -383,6 +385,7 @@ <translation id="780301667611848630">لا، شكرًا</translation> <translation id="7804248752222191302">هناك موقع إلكتروني يستخدم الكاميرا.</translation> <translation id="7807060072011926525">خلاصة مقدَّمة من Google</translation> +<translation id="7822573154188733812">يمنع Chrome المواقع الإلكترونية من استخدام ملفات تعريف الارتباط التابعة لجهات خارجية لتتبُّع نشاطك أثناء التصفُّح. انتقِل إلى الإعدادات من أجل <ph name="BEGIN_LINK" />إدارة إجراءات الحماية من التتبُّع<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">تشغيل الوسائط</translation> <translation id="783819812427904514">إعادة صوت الفيديو</translation> <translation id="7846076177841592234">إلغاء الاختيار</translation> @@ -399,6 +402,7 @@ <translation id="8077120325605624147">السماح لأي موقع إلكتروني تزوره بعرض أي إعلان لك</translation> <translation id="8087000398470557479">هذا المحتوى من <ph name="DOMAIN_NAME" />، وتم عرضه من قبل Google.</translation> <translation id="8088603949666785339">مزيد من الخيارات في "<ph name="BANNER_TITLE" />"</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{سيعيد Chrome فرض قيود على ملفات تعريف الارتباط غدًا.}zero{يتبقى # يوم إلى أن يعيد Chrome فرض قيود على ملفات تعريف الارتباط.}two{يتبقى يومان إلى أن يعيد Chrome فرض قيود على ملفات تعريف الارتباط.}few{تتبقى # أيام إلى أن يعيد Chrome فرض قيود على ملفات تعريف الارتباط.}many{يتبقى # يومًا إلى أن يعيد Chrome فرض قيود على ملفات تعريف الارتباط.}other{يتبقى # يوم إلى أن يعيد Chrome فرض قيود على ملفات تعريف الارتباط.}}</translation> <translation id="8116925261070264013">المواقع الإلكترونية التي تم كتم الصوت فيها</translation> <translation id="813082847718468539">عرض معلومات الموقع</translation> <translation id="8131740175452115882">التأكيد</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb index 4239c39..09eb1f7c 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_as.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">অনুমতি দিয়া হৈছে</translation> <translation id="429312253194641664">ছাইটটোৱে মিডিয়া প্লে’ কৰি আছে</translation> <translation id="42981349822642051">বিস্তাৰ কৰক</translation> +<translation id="4336566011000459927">Chromeএ আজি পুনৰ কুকি সীমিত কৰিব</translation> <translation id="4338831206024587507"><ph name="DOMAIN" />ৰ অধীনত থকা আটাইবোৰ ছাইট</translation> <translation id="4402755511846832236">আপুনি এই ডিভাইচটো সক্ৰিয়ভাৱে ব্যৱহাৰ কৰি থকাৰ বিষয়ে ছাইটসমূহে জনাটো অৱৰোধ কৰক</translation> <translation id="4412992751769744546">তৃতীয় পক্ষৰ কুকিৰ অনুমতি দিয়ক</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">এই ছাইটলৈ থকা আপোনাৰ সংযোগটো সুৰক্ষিত নহয়</translation> <translation id="6181444274883918285">ব্যতিক্ৰম ছাইট যোগ কৰক</translation> <translation id="6192792657125177640">ব্যতিক্রমসমূহ</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chromeএ কাইলৈ পুনৰ কুকি অৱৰোধ কৰিব}one{কুকিসমূহ পুনৰ অৱৰোধ কৰালৈ # দিন আছে}other{কুকিসমূহ পুনৰ অৱৰোধ কৰালৈ # দিন আছে}}</translation> <translation id="6195163219142236913">তৃতীয় পক্ষৰ কুকি সীমিত কৰা হৈছে</translation> <translation id="6196640612572343990">তৃতীয়-পক্ষৰ কুকিসমূহ অৱৰোধ কৰক</translation> <translation id="6205314730813004066">বিজ্ঞাপনৰ গোপনীয়তা</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">নালাগে, ধন্যবাদ</translation> <translation id="7804248752222191302">এটা ছাইটে আপোনাৰ কেমেৰা ব্যৱহাৰ কৰি আছে</translation> <translation id="7807060072011926525">Googleএ প্ৰদান কৰিছে</translation> +<translation id="7822573154188733812">আপুনি ব্ৰাউজ কৰি থাকোঁতে ছাইটসমূহে আপোনাক ট্ৰেক কৰিবলৈ তৃতীয় পক্ষৰ কুকিৰ ব্যৱহাৰ কৰাটো Chromeএ অৱৰোধ কৰে। <ph name="BEGIN_LINK" />আপোনাৰ ট্ৰেকিঙৰ সুৰক্ষাসমূহ পৰিচালনা কৰিবলৈ<ph name="END_LINK" /> ছেটিঙলৈ যাওক।</translation> <translation id="7835852323729233924">মিডিয়া প্লে’ হৈ আছে</translation> <translation id="783819812427904514">ভিডিঅ' আনমিউট কৰক</translation> <translation id="7846076177841592234">বাছনি বাতিল কৰক</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">আপুনি চোৱা যিকোনো ছাইটে আপোনাক যিকোনো বিজ্ঞাপন দেখুৱাব পাৰে</translation> <translation id="8087000398470557479">এই সমল Googleএ যোগান ধৰা <ph name="DOMAIN_NAME" />ৰ।</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" />টোত অধিক বিকল্প</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chromeএ কাইলৈ পুনৰ কুকি সীমিত কৰিব}one{Chromeএ পুনৰ কুকি সীমিত কৰিবলৈ # দিন আছে}other{Chromeএ পুনৰ কুকি সীমিত কৰিবলৈ # দিন আছে}}</translation> <translation id="8116925261070264013">মিউট আছে</translation> <translation id="813082847718468539">ছাইটৰ তথ্য চাওক</translation> <translation id="8131740175452115882">নিশ্চিত কৰক</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb index b846e873..eb663277 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ca.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">Permès</translation> <translation id="429312253194641664">Un lloc web està reproduint contingut multimèdia</translation> <translation id="42981349822642051">Desplega</translation> +<translation id="4336566011000459927">Chrome tornarà a limitar les galetes avui</translation> <translation id="4338831206024587507">Tots els llocs web de <ph name="DOMAIN" /></translation> <translation id="4402755511846832236">Bloqueja els llocs web perquè no sàpiguen quan estàs utilitzant aquest dispositiu de manera activa</translation> <translation id="4412992751769744546">Permet les galetes de tercers</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">La connexió amb aquest lloc web no és segura</translation> <translation id="6181444274883918285">Afegeix excepció per a un lloc web</translation> <translation id="6192792657125177640">Excepcions</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome tornarà a bloquejar les galetes demà}other{# dies perquè es tornin a bloquejar les galetes}}</translation> <translation id="6195163219142236913">Galetes de tercers limitades</translation> <translation id="6196640612572343990">Bloqueja les galetes de tercers</translation> <translation id="6205314730813004066">Privadesa d'anuncis</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">No, gràcies</translation> <translation id="7804248752222191302">Un lloc web està utilitzant la càmera</translation> <translation id="7807060072011926525">Proporcionat per Google</translation> +<translation id="7822573154188733812">Chrome bloqueja els llocs web perquè no utilitzin galetes de tercers per fer un seguiment de la teva activitat mentre navegues. Visita la configuració per <ph name="BEGIN_LINK" />gestionar les proteccions de seguiment<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Reproduint contingut multimèdia</translation> <translation id="783819812427904514">Deixa de silenciar el vídeo</translation> <translation id="7846076177841592234">Cancel·la la selecció</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">Qualsevol lloc web que visitis pot mostrar-te qualsevol anunci</translation> <translation id="8087000398470557479">Aquest contingut és del domini <ph name="DOMAIN_NAME" />, oferit per Google.</translation> <translation id="8088603949666785339">Més opcions a <ph name="BANNER_TITLE" /></translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome tornarà a limitar les galetes demà}other{# dies perquè Chrome torni a limitar les galetes}}</translation> <translation id="8116925261070264013">Silenciats</translation> <translation id="813082847718468539">Mostra la informació del lloc web</translation> <translation id="8131740175452115882">Confirma</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb index 652a08e..75c1b00 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_el.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">Επιτρέπεται</translation> <translation id="429312253194641664">Ένας ιστότοπος κάνει αναπαραγωγή μέσων</translation> <translation id="42981349822642051">Επέκταση</translation> +<translation id="4336566011000459927">Το Chrome θα περιορίσει ξανά τα cookie σήμερα</translation> <translation id="4338831206024587507">Όλοι οι ιστότοποι στον τομέα <ph name="DOMAIN" /></translation> <translation id="4402755511846832236">Να μην επιτρέπεται σε ιστοτόπους να γνωρίζουν πότε χρησιμοποιείτε τη συσκευή ενεργά</translation> <translation id="4412992751769744546">Αποδοχή cookie τρίτου μέρους</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">Η σύνδεσή σας σε αυτόν τον ιστότοπο δεν είναι ασφαλής</translation> <translation id="6181444274883918285">Προσθήκη εξαίρεσης ιστότοπου</translation> <translation id="6192792657125177640">Εξαιρέσεις</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Το Chrome θα αποκλείσει ξανά τα cookie αύριο}other{# ημέρες έως ότου αποκλειστούν ξανά τα cookie}}</translation> <translation id="6195163219142236913">Τα cookie τρίτου μέρους περιορίζονται</translation> <translation id="6196640612572343990">Αποκλεισμός cookie τρίτων</translation> <translation id="6205314730813004066">Απόρρητο διαφημίσεων</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">Όχι, ευχαριστώ</translation> <translation id="7804248752222191302">Ένας ιστότοπος χρησιμοποιεί την κάμερά σας.</translation> <translation id="7807060072011926525">Παρέχεται από την Google</translation> +<translation id="7822573154188733812">Το Chrome δεν επιτρέπει στους ιστοτόπους να χρησιμοποιούν cookie τρίτου μέρους που σας παρακολουθούν καθώς περιηγείστε. Μεταβείτε στις ρυθμίσεις για να <ph name="BEGIN_LINK" />διαχειριστείτε τα μέτρα προστασίας από παρακολούθηση<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Αναπαραγωγή πολυμέσων</translation> <translation id="783819812427904514">Κατάργηση σίγασης βίντεο</translation> <translation id="7846076177841592234">Ακύρωση επιλογής</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">Οποιοσδήποτε ιστότοπος που επισκέπτεστε μπορεί να προβάλει οποιαδήποτε διαφήμιση σε εσάς</translation> <translation id="8087000398470557479">Αυτό το περιεχόμενο προέρχεται από το <ph name="DOMAIN_NAME" /> και παρέχεται από την Google.</translation> <translation id="8088603949666785339">Περισσότερες επιλογές στο <ph name="BANNER_TITLE" /></translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Το Chrome θα περιορίσει ξανά τα cookie αύριο}other{# ημέρες έως ότου το Chrome περιορίσει ξανά τα cookie}}</translation> <translation id="8116925261070264013">Σε σίγαση</translation> <translation id="813082847718468539">Προβολή πληροφοριών τοποθεσίας</translation> <translation id="8131740175452115882">Επιβεβαίωση</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb index ed901bf..db4243b 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_en-GB.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">Related sites</translation> <translation id="1644574205037202324">History</translation> <translation id="1647582022260550163">Are you sure that you want to reset permissions, and clear cookies and site data?</translation> +<translation id="1652197001188145583">When on, sites can ask to use NFC devices. When off, sites can't use NFC devices.</translation> <translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> <translation id="1677097821151855053">Cookies and other site data are used to remember you, for example, to sign you in or to personalise ads. To manage cookies for all sites, see <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> <translation id="169515064810179024">Block sites from accessing motion sensors</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">Make text and images larger or smaller for all sites that you visit</translation> <translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1985247341569771101">When on, sites can use your device's motion sensors. When off, sites can't use motion sensors.</translation> <translation id="1989112275319619282">Browse</translation> <translation id="1994173015038366702">Site URL</translation> <translation id="2004697686368036666">Features on some sites may not work</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">Turn off camera</translation> <translation id="2717722538473713889">Email addresses</translation> <translation id="2750481671343847896">Sites can show sign-in prompts from identity services.</translation> +<translation id="2790501146643349491">When on, recently closed sites can finish sending and receiving data. When off, recently closed sites can't finish sending or receiving data.</translation> <translation id="2822354292072154809">Are you sure that you want to reset all site permissions for <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2850913818900871965">Request mobile view</translation> <translation id="2870560284913253234">Site</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">Addresses</translation> <translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> <translation id="2932883381142163287">Report abuse</translation> +<translation id="2939338015096024043">When on, sites can ask to track your camera position and learn about your surroundings. When off, sites can't track your camera position or learn about your surroundings.</translation> <translation id="2968755619301702150">Certificate viewer</translation> <translation id="2979365474350987274">Third-party cookies are limited</translation> <translation id="3008272652534848354">Reset permissions</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> <translation id="321187648315454507">To let <ph name="APP_NAME" /> send you notifications, also turn on notifications in <ph name="BEGIN_LINK" />Android settings<ph name="END_LINK" />.</translation> <translation id="3227137524299004712">Microphone</translation> +<translation id="3242646949159196181">When on, sites can play sound. When off, sites can't play sound.</translation> <translation id="3277252321222022663">Allow sites to access sensors (recommended)</translation> <translation id="3285500645985761267">Allow related sites to see your activity in the group</translation> <translation id="3295019059349372795">Chapter 11: The Wonderful Emerald City of Oz</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">Third-party cookies blocked</translation> +<translation id="3448554387819310837">When on, sites can ask to use your camera. When off, sites can't use your camera.</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome will block cookies again tomorrow}other{# days until Chrome blocks cookies again}}</translation> <translation id="3521663503435878242">Sites under <ph name="DOMAIN" /></translation> <translation id="3538390592868664640">Block sites from creating a 3D map of your surroundings or tracking camera position</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">Mute sites that play sound</translation> <translation id="3602290021589620013">Preview</translation> <translation id="3628308229821498208">Suggested searches</translation> +<translation id="3697164069658504920">When on, sites can ask to use USB devices. When off, sites can't use USB devices.</translation> <translation id="3707034683772193706">A site that you visit can save a small amount of info with Chrome, mainly to validate that you're not a bot</translation> <translation id="3721953990244350188">Dismiss and show next available action</translation> <translation id="3744111561329211289">Background sync</translation> @@ -210,12 +217,14 @@ <translation id="4645575059429386691">Managed by your parent</translation> <translation id="4670064810192446073">Virtual reality</translation> <translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4755971844837804407">When on, sites can show any ad to you. When off, sites can't show intrusive or misleading ads.</translation> <translation id="4779083564647765204">Zoom</translation> <translation id="4811450222531576619">Learn about its source and topic</translation> <translation id="4836046166855586901">Ask when a site wants to know when you're actively using this device</translation> <translation id="483914009762354899">Include all sites under this domain</translation> <translation id="4883854917563148705">Managed settings cannot be reset</translation> <translation id="4887024562049524730">Ask before allowing sites to use your virtual reality device and data (recommended)</translation> +<translation id="4953688446973710931">When on, sites can ask to download multiple files automatically. When off, sites can't download multiple files automatically.</translation> <translation id="4955223779495905865">A site that you visit can embed content from other sites, for example images, ads and text. Any of these sites can save cookies and other data to personalise your experience.</translation> <translation id="4962975101802056554">Revoke all permissions for device</translation> <translation id="497421865427891073">go forward</translation> @@ -230,6 +239,7 @@ <translation id="5063480226653192405">Usage</translation> <translation id="5091013926750941408">Mobile site</translation> <translation id="509133520954049755">Request desktop view</translation> +<translation id="5091663350197390230">When on, sites can use JavaScript. When off, sites can't use JavaScript.</translation> <translation id="5099358668261120049">This will clear all data and cookies stored by <ph name="ORIGIN" /> or by its app on your home screen.</translation> <translation id="5100237604440890931">Collapsed – click to expand.</translation> <translation id="5123685120097942451">Incognito tab</translation> @@ -241,6 +251,7 @@ <translation id="5246825184569358663">This action will delete all local data, including cookies, and reset all permissions for <ph name="DOMAIN" /> and all sites under it</translation> <translation id="5264323282659631142">Remove '<ph name="CHIP_LABEL" />'</translation> <translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5295729974480418933">When on, sites can ask to use info that they've saved about you. When off, sites can't ask to use info that they've saved about you.</translation> <translation id="5300589172476337783">Show</translation> <translation id="5301954838959518834">OK, got it</translation> <translation id="5317780077021120954">Save</translation> @@ -251,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(+ 1 more)}other{(+ # more)}}</translation> <translation id="5403592356182871684">Names</translation> <translation id="5438097262470833822">This choice will reset permissions for <ph name="WEBSITE" /></translation> +<translation id="5459413148890178711">When on, sites can ask for your location. When off, sites can't see your location.</translation> <translation id="5489227211564503167">Elapsed time <ph name="ELAPSED_TIME" /> of <ph name="TOTAL_TIME" />.</translation> <translation id="5502860503640766021"><ph name="PERMISSION_1" /> allowed, <ph name="PERMISSION_2" /> blocked</translation> <translation id="5505264765875738116">Sites can't ask to send notifications</translation> @@ -271,6 +283,8 @@ <translation id="5740126560802162366">Sites can save data on your device</translation> <translation id="5771720122942595109"><ph name="PERMISSION_1" /> blocked</translation> <translation id="5804241973901381774">Permissions</translation> +<translation id="5844448279347999754">When on, sites can ask to see text and images saved to your clipboard. When off, sites can't see text or images saved to your clipboard.</translation> +<translation id="5853982612236235577">When on, sites can ask to send notifications. When off, sites can't send notifications.</translation> <translation id="5860033963881614850">Off</translation> <translation id="5876056640971328065">Pause video</translation> <translation id="5884085660368669834">Site preference</translation> @@ -289,7 +303,9 @@ <translation id="6042308850641462728">More</translation> <translation id="6064125863973209585">Completed downloads</translation> <translation id="6071501408666570960">You may be signed out of this site</translation> +<translation id="6120483543004435978">When on, sites can ask to know when you're actively using your device. When off, sites can't know when you're actively using your device.</translation> <translation id="6165508094623778733">Learn more</translation> +<translation id="6171020522141473435">When on, sites can ask to use Bluetooth devices. When off, sites can't use Bluetooth devices.</translation> <translation id="6177111841848151710">Blocked for current search engine</translation> <translation id="6177128806592000436">Your connection to this site is not secure</translation> <translation id="6181444274883918285">Add site exception</translation> @@ -315,6 +331,7 @@ <translation id="6500423977866688905">When the window is narrow, request mobile view</translation> <translation id="6527303717912515753">Share</translation> <translation id="652937045869844725">Try allowing third-party cookies, which means less protection but that site features are more likely to work</translation> +<translation id="6530703012083415527">When on, sites can use pop-ups and redirects. When off, sites can't use pop-ups and redirects.</translation> <translation id="6545864417968258051">Bluetooth scanning</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> and <ph name="NUM_MORE" /> more blocked}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> and <ph name="NUM_MORE" /> more blocked}}</translation> <translation id="6554732001434021288">Last visited <ph name="NUM_DAYS" /> days ago</translation> @@ -358,6 +375,7 @@ <translation id="7243308994586599757">Options available near bottom of the screen</translation> <translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> <translation id="7260727271532453612"><ph name="PERMISSION_1" /> and <ph name="PERMISSION_2" /> allowed</translation> +<translation id="7276071417425470385">When on, sites can ask to use virtual reality devices. When off, sites can't use virtual reality devices.</translation> <translation id="7284451015630589124">You blocked sites from using third-party cookies to track you as you browse. Visit settings to <ph name="BEGIN_LINK" />manage your tracking protections<ph name="END_LINK" />.</translation> <translation id="7302486331832100261">You usually block notifications. To allow, tap Details.</translation> <translation id="7366415735885268578">Add a site</translation> @@ -369,6 +387,7 @@ <translation id="7425915948813553151">Dark theme for sites</translation> <translation id="7474522811371247902">Chrome limits most sites from using third-party cookies. But third-party cookies are allowed on this site because it relies on them to provide basic services.\n\nVisit settings to <ph name="BEGIN_LINK" />manage your tracking protections<ph name="END_LINK" />.</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">When on, sites can show sign-in prompts. When off, sites can't show sign-in prompts.</translation> <translation id="7554752735887601236">A site is using your microphone</translation> <translation id="7561196759112975576">Always</translation> <translation id="757524316907819857">Block sites from playing protected content</translation> @@ -393,6 +412,7 @@ <translation id="7940722705963108451">Remind me</translation> <translation id="7974024493641668069">{COUNT,plural, =1{<ph name="FPS_MEMBERS_COUNT" /> site in <ph name="FPS_OWNER" />'s group of sites that can see your activity in the group}other{<ph name="FPS_MEMBERS_COUNT" /> sites in <ph name="FPS_OWNER" />'s group of sites that can see your activity in the group}}</translation> <translation id="7986741934819883144">Select a contact</translation> +<translation id="7990211076305263060">When on, sites can ask to use your microphone. When off, sites can't use your microphone.</translation> <translation id="8007176423574883786">Turned off for this device</translation> <translation id="802154636333426148">Download failed</translation> <translation id="8042586301629853791">Sort by:</translation> @@ -403,6 +423,7 @@ <translation id="8088603949666785339">More options in the <ph name="BANNER_TITLE" /></translation> <translation id="8113501330600751161">{DAYS,plural, =1{Chrome will limit cookies again tomorrow}other{# days until Chrome limits cookies again}}</translation> <translation id="8116925261070264013">Muted</translation> +<translation id="8117244575099414087">When on, sites can use your device's sensors. When off, sites can't use sensors.</translation> <translation id="813082847718468539">View site information</translation> <translation id="8131740175452115882">Confirm</translation> <translation id="8154912474061769055">Features on many sites may not work</translation> @@ -440,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{Cookies allowed for <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> site}other{Cookies allowed for <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> sites}}</translation> <translation id="857943718398505171">Allowed (recommended)</translation> <translation id="8609465669617005112">Move up</translation> +<translation id="8617611086246832542">When on, the desktop view of websites is shown. When off, the mobile view of websites is shown.</translation> <translation id="8649036394979866943">Chrome limits most sites from using third-party cookies to track you as you browse. Visit settings to <ph name="BEGIN_LINK" />manage your tracking protections<ph name="END_LINK" /></translation> <translation id="8676374126336081632">Clear input</translation> <translation id="8681886425883659911">Ads are blocked on sites known to show intrusive or misleading ads</translation> <translation id="868929229000858085">Search your contacts</translation> <translation id="8712637175834984815">Got it</translation> <translation id="8719283222052720129">Turn on permission for <ph name="APP_NAME" /> in <ph name="BEGIN_LINK" />Android settings<ph name="END_LINK" />.</translation> +<translation id="8721719390026067591">When on, sites can ask to look for Bluetooth devices. When off, sites can't look for Bluetooth devices.</translation> <translation id="8725066075913043281">Try again</translation> <translation id="8730621377337864115">Done</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{1 site allowed}other{# sites allowed}}</translation> @@ -469,6 +492,7 @@ <translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> <translation id="8986362086234534611">Forget</translation> <translation id="8990043154272859344">You'll be signed out of all sites</translation> +<translation id="9002538116239926534">When on, sites can save data on your device. When off, sites can't save data on your device.</translation> <translation id="9011903857143958461"><ph name="SITE_NAME" /> allowed</translation> <translation id="9019902583201351841">Managed by your parents</translation> <translation id="9039697262778250930">You may be signed out of these sites</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb index 27f1d79..a386f7a8 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_eu.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">Baimenduta</translation> <translation id="429312253194641664">Webgune bat multimedia-edukia erreproduzitzen ari da</translation> <translation id="42981349822642051">Zabaldu</translation> +<translation id="4336566011000459927">Gaur mugatuko ditu cookieak berriro Chrome-k</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> domeinuko webgune guztiak</translation> <translation id="4402755511846832236">Ez utzi jakiten webguneei gailua noiz erabiltzen ari zaren</translation> <translation id="4412992751769744546">Onartu hirugarrenen cookieak</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">Webgune honetarako konexioa ez da guztiz segurua</translation> <translation id="6181444274883918285">Gehitu webgune bat salbuespen gisa</translation> <translation id="6192792657125177640">Salbuespenak</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Bihar blokeatuko ditu cookieak berriro Chrome-k}other{# egun barru blokeatuko dira berriro cookieak}}</translation> <translation id="6195163219142236913">Hirugarrenen cookieak mugatuta</translation> <translation id="6196640612572343990">Blokeatu hirugarrenen cookieak</translation> <translation id="6205314730813004066">Iragarkien pribatutasuna</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">Ez, eskerrik asko</translation> <translation id="7804248752222191302">Webgune bat kamera erabiltzen ari da</translation> <translation id="7807060072011926525">Google-k eman du</translation> +<translation id="7822573154188733812">Arakatzen duzun bitartean zure jarraipena egiteko hirugarrenen cookieak erabiltzea eragozten die Chrome-k webguneei. Joan ezarpenetara <ph name="BEGIN_LINK" />jarraipenaren aurkako babesa kudeatzeko<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Multimedia-edukia erreproduzitzen</translation> <translation id="783819812427904514">Aktibatu bideoaren audioa</translation> <translation id="7846076177841592234">Utzi hautapena bertan behera</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">Bisitatzen dituzun webgune guztiek edozein iragarki erakusteko aukera dute</translation> <translation id="8087000398470557479">Eduki hau <ph name="DOMAIN_NAME" /> domeinukoa da eta Google-k eskaintzen du.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> banda-mezuko aukera gehiago</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Bihar mugatuko ditu cookieak berriro Chrome-k}other{# egun barru mugatuko ditu cookieak berriro Chrome-k}}</translation> <translation id="8116925261070264013">Audioa desaktibatuta</translation> <translation id="813082847718468539">Ikusi webgunearen informazioa</translation> <translation id="8131740175452115882">Berretsi</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb index 79b78a52c..ea2b3d8 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_fil.xtb
@@ -23,6 +23,7 @@ <translation id="1415402041810619267">Naputol ang URL</translation> <translation id="1426410128494586442">Oo</translation> <translation id="1448064542941920355">Bawasan ang pag-zoom</translation> +<translation id="146867109637325312">{COUNT,plural, =1{<ph name="SITE_COUNT" /> site}one{<ph name="SITE_COUNT" /> site}other{<ph name="SITE_COUNT" /> na site}}</translation> <translation id="1510341833810331442">Hindi pinapayagan ang mga site na mag-save ng data sa iyong device</translation> <translation id="1547123415014299762">Pinapayagan ang third-party na cookies</translation> <translation id="1568470248891039841">Puwedeng mag-embed ng content mula sa iba pang site ang mga site na binibisita mo, halimbawa, mga larawan, ad, at text. Puwedeng humingi ang iba pang site na ito ng pahintulot na gamitin ang impormasyong na-save ng mga ito tungkol sa iyo habang nagba-browse ka sa site. <ph name="BEGIN_LINK" />Matuto pa tungkol sa naka-embed na content<ph name="END_LINK" /></translation> @@ -191,6 +192,7 @@ <translation id="4278390842282768270">Pinapayagan</translation> <translation id="429312253194641664">May site na nagpe-play ng media</translation> <translation id="42981349822642051">Palawakin</translation> +<translation id="4336566011000459927">Maglilimita ulit ang Chrome ng cookies ngayong araw</translation> <translation id="4338831206024587507">Lahat ng site sa ilalim ng <ph name="DOMAIN" /></translation> <translation id="4402755511846832236">Pigilan ang mga site na malaman kung kailan mo aktibong ginagamit ang device na ito</translation> <translation id="4412992751769744546">Payagan ang third-party na cookies</translation> @@ -264,6 +266,7 @@ <translation id="5677928146339483299">Naka-block</translation> <translation id="5689516760719285838">Lokasyon</translation> <translation id="5690795753582697420">Naka-off ang camera sa mga setting ng Android</translation> +<translation id="5691080386278724773">Magagamit ng <ph name="SITE" /> ang iyong impormasyon habang nagba-browse ka</translation> <translation id="5700761515355162635">Pinapayagan ang third-party na cookies</translation> <translation id="5706552988683188916">Dine-delete nito ang cookies at iba pang data ng site para sa <ph name="WEBSITE" /></translation> <translation id="5723967018671998714">Bina-block ang third-party na cookies sa Incognito mode</translation> @@ -293,6 +296,7 @@ <translation id="6177128806592000436">Hindi ligtas ang iyong koneksyon sa site na ito</translation> <translation id="6181444274883918285">Magdagdag ng pagbubukod ng site</translation> <translation id="6192792657125177640">Mga Pagbubukod</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Magba-block ulit ang Chrome ng cookies bukas}one{# araw bago i-block ulit ang cookies}other{# na araw bago i-block ulit ang cookies}}</translation> <translation id="6195163219142236913">Limitado ang third-party na cookies</translation> <translation id="6196640612572343990">I-block ang mga third-party na cookie</translation> <translation id="6205314730813004066">Privacy sa mga ad</translation> @@ -302,6 +306,7 @@ <translation id="6262279340360821358">Naka-block ang <ph name="PERMISSION_1" /> at <ph name="PERMISSION_2" /></translation> <translation id="6270391203985052864">Puwedeng humiling ang mga site na magpadala ng mga notification</translation> <translation id="6295158916970320988">Lahat ng site</translation> +<translation id="6304434827459067558">Naka-block ang <ph name="SITE" /> sa paggamit ng iyong impormasyon sa</translation> <translation id="6320088164292336938">Mag-vibrate</translation> <translation id="6344622098450209924">Proteksyon sa Pag-track</translation> <translation id="6367753977865761591">I-block ang third-party na pag-sign in para sa partikular na site.</translation> @@ -382,6 +387,7 @@ <translation id="780301667611848630">Hindi salamat</translation> <translation id="7804248752222191302">Ginagamit ng isang site ang iyong camera</translation> <translation id="7807060072011926525">Ibinibigay ng Google</translation> +<translation id="7822573154188733812">Bina-block ng Chrome ang mga site para hindi makagamit ng third-party na cookies para ma-track ka habang nagba-browse ka. Tingnan ang mga setting para <ph name="BEGIN_LINK" />pamahalaan ang iyong mga proteksyon sa pag-track<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Nagpe-play ng media</translation> <translation id="783819812427904514">I-unmute ang video</translation> <translation id="7846076177841592234">Kanselahin ang pinili</translation> @@ -398,6 +404,7 @@ <translation id="8077120325605624147">Puwedeng magpakita ng anumang ad sa iyo ang anumang site na bibisitahin mo</translation> <translation id="8087000398470557479">Ang content na ito ay mula sa <ph name="DOMAIN_NAME" />, na ipinadala ng Google.</translation> <translation id="8088603949666785339">Higit pang opsyon sa <ph name="BANNER_TITLE" /></translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Maglilimita ulit ang Chrome ng cookies bukas}one{# araw bago maglimita ulit ang Chrome ng cookies}other{# na araw bago maglimita ulit ang Chrome ng cookies}}</translation> <translation id="8116925261070264013">Naka-mute</translation> <translation id="813082847718468539">Tingnan ang impormasyon ng site</translation> <translation id="8131740175452115882">Kumpirmahin</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb index 30c9414c..a87107ea 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_hi.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">अनुमति है</translation> <translation id="429312253194641664">किसी साइट पर मीडिया चल रहा है</translation> <translation id="42981349822642051">विस्तृत करें</translation> +<translation id="4336566011000459927">Chrome आज फिर से कुकी को सीमित करेगा</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> की सभी साइटें</translation> <translation id="4402755511846832236">साइटों को यह जानने से रोकें कि आप इस डिवाइस का इस्तेमाल कब करते हैं</translation> <translation id="4412992751769744546">तृतीय-पक्ष कुकी को अनुमति दें</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">इस साइट से आपका कनेक्शन सुरक्षित नहीं है</translation> <translation id="6181444274883918285">अपवाद वाली साइट जोड़ें</translation> <translation id="6192792657125177640">अपवाद</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome कल फिर से कुकी ब्लॉक करेगा}one{# दिन बाद कुकी फिर से ब्लॉक कर दी जाएंगी}other{# दिनों के बाद कुकी फिर से ब्लॉक कर दी जाएंगी}}</translation> <translation id="6195163219142236913">तीसरे पक्ष की कुकी सीमित हैं</translation> <translation id="6196640612572343990">तीसरे पक्ष की कुकी ब्लॉक करें</translation> <translation id="6205314730813004066">विज्ञापन से जुड़ी निजता सेटिंग</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">नहीं, रहने दें</translation> <translation id="7804248752222191302">कोई साइट आपका कैमरा इस्तेमाल कर रही है</translation> <translation id="7807060072011926525">Google से मिला फ़ीड</translation> +<translation id="7822573154188733812">Chrome, साइटों को तीसरे पक्ष की कुकी इस्तेमाल करने से रोकता है, ताकि वे आपको ब्राउज़ करते समय ट्रैक न कर सकें. <ph name="BEGIN_LINK" />अपनी ट्रैकिंग सुरक्षा को मैनेज करने<ph name="END_LINK" /> के लिए सेटिंग पर जाएं.</translation> <translation id="7835852323729233924">चलाया जा रहा मीडिया</translation> <translation id="783819812427904514">वीडियो अनम्यूट करें</translation> <translation id="7846076177841592234">चुना गया हटाएं</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">किसी भी साइट को देखने पर, आपको कोई भी विज्ञापन दिख सकता है</translation> <translation id="8087000398470557479">यह सामग्री <ph name="DOMAIN_NAME" /> की है जिसे Google के द्वारा वितरित किया गया है.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> में ज़्यादा विकल्प</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome कल फिर से कुकी को सीमित करेगा}one{Chrome # दिन बाद फिर से कुकी को सीमित करेगा}other{Chrome # दिनों के बाद फिर से कुकी को सीमित करेगा}}</translation> <translation id="8116925261070264013">आवाज़ बंद की गई</translation> <translation id="813082847718468539">साइट जानकारी देखें</translation> <translation id="8131740175452115882">पुष्टि करें</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb index a792872..6ed752f 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ja.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">関連サイト</translation> <translation id="1644574205037202324">履歴</translation> <translation id="1647582022260550163">権限をリセットし、Cookie とサイトデータを削除してもよろしいですか?</translation> +<translation id="1652197001188145583">オンにすると、サイトは NFC デバイスの使用を要求できます。オフにすると、サイトは NFC デバイスを使用できません。</translation> <translation id="1660204651932907780">音声の再生をサイトに許可する(推奨)</translation> <translation id="1677097821151855053">Cookie と他のサイトデータは、ログインや広告のパーソナライズなどでユーザーを覚えておくために使用されます。すべてのサイトの Cookie を管理するには、<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />をご覧ください。</translation> <translation id="169515064810179024">サイトによるモーション センサーへのアクセスをブロックする</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / <ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">アクセスしたすべてのサイトでテキストと画像を拡大または縮小して表示します</translation> <translation id="1984937141057606926">サードパーティ以外は許可</translation> +<translation id="1985247341569771101">オンにすると、サイトはデバイスのモーション センサーを使用できます。オフにすると、サイトはモーション センサーを使用できません。</translation> <translation id="1989112275319619282">閲覧</translation> <translation id="1994173015038366702">サイトの URL</translation> <translation id="2004697686368036666">一部のサイトで機能を使用できなくなる可能性があります</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">カメラをオフにする</translation> <translation id="2717722538473713889">メールアドレス</translation> <translation id="2750481671343847896">サイトで ID サービスからのログイン メッセージを表示できるようにします。</translation> +<translation id="2790501146643349491">オンにすると、最近閉じたサイトのデータの送受信を完了できます。オフにすると、最近閉じたサイトのデータの送受信を完了できません。</translation> <translation id="2822354292072154809">「<ph name="CHOSEN_OBJECT_NAME" />」に関するすべてのサイト権限をリセットしてもよろしいですか?</translation> <translation id="2850913818900871965">モバイルビューをリクエストする</translation> <translation id="2870560284913253234">ウェブサイト</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">住所</translation> <translation id="2910701580606108292">保護されたコンテンツの再生をサイトに許可する前に確認する</translation> <translation id="2932883381142163287">不正行為を報告</translation> +<translation id="2939338015096024043">オンにすると、サイトはカメラ位置の追跡と周囲の状況の検出を要求できます。オフにすると、サイトはカメラ位置の追跡や周囲の状況の検出を行えません。</translation> <translation id="2968755619301702150">証明書ビューア</translation> <translation id="2979365474350987274">サードパーティ Cookie が制限されています</translation> <translation id="3008272652534848354">権限をリセット</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> の保存データ</translation> <translation id="321187648315454507"><ph name="APP_NAME" /> に通知の送信を許可するには、<ph name="BEGIN_LINK" />Android の設定<ph name="END_LINK" />でも通知をオンにしてください。</translation> <translation id="3227137524299004712">マイク</translation> +<translation id="3242646949159196181">オンにすると、サイトは音声を再生できます。オフにすると、サイトは音声を再生できません。</translation> <translation id="3277252321222022663">サイトによるセンサーへのアクセスを許可する(推奨)</translation> <translation id="3285500645985761267">関連サイトにグループ内のアクティビティの確認を許可する</translation> <translation id="3295019059349372795">第 11 章: オズの不思議なエメラルド シティ</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">サイトに現在地の認識を許可する前に確認する(推奨)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" />%%</translation> <translation id="344449859752187052">サードパーティ Cookie がブロックされています</translation> +<translation id="3448554387819310837">オンにすると、サイトはカメラの使用を要求できます。オフにすると、サイトはカメラを使用できません。</translation> <translation id="3465378418721443318">{DAYS,plural, =1{明日、Chrome で Cookie を再びブロックします}other{Chrome で Cookie を再びブロックするまであと # 日}}</translation> <translation id="3521663503435878242"><ph name="DOMAIN" /> のサイト</translation> <translation id="3538390592868664640">サイトによる周囲の 3D マップの作成またはカメラ位置の追跡をブロックします</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">音声が再生されるサイトをミュートする</translation> <translation id="3602290021589620013">プレビュー</translation> <translation id="3628308229821498208">提案された検索</translation> +<translation id="3697164069658504920">オンにすると、サイトは USB デバイスの使用を要求できます。オフにすると、サイトは USB デバイスを使用できません。</translation> <translation id="3707034683772193706">アクセス先のサイトは、主にあなたが bot でないことを確認する少量の情報を Chrome に保存できます。</translation> <translation id="3721953990244350188">非表示にして、次に実行可能なアクションを表示</translation> <translation id="3744111561329211289">バックグラウンド同期</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">許可</translation> <translation id="429312253194641664">サイトでメディアが再生されています</translation> <translation id="42981349822642051">展開</translation> +<translation id="4336566011000459927">今日、Chrome で Cookie を再び制限します</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> のすべてのサイト</translation> <translation id="4402755511846832236">サイトによるこのデバイスのアクティブ状態の検出をブロックする</translation> <translation id="4412992751769744546">サードパーティの Cookie を許可する</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">保護者により管理されています</translation> <translation id="4670064810192446073">バーチャル リアリティ(VR)</translation> <translation id="4751476147751820511">モーション センサーまたは光センサー</translation> +<translation id="4755971844837804407">オンにすると、サイトはユーザーにあらゆる広告を表示できます。オフにすると、サイトは煩わしい広告や誤解を招く広告を表示できません。</translation> <translation id="4779083564647765204">ズーム</translation> <translation id="4811450222531576619">ソースとトピックの詳細</translation> <translation id="4836046166855586901">サイトからこのデバイスのアクティブ状態の検出を求められたときに確認する</translation> <translation id="483914009762354899">このドメインのすべてのサイトを含める</translation> <translation id="4883854917563148705">管理者による設定はリセットできません</translation> <translation id="4887024562049524730">サイトにバーチャル リアリティ デバイスとデータの使用を許可する前に確認する(推奨)</translation> +<translation id="4953688446973710931">オンにすると、サイトは複数のファイルの自動ダウンロードを要求できます。オフにすると、サイトは複数のファイルを自動ダウンロードできません。</translation> <translation id="4955223779495905865">アクセスしたサイトに他のサイトのコンテンツ(画像、広告、テキストなど)が埋め込まれている場合があります。これらすべてのサイトで Cookie などのデータが保存され、エクスペリエンスのパーソナライズに使用される可能性があります。</translation> <translation id="4962975101802056554">デバイスのすべての権限を取り消します</translation> <translation id="497421865427891073">次に進む</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">使用状況</translation> <translation id="5091013926750941408">モバイルサイト</translation> <translation id="509133520954049755">デスクトップ ビューで表示する</translation> +<translation id="5091663350197390230">オンにすると、サイトは JavaScript を使用できます。オフにすると、サイトは JavaScript を使用できません。</translation> <translation id="5099358668261120049"><ph name="ORIGIN" /> またはホーム画面の同アプリにより保存されたデータと Cookie がすべて削除されます。</translation> <translation id="5100237604440890931">折りたたまれています - クリックすると展開します。</translation> <translation id="5123685120097942451">シークレット タブ</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">この操作を行うと、Cookie を含むすべてのローカルデータが削除され、<ph name="DOMAIN" /> とその下にある全サイトの全権限がリセットされます</translation> <translation id="5264323282659631142"><ph name="CHIP_LABEL" /> を削除</translation> <translation id="528192093759286357">全画面表示を終了するには、上からドラッグして、戻るボタンをタップします。</translation> +<translation id="5295729974480418933">オンにすると、サイトはユーザーに関して保存した情報の使用を要求できます。オフにすると、サイトはユーザーに関して保存した情報の使用を要求できません。</translation> <translation id="5300589172476337783">表示</translation> <translation id="5301954838959518834">OK</translation> <translation id="5317780077021120954">保存</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(他 1 件)}other{(他 # 件)}}</translation> <translation id="5403592356182871684">名前</translation> <translation id="5438097262470833822">これを選択すると、<ph name="WEBSITE" /> の権限がリセットされます</translation> +<translation id="5459413148890178711">オンにすると、サイトは位置情報を要求できます。オフにすると、サイトは位置情報を参照できません。</translation> <translation id="5489227211564503167"><ph name="TOTAL_TIME" /> のうち <ph name="ELAPSED_TIME" /> 経過しました。</translation> <translation id="5502860503640766021"><ph name="PERMISSION_1" />を許可、<ph name="PERMISSION_2" />をブロック</translation> <translation id="5505264765875738116">通知を送信するかどうかの確認をサイトに許可しない</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">サイトはデバイスにデータを保存できます</translation> <translation id="5771720122942595109"><ph name="PERMISSION_1" />をブロック</translation> <translation id="5804241973901381774">権限</translation> +<translation id="5844448279347999754">オンにすると、サイトはクリップボードに保存されたテキストや画像の参照を要求できます。オフにすると、サイトはクリップボードに保存されたテキストや画像を参照できません。</translation> +<translation id="5853982612236235577">オンにすると、サイトは通知の送信を要求できます。オフにすると、サイトは通知を送信できません。</translation> <translation id="5860033963881614850">OFF</translation> <translation id="5876056640971328065">動画を一時停止</translation> <translation id="5884085660368669834">サイトの設定</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">もっと見る</translation> <translation id="6064125863973209585">完了したダウンロード</translation> <translation id="6071501408666570960">このサイトからログアウトされる可能性があります</translation> +<translation id="6120483543004435978">オンにすると、サイトはデバイスのアクティブ状態の検出を要求できます。オフにすると、サイトはデバイスのアクティブ状態を検出できません。</translation> <translation id="6165508094623778733">詳細</translation> +<translation id="6171020522141473435">オンにすると、サイトは Bluetooth デバイスの使用を要求できます。オフにすると、サイトは Bluetooth デバイスを使用できません。</translation> <translation id="6177111841848151710">現在の検索エンジンに対してはブロック</translation> <translation id="6177128806592000436">このサイトへの接続は保護されていません</translation> <translation id="6181444274883918285">サイトの例外を追加</translation> <translation id="6192792657125177640">例外</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{明日、Chrome で Cookie を再びブロックします}other{Cookie を再びブロックするまであと # 日です}}</translation> <translation id="6195163219142236913">サードパーティ Cookie が制限されています</translation> <translation id="6196640612572343990">サードパーティの Cookie をブロックする</translation> <translation id="6205314730813004066">広告プライバシー</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">ウィンドウが狭い場合はモバイルビューをリクエストする</translation> <translation id="6527303717912515753">共有</translation> <translation id="652937045869844725">サードパーティ Cookie を許可してみてください。保護の強度は低下しますが、サイトの機能が動作する可能性が高くなります</translation> +<translation id="6530703012083415527">オンにすると、サイトはポップアップとリダイレクトを使用できます。オフにすると、サイトはポップアップとリダイレクトを使用できません。</translation> <translation id="6545864417968258051">Bluetooth のスキャン</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{<ph name="PERMISSION_1" />、<ph name="PERMISSION_2" />、他 <ph name="NUM_MORE" /> 個の権限がブロックされています}other{<ph name="PERMISSION_1" />、<ph name="PERMISSION_2" />、他 <ph name="NUM_MORE" /> 個の権限がブロックされています}}</translation> <translation id="6554732001434021288">最終アクセス日: <ph name="NUM_DAYS" /> 日前</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">画面の下の方にオプションがあります</translation> <translation id="7250468141469952378"><ph name="ITEM_COUNT" /> 件選択されています</translation> <translation id="7260727271532453612"><ph name="PERMISSION_1" />、<ph name="PERMISSION_2" />を許可</translation> +<translation id="7276071417425470385">オンにすると、サイトはバーチャル リアリティ デバイスの使用を要求できます。オフにすると、サイトはバーチャル リアリティ デバイスを使用できません。</translation> <translation id="7284451015630589124">ブラウジング中にトラッキングされないように、サイトによるサードパーティ Cookie の使用をブロックしました。<ph name="BEGIN_LINK" />トラッキング防止機能を管理<ph name="END_LINK" />するには、設定にアクセスしてください。</translation> <translation id="7302486331832100261">通知はデフォルトでブロックされています。許可するには [詳細] をタップしてください。</translation> <translation id="7366415735885268578">サイトの追加</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">サイトのダークモード</translation> <translation id="7474522811371247902">Chrome ではほとんどのサイトに対してサードパーティ Cookie の使用を制限しています。しかしこのサイトでは、基本的なサービスの提供にサードパーティ Cookie を使用しているため許可されています。\n\n<ph name="BEGIN_LINK" />トラッキング防止機能を管理する<ph name="END_LINK" />には、設定に移動してください。</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">オンにすると、サイトはログイン メッセージを表示できます。オフにすると、サイトはログイン メッセージを表示できません。</translation> <translation id="7554752735887601236">サイトでマイクが使用されています</translation> <translation id="7561196759112975576">常に使用</translation> <translation id="757524316907819857">サイトでの保護されたコンテンツの再生をブロックする</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">同意しない</translation> <translation id="7804248752222191302">サイトでカメラが使用されています</translation> <translation id="7807060072011926525">Google から提供</translation> +<translation id="7822573154188733812">Chrome では、サードパーティ Cookie の使用を制限し、ブラウジング中のユーザーをトラッキングできないようにしています。<ph name="BEGIN_LINK" />トラッキング防止機能を管理<ph name="END_LINK" />するには、設定にアクセスしてください。</translation> <translation id="7835852323729233924">再生中のメディア</translation> <translation id="783819812427904514">動画のミュートを解除</translation> <translation id="7846076177841592234">選択解除</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">リマインダーの設定</translation> <translation id="7974024493641668069">{COUNT,plural, =1{グループでのアクティビティを確認できる <ph name="FPS_OWNER" /> のサイトグループの <ph name="FPS_MEMBERS_COUNT" /> 件のサイト}other{グループでのアクティビティを確認できる <ph name="FPS_OWNER" /> のサイトグループの <ph name="FPS_MEMBERS_COUNT" /> 件のサイト}}</translation> <translation id="7986741934819883144">連絡先の選択</translation> +<translation id="7990211076305263060">オンにすると、サイトはマイクの使用を要求できます。オフにすると、サイトはマイクを使用できません。</translation> <translation id="8007176423574883786">このデバイスに対して無効</translation> <translation id="802154636333426148">ダウンロード エラー</translation> <translation id="8042586301629853791">並べ替え:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">アクセスしたすべてのサイトであらゆる広告の表示が許可されます</translation> <translation id="8087000398470557479"><ph name="DOMAIN_NAME" /> のコンテンツを Google から配信しています。</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> のその他のオプション</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{明日、Chrome で Cookie を再び制限します}other{Chrome で Cookie を再び制限するまであと # 日です}}</translation> <translation id="8116925261070264013">ミュート中</translation> +<translation id="8117244575099414087">オンにすると、サイトはデバイスのセンサーを使用できます。オフにすると、サイトはセンサーを使用できません。</translation> <translation id="813082847718468539">サイト情報を表示</translation> <translation id="8131740175452115882">確認</translation> <translation id="8154912474061769055">多くのサイトで機能を使用できなくなる可能性があります</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{<ph name="FPS_OWNER" /> の <ph name="FPS_MEMBERS_COUNT" /> 件のサイトで Cookie が許可されています}other{<ph name="FPS_OWNER" /> の <ph name="FPS_MEMBERS_COUNT" /> 件のサイトで Cookie が許可されています}}</translation> <translation id="857943718398505171">許可(推奨)</translation> <translation id="8609465669617005112">上に移動</translation> +<translation id="8617611086246832542">オンにすると、ウェブサイトのデスクトップ ビューが表示されます。オフにすると、ウェブサイトのモバイルビューが表示されます。</translation> <translation id="8649036394979866943">Chrome はほとんどのサイトに対してサードパーティ Cookie の使用を制限し、ブラウジング中のユーザーをトラッキングできないようにしています。<ph name="BEGIN_LINK" />トラッキング防止機能を管理<ph name="END_LINK" />するには、設定にアクセスしてください</translation> <translation id="8676374126336081632">入力内容を消去</translation> <translation id="8681886425883659911">煩わしい広告や誤解を招く広告が表示されることがわかっているサイトで広告がブロックされます</translation> <translation id="868929229000858085">連絡先を検索</translation> <translation id="8712637175834984815">OK</translation> <translation id="8719283222052720129"><ph name="BEGIN_LINK" />Android の設定<ph name="END_LINK" />で <ph name="APP_NAME" /> の権限を有効にしてください。</translation> +<translation id="8721719390026067591">オンにすると、サイトは Bluetooth デバイスの検出を要求できます。オフにすると、サイトは Bluetooth デバイスを検出できません。</translation> <translation id="8725066075913043281">やり直し</translation> <translation id="8730621377337864115">完了</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{1 件のサイトが許可されています}other{# 件のサイトが許可されています}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698"><ph name="URL" /> にアクセスできません</translation> <translation id="8986362086234534611">削除</translation> <translation id="8990043154272859344">すべてのサイトからログアウトします</translation> +<translation id="9002538116239926534">オンにすると、サイトはデバイスにデータを保存できます。オフにすると、サイトはデバイスにデータを保存できません。</translation> <translation id="9011903857143958461"><ph name="SITE_NAME" /> を許可しました</translation> <translation id="9019902583201351841">保護者により管理されています</translation> <translation id="9039697262778250930">これらのサイトからログアウトする可能性があります</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb index 3c4ad02..3d148db5 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ko.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">허용됨</translation> <translation id="429312253194641664">사이트에서 미디어 재생 중</translation> <translation id="42981349822642051">펼치기</translation> +<translation id="4336566011000459927">오늘 Chrome에서 다시 쿠키를 제한합니다.</translation> <translation id="4338831206024587507"><ph name="DOMAIN" />의 모든 사이트</translation> <translation id="4402755511846832236">사용자가 현재 기기를 사용 중인지 사이트에서 알 수 없도록 차단합니다.</translation> <translation id="4412992751769744546">서드 파티 쿠키 허용</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">이 사이트는 보안 연결(HTTPS)이 사용되지 않았습니다.</translation> <translation id="6181444274883918285">사이트 예외 추가</translation> <translation id="6192792657125177640">예외</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{내일 Chrome에서 다시 쿠키를 차단합니다}other{#일 후 쿠키가 다시 차단됩니다.}}</translation> <translation id="6195163219142236913">서드 파티 쿠키 제한됨</translation> <translation id="6196640612572343990">서드 파티 쿠키 차단</translation> <translation id="6205314730813004066">광고 개인 정보 보호</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">취소</translation> <translation id="7804248752222191302">사이트에서 카메라 사용 중</translation> <translation id="7807060072011926525">Google 제공</translation> +<translation id="7822573154188733812">Chrome에서는 사이트가 서드 파티 쿠키를 사용하여 사용자의 탐색 활동을 추적하지 못하도록 사이트를 차단합니다. 설정으로 이동하여 <ph name="BEGIN_LINK" />추적 보호 조치를 관리<ph name="END_LINK" />하세요.</translation> <translation id="7835852323729233924">재생 중인 미디어</translation> <translation id="783819812427904514">동영상 음소거 해제</translation> <translation id="7846076177841592234">선택 취소</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">어떤 사이트에서나 광고를 게재할 수 있습니다.</translation> <translation id="8087000398470557479">이 콘텐츠의 출처는 Google에서 제공하는 <ph name="DOMAIN_NAME" />입니다.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> 옵션 더보기</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{내일 Chrome에서 다시 쿠키를 제한합니다}other{#일 후 Chrome에서 다시 쿠키를 제한합니다.}}</translation> <translation id="8116925261070264013">음소거됨</translation> <translation id="813082847718468539">사이트 정보 보기</translation> <translation id="8131740175452115882">확인</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb index cbb758d..c58957d 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_lt.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">Susijusios svetainės</translation> <translation id="1644574205037202324">Istorija</translation> <translation id="1647582022260550163">Ar tikrai norite nustatyti leidimus iš naujo ir išvalyti slapukus bei svetainių duomenis?</translation> +<translation id="1652197001188145583">Įjungus svetainėse gali būti prašoma naudoti NFC įrenginius. Išjungus svetainėse negalima naudoti NFC įrenginių.</translation> <translation id="1660204651932907780">Leisti svetainėms leisti garsą (rekomenduojama)</translation> <translation id="1677097821151855053">Slapukai ir kiti svetainės duomenys naudojami siekiant jus prisiminti, pvz., prisijungiant ar suasmeninant skelbimus. Norėdami tvarkyti visų svetainių slapukus, žr. skiltį <ph name="BEGIN_LINK" />„Nustatymai“<ph name="END_LINK" />.</translation> <translation id="169515064810179024">Svetainės užblokuotos, kad nepasiektų judesio jutiklių</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> iš <ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">Padidinkite arba sumažinkite tekstą ir vaizdus visose svetainėse, kuriose lankotės</translation> <translation id="1984937141057606926">Leidžiama (išskyrus trečiąsias šalis)</translation> +<translation id="1985247341569771101">Įjungus svetainėse gali būti naudojami įrenginio judesio jutikliai. Išjungus svetainėse negalima naudoti judesio jutiklių.</translation> <translation id="1989112275319619282">Naršyti</translation> <translation id="1994173015038366702">Svetainės URL</translation> <translation id="2004697686368036666">Funkcijos gali neveikti kai kuriose svetainėse</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">Išjungti fotoaparatą</translation> <translation id="2717722538473713889">El. pašto adresai</translation> <translation id="2750481671343847896">Svetainėse gali būti rodomi raginimai prisijungti iš tapatybės nustatymo paslaugų.</translation> +<translation id="2790501146643349491">Įjungus neseniai uždarytose svetainėse galima baigti siųsti ir gauti duomenis. Išjungus neseniai uždarytose svetainėse negalima baigti siųsti ar gauti duomenų.</translation> <translation id="2822354292072154809">Ar tikrai norite iš naujo nustatyti visus „<ph name="CHOSEN_OBJECT_NAME" />“ svetainės leidimus?</translation> <translation id="2850913818900871965">Pateikti užklausą dėl rodinio versijos mobiliesiems</translation> <translation id="2870560284913253234">Svetainė</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">Adresai</translation> <translation id="2910701580606108292">Paklausti prieš leidžiant svetainėms leisti saugomą turinį</translation> <translation id="2932883381142163287">Pranešti apie piktnaudžiavimą</translation> +<translation id="2939338015096024043">Įjungus svetainėse gali būti prašoma stebėti fotoaparato padėtį ir sužinoti apie jūsų aplinką. Išjungus svetainės negali stebėti fotoaparato padėties ar sužinoti apie jūsų aplinką.</translation> <translation id="2968755619301702150">Sertifikato peržiūros priemonė</translation> <translation id="2979365474350987274">Trečiųjų šalių slapukai ribojami</translation> <translation id="3008272652534848354">Iš naujo nustatyti leidimus</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905">Išsaugota duomenų: <ph name="STORAGE_AMOUNT" /></translation> <translation id="321187648315454507">Norėdami leisti „<ph name="APP_NAME" />“ siųsti pranešimus, taip pat įjunkite juos <ph name="BEGIN_LINK" />„Android“ nustatymuose<ph name="END_LINK" />.</translation> <translation id="3227137524299004712">Mikrofonas</translation> +<translation id="3242646949159196181">Įjungus svetainėse galima leisti garsą. Išjungus svetainėse negalima leisti garso.</translation> <translation id="3277252321222022663">Leidžiama svetainėms pasiekti jutiklius (rekomenduojama)</translation> <translation id="3285500645985761267">Leisti susijusioms svetainėms peržiūrėti jūsų veiklą grupėje</translation> <translation id="3295019059349372795">11 skyrius. Nuostabusis Smaragdo miestas</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">Klausti prieš leidžiant svetainėms žinoti vietą (rekomenduojama)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">Trečiųjų šalių slapukai užblokuoti</translation> +<translation id="3448554387819310837">Įjungus svetainėse gali būti prašoma naudoti fotoaparatą. Išjungus svetainėse negalima naudoti fotoaparato.</translation> <translation id="3465378418721443318">{DAYS,plural, =1{„Chrome“ vėl užblokuos slapukus rytoj}one{Liko # diena, kol „Chrome“ vėl užblokuos slapukus}few{Liko # dienos, kol „Chrome“ vėl užblokuos slapukus}many{Liko # dienos, kol „Chrome“ vėl užblokuos slapukus}other{Liko # dienų, kol „Chrome“ vėl užblokuos slapukus}}</translation> <translation id="3521663503435878242">Svetainės, priklausančios <ph name="DOMAIN" /></translation> <translation id="3538390592868664640">Blokuoti, kad svetainės nekurtų jūsų aplinkos 3D žemėlapio ir nestebėtų kameros padėties</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">Nutildyti svetaines, kurios leidžia garsą</translation> <translation id="3602290021589620013">Peržiūra</translation> <translation id="3628308229821498208">Siūlomos paieškos</translation> +<translation id="3697164069658504920">Įjungus svetainėse gali būti prašoma naudoti USB įrenginius. Išjungus svetainėse negalima naudoti USB įrenginių.</translation> <translation id="3707034683772193706">Svetainė, kurioje lankotės, gali išsaugoti nedidelį kiekį informacijos „Chrome“, kad būtų galima patvirtinti, jog nesate robotas</translation> <translation id="3721953990244350188">Atsisakyti ir rodyti kitą galimą veiksmą</translation> <translation id="3744111561329211289">Fono sinchronizavimas</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">Leidžiama</translation> <translation id="429312253194641664">Svetainėje leidžiama medija</translation> <translation id="42981349822642051">Išskleisti</translation> +<translation id="4336566011000459927">„Chrome“ šiandien vėl apribos slapukus</translation> <translation id="4338831206024587507">Visos svetainės su domenu <ph name="DOMAIN" /></translation> <translation id="4402755511846832236">Neleisti svetainėms žinoti, kada aktyviai naudojate šį įrenginį</translation> <translation id="4412992751769744546">Leisti trečiųjų šalių slapukus</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">Tvarko vienas iš jūsų tėvų</translation> <translation id="4670064810192446073">Virtualioji realybė</translation> <translation id="4751476147751820511">Judesio arba šviesos jutikliai</translation> +<translation id="4755971844837804407">Įjungus svetainėse gali būti rodomas jums bet koks skelbimas. Išjungus svetainėse negalima rodyti nepageidaujamų ar klaidinančių skelbimų.</translation> <translation id="4779083564647765204">Keisti mastelį</translation> <translation id="4811450222531576619">Sužinokite apie jo šaltinį ir temą</translation> <translation id="4836046166855586901">Klausti, kai svetainė nori žinoti, kada aktyviai naudojate šį įrenginį</translation> <translation id="483914009762354899">Įtraukti visas šio domeno svetaines</translation> <translation id="4883854917563148705">Tvarkomų nustatymų negalima nustatyti iš naujo</translation> <translation id="4887024562049524730">Klausti prieš leidžiant svetainėms naudoti virtualiosios realybės įrenginį ir duomenis (rekomenduojama)</translation> +<translation id="4953688446973710931">Įjungus svetainėse gali būti prašoma automatiškai atsisiųsti kelis failus. Išjungus svetainėse negalima automatiškai atsisiųsti kelių failų.</translation> <translation id="4955223779495905865">Svetainėje, kurioje lankotės, gali būti įterpta turinio iš kitų svetainių, pvz., vaizdų, skelbimų ir teksto. Bet kurioje iš šių svetainių gali būti išsaugomi slapukai ir kiti duomenys jums teikiamoms funkcijoms suasmeninti.</translation> <translation id="4962975101802056554">Anuliuoti visus įrenginio leidimus</translation> <translation id="497421865427891073">Eiti pirmyn</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">Naudojimas</translation> <translation id="5091013926750941408">Svetainė mobiliesiems</translation> <translation id="509133520954049755">Pateikti užklausą dėl rodinio versijos staliniams kompiuteriams</translation> +<translation id="5091663350197390230">Įjungus svetainėse galima naudoti „JavaScript“. Išjungus svetainėse negalima naudoti „JavaScript“.</translation> <translation id="5099358668261120049">Bus ištrinti visi duomenys ir slapukai, kuriuos domenas <ph name="ORIGIN" /> arba jo programa saugo jūsų pagrindiniame ekrane.</translation> <translation id="5100237604440890931">Sutraukta – spustelėkite, kad išskleistumėte</translation> <translation id="5123685120097942451">Inkognito skirtukas</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">Atlikus šį veiksmą bus ištrinti visi vietiniai duomenys, įskaitant slapukus, taip pat bus iš naujo nustatyti visi <ph name="DOMAIN" /> ir jame esančių svetainių leidimai</translation> <translation id="5264323282659631142">Pašalinti „<ph name="CHIP_LABEL" />“</translation> <translation id="528192093759286357">Vilkite žymeklį nuo viršaus ir palieskite mygtuką „Atgal“, kad išeitumėte iš viso ekrano režimo.</translation> +<translation id="5295729974480418933">Įjungus svetainėse gali būti prašoma naudoti apie jus išsaugotą informaciją. Išjungus svetainėse negali būti prašoma naudoti apie jus išsaugotos informacijos.</translation> <translation id="5300589172476337783">Rodyti</translation> <translation id="5301954838959518834">Gerai, supratau</translation> <translation id="5317780077021120954">Išsaugoti</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(ir dar 1)}one{(ir dar #)}few{(ir dar #)}many{(ir dar #)}other{(ir dar #)}}</translation> <translation id="5403592356182871684">Pavadinimai</translation> <translation id="5438097262470833822">Bus iš naujo nustatyti svetainės <ph name="WEBSITE" /> leidimai</translation> +<translation id="5459413148890178711">Įjungus svetainėse gali būti prašoma jūsų vietovės informacijos. Išjungus svetainės negali matyti jūsų vietovės.</translation> <translation id="5489227211564503167">Praėjęs laikas: <ph name="ELAPSED_TIME" /> iš <ph name="TOTAL_TIME" />.</translation> <translation id="5502860503640766021">Leidžiama: <ph name="PERMISSION_1" />, užblokuota: <ph name="PERMISSION_2" /></translation> <translation id="5505264765875738116">Svetainės negali prašyti siųsti pranešimus</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">Svetainės gali išsaugoti duomenis įrenginyje</translation> <translation id="5771720122942595109">Užblokuota: <ph name="PERMISSION_1" /></translation> <translation id="5804241973901381774">Leidimai</translation> +<translation id="5844448279347999754">Įjungus svetainėse gali būti prašoma peržiūrėti tekstą ir vaizdus, išsaugotus jūsų iškarpinėje. Išjungus svetainės negali matyti teksto ar vaizdų, išsaugotų jūsų iškarpinėje.</translation> +<translation id="5853982612236235577">Įjungus svetainėse gali būti prašoma siųsti pranešimus. Išjungus svetainės negali siųsti pranešimų.</translation> <translation id="5860033963881614850">Išjungta</translation> <translation id="5876056640971328065">Pristabdyti vaizdo įrašą</translation> <translation id="5884085660368669834">Svetainės nuostata</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">Daugiau</translation> <translation id="6064125863973209585">Baigti atsisiuntimai</translation> <translation id="6071501408666570960">Galite būti atjungti šioje svetainėje</translation> +<translation id="6120483543004435978">Įjungus svetainėse gali būti prašoma leisti sužinoti, kada aktyviai naudojate įrenginį. Išjungus svetainės nežino, kada aktyviai naudojate įrenginį.</translation> <translation id="6165508094623778733">Sužinokite daugiau</translation> +<translation id="6171020522141473435">Įjungus svetainėse gali būti prašoma naudoti „Bluetooth“ įrenginius. Išjungus svetainėse negalima naudoti „Bluetooth“ įrenginių.</translation> <translation id="6177111841848151710">Užblokuota dabartiniam paieškos varikliui</translation> <translation id="6177128806592000436">Ryšys su šia svetaine nėra saugus</translation> <translation id="6181444274883918285">Pridėti svetainės išimtį</translation> <translation id="6192792657125177640">Išimtys</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{„Chrome“ vėl užblokuos slapukus rytoj}one{Liko # diena, kol slapukai vėl bus užblokuoti}few{Liko # dienos, kol slapukai vėl bus užblokuoti}many{Liko # dienos, kol slapukai vėl bus užblokuoti}other{Liko # dienų, kol slapukai vėl bus užblokuoti}}</translation> <translation id="6195163219142236913">Trečiųjų šalių slapukai apriboti</translation> <translation id="6196640612572343990">Blokuoti trečiosios šalies slapukus</translation> <translation id="6205314730813004066">Su skelbimais susijęs privatumas</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">Kai langas bus siauras, pateikite užklausą dėl rodinio versijos mobiliesiems</translation> <translation id="6527303717912515753">Bendrinti</translation> <translation id="652937045869844725">Pabandykite leisti trečiųjų šalių slapukus, o tai reiškia, kad turėsite mažiau apsaugos, bet labiau tikėtina, kad svetainės funkcijos veiks</translation> +<translation id="6530703012083415527">Įjungus svetainėse galima naudoti iššokančiuosius langus ir peradresavimus. Išjungus svetainėse negalima naudoti iššokančiųjų langų ir peradresavimų.</translation> <translation id="6545864417968258051">„Bluetooth“ nuskaitymas</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{Užblokuota: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ir dar <ph name="NUM_MORE" />}one{Užblokuota: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ir dar <ph name="NUM_MORE" />}few{Užblokuota: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ir dar <ph name="NUM_MORE" />}many{Užblokuota: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ir dar <ph name="NUM_MORE" />}other{Užblokuota: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ir dar <ph name="NUM_MORE" />}}</translation> <translation id="6554732001434021288">Paskutinį kartą lankytasi prieš <ph name="NUM_DAYS" /> d.</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">Parinktys pasiekiamos netoli ekrano apačios</translation> <translation id="7250468141469952378">Pasirinkta: <ph name="ITEM_COUNT" /></translation> <translation id="7260727271532453612">Leidžiama: <ph name="PERMISSION_1" /> ir <ph name="PERMISSION_2" /></translation> +<translation id="7276071417425470385">Įjungus svetainėse gali būti prašoma naudoti virtualiosios realybės įrenginius. Išjungus svetainėse negalima naudoti virtualiosios realybės įrenginių.</translation> <translation id="7284451015630589124">Užblokavote svetaines, kad nebūtų naudojami trečiųjų šalių slapukai, siekiant jus stebėti, kai naršote. Apsilankykite nustatymuose, kad galėtumėte <ph name="BEGIN_LINK" />tvarkyti stebėjimo apsaugas<ph name="END_LINK" />.</translation> <translation id="7302486331832100261">Įprastai blokuojate pranešimus. Norėdami leisti, palieskite „Išsami informacija“.</translation> <translation id="7366415735885268578">Svetainės pridėjimas</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">Tamsioji tema, skirta svetainėms</translation> <translation id="7474522811371247902">„Chrome“ daugelyje svetainių riboja trečiųjų šalių slapukų naudojimą. Tačiau trečiųjų šalių slapukai leidžiami šioje svetainėje, nes jie priklauso nuo jų teikiamų pagrindinių paslaugų.\n\nApsilankykite nustatymuose, kad galėtumėte <ph name="BEGIN_LINK" />tvarkyti stebėjimo apsaugas<ph name="END_LINK" />.</translation> <translation id="7521387064766892559">„JavaScript“</translation> +<translation id="7547989957535180761">Įjungus svetainėse gali būti rodomi raginimai prisijungti. Išjungus svetainėse negalima rodyti raginimų prisijungti.</translation> <translation id="7554752735887601236">Svetainėje naudojamas jūsų mikrofonas</translation> <translation id="7561196759112975576">Visada</translation> <translation id="757524316907819857">Užblokuoti svetaines, kad neleistų apsaugoto turinio</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">Ačiū, ne</translation> <translation id="7804248752222191302">Svetainėje naudojamas jūsų fotoaparatas</translation> <translation id="7807060072011926525">Pateikė „Google“</translation> +<translation id="7822573154188733812">„Chrome“ neleidžia svetainėms naudoti trečiųjų šalių slapukų, siekiant jus stebėti, kai naršote. Apsilankykite nustatymuose, kad galėtumėte <ph name="BEGIN_LINK" />tvarkyti stebėjimo apsaugas<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Leidžiama medija</translation> <translation id="783819812427904514">Įjungti vaizdo įrašo garsą</translation> <translation id="7846076177841592234">Atšaukti pasirinkimą</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">Priminti</translation> <translation id="7974024493641668069">{COUNT,plural, =1{<ph name="FPS_MEMBERS_COUNT" /> svetainė, priklausanti <ph name="FPS_OWNER" /> svetainių grupei, gali matyti jūsų veiklą grupėje}one{<ph name="FPS_MEMBERS_COUNT" /> svetainė, priklausanti <ph name="FPS_OWNER" /> svetainių grupei, gali matyti jūsų veiklą grupėje}few{<ph name="FPS_MEMBERS_COUNT" /> svetainės, priklausančios <ph name="FPS_OWNER" /> svetainių grupei, gali matyti jūsų veiklą grupėje}many{<ph name="FPS_MEMBERS_COUNT" /> svetainės, priklausančios <ph name="FPS_OWNER" /> svetainių grupei, gali matyti jūsų veiklą grupėje}other{<ph name="FPS_MEMBERS_COUNT" /> svetainių, priklausančių <ph name="FPS_OWNER" /> svetainių grupei, gali matyti jūsų veiklą grupėje}}</translation> <translation id="7986741934819883144">Pasirinkite kontaktą</translation> +<translation id="7990211076305263060">Įjungus svetainėse gali būti prašoma naudoti mikrofoną. Išjungus svetainės negali naudoti mikrofono.</translation> <translation id="8007176423574883786">Išjungta šiame įrenginyje</translation> <translation id="802154636333426148">Įvyko atsisiuntimo klaida</translation> <translation id="8042586301629853791">Rūšiuoti pagal:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">Bet kokia svetainė, kurioje lankotės, gali rodyti jums bet kokį skelbimą</translation> <translation id="8087000398470557479">Šis turinys yra iš domeno <ph name="DOMAIN_NAME" />, kurį teikia „Google“.</translation> <translation id="8088603949666785339">Daugiau parinkčių skiltyje „<ph name="BANNER_TITLE" />“</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{„Chrome“ rytoj vėl apribos slapukus}one{Liko # diena, kol „Chrome“ vėl apribos slapukus}few{Liko # dienos, kol „Chrome“ vėl apribos slapukus}many{Liko # dienos, kol „Chrome“ vėl apribos slapukus}other{Liko # dienų, kol „Chrome“ vėl apribos slapukus}}</translation> <translation id="8116925261070264013">Išjungta</translation> +<translation id="8117244575099414087">Įjungus svetainėse gali būti naudojami įrenginio jutikliai. Išjungus svetainėse negalima naudoti jutiklių.</translation> <translation id="813082847718468539">Žiūrėti svetainės informaciją</translation> <translation id="8131740175452115882">Patvirtinti</translation> <translation id="8154912474061769055">Funkcijos gali neveikti daugybėje svetainių</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{Slapukai leidžiami <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> svetainėje}one{Slapukai leidžiami <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> svetainėje}few{Slapukai leidžiami <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> svetainėse}many{Slapukai leidžiami <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> svetainės}other{Slapukai leidžiami <ph name="FPS_MEMBERS_COUNT" /> <ph name="FPS_OWNER" /> svetainių}}</translation> <translation id="857943718398505171">Leidžiama (rekomenduojama)</translation> <translation id="8609465669617005112">Perkelti į viršų</translation> +<translation id="8617611086246832542">Įjungus rodoma svetainių rodinio versija staliniams kompiuteriams. Išjungus rodoma svetainių rodinio versija mobiliesiems.</translation> <translation id="8649036394979866943">„Chrome“ daugelyje svetainių riboja trečiųjų šalių slapukų naudojimą, siekiant stebėti jus, kai naršote. Apsilankykite nustatymuose, kad galėtumėte <ph name="BEGIN_LINK" />tvarkyti stebėjimo apsaugas<ph name="END_LINK" />.</translation> <translation id="8676374126336081632">Išvalyti įvestą tekstą</translation> <translation id="8681886425883659911">Skelbimai blokuojami svetainėse, kuriose rodomi nepageidaujami arba klaidinantys skelbimai</translation> <translation id="868929229000858085">Ieškokite savo kontaktuose</translation> <translation id="8712637175834984815">Supratau</translation> <translation id="8719283222052720129">Įjunkite „<ph name="APP_NAME" />“ leidimą <ph name="BEGIN_LINK" />„Android“ nustatymuose<ph name="END_LINK" />.</translation> +<translation id="8721719390026067591">Įjungus svetainėse gali būti prašoma ieškoti „Bluetooth“ įrenginių. Išjungus svetainėse negalima ieškoti „Bluetooth“ įrenginių.</translation> <translation id="8725066075913043281">Bandyti dar kartą</translation> <translation id="8730621377337864115">Atlikta</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{Leidžiama viena svetainė}one{Leidžiama # svetainė}few{Leidžiamos # svetainės}many{Leidžiama # svetainės}other{Leidžiama # svetainių}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698">Naršymas nepasiekiamas: <ph name="URL" /></translation> <translation id="8986362086234534611">Pamiršti</translation> <translation id="8990043154272859344">Būsite atjungti nuo visų svetainių</translation> +<translation id="9002538116239926534">Įjungus svetainės gali išsaugoti duomenis įrenginyje. Išjungus svetainės negali išsaugoti duomenų įrenginyje.</translation> <translation id="9011903857143958461">Leidžiama: <ph name="SITE_NAME" /></translation> <translation id="9019902583201351841">Tvarko jūsų tėvai</translation> <translation id="9039697262778250930">Galite būti atjungti nuo šių svetainių</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb index 82075b35..8f7e365f 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ml.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">അനുവദനീയം</translation> <translation id="429312253194641664">സൈറ്റ്, മീഡിയ പ്ലേ ചെയ്യുന്നു</translation> <translation id="42981349822642051">വികസിപ്പിക്കുക</translation> +<translation id="4336566011000459927">Chrome ഇന്ന് വീണ്ടും കുക്കികൾ പരിമിതപ്പെടുത്തും</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> എന്നതിന് കീഴിലുള്ള എല്ലാ സൈറ്റുകളും</translation> <translation id="4402755511846832236">നിങ്ങൾ ഈ ഉപകരണം സജീവമായി ഉപയോഗിക്കുന്നത് അറിയുന്നതിൽ നിന്ന് സൈറ്റുകളെ ബ്ലോക്ക് ചെയ്യുന്നു</translation> <translation id="4412992751769744546">മൂന്നാം കക്ഷി കുക്കികളെ അനുവദിക്കുക</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">ഈ സൈറ്റിലേക്കുള്ള നിങ്ങളുടെ കണക്ഷൻ സുരക്ഷിതമല്ല</translation> <translation id="6181444274883918285">സൈറ്റിനെ ഒഴിവാക്കൽ ലിസ്റ്റിൽ ചേർക്കുക</translation> <translation id="6192792657125177640">അപവാദങ്ങള്</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome നാളെ വീണ്ടും കുക്കികൾ ബ്ലോക്ക് ചെയ്യും}other{# ദിവസത്തിന് ശേഷം വീണ്ടും കുക്കികൾ ബ്ലോക്ക് ചെയ്യും}}</translation> <translation id="6195163219142236913">മൂന്നാം കക്ഷി കുക്കികൾ പരിമിതപ്പെടുത്തിയിരിക്കുന്നു</translation> <translation id="6196640612572343990">മൂന്നാം കക്ഷി കുക്കികള് ബ്ലോക്കുചെയ്യുക</translation> <translation id="6205314730813004066">പരസ്യവുമായി ബന്ധപ്പെട്ട സ്വകാര്യത</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">വേണ്ട നന്ദി</translation> <translation id="7804248752222191302">ഒരു സൈറ്റ് നിങ്ങളുടെ ക്യാമറ ഉപയോഗിക്കുന്നു</translation> <translation id="7807060072011926525">Google നൽകുന്നത്</translation> +<translation id="7822573154188733812">നിങ്ങൾ ബ്രൗസ് ചെയ്യുമ്പോൾ നിങ്ങളെ ട്രാക്ക് ചെയ്യുന്നതിന് മൂന്നാം കക്ഷി കുക്കികൾ ഉപയോഗിക്കുന്നതിൽ നിന്ന് സൈറ്റുകളെ Chrome ബ്ലോക്ക് ചെയ്യുന്നു. <ph name="BEGIN_LINK" />നിങ്ങളുടെ ട്രാക്ക് ചെയ്യൽ പരിരക്ഷകൾ മാനേജ് ചെയ്യാൻ<ph name="END_LINK" /> ക്രമീകരണം സന്ദർശിക്കുക.</translation> <translation id="7835852323729233924">മീഡിയ പ്ലേ ചെയ്യുന്നു</translation> <translation id="783819812427904514">വീഡിയോ അൺമ്യൂട്ട് ചെയ്യുക</translation> <translation id="7846076177841592234">തിരഞ്ഞെടുത്തത് റദ്ദാക്കുക</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">നിങ്ങൾ സന്ദർശിക്കുന്ന ഏത് സൈറ്റിനും ഏത് പരസ്യവും നിങ്ങളെ കാണിക്കാനാകും</translation> <translation id="8087000398470557479">ഈ ഉള്ളടക്കം Google-ൽ നിന്നുള്ള <ph name="DOMAIN_NAME" /> ഡൊമെയ്നിൽ നിന്നുള്ളതാണ്.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> എന്നതിലെ കൂടുതൽ ഓപ്ഷനുകൾ</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome നാളെ വീണ്ടും കുക്കികൾ പരിമിതപ്പെടുത്തും}other{# ദിവസത്തിന് ശേഷം Chrome വീണ്ടും കുക്കികൾ പരിമിതപ്പെടുത്തും}}</translation> <translation id="8116925261070264013">മ്യൂട്ടുചെയ്തു</translation> <translation id="813082847718468539">സൈറ്റ് വിവരങ്ങള് കാണുക</translation> <translation id="8131740175452115882">സ്ഥിരീകരിക്കുക</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb index 4ec58faf..5b75387 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">अनुमत</translation> <translation id="429312253194641664">साइट मीडिया प्ले करत आहे</translation> <translation id="42981349822642051">विस्तृत करा</translation> +<translation id="4336566011000459927">Chrome आज पुन्हा कुकी मर्यादित करेल</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> अंतर्गत सर्व साइट</translation> <translation id="4402755511846832236">तुम्ही हे डिव्हाइस ॲक्टिव्हपणे कधी वापरता हे साइटना जाणून घेण्यापासून ब्लॉक करा</translation> <translation id="4412992751769744546">तृतीय-पक्ष कुकीजना अनुमती द्या</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">या साइटवरील तुमचे कनेक्शन सुरक्षित नाही</translation> <translation id="6181444274883918285">साइट एक्सेप्शन जोडा</translation> <translation id="6192792657125177640">अपवाद</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome उद्या पुन्हा कुकी ब्लॉक करेल}other{# दिवसांनी कुकी पुन्हा ब्लॉक केल्या जातील}}</translation> <translation id="6195163219142236913">तृतीय पक्ष कुकी मर्यादित आहेत</translation> <translation id="6196640612572343990">तृतीय पक्ष कुकी ब्लॉक करा</translation> <translation id="6205314730813004066">जाहिरातींशी संबंधित गोपनीयता</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">नाही, नको</translation> <translation id="7804248752222191302">साइट तुमचा कॅमेरा वापरत आहे</translation> <translation id="7807060072011926525">Google द्वारे पुरवलेली</translation> +<translation id="7822573154188733812">तुम्ही ब्राउझ करत असताना तुम्हाला ट्रॅक करण्यासाठी Chrome हे साइटना तृतीय पक्ष कुकी वापरण्यापासून ब्लॉक करते. <ph name="BEGIN_LINK" />तुमच्या ट्रॅकिंगपासून संरक्षणांचे व्यवस्थापन करणे<ph name="END_LINK" /> यासाठी सेटिंग्जना भेट द्या.</translation> <translation id="7835852323729233924">मीडिया प्ले करत आहे</translation> <translation id="783819812427904514">व्हिडिओ अनम्यूट करा</translation> <translation id="7846076177841592234">निवड रद्द करा</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">तुम्ही भेट देता ती कोणतीही साइट तुम्हाला कोणतीही जाहिरात दाखवू शकते</translation> <translation id="8087000398470557479">Google ने वितरित केलेली ही आशय, <ph name="DOMAIN_NAME" /> मधील आहे.</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> मध्ये आणखी पर्याय</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome उद्या पुन्हा कुकी मर्यादित करेल}other{Chrome पुन्हा # दिवसांनी कुकी मर्यादित करेल}}</translation> <translation id="8116925261070264013">म्यूट केले</translation> <translation id="813082847718468539">साइटची माहिती पहा</translation> <translation id="8131740175452115882">पुष्टी करा</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb index c2bd5dd..edd2a75 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
@@ -23,6 +23,7 @@ <translation id="1415402041810619267">URL terpangkas</translation> <translation id="1426410128494586442">Ya</translation> <translation id="1448064542941920355">Zum keluar</translation> +<translation id="146867109637325312">{COUNT,plural, =1{<ph name="SITE_COUNT" /> laman}other{<ph name="SITE_COUNT" /> laman}}</translation> <translation id="1510341833810331442">Laman tidak dibenarkan menyimpan data pada peranti anda</translation> <translation id="1547123415014299762">Kuki pihak ketiga dibenarkan</translation> <translation id="1568470248891039841">Laman yang anda lawati boleh membenamkan kandungan daripada laman lain, contohnya imej, iklan dan teks. Laman lain boleh meminta kebenaran anda untuk menggunakan maklumat yang disimpan tentang anda ketika anda menyemak imbas laman tersebut. <ph name="BEGIN_LINK" />Ketahui lebih lanjut tentang kandungan terbenam<ph name="END_LINK" /></translation> @@ -31,6 +32,7 @@ <translation id="1633720957382884102">Laman yang berkaitan</translation> <translation id="1644574205037202324">Sejarah</translation> <translation id="1647582022260550163">Adakah anda pasti mahu menetapkan semula kebenaran dan mengosongkan kuki serta data laman?</translation> +<translation id="1652197001188145583">Apabila dihidupkan, laman dapat meminta untuk menggunakan peranti NFC. Apabila dimatikan, laman tidak dapat menggunakan peranti NFC.</translation> <translation id="1660204651932907780">Benarkan tapak untuk memainkan bunyi (disyorkan)</translation> <translation id="1677097821151855053">Kuki dan data tapak lain digunakan untuk mengingat anda, misalnya untuk log anda masuk atau memperibadikan iklan. Untuk mengurus kuki bagi semua tapak, lihat <ph name="BEGIN_LINK" />Tetapan<ph name="END_LINK" />.</translation> <translation id="169515064810179024">Sekat tapak daripada mengakses penderia gerakan</translation> @@ -46,6 +48,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / <ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">Jadikan teks dan imej lebih besar atau lebih kecil untuk semua laman yang anda lawati</translation> <translation id="1984937141057606926">Dibenarkan, kecuali pihak ketiga</translation> +<translation id="1985247341569771101">Apabila dihidupkan, laman dapat menggunakan penderia gerakan peranti anda. Apabila dimatikan, laman tidak dapat menggunakan penderia gerakan.</translation> <translation id="1989112275319619282">Semak Imbas</translation> <translation id="1994173015038366702">URL tapak</translation> <translation id="2004697686368036666">Ciri pada sesetengah laman mungkin tidak berfungsi</translation> @@ -106,6 +109,7 @@ <translation id="2713106313042589954">Matikan kamera</translation> <translation id="2717722538473713889">Alamat e-mel</translation> <translation id="2750481671343847896">Laman boleh menunjukkan gesaan log masuk daripada perkhidmatan identiti.</translation> +<translation id="2790501146643349491">Apabila dihidupkan, laman yang ditutup baru-baru ini dapat menyelesaikan penghantaran dan penerimaan data. Apabila dimatikan, laman yang ditutup baru-baru ini tidak dapat menyelesaikan penghantaran atau penerimaan data.</translation> <translation id="2822354292072154809">Adakah anda pasti mahu menetapkan semula semua kebenaran tapak untuk <ph name="CHOSEN_OBJECT_NAME" />?</translation> <translation id="2850913818900871965">Minta paparan mudah alih</translation> <translation id="2870560284913253234">Tapak</translation> @@ -114,6 +118,7 @@ <translation id="2903493209154104877">Alamat</translation> <translation id="2910701580606108292">Tanya sebelum membenarkan tapak memainkan kandungan yang dilindungi</translation> <translation id="2932883381142163287">Laporkan penyalahgunaan</translation> +<translation id="2939338015096024043">Apabila dihidupkan, laman dapat meminta untuk menjejaki kedudukan kamera anda dan mengetahui tentang persekitaran anda. Apabila dimatikan, laman tidak dapat menjejaki kedudukan kamera anda dan mengetahui tentang persekitaran anda.</translation> <translation id="2968755619301702150">Pemapar sijil</translation> <translation id="2979365474350987274">Kuki pihak ketiga adalah terhad</translation> <translation id="3008272652534848354">Tetapkan semula kebenaran</translation> @@ -132,6 +137,7 @@ <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> data disimpan</translation> <translation id="321187648315454507">Untuk membolehkan <ph name="APP_NAME" /> menghantar pemberitahuan kepada anda, hidupkan juga pemberitahuan dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation> <translation id="3227137524299004712">Mikrofon</translation> +<translation id="3242646949159196181">Apabila dihidupkan, laman dapat memainkan bunyi. Apabila dimatikan, laman tidak dapat memainkan bunyi.</translation> <translation id="3277252321222022663">Benarkan tapak mengakses penderia (disyorkan)</translation> <translation id="3285500645985761267">Benarkan laman berkaitan melihat aktiviti anda dalam kumpulan</translation> <translation id="3295019059349372795">Bab 11: Oz, Kota Zamrud yang Menakjubkan</translation> @@ -142,6 +148,7 @@ <translation id="3386292677130313581">Tanya sebelum membenarkan tapak mengetahui lokasi anda (disyorkan)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">Kuki pihak ketiga disekat</translation> +<translation id="3448554387819310837">Apabila dihidupkan, laman dapat meminta untuk menggunakan kamera anda. Apabila dimatikan, laman tidak dapat menggunakan kamera anda.</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome akan menyekat kuki lagi esok}other{# hari sehingga Chrome menyekat kuki lagi}}</translation> <translation id="3521663503435878242">Laman di bawah <ph name="DOMAIN" /></translation> <translation id="3538390592868664640">Sekat tapak daripada membuat peta 3D bagi persekitaran anda atau menjejaki kedudukan kamera</translation> @@ -154,6 +161,7 @@ <translation id="3600792891314830896">Redam tapak yang memainkan bunyi</translation> <translation id="3602290021589620013">Pratonton</translation> <translation id="3628308229821498208">Carian cadangan</translation> +<translation id="3697164069658504920">Apabila dihidupkan, laman dapat meminta untuk menggunakan peranti USB. Apabila dimatikan, laman tidak dapat menggunakan peranti USB.</translation> <translation id="3707034683772193706">Laman yang anda lawati boleh menyimpan sedikit maklumat dengan Chrome, terutamanya untuk mengesahkan bahawa anda bukan bot</translation> <translation id="3721953990244350188">Ketepikan dan tunjukkan tindakan seterusnya yang tersedia</translation> <translation id="3744111561329211289">Penyegerakan latar belakang</translation> @@ -210,12 +218,14 @@ <translation id="4645575059429386691">Diurus oleh ibu bapa anda</translation> <translation id="4670064810192446073">Realiti maya</translation> <translation id="4751476147751820511">Penderia gerakan atau cahaya</translation> +<translation id="4755971844837804407">Apabila dihidupkan, laman dapat memaparkan sebarang iklan kepada anda. Apabila dimatikan, laman tidak dapat memaparkan iklan yang mengganggu atau mengelirukan.</translation> <translation id="4779083564647765204">Zum</translation> <translation id="4811450222531576619">Ketahui tentang sumber dan topik halaman ini</translation> <translation id="4836046166855586901">Tanya apabila laman ingin mengetahui waktu anda menggunakan peranti ini dengan aktif</translation> <translation id="483914009762354899">Sertakan semua laman di bawah domain ini</translation> <translation id="4883854917563148705">Tetapan yang diurus tidak dapat ditetapkan semula</translation> <translation id="4887024562049524730">Tanya sebelum membenarkan tapak menggunakan peranti dan data realiti maya anda (disyorkan)</translation> +<translation id="4953688446973710931">Apabila dihidupkan, laman dapat meminta untuk memuat turun berbilang fail secara automatik. Apabila dimatikan, laman tidak dapat memuat turun berbilang fail secara automatik.</translation> <translation id="4955223779495905865">Laman yang anda lawati boleh membenamkan kandungan daripada laman lain, contohnya imej, iklan dan teks. Mana-mana laman ini boleh menyimpan kuki dan data lain untuk memperibadikan pengalaman anda.</translation> <translation id="4962975101802056554">Batalkan semua kebenaran untuk peranti</translation> <translation id="497421865427891073">Ke hadapan</translation> @@ -230,6 +240,7 @@ <translation id="5063480226653192405">Penggunaan</translation> <translation id="5091013926750941408">Laman mudah alih</translation> <translation id="509133520954049755">Minta paparan desktop</translation> +<translation id="5091663350197390230">Apabila dihidupkan, laman dapat menggunakan JavaScript. Apabila dimatikan, laman tidak dapat menggunakan JavaScript.</translation> <translation id="5099358668261120049">Tindakan ini akan memadamkan semua data dan kuki yang disimpan oleh <ph name="ORIGIN" /> atau oleh apl pada Skrin utama anda.</translation> <translation id="5100237604440890931">Diruntuhkan - klik untuk mengembangkan.</translation> <translation id="5123685120097942451">Tab Inkognito</translation> @@ -241,6 +252,7 @@ <translation id="5246825184569358663">Tindakan ini akan memadamkan semua data setempat, termasuk kuki, dan menetapkan semula semua kebenaran untuk <ph name="DOMAIN" /> serta semua laman dalam bahagian domain ini</translation> <translation id="5264323282659631142">Alih keluar '<ph name="CHIP_LABEL" />'</translation> <translation id="528192093759286357">Seret dari atas dan sentuh butang kembali untuk keluar daripada skrin penuh.</translation> +<translation id="5295729974480418933">Apabila dihidupkan, laman dapat meminta untuk menggunakan maklumat yang disimpan tentang anda. Apabila dimatikan, laman tidak dapat meminta untuk menggunakan maklumat yang disimpan tentang anda.</translation> <translation id="5300589172476337783">Paparkan</translation> <translation id="5301954838959518834">OK, faham</translation> <translation id="5317780077021120954">Simpan</translation> @@ -251,6 +263,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(+ 1 lagi)}other{(+ # lagi)}}</translation> <translation id="5403592356182871684">Nama</translation> <translation id="5438097262470833822">Pilihan ini akan menetapkan semula kebenaran untuk <ph name="WEBSITE" /></translation> +<translation id="5459413148890178711">Apabila dihidupkan, laman dapat meminta lokasi anda. Apabila dimatikan, laman tidak dapat melihat lokasi anda.</translation> <translation id="5489227211564503167"><ph name="ELAPSED_TIME" /> masa berlalu daripada <ph name="TOTAL_TIME" /></translation> <translation id="5502860503640766021"><ph name="PERMISSION_1" /> dibenarkan, <ph name="PERMISSION_2" /> disekat</translation> <translation id="5505264765875738116">Tapak tidak boleh membuat permintaan untuk menghantar pemberitahuan</translation> @@ -265,12 +278,15 @@ <translation id="5677928146339483299">Disekat</translation> <translation id="5689516760719285838">Lokasi</translation> <translation id="5690795753582697420">Kamera dimatikan dalam tetapan Android</translation> +<translation id="5691080386278724773"><ph name="SITE" /> boleh menggunakan maklumat anda ketika anda menyemak imbas</translation> <translation id="5700761515355162635">Kuki pihak ketiga dibenarkan</translation> <translation id="5706552988683188916">Tindakan ini memadamkan kuki dan data laman lain untuk <ph name="WEBSITE" /></translation> <translation id="5723967018671998714">Kuki pihak ketiga disekat dalam mod Inkognito</translation> <translation id="5740126560802162366">Laman boleh menyimpan data pada peranti anda</translation> <translation id="5771720122942595109"><ph name="PERMISSION_1" /> disekat</translation> <translation id="5804241973901381774">Kebenaran</translation> +<translation id="5844448279347999754">Apabila dihidupkan, laman dapat meminta untuk melihat teks dan imej yang disimpan pada papan keratan anda. Apabila dimatikan, laman tidak dapat melihat teks atau imej pada papan keratan anda.</translation> +<translation id="5853982612236235577">Apabila dihidupkan, laman dapat meminta untuk menghantar pemberitahuan. Apabila dimatikan, laman tidak dapat menghantar pemberitahuan.</translation> <translation id="5860033963881614850">Dimatikan</translation> <translation id="5876056640971328065">Jeda video</translation> <translation id="5884085660368669834">Pilihan laman</translation> @@ -289,7 +305,9 @@ <translation id="6042308850641462728">Lagi</translation> <translation id="6064125863973209585">Muat turun yang telah selesai</translation> <translation id="6071501408666570960">Anda mungkin akan dilog keluar dari laman ini</translation> +<translation id="6120483543004435978">Apabila dihidupkan, laman dapat meminta untuk mengetahui waktu anda menggunakan peranti secara aktif. Apabila dimatikan, laman tidak dapat mengetahui waktu anda menggunakan peranti secara aktif.</translation> <translation id="6165508094623778733">Ketahui lebih lanjut</translation> +<translation id="6171020522141473435">Apabila dihidupkan, laman dapat meminta untuk menggunakan peranti Bluetooth. Apabila dimatikan, laman tidak dapat menggunakan peranti Bluetooth.</translation> <translation id="6177111841848151710">Disekat untuk enjin carian semasa</translation> <translation id="6177128806592000436">Sambungan anda ke tapak ini tidak selamat</translation> <translation id="6181444274883918285">Tambah pengecualian tapak</translation> @@ -304,6 +322,7 @@ <translation id="6262279340360821358"><ph name="PERMISSION_1" /> dan <ph name="PERMISSION_2" /> disekat</translation> <translation id="6270391203985052864">Tapak boleh membuat permintaan untuk menghantar pemberitahuan</translation> <translation id="6295158916970320988">Semua tapak</translation> +<translation id="6304434827459067558"><ph name="SITE" /> disekat daripada menggunakan maklumat anda pada</translation> <translation id="6320088164292336938">Getar</translation> <translation id="6344622098450209924">Perlindungan Penjejakan</translation> <translation id="6367753977865761591">Sekat log masuk pihak ketiga untuk laman tertentu.</translation> @@ -315,6 +334,7 @@ <translation id="6500423977866688905">Apabila tetingkap sempit, minta paparan mudah alih</translation> <translation id="6527303717912515753">Kongsi</translation> <translation id="652937045869844725">Cuba berikan kebenaran untuk kuki pihak ketiga yang boleh mengurangkan perlindungan tetapi ciri laman lebih berkemungkinan untuk berfungsi</translation> +<translation id="6530703012083415527">Apabila dihidupkan, laman dapat menggunakan tetingkap timbul dan mengubah hala. Apabila dimatikan, laman tidak dapat menggunakan tetingkap timbul dan mengubah hala.</translation> <translation id="6545864417968258051">Pengimbasan Bluetooth</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> dan <ph name="NUM_MORE" /> lagi disekat}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> dan <ph name="NUM_MORE" /> lagi disekat}}</translation> <translation id="6554732001434021288">Terakhir dilawati <ph name="NUM_DAYS" /> hari yang lalu</translation> @@ -358,6 +378,7 @@ <translation id="7243308994586599757">Pilihan tersedia berhampiran bahagian bawah skrin</translation> <translation id="7250468141469952378"><ph name="ITEM_COUNT" /> dipilih</translation> <translation id="7260727271532453612"><ph name="PERMISSION_1" /> dan <ph name="PERMISSION_2" /> dibenarkan</translation> +<translation id="7276071417425470385">Apabila dihidupkan, laman dapat meminta untuk menggunakan peranti realiti maya. Apabila dimatikan, laman tidak dapat menggunakan peranti realiti maya.</translation> <translation id="7284451015630589124">Anda menyekat laman daripada menggunakan kuki pihak ketiga untuk menjejaki anda semasa menyemak imbas. Lawati tetapan untuk <ph name="BEGIN_LINK" />mengurus perlindungan penjejakan anda<ph name="END_LINK" />.</translation> <translation id="7302486331832100261">Anda biasanya menyekat pemberitahuan. Untuk membenarkan pemberitahuan, ketik Butiran.</translation> <translation id="7366415735885268578">Tambahkan tapak</translation> @@ -369,6 +390,7 @@ <translation id="7425915948813553151">Tema gelap untuk laman</translation> <translation id="7474522811371247902">Chrome mengehadkan kebanyakan laman daripada menggunakan kuki pihak ketiga. Namun, kuki pihak ketiga dibenarkan pada laman ini kerana kuki tersebut bergantung pada Chrome untuk memberikan perkhidmatan asas.\n\nAkses tetapan untuk <ph name="BEGIN_LINK" />mengurus perlindungan penjejakan anda<ph name="END_LINK" />.</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">Apabila dihidupkan, laman dapat memaparkan gesaan log masuk. Apabila dimatikan, laman tidak dapat memaparkan gesaan log masuk.</translation> <translation id="7554752735887601236">Suatu tapak sedang menggunakan mikrofon anda</translation> <translation id="7561196759112975576">Sentiasa</translation> <translation id="757524316907819857">Sekat tapak daripada memainkan kandungan yang dilindungi</translation> @@ -393,6 +415,7 @@ <translation id="7940722705963108451">Ingatkan saya</translation> <translation id="7974024493641668069">{COUNT,plural, =1{<ph name="FPS_MEMBERS_COUNT" /> laman dalam kumpulan laman <ph name="FPS_OWNER" /> yang boleh melihat aktiviti anda dalam kumpulan}other{<ph name="FPS_MEMBERS_COUNT" /> laman dalam kumpulan laman <ph name="FPS_OWNER" /> yang boleh melihat aktiviti anda dalam kumpulan}}</translation> <translation id="7986741934819883144">Pilih kenalan</translation> +<translation id="7990211076305263060">Apabila dihidupkan, laman dapat meminta untuk menggunakan mikrofon anda. Apabila dimatikan, laman tidak dapat menggunakan mikrofon anda.</translation> <translation id="8007176423574883786">Dimatikan untuk peranti ini</translation> <translation id="802154636333426148">Muat turun gagal</translation> <translation id="8042586301629853791">Isih mengikut:</translation> @@ -403,6 +426,7 @@ <translation id="8088603949666785339">Lagi pilihan dalam <ph name="BANNER_TITLE" /></translation> <translation id="8113501330600751161">{DAYS,plural, =1{Chrome akan mengehadkan kuki lagi esok}other{# hari sehingga Chrome mengehadkan kuki lagi}}</translation> <translation id="8116925261070264013">Diredam</translation> +<translation id="8117244575099414087">Apabila dihidupkan, laman dapat menggunakan penderia peranti anda. Apabila dimatikan, laman tidak dapat menggunakan penderia.</translation> <translation id="813082847718468539">Lihat maklumat tapak</translation> <translation id="8131740175452115882">Sahkan</translation> <translation id="8154912474061769055">Ciri pada banyak laman mungkin tidak berfungsi</translation> @@ -440,12 +464,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{Kuki dibenarkan untuk <ph name="FPS_MEMBERS_COUNT" /> laman <ph name="FPS_OWNER" />}other{Kuki dibenarkan untuk <ph name="FPS_MEMBERS_COUNT" /> laman <ph name="FPS_OWNER" />}}</translation> <translation id="857943718398505171">Dibenarkan (disyorkan)</translation> <translation id="8609465669617005112">Alihkan ke atas</translation> +<translation id="8617611086246832542">Apabila dihidupkan, paparan desktop laman web akan dipaparkan. Apabila dimatikan, paparan mudah alih laman web akan dipaparkan.</translation> <translation id="8649036394979866943">Chrome mengehadkan kebanyakan laman daripada menggunakan kuki pihak ketiga untuk menjejaki anda semasa menyemak imbas. Lawati tetapan untuk <ph name="BEGIN_LINK" />mengurus perlindungan penjejakan anda<ph name="END_LINK" /></translation> <translation id="8676374126336081632">Kosongkan input</translation> <translation id="8681886425883659911">Iklan disekat di laman yang diketahui memaparkan iklan yang mengganggu atau mengelirukan</translation> <translation id="868929229000858085">Cari dalam kenalan anda</translation> <translation id="8712637175834984815">Faham</translation> <translation id="8719283222052720129">Hidupkan kebenaran untuk <ph name="APP_NAME" /> dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation> +<translation id="8721719390026067591">Apabila dihidupkan, laman dapat meminta untuk mencari peranti Bluetooth. Apabila dimatikan, laman tidak dapat mencari peranti Bluetooth.</translation> <translation id="8725066075913043281">Cuba lagi</translation> <translation id="8730621377337864115">Selesai</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{1 laman dibenarkan}other{# laman dibenarkan}}</translation> @@ -469,6 +495,7 @@ <translation id="8959122750345127698">Tidak dapat mencapai navigasi: <ph name="URL" /></translation> <translation id="8986362086234534611">Lupa</translation> <translation id="8990043154272859344">Anda akan dilog keluar daripada semua laman</translation> +<translation id="9002538116239926534">Apabila dihidupkan, laman dapat menyimpan data pada peranti anda. Apabila dimatikan, laman tidak dapat menyimpan data pada peranti anda.</translation> <translation id="9011903857143958461"><ph name="SITE_NAME" /> dibenarkan</translation> <translation id="9019902583201351841">Diurus oleh ibu bapa anda</translation> <translation id="9039697262778250930">Anda mungkin akan dilog keluar daripada laman ini</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb index c6adb2fd..4dd2514 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ne.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">सम्बन्धित साइटहरू</translation> <translation id="1644574205037202324">इतिहास</translation> <translation id="1647582022260550163">तपाईं साँच्चिकै अनुमतिहरू रिसेट गर्न र कुकी तथा साइटसम्बन्धी डेटा मेटाउन चाहनुहुन्छ?</translation> +<translation id="1652197001188145583">यो सेटिङ अन भएका बेला साइटहरूले NFC डिभाइसहरू प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले NFC डिभाइसहरू प्रयोग गर्न सक्दैनन्।</translation> <translation id="1660204651932907780">साइटहरूलाई आवाज प्ले गर्ने अनुमति दिनुहोस् (सिफारिस गरिएको)</translation> <translation id="1677097821151855053">कुकी र साइटका अन्य डेटा तपाईंको जानकारी याद राख्न प्रयोग गरिन्छन्। जस्तै, कुकी र साइटका अन्य डेटा तपाईंलाई साइन इन गराउन वा तपाईंको चाखअनुसारका विज्ञापन देखाउन प्रयोग गरिन्छन्। सबै साइटका कुकीहरू व्यवस्थापन गर्न <ph name="BEGIN_LINK" />सेटिङ<ph name="END_LINK" />मा जानुहोस्।</translation> <translation id="169515064810179024">साइटहरूलाई चालसम्बन्धी सेन्सरहरूमाथि पहुँच राख्नबाट रोक्नुहोस्</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" /> / <ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">तपाईं जाने सबै साइटका टेक्स्ट तथा फोटोहरू अझ ठुलो वा अझ सानो बनाउनुहोस्</translation> <translation id="1984937141057606926">अनुमति छ, तेस्रो-पक्ष बाहेकलाई</translation> +<translation id="1985247341569771101">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको डिभाइसका मोसन सेन्सरहरू प्रयोग गर्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले मोसन सेन्सरहरू प्रयोग गर्न सक्दैनन्।</translation> <translation id="1989112275319619282">ब्राउज गर्नुहोस्</translation> <translation id="1994173015038366702">साइट URL</translation> <translation id="2004697686368036666">केही साइटका सुविधाहरूले काम नगर्न सक्छन्</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">क्यामेरा अफ गर्नुहोस्</translation> <translation id="2717722538473713889">इमेल ठेगानाहरू</translation> <translation id="2750481671343847896">साइटहरूले पहिचान सेवा प्रदायकहरूबाट प्राप्त साइन इन गर्ने प्रम्प्टहरू देखाउन सक्छन्।</translation> +<translation id="2790501146643349491">यो सेटिङ अन भएका बेला हालसालै बन्द गरिएका साइटहरूले डेटा पठाउने र प्राप्त गर्ने कार्य पूरा गर्न सक्छन्। यो सेटिङ अफ भएका बेला हालसालै बन्द गरिएका साइटहरूले डेटा पठाउने र प्राप्त गर्ने कार्य पूरा गर्न सक्दैनन्।</translation> <translation id="2822354292072154809">तपाईं साँच्चिकै <ph name="CHOSEN_OBJECT_NAME" /> का साइटसम्बन्धी सम्पूर्ण अनुमतिहरू रिसेट गर्न चाहनुहुन्छ?</translation> <translation id="2850913818900871965">मोबाइल भ्यू देखाउन अनुरोध गर्नुहोस्</translation> <translation id="2870560284913253234">साइट</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">ठेगानाहरू</translation> <translation id="2910701580606108292">साइटहरूलाई संरक्षित सामग्री प्ले गर्ने अनुमति दिनुअघि सोध्नुहोस्</translation> <translation id="2932883381142163287">दुरूपयोग रिपोर्ट गर्नुहोस्</translation> +<translation id="2939338015096024043">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको क्यामेराको पोजिसन ट्रयाक गर्ने र तपाईंको वरपरको वातावरणका बारेमा जान्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंको क्यामेराको पोजिसन ट्रयाक गर्न वा तपाईंको वरपरको वातावरणका बारेमा थाहा पाउन सक्दैनन्।</translation> <translation id="2968755619301702150">प्रमाणपत्र दर्शक</translation> <translation id="2979365474350987274">तेस्रो पक्षीय कुकीहरू सीमित गरिएका छन्</translation> <translation id="3008272652534848354">अनुमतिहरू रिसेट गर्नुहोस्</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> भण्डारण डेटा</translation> <translation id="321187648315454507"><ph name="APP_NAME" /> लाई तपाईंलाई सूचनाहरू पठाउन दिन <ph name="BEGIN_LINK" />Android का सेटिङ<ph name="END_LINK" />मा गई सूचनाहरू पनि अन गर्नुहोस्।</translation> <translation id="3227137524299004712">माइक्रोफोन</translation> +<translation id="3242646949159196181">यो सेटिङ अन भएका बेला साइटहरूले साउन्ड बजाउन सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले साउन्ड बजाउन सक्दैनन्।</translation> <translation id="3277252321222022663">साइटहरूलाई सेन्सरहरूमाथि पहुँच राख्ने अनुमति दिनुहोस् (सिफारिस गरिएको)</translation> <translation id="3285500645985761267">सम्बन्धित साइटहरूलाई तपाईंले यो समूहमा गर्ने गतिविधि हेर्ने अनुमति दिइयोस्</translation> <translation id="3295019059349372795">भाग ११: The Wonderful Emerald City of Oz</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">साइटहरूलाई तपाईँको स्थान थाहा पाउने अनुमति दिनु भन्दा पहिले तपाईँलाई सोध्ने (सिफारिस गरिएको)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">तेस्रो पक्षीय कुकीहरू ब्लक गरिएका छन्</translation> +<translation id="3448554387819310837">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको क्यामेरा प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंको क्यामेरा प्रयोग गर्न सक्दैनन्।</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome ले भोलि फेरि कुकीहरू ब्लक गर्ने छ}other{Chrome ले # दिनपछि फेरि कुकीहरू ब्लक गर्ने छ}}</translation> <translation id="3521663503435878242"><ph name="DOMAIN" /> अन्तर्गतका साइटहरू</translation> <translation id="3538390592868664640">साइटहरूलाई आफू वरपरको ठाउँको 3D नक्सा बनाउन वा क्यामेराको अवस्था पत्ता लगाउन नदिनुहोस्</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">आवाज प्ले गर्ने साइटहरूलाई म्युट गर्नुहोस्</translation> <translation id="3602290021589620013">प्रिभ्यु गर्नुहोस्</translation> <translation id="3628308229821498208">सिफारिस गरिएका खोजहरू</translation> +<translation id="3697164069658504920">यो सेटिङ अन भएका बेला साइटहरूले USB डिभाइसहरू प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले USB डिभाइसहरू प्रयोग गर्न सक्दैनन्।</translation> <translation id="3707034683772193706">तपाईंले खोल्ने साइटले मुख्यतः तपाईं कुनै बट होइन भन्ने कुरा पुष्टि गर्न Chrome मा थोरै जानकारी सेभ गर्न सक्छ</translation> <translation id="3721953990244350188">यो कारबाही खारेज गरियोस् र उपलब्ध अर्को कारबाही देखाइयोस्</translation> <translation id="3744111561329211289">पृष्ठभूमिमा सिंक गर्ने सुविधा</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">अनुमति प्राप्त</translation> <translation id="429312253194641664">कुनै साइटले मिडियो प्ले गरिरहेको छ</translation> <translation id="42981349822642051">विस्तृत गर्नुहोस्</translation> +<translation id="4336566011000459927">Chrome ले आज फेरि कुकीहरू सीमित पार्ने छ</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> अन्तर्गतका सबै साइटहरू</translation> <translation id="4402755511846832236">तपाईं यो डिभाइस चलाउँदै हुनुहुन्छ कि हुनुहुन्न भन्ने कुरा साइटहरूलाई थाहा पाउन नदिनुहोस्</translation> <translation id="4412992751769744546">तेस्रो पक्षीय कुकीहरूलाई अनुमति दिनुहोस्</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">तपाईँको अविभावक द्वारा प्रबन्ध गरिएको</translation> <translation id="4670064810192446073">भर्चुअल रियालिटी</translation> <translation id="4751476147751820511">गति वा प्रकाशसम्बन्धी सेन्सरहरू</translation> +<translation id="4755971844837804407">यो सेटिङ अन भएका बेला साइटहरूले तपाईंलाई जुनसुकै विज्ञापन देखाउन सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले अवरोध पुर्याउने खालका वा भ्रामक विज्ञापनहरू देखाउन सक्दैनन्।</translation> <translation id="4779083564647765204">जुम</translation> <translation id="4811450222531576619">यो पेजको स्रोत र विषयका बारेमा जान्नुहोस्</translation> <translation id="4836046166855586901">कुनै साइटले मैले यो डिभाइस चलाइरहेको छु कि छुइनँ भन्ने कुराको जानकारी माग्दा मलाई सोधियोस्</translation> <translation id="483914009762354899">यो डोमेनअन्तर्गतका सबै साइटहरू समावेश गरियोस्</translation> <translation id="4883854917563148705">व्यवस्थित सेटिङ रिसेट गर्न सकिँदैन</translation> <translation id="4887024562049524730">साइटहरूलाई भर्चुअल रियालिटी चल्ने तपाईंको यन्त्र र त्यसमा भएको डेटा प्रयोग गर्न अनुमति दिनुअघि सोध्नुहोस् (सिफारिस गरिएको)</translation> +<translation id="4953688446973710931">यो सेटिङ अन भएका बेला साइटहरूले एकभन्दा बढी फाइलहरू स्वतः डाउनलोड गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले एकभन्दा बढी फाइलहरू स्वतः डाउनलोड गर्न सक्दैनन्।</translation> <translation id="4955223779495905865">तपाईं कुनै साइटमा जानुभयो भने सो साइटले अन्य साइटका फोटो, विज्ञापन र टेक्स्टलगायतका सामग्री इम्बेड गर्न सक्छ। यीमध्ये कुनै पनि साइटले तपाईंले प्रयोग गर्ने सुविधा पर्सनलाइज गर्ने प्रयोजनका लागि कुकी तथा अन्य डेटा सेभ गर्न सक्छ।</translation> <translation id="4962975101802056554">डिभाइसका सबै अनुमतिहरू फिर्ता लिनुहोस्</translation> <translation id="497421865427891073">अगाडि जानुहोस्</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">उपयोग</translation> <translation id="5091013926750941408">मोबाइल साइट</translation> <translation id="509133520954049755">डेस्कटप भ्यू देखाउन अनुरोध गरियोस्</translation> +<translation id="5091663350197390230">यो सेटिङ अन भएका बेला साइटहरूले JavaScript प्रयोग गर्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले JavaScript प्रयोग गर्न सक्दैनन्।</translation> <translation id="5099358668261120049">तपाईंले यसो गर्नुभयो भने <ph name="ORIGIN" /> ले वा यससँग सम्बन्धित एपले तपाईंको होम स्क्रिनमा भण्डारण गरेका सबै डेटा तथा कुकीहरू मेटिने छन्।</translation> <translation id="5100237604440890931">संक्षिप्त भयो - विस्तृत गर्न क्लिक गर्नुहोस्</translation> <translation id="5123685120097942451">इन्कोग्निटो ट्याब</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">तपाईंले यो कार्य गर्नुभयो भने कुकीलगायतका स्थानीय रूपमा भण्डारण गरिएका सबै जानकारी मेटिने छन् र <ph name="DOMAIN" /> तथा यस डोमेनअन्तर्गतका सबै साइटलाई दिइएका सबै अनुमति रिसेट हुने छन्</translation> <translation id="5264323282659631142">'<ph name="CHIP_LABEL" />' हटाउनुहोस्</translation> <translation id="528192093759286357">पूर्ण स्क्रिनबाट बाहिर निस्कनका लागि शीर्षबाट तानेर पछाडि बटनलाई छुनुहोस्।</translation> +<translation id="5295729974480418933">यो सेटिङ अन भएका बेला साइटहरूले तपाईंका बारेमा सेभ गरिएको जानकारी प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंका बारेमा सेभ गरिएको जानकारी प्रयोग गर्ने अनुमति माग्न सक्दैनन्।</translation> <translation id="5300589172476337783">देखाउनुहोस्</translation> <translation id="5301954838959518834">ठिक छ, बुझेँ</translation> <translation id="5317780077021120954">बचत गर्नुहोस्</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(+ १ थप)}other{(+ # थप)}}</translation> <translation id="5403592356182871684">नामहरू</translation> <translation id="5438097262470833822">तपाईंले यो विकल्प रोज्नुभयो भने <ph name="WEBSITE" /> लाई दिइएका अनुमतिहरू रिसेट गरिने छन्</translation> +<translation id="5459413148890178711">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको लोकेसन प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंको लोकेसन हेर्न सक्दैनन्।</translation> <translation id="5489227211564503167"><ph name="TOTAL_TIME" /> मध्ये <ph name="ELAPSED_TIME" /> समय बित्यो।</translation> <translation id="5502860503640766021"><ph name="PERMISSION_1" /> सम्बन्धी अनुमति दिइएको छ, <ph name="PERMISSION_2" /> ब्लक गरिएको छ</translation> <translation id="5505264765875738116">साइटहरूले सूचनाहरू पठाउनका निम्ति अनुमति माग्न सक्दैनन्।</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">साइटहरूले तपाईंको डिभाइसमा जानकारी सेभ गर्न सक्छन्</translation> <translation id="5771720122942595109"><ph name="PERMISSION_1" /> ब्लक गरिएको छ</translation> <translation id="5804241973901381774">अनुमतिहरू</translation> +<translation id="5844448279347999754">यो सेटिङ अन भएका बेला साइटहरूले क्लिपबोर्डमा सेभ गरिएका टेक्स्ट र फोटोहरू हेर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले क्लिपबोर्डमा सेभ गरिएका टेक्स्ट र फोटोहरू हेर्ने सक्दैनन्।</translation> +<translation id="5853982612236235577">यो सेटिङ अन भएका बेला साइटहरूले सूचना पठाउने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले सूचना पठाउन सक्दैनन्।</translation> <translation id="5860033963881614850">बन्द</translation> <translation id="5876056640971328065">भिडियो पज गर्नुहोस्</translation> <translation id="5884085660368669834">साइटसम्बन्धी प्राथमिकता</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">थप</translation> <translation id="6064125863973209585">पूरा भएका डाउनलोडहरू</translation> <translation id="6071501408666570960">तपाईंलाई यो साइटबाट साइन आउट गरिन सक्छ</translation> +<translation id="6120483543004435978">यो सेटिङ अन भएका बेला साइटहरूले तपाईं आफ्नो डिभाइस चलाउँदै हुनुहुन्छ कि हुनुहुन्न भन्ने कुराको जानकारी माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईं आफ्नो डिभाइस चलाउँदै हुनुहुन्छ कि हुनुहुन्न भन्ने कुरा थाहा पाउन सक्दैनन्।</translation> <translation id="6165508094623778733">थप जान्नुहोस्</translation> +<translation id="6171020522141473435">यो सेटिङ अन भएका बेला साइटहरूले ब्लुटुथ डिभाइस प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले ब्लुटुथ डिभाइस प्रयोग गर्न सक्दैनन्।</translation> <translation id="6177111841848151710">हालको खोज इन्जिनका लागि रोक लगाइएको</translation> <translation id="6177128806592000436">यस साइटमा तपाईँको जडान सुरक्षित छैन</translation> <translation id="6181444274883918285">साइटको अपवाद थप्नुुहोस्</translation> <translation id="6192792657125177640">अपवाद</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome ले भोलि फेरि कुकीहरू ब्लक गर्ने छ}other{कुकीहरू अबको # दिनमा फेरि ब्लक गरिने छन्}}</translation> <translation id="6195163219142236913">तेस्रो पक्षीय कुकीहरू सीमित गरिएका छन्</translation> <translation id="6196640612572343990">तेस्रो पक्षीय कुकीहरूमाथि रोक लगाउनुहोस्</translation> <translation id="6205314730813004066">विज्ञापनको गोपनीयता</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">विन्डो सानो भएका बेला मोबाइल भ्यूमा हेर्ने अनुरोध गर्नुहोस्</translation> <translation id="6527303717912515753">साझा गर्नुहोस्</translation> <translation id="652937045869844725">तेस्रो पक्षीय कुकीहरू प्रयोग गर्ने अनुमति दिनुहोस्। यसको अर्थ सुरक्षाको स्तर कम हुन्छ तर साइटका सुविधाहरूले काम गर्न सक्छन्</translation> +<translation id="6530703012083415527">यो सेटिङ अन भएका बेला साइटहरूले पप-अप तथा रिडिरेक्ट गर्ने सुविधा प्रयोग गर्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले पप-अप तथा रिडिरेक्ट गर्ने सुविधा प्रयोग गर्न सक्दैनन्।</translation> <translation id="6545864417968258051">ब्लुटुथ स्क्यान गर्दै</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> र थप <ph name="NUM_MORE" /> सुविधासम्बन्धी अनुमति दिइएको छैन}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> र थप <ph name="NUM_MORE" /> सुविधासम्बन्धी अनुमति दिइएको छैन}}</translation> <translation id="6554732001434021288">पछिल्लो पटक <ph name="NUM_DAYS" /> दिनअघि खोलिएको</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">विकल्पहरू स्क्रिनको तल नजिकै उपलब्ध छ</translation> <translation id="7250468141469952378"><ph name="ITEM_COUNT" /> चयन गरिए</translation> <translation id="7260727271532453612"><ph name="PERMISSION_1" /> र <ph name="PERMISSION_2" /> सम्बन्धी अनुमति दिइएको छ</translation> +<translation id="7276071417425470385">यो सेटिङ अन भएका बेला साइटहरूले भर्चुअल रियालिटी डिभाइसहरू प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले भर्चुअल रियालिटी डिभाइसहरू प्रयोग गर्न सक्दैनन्।</translation> <translation id="7284451015630589124">तपाईंले आफूले ब्राउज गरिरहेका बेला तपाईंलाई ट्र्याक गर्ने साइटहरूलाई तेस्रो पक्षीय कुकी प्रयोग गर्न रोक लगाउनुभएको छ। <ph name="BEGIN_LINK" />ट्र्याकिङबाट सुरक्षित राख्ने सुविधा व्यवस्थापन गर्न<ph name="END_LINK" /> सेटिङमा जानुहोस्।</translation> <translation id="7302486331832100261">तपाईं सामान्यतया सूचनाहरूमाथि रोक लगाउनुहुन्छ। अनुमति दिन विवरणहरूमा ट्याप गर्नुहोस्।</translation> <translation id="7366415735885268578">कुनै साइट थप्नुहोस्</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">साइटहरूमा लागू हुने अँध्यारो थिम</translation> <translation id="7474522811371247902">Chrome ले अधिकांश साइटहरूमा तेस्रो पक्षीय कुकीहरू प्रयोग गर्न दिँदैन। तर यो साइट आधारभूत सेवाहरू प्रदान गर्न तेस्रो-पक्ष कुकीहरूमा भर पर्ने भएकाले यो साइटमा ती तेस्रो-पक्ष कुकीहरू अन गर्ने अनुमति दिइएको छ।\n\n<ph name="BEGIN_LINK" />ट्र्याकिङबाट सुरक्षित राख्ने सुविधा व्यवस्थापन गर्न<ph name="END_LINK" /> सेटिङमा जानुहोस्।</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">यो सेटिङ अन भएका बेला साइटहरूले साइन इन गर्ने प्रम्प्टहरू देखाउन सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले साइन इन गर्ने प्रम्प्टहरू देखाउन सक्दैनन्।</translation> <translation id="7554752735887601236">कुनै साइटले तपाईंको माइक्रोफोन प्रयोग गर्दै छ</translation> <translation id="7561196759112975576">सधैं</translation> <translation id="757524316907819857">साइटहरूलाई संरक्षित सामग्री प्ले गर्न रोक लगाउनुहोस्</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">भयो, धन्यवाद</translation> <translation id="7804248752222191302">कुनै साइटले तपाईंको क्यामेरा प्रयोग गर्दै छ</translation> <translation id="7807060072011926525">Google ले प्रदान गरेको</translation> +<translation id="7822573154188733812">Chrome ले साइटहरूलाई तपाईंले ब्राउज गरिरहेका बेला तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि तेस्रो पक्षीय कुकीहरू प्रयोग गर्न दिँदैन। <ph name="BEGIN_LINK" />ट्र्याकिङबाट सुरक्षित राख्ने सुविधा व्यवस्थापन गर्न<ph name="END_LINK" /> सेटिङमा जानुहोस्।</translation> <translation id="7835852323729233924">प्ले भइरहेको मिडिया</translation> <translation id="783819812427904514">भिडियो अनम्युट गर्नुहोस्</translation> <translation id="7846076177841592234">चयन रद्द गर्नुहोस्</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">मलाई स्मरण गराइयोस्</translation> <translation id="7974024493641668069">{COUNT,plural, =1{<ph name="FPS_OWNER" /> का साइटहरूको समूहमा भएको <ph name="FPS_MEMBERS_COUNT" /> वटा साइटले यस समूहमा तपाईंको गतिविधि देख्न सक्छ}other{<ph name="FPS_OWNER" /> का साइटहरूको समूहमा भएका <ph name="FPS_MEMBERS_COUNT" /> वटा साइटले यस समूहमा तपाईंको गतिविधि देख्न सक्छन्}}</translation> <translation id="7986741934819883144">कुनै सम्पर्क ठेगाना चयन गर्नुहोस्</translation> +<translation id="7990211076305263060">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको माइक्रोफोन प्रयोग गर्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंको माइक्रोफोन प्रयोग गर्न सक्दैनन्।</translation> <translation id="8007176423574883786">यस डिभाइसका लागि बन्द गरियो।</translation> <translation id="802154636333426148">डाउनलोड गर्न सकिएन</translation> <translation id="8042586301629853791">यसअनुसार क्रमबद्ध गर्नुहोस्:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">तपाईंले खोल्ने कुनै पनि साइटले तपाईंलाई जुनसुकै विज्ञापन देखाउन सक्छ</translation> <translation id="8087000398470557479">यो Google द्वारा डेलिभर गरिएको <ph name="DOMAIN_NAME" /> को सामग्री हो।</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" /> मा गई थप विकल्पहरू हेर्नुहोस्</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome ले भोलि फेरि कुकीहरू सीमित पार्ने छ}other{Chrome ले अबको # दिनमा फेरि कुकीहरू सीमित पार्ने छ}}</translation> <translation id="8116925261070264013">म्युट गरियो</translation> +<translation id="8117244575099414087">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको डिभाइसका सेन्सरहरू प्रयोग गर्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले सेन्सरहरू प्रयोग गर्न सक्दैनन्।</translation> <translation id="813082847718468539">साइट जानकारी हेर्नुहोस्</translation> <translation id="8131740175452115882">निश्चित</translation> <translation id="8154912474061769055">कयौँ साइटका सुविधाहरूले काम नगर्न सक्छन्</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{<ph name="FPS_OWNER" /> को <ph name="FPS_MEMBERS_COUNT" /> वटा साइटलाई कुकी प्रयोग गर्ने अनुमति दिइएको छ}other{<ph name="FPS_OWNER" /> का <ph name="FPS_MEMBERS_COUNT" /> वटा साइटलाई कुकी प्रयोग गर्ने अनुमति दिइएको छ}}</translation> <translation id="857943718398505171">(सिफारिस गरिएको) अनुमति दिएको</translation> <translation id="8609465669617005112">माथि सार्नुहोस्</translation> +<translation id="8617611086246832542">यो सेटिङ अन भएका बेला वेबसाइटको डेस्कटप भ्यू देखाइन्छ। यो सेटिङ अफ भएका बेला वेबसाइटको मोबाइल भ्यू देखाइन्छ।</translation> <translation id="8649036394979866943">तपाईंले साइटहरू ब्राउज गरिरहेका बेला तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि Chrome ले अधिकांश साइटहरूमा तेस्रो पक्षीय कुकी प्रयोग गर्ने कार्य सीमित गर्छ। <ph name="BEGIN_LINK" />ट्र्याकिङबाट सुरक्षित राख्ने सुविधा व्यवस्थापन गर्न<ph name="END_LINK" /> सेटिङमा जानुहोस्</translation> <translation id="8676374126336081632">आगत मेटाउनुहोस्</translation> <translation id="8681886425883659911">हस्तक्षेपकारी वा भ्रामक विज्ञापनहरू देखाउने साइटहरूमा विज्ञापन ब्लक गरिन्छ</translation> <translation id="868929229000858085">आफ्ना सम्पर्कहरू खोज्नुहोस्</translation> <translation id="8712637175834984815">भयो</translation> <translation id="8719283222052720129"><ph name="BEGIN_LINK" />Android का सेटिङ<ph name="END_LINK" />मा गई <ph name="APP_NAME" /> लाई अनुमति दिनुहोस्।</translation> +<translation id="8721719390026067591">यो सेटिङ अन भएका बेला साइटहरूले ब्लुटुथ डिभाइसहरू खोज्ने अनुमति माग्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले ब्लुटुथ डिभाइसहरू खोज्न सक्दैनन्।</translation> <translation id="8725066075913043281">पुन: प्रयास गर्नुहोस्</translation> <translation id="8730621377337864115">गरियो</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{एउटा साइटलाई कुकी प्रयोग गर्ने अनुमति दिइएको छ}other{# वटा साइटलाई कुकी प्रयोग गर्ने अनुमति दिइएको छ}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698">नेभिगेशन पहुँचयोग्य छैन: <ph name="URL" /></translation> <translation id="8986362086234534611">बिर्सनुहोस्</translation> <translation id="8990043154272859344">तपाईंलाई सबै साइटहरूबाट साइन आउट गरिने छ</translation> +<translation id="9002538116239926534">यो सेटिङ अन भएका बेला साइटहरूले तपाईंको डिभाइसमा डेटा सेभ गर्न सक्छन्। यो सेटिङ अफ भएका बेला साइटहरूले तपाईंको डिभाइसमा डेटा सेभ गर्न सक्दैनन्।</translation> <translation id="9011903857143958461"><ph name="SITE_NAME" /> लाई अनुमति दिइएको छ</translation> <translation id="9019902583201351841">तपाईँको अविभावक द्वारा व्यवस्थित</translation> <translation id="9039697262778250930">तपाईंलाई यी साइटहरूबाट साइन आउट गरिन सक्छ</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb index 2310429..df06033 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_sl.xtb
@@ -191,6 +191,7 @@ <translation id="4278390842282768270">Dovoljeno</translation> <translation id="429312253194641664">Spletno mesto predvaja predstavnost</translation> <translation id="42981349822642051">Razširi</translation> +<translation id="4336566011000459927">Chrome bo danes znova omejil piškotke</translation> <translation id="4338831206024587507">Vsa spletna mesta v domeni <ph name="DOMAIN" />.</translation> <translation id="4402755511846832236">Preprečevanje, da bi spletna mesta vedela, kdaj aktivno uporabljate to napravo.</translation> <translation id="4412992751769744546">Omogočanje piškotkov drugih spletnih mest</translation> @@ -293,6 +294,7 @@ <translation id="6177128806592000436">Povezava s tem spletnim mestom ni varna</translation> <translation id="6181444274883918285">Dodaj izjemo za spletno mesto</translation> <translation id="6192792657125177640">Izjeme</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome bo znova blokiral piškotke jutri}one{Še # dan in piškotki bodo znova blokirani}two{Še # dneva in piškotki bodo znova blokirani}few{Še # dni in piškotki bodo znova blokirani}other{Še # dni in piškotki bodo znova blokirani}}</translation> <translation id="6195163219142236913">Piškotki tretjih oseb so omejeni</translation> <translation id="6196640612572343990">Blokiraj piškotke drugih spletnih mest</translation> <translation id="6205314730813004066">Zasebnost pri oglaševanju</translation> @@ -382,6 +384,7 @@ <translation id="780301667611848630">Ne, hvala</translation> <translation id="7804248752222191302">Spletno mesto uporablja kamero</translation> <translation id="7807060072011926525">Zagotavlja Google</translation> +<translation id="7822573154188733812">Chrome spletnim mestom onemogoči uporabo piškotkov tretjih oseb za vaše sledenje med brskanjem. Obiščite nastavitve, če želite <ph name="BEGIN_LINK" />upravljati zaščito pred sledenjem<ph name="END_LINK" />.</translation> <translation id="7835852323729233924">Predvajanje predstavnosti</translation> <translation id="783819812427904514">Vklop videa</translation> <translation id="7846076177841592234">Prekliči izbor</translation> @@ -398,6 +401,7 @@ <translation id="8077120325605624147">Vsa spletna mesta, ki jih obiščete, vam lahko prikazujejo kateri koli oglas.</translation> <translation id="8087000398470557479">Ta vsebina je iz domene <ph name="DOMAIN_NAME" /> in jo prikazuje Google.</translation> <translation id="8088603949666785339">Več možnosti v pasici <ph name="BANNER_TITLE" /></translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome bo jutri znova omejil piškotke}one{Še # dan in Chrome bo znova omejil piškotke}two{Še # dneva in Chrome bo znova omejil piškotke}few{Še # dni in Chrome bo znova omejil piškotke}other{Še # dni in Chrome bo znova omejil piškotke}}</translation> <translation id="8116925261070264013">Prezrto</translation> <translation id="813082847718468539">Ogled podatkov o mestu</translation> <translation id="8131740175452115882">Potrdi</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb index 0f8e9c8..a1b26f5f 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_th.xtb
@@ -23,6 +23,7 @@ <translation id="1415402041810619267">ตัด URL ให้สั้นลงแล้ว</translation> <translation id="1426410128494586442">ยอมรับ</translation> <translation id="1448064542941920355">ลดการซูม</translation> +<translation id="146867109637325312">{COUNT,plural, =1{<ph name="SITE_COUNT" /> เว็บไซต์}other{<ph name="SITE_COUNT" /> เว็บไซต์}}</translation> <translation id="1510341833810331442">ไม่อนุญาตให้เว็บไซต์บันทึกข้อมูลในอุปกรณ์ของคุณ</translation> <translation id="1547123415014299762">อนุญาตคุกกี้ของบุคคลที่สาม</translation> <translation id="1568470248891039841">เว็บไซต์ที่คุณเข้าชมสามารถฝังเนื้อหาจากเว็บไซต์อื่นๆ เช่น รูปภาพ โฆษณา และข้อความ เว็บไซต์อื่นๆ เหล่านี้สามารถขอสิทธิ์ใช้ข้อมูลที่บันทึกไว้เกี่ยวกับตัวคุณขณะที่เรียกดูเว็บไซต์ <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติมเกี่ยวกับเนื้อหาที่ฝัง<ph name="END_LINK" /></translation> @@ -277,6 +278,7 @@ <translation id="5677928146339483299">ถูกบล็อก</translation> <translation id="5689516760719285838">ตำแหน่ง</translation> <translation id="5690795753582697420">กล้องปิดอยู่ในการตั้งค่า Android</translation> +<translation id="5691080386278724773"><ph name="SITE" /> ใช้ข้อมูลของคุณได้ในขณะที่คุณเรียกดู</translation> <translation id="5700761515355162635">อนุญาตคุกกี้ของบุคคลที่สามแล้ว</translation> <translation id="5706552988683188916">การดำเนินการนี้จะลบคุกกี้และข้อมูลเว็บไซต์อื่นๆ ของ <ph name="WEBSITE" /></translation> <translation id="5723967018671998714">บล็อกคุกกี้ของบุคคลที่สามในโหมดไม่ระบุตัวตนอยู่</translation> @@ -320,6 +322,7 @@ <translation id="6262279340360821358">บล็อก<ph name="PERMISSION_1" />และ<ph name="PERMISSION_2" /></translation> <translation id="6270391203985052864">เว็บไซต์ขออนุญาตเพื่อส่งการแจ้งเตือนได้</translation> <translation id="6295158916970320988">เว็บไซต์ทั้งหมด</translation> +<translation id="6304434827459067558"><ph name="SITE" /> ถูกบล็อกไม่ให้ใช้ข้อมูลของคุณใน</translation> <translation id="6320088164292336938">สั่น</translation> <translation id="6344622098450209924">การป้องกันการติดตาม</translation> <translation id="6367753977865761591">บล็อกการลงชื่อเข้าใช้ของบุคคลที่สามสำหรับบางเว็บไซต์</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb index b372e39..124d8dd 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-HK.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">相關網站</translation> <translation id="1644574205037202324">記錄</translation> <translation id="1647582022260550163">確定要重設權限,並清除 Cookie 和網站資料嗎?</translation> +<translation id="1652197001188145583">如果啟用,網站就可以要求使用 NFC 裝置。如果停用,網站將無法使用 NFC 裝置。</translation> <translation id="1660204651932907780">允許網站播放音效 (建議)</translation> <translation id="1677097821151855053">系統會使用 Cookie 和其他網站資料記住您的身分,例如登入帳戶或個人化廣告。如要管理所有網站的 Cookie,請參閱「<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />」。</translation> <translation id="169515064810179024">禁止網站存取動作感應器</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248">已下載:<ph name="BYTES_DOWNLOADED_WITH_UNITS" />,總大小:<ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">在您瀏覽的所有網站上縮放文字和圖片</translation> <translation id="1984937141057606926">已允許 (第三方除外)</translation> +<translation id="1985247341569771101">如果啟用,網站就可以使用裝置的動作感應器。如果停用,網站將無法使用動作感應器。</translation> <translation id="1989112275319619282">瀏覽</translation> <translation id="1994173015038366702">網站網址</translation> <translation id="2004697686368036666">部分網站的功能可能會無法正常運作</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">關閉攝錄機</translation> <translation id="2717722538473713889">電郵地址</translation> <translation id="2750481671343847896">網站可顯示來自身分服務的登入提示。</translation> +<translation id="2790501146643349491">如果啟用,最近關閉的網站就可以完成資料收發作業。如果停用,最近關閉的網站將無法完成資料收發作業。</translation> <translation id="2822354292072154809">確定要重設「<ph name="CHOSEN_OBJECT_NAME" />」的所有網站權限嗎?</translation> <translation id="2850913818900871965">要求使用流動裝置檢視模式</translation> <translation id="2870560284913253234">網站</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">地址</translation> <translation id="2910701580606108292">網站播放受保護內容前先詢問您</translation> <translation id="2932883381142163287">舉報濫用</translation> +<translation id="2939338015096024043">如果啟用,網站就可以要求追蹤攝影機位置,並瞭解周遭環境動靜。如果停用,網站將無法追蹤攝影機位置,也無法瞭解周遭環境動靜。</translation> <translation id="2968755619301702150">憑證檢視者</translation> <translation id="2979365474350987274">限制使用第三方 Cookie</translation> <translation id="3008272652534848354">重設權限</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905">已使用 <ph name="STORAGE_AMOUNT" /> 儲存空間</translation> <translation id="321187648315454507">如要讓 <ph name="APP_NAME" /> 傳送通知,請一併在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中開啟通知功能。</translation> <translation id="3227137524299004712">麥克風</translation> +<translation id="3242646949159196181">如果啟用,網站就可以播放音效。如果停用,網站將無法播放音效。</translation> <translation id="3277252321222022663">允許網站存取感應器 (建議)</translation> <translation id="3285500645985761267">允許相關網站查看您在群組中的活動</translation> <translation id="3295019059349372795">第 11 章:奧茲國的奇妙翡翠城</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">允許網站存取您的位置前先詢問您 (建議)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" /> %%</translation> <translation id="344449859752187052">已封鎖第三方 Cookie</translation> +<translation id="3448554387819310837">如果啟用,網站就可以要求使用攝影機。如果停用,網站將無法使用攝影機。</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome 將於明天再次封鎖 Cookie}other{Chrome 將於 # 天後再次封鎖 Cookie}}</translation> <translation id="3521663503435878242"><ph name="DOMAIN" /> 下的網站</translation> <translation id="3538390592868664640">禁止網站建立您身處環境的 3D 地圖或追蹤攝錄機位置</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">將播放音效的網站設為靜音</translation> <translation id="3602290021589620013">預覽</translation> <translation id="3628308229821498208">建議搜尋</translation> +<translation id="3697164069658504920">如果啟用,網站就可以要求使用 USB 裝置。如果停用,網站將無法使用 USB 裝置。</translation> <translation id="3707034683772193706">您瀏覽的網站可將少量資料儲存至 Chrome,主要用來證明您不是機器人</translation> <translation id="3721953990244350188">閂同顯示下一個可以執行嘅操作</translation> <translation id="3744111561329211289">背景同步處理</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">已允許</translation> <translation id="429312253194641664">網站正在播放媒體</translation> <translation id="42981349822642051">展開</translation> +<translation id="4336566011000459927">Chrome 將於今天再次限制 Cookie</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> 下的所有網站</translation> <translation id="4402755511846832236">禁止網站取得此裝置的使用狀態</translation> <translation id="4412992751769744546">允許第三方 Cookie</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">由您的家長管理</translation> <translation id="4670064810192446073">虛擬實境</translation> <translation id="4751476147751820511">動態或光線感應器</translation> +<translation id="4755971844837804407">如果啟用,網站就可以向你顯示任何廣告。如果停用,網站將無法顯示誤導性或侵入式廣告。</translation> <translation id="4779083564647765204">縮放</translation> <translation id="4811450222531576619">瞭解頁面的來源和主題</translation> <translation id="4836046166855586901">在網站要求知道您是否正在使用此裝置時詢問您</translation> <translation id="483914009762354899">包含此網域下的所有網站</translation> <translation id="4883854917563148705">無法重設受管理的設定</translation> <translation id="4887024562049524730">在允許網站使用您的虛擬實境裝置和資料前先詢問您 (建議)</translation> +<translation id="4953688446973710931">如果啟用,網站就可以要求自動下載多個檔案。如果停用,網站將無法自動下載多個檔案。</translation> <translation id="4955223779495905865">您瀏覽的網站可以嵌入其他網站的內容,例如圖片、廣告和文字。上述的任何網站都可儲存 Cookie 和其他資料,為您提供個人化體驗。</translation> <translation id="4962975101802056554">撤銷裝置所有的權限</translation> <translation id="497421865427891073">往前</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">使用狀況</translation> <translation id="5091013926750941408">流動網站</translation> <translation id="509133520954049755">要求桌面電腦檢視模式</translation> +<translation id="5091663350197390230">如果啟用,網站就可以使用 JavaScript。如果停用,網站將無法使用 JavaScript,</translation> <translation id="5099358668261120049">這會刪除 <ph name="ORIGIN" /> 或該網站在主畫面上的應用程式儲存的所有資料和 Cookie。</translation> <translation id="5100237604440890931">已收合 - 點擊即可展開。</translation> <translation id="5123685120097942451">無痕式分頁</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">此操作會刪除 Cookie 等所有本機資料,並重設 <ph name="DOMAIN" /> 和該網域中每個網站的所有權限</translation> <translation id="5264323282659631142">移除「<ph name="CHIP_LABEL" />」</translation> <translation id="528192093759286357">由上而下拖曳,然後輕觸返回按鈕即可退出全螢幕。</translation> +<translation id="5295729974480418933">如果啟用,網站就可以在儲存你的資訊後要求使用這些資訊。如果停用,網站就無法要求使用這些資訊。</translation> <translation id="5300589172476337783">顯示</translation> <translation id="5301954838959518834">好,我知道了</translation> <translation id="5317780077021120954">儲存</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(還有 1 個)}other{(還有 # 個)}}</translation> <translation id="5403592356182871684">名稱</translation> <translation id="5438097262470833822">此選項將會清除 <ph name="WEBSITE" /> 的權限</translation> +<translation id="5459413148890178711">如果啟用,網站就可以要求取得你的位置資訊。如果停用,網站將無法查看你的位置資訊。</translation> <translation id="5489227211564503167">播咗嘅時間係 <ph name="ELAPSED_TIME" />,影片總長度係 <ph name="TOTAL_TIME" />。</translation> <translation id="5502860503640766021">已允許「<ph name="PERMISSION_1" />」,已封鎖「<ph name="PERMISSION_2" />」</translation> <translation id="5505264765875738116">網站將無法要求向您傳送通知</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">網站可在裝置上儲存資料</translation> <translation id="5771720122942595109">已封鎖「<ph name="PERMISSION_1" />」</translation> <translation id="5804241973901381774">權限</translation> +<translation id="5844448279347999754">如果啟用,網站就可以要求查看已儲存到剪貼簿的文字和圖片。如果停用,網站將無法查看已儲存到剪貼簿的文字或圖片。</translation> +<translation id="5853982612236235577">如果啟用,網站就可以要求傳送通知。如果停用,網站將無法傳送通知。</translation> <translation id="5860033963881614850">關閉</translation> <translation id="5876056640971328065">暫停影片</translation> <translation id="5884085660368669834">網站偏好設定</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">更多選項</translation> <translation id="6064125863973209585">下載完成</translation> <translation id="6071501408666570960">您可能會登出此網站</translation> +<translation id="6120483543004435978">如果啟用,網站就可以要求偵測你是否正在使用裝置。如果停用,網站將無法得知你是否正在使用裝置。</translation> <translation id="6165508094623778733">瞭解更多資料</translation> +<translation id="6171020522141473435">如果啟用,網站就可以要求使用藍牙裝置。如果停用,網站將無法使用藍牙裝置。</translation> <translation id="6177111841848151710">禁止目前的搜尋引擎使用</translation> <translation id="6177128806592000436">您與此網站的連線並非完全安全</translation> <translation id="6181444274883918285">新增例外網站</translation> <translation id="6192792657125177640">例外</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome 將於明天再次封鎖 Cookie}other{# 天後將再次封鎖 Cookie}}</translation> <translation id="6195163219142236913">已限制第三方 Cookie</translation> <translation id="6196640612572343990">封鎖第三方 Cookie</translation> <translation id="6205314730813004066">廣告私隱權</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">視窗縮小時要求使用流動裝置檢視模式</translation> <translation id="6527303717912515753">分享</translation> <translation id="652937045869844725">請嘗試允許使用第三方 Cookie,這代表保護程度較低,但網站功能較容易運作</translation> +<translation id="6530703012083415527">如果啟用,網站就可以使用彈出式視窗和重新導向。如果停用,網站將無法使用彈出式視窗和重新導向。</translation> <translation id="6545864417968258051">藍牙掃瞄</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{已封鎖「<ph name="PERMISSION_1" />」、「<ph name="PERMISSION_2" />」和另外 <ph name="NUM_MORE" /> 項權限}other{已封鎖「<ph name="PERMISSION_1" />」、「<ph name="PERMISSION_2" />」和另外 <ph name="NUM_MORE" /> 項權限}}</translation> <translation id="6554732001434021288">上次瀏覽日期:<ph name="NUM_DAYS" /> 天前</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">您可在畫面底部附近找到選項</translation> <translation id="7250468141469952378">揀咗 <ph name="ITEM_COUNT" /> 個</translation> <translation id="7260727271532453612">已允許「<ph name="PERMISSION_1" />」和「<ph name="PERMISSION_2" />」</translation> +<translation id="7276071417425470385">如果啟用,網站就可以要求使用虛擬實境裝置。如果停用,網站將無法使用虛擬實境裝置。</translation> <translation id="7284451015630589124">你已禁止網站使用第三方 Cookie 追蹤瀏覽網站的使用者。請前往設定頁面<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" />。</translation> <translation id="7302486331832100261">您通常會封鎖通知。如要允許,請輕按 [詳情]。</translation> <translation id="7366415735885268578">新增網站</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">網站深色主題背景</translation> <translation id="7474522811371247902">Chrome 會限制大部分網站使用第三方 Cookie。不過,由於此網站需要使用 Cookie 才能提供基本服務,因此系統允許在此網站使用第三方 Cookie。\n\n請前往設定以<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" />。</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">如果啟用,網站就可以顯示登入提示。如果停用,網站將無法顯示登入提示。</translation> <translation id="7554752735887601236">有網站正在使用您的麥克風</translation> <translation id="7561196759112975576">永遠使用</translation> <translation id="757524316907819857">禁止網站播放受保護內容</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">不用了,謝謝</translation> <translation id="7804248752222191302">有網站正在使用您的相機</translation> <translation id="7807060072011926525">由 Google 提供</translation> +<translation id="7822573154188733812">Chrome 會禁止網站使用第三方 Cookie 追蹤瀏覽活動。你可以前往設定頁面<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" />。</translation> <translation id="7835852323729233924">正在播放媒體</translation> <translation id="783819812427904514">將影片取消靜音</translation> <translation id="7846076177841592234">取消選取</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">提醒我</translation> <translation id="7974024493641668069">{COUNT,plural, =1{<ph name="FPS_OWNER" /> 網站群組中的 <ph name="FPS_MEMBERS_COUNT" /> 個網站可查看您在群組中的活動}other{<ph name="FPS_OWNER" /> 網站群組中的 <ph name="FPS_MEMBERS_COUNT" /> 個網站可查看您在群組中的活動}}</translation> <translation id="7986741934819883144">選取聯絡人</translation> +<translation id="7990211076305263060">如果啟用,網站就可以要求使用麥克風。如果停用,網站將無法使用麥克風。</translation> <translation id="8007176423574883786">已為這部裝置關閉</translation> <translation id="802154636333426148">下載失敗</translation> <translation id="8042586301629853791">排序方式:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">您瀏覽的網站都可向您顯示所有廣告</translation> <translation id="8087000398470557479">此內容來自 <ph name="DOMAIN_NAME" />,由 Google 提供。</translation> <translation id="8088603949666785339"><ph name="BANNER_TITLE" />嘅其他選項</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome 將於明天再次限制 Cookie}other{Chrome 將於 # 天後再次限制 Cookie}}</translation> <translation id="8116925261070264013">已設為靜音的網站</translation> +<translation id="8117244575099414087">如果啟用,網站就可以使用裝置的感應器。如果停用,網站將無法使用感應器。</translation> <translation id="813082847718468539">檢視網站資料</translation> <translation id="8131740175452115882">確定</translation> <translation id="8154912474061769055">很多網站的功能可能會無法正常運作</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{已允許 <ph name="FPS_MEMBERS_COUNT" /> 個 <ph name="FPS_OWNER" /> 網站使用 Cookie}other{已允許 <ph name="FPS_MEMBERS_COUNT" /> 個 <ph name="FPS_OWNER" /> 網站使用 Cookie}}</translation> <translation id="857943718398505171">允許 (建議)</translation> <translation id="8609465669617005112">向上移</translation> +<translation id="8617611086246832542">如果啟用,系統將顯示網站的電腦檢視畫面。如果停用,系統將顯示網站的行動裝置檢視畫面。</translation> <translation id="8649036394979866943">Chrome 會限制大部份網站使用第三方 Cookie 追蹤瀏覽網站的使用者。請前往設定頁面<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" /></translation> <translation id="8676374126336081632">清除輸入</translation> <translation id="8681886425883659911">已在網站上封鎖已知的滋擾性或誤導廣告。</translation> <translation id="868929229000858085">搜尋您的聯絡人</translation> <translation id="8712637175834984815">我知道了</translation> <translation id="8719283222052720129">請在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中為 <ph name="APP_NAME" /> 啟用此權限。</translation> +<translation id="8721719390026067591">如果啟用,網站就可以要求尋找藍牙裝置。如果停用,網站將無法尋找藍牙裝置。</translation> <translation id="8725066075913043281">再試一次</translation> <translation id="8730621377337864115">完成</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{已允許 1 個網站}other{已允許 # 個網站}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698">無法存取瀏覽網址:<ph name="URL" /></translation> <translation id="8986362086234534611">清除</translation> <translation id="8990043154272859344">您將會從所有網站登出</translation> +<translation id="9002538116239926534">如果啟用,網站就可以在裝置上儲存資料。如果停用,網站將無法在裝置上儲存資料。</translation> <translation id="9011903857143958461">已允許 <ph name="SITE_NAME" /></translation> <translation id="9019902583201351841">由您的家長管理</translation> <translation id="9039697262778250930">您可能會登出這些網站</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb index 8fe64ea..ca035af 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_zh-TW.xtb
@@ -31,6 +31,7 @@ <translation id="1633720957382884102">相關網站</translation> <translation id="1644574205037202324">歷史記錄</translation> <translation id="1647582022260550163">確定要重設權限,並且清除 Cookie 和網站資料嗎?</translation> +<translation id="1652197001188145583">如果啟用,網站就可以要求使用 NFC 裝置。如果停用,網站將無法使用 NFC 裝置。</translation> <translation id="1660204651932907780">允許網站播放音訊 (建議)</translation> <translation id="1677097821151855053">系統會使用 Cookie 和其他網站資料來記住你,以便將你登入帳戶或是提供個人化廣告等服務。如要管理所有網站的 Cookie,請查看<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />。</translation> <translation id="169515064810179024">禁止網站存取動作感應器</translation> @@ -46,6 +47,7 @@ <translation id="1923695749281512248">已下載:<ph name="BYTES_DOWNLOADED_WITH_UNITS" />,總大小:<ph name="FILE_SIZE_WITH_UNITS" /></translation> <translation id="1979673356880165407">在你造訪的所有網站上縮放文字和圖片</translation> <translation id="1984937141057606926">允許 (第三方網站除外)</translation> +<translation id="1985247341569771101">如果啟用,網站就可以使用裝置的動作感應器。如果停用,網站將無法使用動作感應器。</translation> <translation id="1989112275319619282">瀏覽</translation> <translation id="1994173015038366702">網站網址</translation> <translation id="2004697686368036666">某些網站的功能可能無法運作</translation> @@ -106,6 +108,7 @@ <translation id="2713106313042589954">關閉攝影機</translation> <translation id="2717722538473713889">電子郵件地址</translation> <translation id="2750481671343847896">網站可以顯示身分識別服務的登入提示。</translation> +<translation id="2790501146643349491">如果啟用,最近關閉的網站就可以完成資料收發作業。如果停用,最近關閉的網站將無法完成資料收發作業。</translation> <translation id="2822354292072154809">確定要重設「<ph name="CHOSEN_OBJECT_NAME" />」的所有網站權限嗎?</translation> <translation id="2850913818900871965">要求使用行動裝置檢視畫面</translation> <translation id="2870560284913253234">網站</translation> @@ -114,6 +117,7 @@ <translation id="2903493209154104877">地址</translation> <translation id="2910701580606108292">允許網站播放受保護的內容前,必須先詢問你</translation> <translation id="2932883381142163287">檢舉濫用情形</translation> +<translation id="2939338015096024043">如果啟用,網站就可以要求追蹤攝影機位置,並瞭解周遭環境動靜。如果停用,網站將無法追蹤攝影機位置,也無法瞭解周遭環境動靜。</translation> <translation id="2968755619301702150">憑證檢視器</translation> <translation id="2979365474350987274">限制使用第三方 Cookie</translation> <translation id="3008272652534848354">重設權限</translation> @@ -132,6 +136,7 @@ <translation id="3198916472715691905">儲存了 <ph name="STORAGE_AMOUNT" /> 的資料</translation> <translation id="321187648315454507">如要允許 <ph name="APP_NAME" /> 傳送通知,請一併在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中開啟通知功能。</translation> <translation id="3227137524299004712">麥克風</translation> +<translation id="3242646949159196181">如果啟用,網站就可以播放音效。如果停用,網站將無法播放音效。</translation> <translation id="3277252321222022663">允許網站存取感應器 (建議)</translation> <translation id="3285500645985761267">允許相關網站查看你在群組中的活動</translation> <translation id="3295019059349372795">第 11 章:奧茲國的翡翠城</translation> @@ -142,6 +147,7 @@ <translation id="3386292677130313581">允許網站存取你的位置資訊前,必須先詢問你 (建議)</translation> <translation id="3403537308306431953"><ph name="ZOOM_LEVEL" />%%</translation> <translation id="344449859752187052">已封鎖第三方 Cookie</translation> +<translation id="3448554387819310837">如果啟用,網站就可以要求使用攝影機。如果停用,網站將無法使用攝影機。</translation> <translation id="3465378418721443318">{DAYS,plural, =1{Chrome 將於明天再次封鎖 Cookie}other{Chrome 將於 # 天後再次封鎖 Cookie}}</translation> <translation id="3521663503435878242"><ph name="DOMAIN" /> 底下的網站</translation> <translation id="3538390592868664640">禁止網站根據你的周遭環境建立 3D 地圖或追蹤攝影機位置</translation> @@ -154,6 +160,7 @@ <translation id="3600792891314830896">將播放音訊的網站設為靜音</translation> <translation id="3602290021589620013">預覽</translation> <translation id="3628308229821498208">建議搜尋</translation> +<translation id="3697164069658504920">如果啟用,網站就可以要求使用 USB 裝置。如果停用,網站將無法使用 USB 裝置。</translation> <translation id="3707034683772193706">你造訪的網站可將少量資訊儲存在 Chrome,主要用來證明你不是機器人</translation> <translation id="3721953990244350188">關閉並顯示下一個可執行的動作</translation> <translation id="3744111561329211289">背景同步處理</translation> @@ -191,6 +198,7 @@ <translation id="4278390842282768270">允許</translation> <translation id="429312253194641664">一個網站正在播放媒體內容</translation> <translation id="42981349822642051">展開</translation> +<translation id="4336566011000459927">Chrome 將於今天再次限制 Cookie</translation> <translation id="4338831206024587507"><ph name="DOMAIN" /> 底下的所有網站</translation> <translation id="4402755511846832236">禁止網站取得這部裝置的使用狀態</translation> <translation id="4412992751769744546">允許第三方 Cookie</translation> @@ -209,12 +217,14 @@ <translation id="4645575059429386691">你的家長已停用這項功能</translation> <translation id="4670064810192446073">虛擬實境</translation> <translation id="4751476147751820511">動作或光源感應器</translation> +<translation id="4755971844837804407">如果啟用,網站就可以向你顯示任何廣告。如果停用,網站將無法顯示誤導性或侵入式廣告。</translation> <translation id="4779083564647765204">縮放</translation> <translation id="4811450222531576619">瞭解來源和主題</translation> <translation id="4836046166855586901">允許網站詢問你使用這部裝置的時間</translation> <translation id="483914009762354899">包括這個網域中的所有網站</translation> <translation id="4883854917563148705">無法重設受管理的設定</translation> <translation id="4887024562049524730">系統必須先詢問你,才能允許網站使用你的虛擬實境裝置和資料 (建議設定)</translation> +<translation id="4953688446973710931">如果啟用,網站就可以要求自動下載多個檔案。如果停用,網站將無法自動下載多個檔案。</translation> <translation id="4955223779495905865">你造訪的網站可以嵌入其他網站的內容,例如圖片、廣告和文字。這些網站可以儲存 Cookie 和其他資料,為你提供個人化體驗。</translation> <translation id="4962975101802056554">撤銷裝置的所有權限</translation> <translation id="497421865427891073">往前</translation> @@ -229,6 +239,7 @@ <translation id="5063480226653192405">用量</translation> <translation id="5091013926750941408">行動版網站</translation> <translation id="509133520954049755">要求電腦檢視畫面</translation> +<translation id="5091663350197390230">如果啟用,網站就可以使用 JavaScript。如果停用,網站將無法使用 JavaScript,</translation> <translation id="5099358668261120049">這會刪除 <ph name="ORIGIN" /> 或該網站在主畫面上的應用程式儲存的所有資料和 Cookie。</translation> <translation id="5100237604440890931">已收合 - 按一下即可展開。</translation> <translation id="5123685120097942451">無痕式分頁</translation> @@ -240,6 +251,7 @@ <translation id="5246825184569358663">這項操作會刪除 Cookie 等所有本機資料,並重設 <ph name="DOMAIN" /> 和該網域中每個網站的所有權限</translation> <translation id="5264323282659631142">移除「<ph name="CHIP_LABEL" />」</translation> <translation id="528192093759286357">從頂端拖曳並輕觸返回按鈕即可結束全螢幕模式。</translation> +<translation id="5295729974480418933">如果啟用,網站就可以在儲存你的資訊後要求使用這些資訊。如果停用,網站就無法要求使用這些資訊。</translation> <translation id="5300589172476337783">顯示</translation> <translation id="5301954838959518834">好,我知道了</translation> <translation id="5317780077021120954">儲存</translation> @@ -250,6 +262,7 @@ <translation id="5394307150471348411">{DETAIL_COUNT,plural, =1{(還有 1 個)}other{(還有 # 個)}}</translation> <translation id="5403592356182871684">名稱</translation> <translation id="5438097262470833822">這會重設 <ph name="WEBSITE" /> 的權限</translation> +<translation id="5459413148890178711">如果啟用,網站就可以要求取得你的位置資訊。如果停用,網站將無法查看你的位置資訊。</translation> <translation id="5489227211564503167">經過時間:<ph name="ELAPSED_TIME" />,影片總長:<ph name="TOTAL_TIME" />。</translation> <translation id="5502860503640766021">已允許「<ph name="PERMISSION_1" />」,已封鎖「<ph name="PERMISSION_2" />」</translation> <translation id="5505264765875738116">網站無法要求傳送通知給你</translation> @@ -270,6 +283,8 @@ <translation id="5740126560802162366">網站可將資料儲存到裝置</translation> <translation id="5771720122942595109">已封鎖「<ph name="PERMISSION_1" />」</translation> <translation id="5804241973901381774">權限</translation> +<translation id="5844448279347999754">如果啟用,網站就可以要求查看已儲存到剪貼簿的文字和圖片。如果停用,網站將無法查看已儲存到剪貼簿的文字或圖片。</translation> +<translation id="5853982612236235577">如果啟用,網站就可以要求傳送通知。如果停用,網站將無法傳送通知。</translation> <translation id="5860033963881614850">關閉</translation> <translation id="5876056640971328065">暫停影片</translation> <translation id="5884085660368669834">網站偏好設定</translation> @@ -288,11 +303,14 @@ <translation id="6042308850641462728">更多</translation> <translation id="6064125863973209585">下載完成</translation> <translation id="6071501408666570960">系統可能會將你登出這個網站</translation> +<translation id="6120483543004435978">如果啟用,網站就可以要求偵測你是否正在使用裝置。如果停用,網站將無法得知你是否正在使用裝置。</translation> <translation id="6165508094623778733">瞭解詳情</translation> +<translation id="6171020522141473435">如果啟用,網站就可以要求使用藍牙裝置。如果停用,網站將無法使用藍牙裝置。</translation> <translation id="6177111841848151710">禁止目前的搜尋引擎存取位置資訊</translation> <translation id="6177128806592000436">你與這個網站的連線不安全</translation> <translation id="6181444274883918285">新增例外網站</translation> <translation id="6192792657125177640">例外</translation> +<translation id="6194967801833346599">{DAYS,plural, =1{Chrome 將於明天再次封鎖 Cookie}other{# 天後將再次封鎖 Cookie}}</translation> <translation id="6195163219142236913">已限制第三方 Cookie</translation> <translation id="6196640612572343990">封鎖第三方 Cookie</translation> <translation id="6205314730813004066">廣告隱私權設定</translation> @@ -313,6 +331,7 @@ <translation id="6500423977866688905">視窗縮小時要求使用行動裝置檢視畫面</translation> <translation id="6527303717912515753">分享</translation> <translation id="652937045869844725">請嘗試允許使用第三方 Cookie,這代表保護程度較低,但網站功能較容易運作</translation> +<translation id="6530703012083415527">如果啟用,網站就可以使用彈出式視窗和重新導向。如果停用,網站將無法使用彈出式視窗和重新導向。</translation> <translation id="6545864417968258051">藍牙掃描</translation> <translation id="6552800053856095716">{PERMISSIONS_SUMMARY_BLOCKED,plural, =1{已封鎖「<ph name="PERMISSION_1" />」、「<ph name="PERMISSION_2" />」和另外 <ph name="NUM_MORE" /> 項權限}other{已封鎖「<ph name="PERMISSION_1" />」、「<ph name="PERMISSION_2" />」和另外 <ph name="NUM_MORE" /> 項權限}}</translation> <translation id="6554732001434021288">上次造訪日期:<ph name="NUM_DAYS" /> 天前</translation> @@ -356,6 +375,7 @@ <translation id="7243308994586599757">選項在接近畫面底部的位置</translation> <translation id="7250468141469952378">已選取 <ph name="ITEM_COUNT" /> 個項目</translation> <translation id="7260727271532453612">已允許「<ph name="PERMISSION_1" />」和「<ph name="PERMISSION_2" />」</translation> +<translation id="7276071417425470385">如果啟用,網站就可以要求使用虛擬實境裝置。如果停用,網站將無法使用虛擬實境裝置。</translation> <translation id="7284451015630589124">你已禁止網站使用第三方 Cookie 追蹤瀏覽網站的使用者。前往設定頁面<ph name="BEGIN_LINK" />管理追蹤防護設定<ph name="END_LINK" />。</translation> <translation id="7302486331832100261">你通常會封鎖通知。如要允許通知,請輕觸 [詳細資料]。</translation> <translation id="7366415735885268578">新增網站</translation> @@ -367,6 +387,7 @@ <translation id="7425915948813553151">網站的深色主題</translation> <translation id="7474522811371247902">Chrome 會限制大多數網站使用第三方 Cookie,但允許這個網站使用第三方 Cookie,因為這個網站需要使用 Cookie 才能提供基本服務。\n\n前往設定頁面<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" />。</translation> <translation id="7521387064766892559">JavaScript</translation> +<translation id="7547989957535180761">如果啟用,網站就可以顯示登入提示。如果停用,網站將無法顯示登入提示。</translation> <translation id="7554752735887601236">有網站正在使用你的麥克風</translation> <translation id="7561196759112975576">一律使用</translation> <translation id="757524316907819857">禁止網站播放受保護的內容</translation> @@ -382,6 +403,7 @@ <translation id="780301667611848630">不用了,謝謝</translation> <translation id="7804248752222191302">有網站正在使用你的攝影機</translation> <translation id="7807060072011926525">由 Google 提供</translation> +<translation id="7822573154188733812">Chrome 會禁止網站使用第三方 Cookie 追蹤瀏覽活動。你可以前往設定頁面<ph name="BEGIN_LINK" />管理追蹤保護功能<ph name="END_LINK" />。</translation> <translation id="7835852323729233924">正在播放媒體</translation> <translation id="783819812427904514">將影片取消靜音</translation> <translation id="7846076177841592234">全部取消選取</translation> @@ -390,6 +412,7 @@ <translation id="7940722705963108451">提醒我</translation> <translation id="7974024493641668069">{COUNT,plural, =1{在 <ph name="FPS_OWNER" /> 的網站群組中,有 <ph name="FPS_MEMBERS_COUNT" /> 個網站可以查看你在群組中的活動}other{在 <ph name="FPS_OWNER" /> 的網站群組中,有 <ph name="FPS_MEMBERS_COUNT" /> 個網站可以查看你在群組中的活動}}</translation> <translation id="7986741934819883144">選取聯絡人</translation> +<translation id="7990211076305263060">如果啟用,網站就可以要求使用麥克風。如果停用,網站將無法使用麥克風。</translation> <translation id="8007176423574883786">已在這個裝置上關閉</translation> <translation id="802154636333426148">下載失敗</translation> <translation id="8042586301629853791">排序依據:</translation> @@ -398,7 +421,9 @@ <translation id="8077120325605624147">你造訪的網站都能對你顯示所有廣告</translation> <translation id="8087000398470557479">這個內容來自 <ph name="DOMAIN_NAME" />,由 Google 所提供。</translation> <translation id="8088603949666785339">「<ph name="BANNER_TITLE" />」的其他選項</translation> +<translation id="8113501330600751161">{DAYS,plural, =1{Chrome 將於明天再次限制 Cookie}other{Chrome 將於 # 天後再次限制 Cookie}}</translation> <translation id="8116925261070264013">已設為靜音</translation> +<translation id="8117244575099414087">如果啟用,網站就可以使用裝置的感應器。如果停用,網站將無法使用感應器。</translation> <translation id="813082847718468539">查看網站資訊</translation> <translation id="8131740175452115882">確認</translation> <translation id="8154912474061769055">許多網站的功能可能無法運作</translation> @@ -436,12 +461,14 @@ <translation id="8564613706851221529">{COUNT,plural, =1{已允許 <ph name="FPS_MEMBERS_COUNT" /> 個 <ph name="FPS_OWNER" /> 網站使用 Cookie}other{已允許 <ph name="FPS_MEMBERS_COUNT" /> 個 <ph name="FPS_OWNER" /> 網站使用 Cookie}}</translation> <translation id="857943718398505171">已允許 (建議)</translation> <translation id="8609465669617005112">上移</translation> +<translation id="8617611086246832542">如果啟用,系統將顯示網站的電腦檢視畫面。如果停用,系統將顯示網站的行動裝置檢視畫面。</translation> <translation id="8649036394979866943">Chrome 會限制大多數網站使用第三方 Cookie 追蹤瀏覽網站的使用者。前往設定頁面<ph name="BEGIN_LINK" />管理追蹤防護設定<ph name="END_LINK" />。</translation> <translation id="8676374126336081632">清除輸入</translation> <translation id="8681886425883659911">已在網站上封鎖已知的侵入式廣告或誤導性廣告</translation> <translation id="868929229000858085">搜尋聯絡人</translation> <translation id="8712637175834984815">我瞭解了</translation> <translation id="8719283222052720129">請在 <ph name="BEGIN_LINK" />Android 設定<ph name="END_LINK" />中啟用「<ph name="APP_NAME" />」的權限。</translation> +<translation id="8721719390026067591">如果啟用,網站就可以要求尋找藍牙裝置。如果停用,網站將無法尋找藍牙裝置。</translation> <translation id="8725066075913043281">再試一次</translation> <translation id="8730621377337864115">完成</translation> <translation id="8736193154595564524">{NUM_SELECTED,plural, =1{已允許 1 個網站}other{已允許 # 個網站}}</translation> @@ -465,6 +492,7 @@ <translation id="8959122750345127698">瀏覽的網址無法存取:<ph name="URL" /></translation> <translation id="8986362086234534611">清除</translation> <translation id="8990043154272859344">系統會將你登出所有網站</translation> +<translation id="9002538116239926534">如果啟用,網站就可以在裝置上儲存資料。如果停用,網站將無法在裝置上儲存資料。</translation> <translation id="9011903857143958461">已允許「<ph name="SITE_NAME" />」</translation> <translation id="9019902583201351841">你的家長已停用這項功能</translation> <translation id="9039697262778250930">系統可能已將你登出這些網站</translation>
diff --git a/components/commerce/core/android/BUILD.gn b/components/commerce/core/android/BUILD.gn index 810f28dd..8005589 100644 --- a/components/commerce/core/android/BUILD.gn +++ b/components/commerce/core/android/BUILD.gn
@@ -32,8 +32,10 @@ } java_cpp_enum("java_enum_srcjar") { - sources = - [ "//components/commerce/core/subscriptions/commerce_subscription.h" ] + sources = [ + "//components/commerce/core/commerce_types.h", + "//components/commerce/core/subscriptions/commerce_subscription.h", + ] } robolectric_library("junit_tests") {
diff --git a/components/commerce/core/android/java/src/org/chromium/components/commerce/core/ShoppingService.java b/components/commerce/core/android/java/src/org/chromium/components/commerce/core/ShoppingService.java index 8be8b4be..ccfaa971d 100644 --- a/components/commerce/core/android/java/src/org/chromium/components/commerce/core/ShoppingService.java +++ b/components/commerce/core/android/java/src/org/chromium/components/commerce/core/ShoppingService.java
@@ -72,6 +72,51 @@ } } + /** A price point consisting of a date and the price on it. */ + public static final class PricePoint { + public final String date; + public final long price; + + public PricePoint(String date, long price) { + this.date = date; + this.price = price; + } + } + + /** A data container for price insights info provided by the shopping service. */ + public static final class PriceInsightsInfo { + public final Optional<Long> productClusterId; + public final String currencyCode; + public final Optional<Long> typicalLowPriceMicros; + public final Optional<Long> typicalHighPriceMicros; + public final Optional<String> catalogAttributes; + public final List<PricePoint> catalogHistoryPrices; + public final Optional<GURL> jackpotUrl; + public final @PriceBucket int priceBucket; + public final boolean hasMultipleCatalogs; + + public PriceInsightsInfo( + Optional<Long> productClusterId, + String currencyCode, + Optional<Long> typicalLowPriceMicros, + Optional<Long> typicalHighPriceMicros, + Optional<String> catalogAttributes, + List<PricePoint> catalogHistoryPrices, + Optional<GURL> jackpotUrl, + @PriceBucket int priceBucket, + boolean hasMultipleCatalogs) { + this.productClusterId = productClusterId; + this.currencyCode = currencyCode; + this.typicalLowPriceMicros = typicalLowPriceMicros; + this.typicalHighPriceMicros = typicalHighPriceMicros; + this.catalogAttributes = catalogAttributes; + this.catalogHistoryPrices = catalogHistoryPrices; + this.jackpotUrl = jackpotUrl; + this.priceBucket = priceBucket; + this.hasMultipleCatalogs = hasMultipleCatalogs; + } + } + /** A callback for acquiring product information about a page. */ public interface ProductInfoCallback { /** @@ -92,6 +137,17 @@ void onResult(GURL url, MerchantInfo info); } + /** A callback for acquiring price insights information about a page. */ + public interface PriceInsightsInfoCallback { + /** + * A notification that fetching price insights information for the URL has completed. + * + * @param url The URL the price insights info was fetched for. + * @param info The price insights info for the URL or {@code null} if none is available. + */ + void onResult(GURL url, PriceInsightsInfo info); + } + /** A pointer to the native side of the object. */ private long mNativeShoppingServiceAndroid; @@ -110,7 +166,10 @@ * object will be null if there is none available. */ public void getProductInfoForUrl(GURL url, ProductInfoCallback callback) { - if (mNativeShoppingServiceAndroid == 0) return; + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(url, null); + return; + } ShoppingServiceJni.get().getProductInfoForUrl( mNativeShoppingServiceAndroid, this, url, callback); @@ -136,13 +195,33 @@ * object will be null if there is none available. */ public void getMerchantInfoForUrl(GURL url, MerchantInfoCallback callback) { - if (mNativeShoppingServiceAndroid == 0) return; + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(url, null); + return; + } ShoppingServiceJni.get().getMerchantInfoForUrl( mNativeShoppingServiceAndroid, this, url, callback); } /** + * Fetch price insights information for a URL. + * + * @param url The URL to fetch price insights info for. + * @param callback The callback that will run after the fetch is completed. The price insights + * info object will be null if there is none available. + */ + public void getPriceInsightsInfoForUrl(GURL url, PriceInsightsInfoCallback callback) { + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(url, null); + return; + } + + ShoppingServiceJni.get() + .getPriceInsightsInfoForUrl(mNativeShoppingServiceAndroid, this, url, callback); + } + + /** * Requests that the service fetch the price notification email preference from the backend. * This call will update the preference kept by the pref service directly -- changes to the * value should also be observed through the pref service. This method should only be used in @@ -163,7 +242,10 @@ /** Create new subscriptions in batch. */ public void subscribe(CommerceSubscription sub, Callback<Boolean> callback) { - if (mNativeShoppingServiceAndroid == 0) return; + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(false); + return; + } assert sub.userSeenOffer != null; ShoppingServiceJni.get().subscribe(mNativeShoppingServiceAndroid, this, sub.type, @@ -173,7 +255,10 @@ /** Delete existing subscriptions in batch. */ public void unsubscribe(CommerceSubscription sub, Callback<Boolean> callback) { - if (mNativeShoppingServiceAndroid == 0) return; + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(false); + return; + } ShoppingServiceJni.get().unsubscribe(mNativeShoppingServiceAndroid, this, sub.type, sub.idType, sub.managementType, sub.id, callback); @@ -185,7 +270,10 @@ * @param callback A callback executed when the state of the subscription is known. */ public void isSubscribed(CommerceSubscription sub, Callback<Boolean> callback) { - if (mNativeShoppingServiceAndroid == 0) return; + if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(false); + return; + } ShoppingServiceJni.get().isSubscribed(mNativeShoppingServiceAndroid, this, sub.type, sub.idType, sub.managementType, sub.id, callback); @@ -214,6 +302,7 @@ public void getAllPriceTrackedBookmarks(Callback<List<BookmarkId>> callback) { if (mNativeShoppingServiceAndroid == 0) { + callback.onResult(new ArrayList<>()); return; } ShoppingServiceJni.get().getAllPriceTrackedBookmarks( @@ -264,6 +353,16 @@ mNativeShoppingServiceAndroid, this); } + // This is a feature check for the "price insights", which will return true + // if the user has the feature flag enabled, has MSBB enabled, and (if + // applicable) is in an eligible country and locale. + public boolean isPriceInsightsEligible() { + if (mNativeShoppingServiceAndroid == 0) return false; + + return ShoppingServiceJni.get() + .isPriceInsightsEligible(mNativeShoppingServiceAndroid, this); + } + @CalledByNative private void destroy() { mNativeShoppingServiceAndroid = 0; @@ -310,6 +409,65 @@ } @CalledByNative + private static List<PricePoint> createPricePointAndAddToList( + List<PricePoint> points, String date, long price) { + if (points == null) { + points = new ArrayList<>(); + } + PricePoint point = new PricePoint(date, price); + points.add(point); + return points; + } + + @CalledByNative + private static PriceInsightsInfo createPriceInsightsInfo( + boolean hasProductClusterId, + long productClusterId, + String currencyCode, + boolean hasTypicalLowPrice, + long typicalLowPriceMicros, + boolean hasTypicalHighPrice, + long typicalHighPriceMicros, + boolean hasCatalogAttributes, + String catalogAttributes, + List<PricePoint> catalogHistoryPrices, + boolean hasJackpotUrl, + GURL jackpotUrl, + int priceBucket, + boolean hasMultipleCatalogs) { + Optional<Long> clusterId = + hasProductClusterId ? Optional.of(productClusterId) : Optional.empty(); + Optional<Long> lowPrice = + hasTypicalLowPrice ? Optional.of(typicalLowPriceMicros) : Optional.empty(); + Optional<Long> highPrice = + hasTypicalHighPrice ? Optional.of(typicalHighPriceMicros) : Optional.empty(); + Optional<String> attributes = + hasCatalogAttributes ? Optional.of(catalogAttributes) : Optional.empty(); + Optional<GURL> jackpot = hasJackpotUrl ? Optional.of(jackpotUrl) : Optional.empty(); + + if (catalogHistoryPrices == null) { + catalogHistoryPrices = new ArrayList<>(); + } + + return new PriceInsightsInfo( + clusterId, + currencyCode, + lowPrice, + highPrice, + attributes, + catalogHistoryPrices, + jackpot, + priceBucket, + hasMultipleCatalogs); + } + + @CalledByNative + private static void runPriceInsightsInfoCallback( + PriceInsightsInfoCallback callback, GURL url, PriceInsightsInfo info) { + callback.onResult(url, info); + } + + @CalledByNative private static CommerceSubscription createSubscription( int type, int idType, int managementType, String id) { return new CommerceSubscription(type, idType, id, managementType, null); @@ -354,5 +512,11 @@ boolean isMerchantViewerEnabled(long nativeShoppingServiceAndroid, ShoppingService caller); boolean isCommercePriceTrackingEnabled( long nativeShoppingServiceAndroid, ShoppingService caller); + void getPriceInsightsInfoForUrl( + long nativeShoppingServiceAndroid, + ShoppingService caller, + GURL url, + PriceInsightsInfoCallback callback); + boolean isPriceInsightsEligible(long nativeShoppingServiceAndroid, ShoppingService caller); } }
diff --git a/components/commerce/core/android/shopping_service_android.cc b/components/commerce/core/android/shopping_service_android.cc index 7bf9d34..496afb7 100644 --- a/components/commerce/core/android/shopping_service_android.cc +++ b/components/commerce/core/android/shopping_service_android.cc
@@ -147,6 +147,57 @@ info_java_object); } +void ShoppingServiceAndroid::GetPriceInsightsInfoForUrl( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& j_gurl, + const JavaParamRef<jobject>& j_callback) { + CHECK(shopping_service_); + + GURL url = *url::GURLAndroid::ToNativeGURL(env, j_gurl); + + shopping_service_->GetPriceInsightsInfoForUrl( + url, + base::BindOnce(&ShoppingServiceAndroid::HandlePriceInsightsInfoCallback, + weak_ptr_factory_.GetWeakPtr(), env, + ScopedJavaGlobalRef<jobject>(j_callback))); +} + +void ShoppingServiceAndroid::HandlePriceInsightsInfoCallback( + JNIEnv* env, + const ScopedJavaGlobalRef<jobject>& callback, + const GURL& url, + const absl::optional<PriceInsightsInfo>& info) { + ScopedJavaLocalRef<jobject> info_java_object(nullptr); + if (info.has_value()) { + ScopedJavaLocalRef<jobject> j_price_points = nullptr; + for (const auto& point : info->catalog_history_prices) { + j_price_points = Java_ShoppingService_createPricePointAndAddToList( + env, j_price_points, ConvertUTF8ToJavaString(env, std::get<0>(point)), + std::get<1>(point)); + } + + info_java_object = Java_ShoppingService_createPriceInsightsInfo( + env, info->product_cluster_id.has_value(), + info->product_cluster_id.value_or(0), + ConvertUTF8ToJavaString(env, info->currency_code), + info->typical_low_price_micros.has_value(), + info->typical_low_price_micros.value_or(0), + info->typical_high_price_micros.has_value(), + info->typical_high_price_micros.value_or(0), + info->catalog_attributes.has_value(), + ConvertUTF8ToJavaString(env, info->catalog_attributes.value_or("")), + j_price_points, info->jackpot_url.has_value(), + url::GURLAndroid::FromNativeGURL(env, + info->jackpot_url.value_or(GURL())), + static_cast<int>(info->price_bucket), info->has_multiple_catalogs); + } + + Java_ShoppingService_runPriceInsightsInfoCallback( + env, callback, url::GURLAndroid::FromNativeGURL(env, url), + info_java_object); +} + void ShoppingServiceAndroid::FetchPriceEmailPref( JNIEnv* env, const JavaParamRef<jobject>& obj) { @@ -315,4 +366,12 @@ return shopping_service_->IsCommercePriceTrackingEnabled(); } +bool ShoppingServiceAndroid::IsPriceInsightsEligible( + JNIEnv* env, + const JavaParamRef<jobject>& obj) { + CHECK(shopping_service_); + + return shopping_service_->IsPriceInsightsEligible(); +} + } // namespace commerce
diff --git a/components/commerce/core/android/shopping_service_android.h b/components/commerce/core/android/shopping_service_android.h index 4888e8e..fb21e4b 100644 --- a/components/commerce/core/android/shopping_service_android.h +++ b/components/commerce/core/android/shopping_service_android.h
@@ -49,6 +49,11 @@ const JavaParamRef<jobject>& j_gurl, const JavaParamRef<jobject>& j_callback); + void GetPriceInsightsInfoForUrl(JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jobject>& j_gurl, + const JavaParamRef<jobject>& j_callback); + void FetchPriceEmailPref(JNIEnv* env, const JavaParamRef<jobject>& obj); void ScheduleSavedProductUpdate(JNIEnv* env, @@ -99,6 +104,8 @@ bool IsCommercePriceTrackingEnabled(JNIEnv* env, const JavaParamRef<jobject>& obj); + bool IsPriceInsightsEligible(JNIEnv* env, const JavaParamRef<jobject>& obj); + ScopedJavaGlobalRef<jobject> java_ref() { return java_ref_; } private: @@ -112,6 +119,12 @@ const GURL& url, absl::optional<MerchantInfo> info); + void HandlePriceInsightsInfoCallback( + JNIEnv* env, + const ScopedJavaGlobalRef<jobject>& callback, + const GURL& url, + const absl::optional<PriceInsightsInfo>& info); + void OnSubscribe(const CommerceSubscription& sub, bool succeeded) override; void OnUnsubscribe(const CommerceSubscription& sub, bool succeeded) override;
diff --git a/components/commerce/core/commerce_types.h b/components/commerce/core/commerce_types.h index cb149b56..aa8b961 100644 --- a/components/commerce/core/commerce_types.h +++ b/components/commerce/core/commerce_types.h
@@ -73,6 +73,8 @@ }; // Position of current price with respect to the typical price range. +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.commerce.core enum class PriceBucket { kUnknown = 0, kLowPrice = 1,
diff --git a/components/desks_storage/core/desk_template_conversion.cc b/components/desks_storage/core/desk_template_conversion.cc index 7df70cc..ab9c042 100644 --- a/components/desks_storage/core/desk_template_conversion.cc +++ b/components/desks_storage/core/desk_template_conversion.cc
@@ -91,6 +91,7 @@ constexpr char kEventFlag[] = "event_flag"; constexpr char kFirstNonPinnedTabIndex[] = "first_non_pinned_tab_index"; constexpr char kIsAppTypeBrowser[] = "is_app"; +constexpr char kLacrosProfileId[] = "lacros_profile_id"; constexpr char kLaunchContainer[] = "launch_container"; constexpr char kLaunchContainerWindow[] = "LAUNCH_CONTAINER_WINDOW"; constexpr char kLaunchContainerUnspecified[] = "LAUNCH_CONTAINER_UNSPECIFIED"; @@ -465,6 +466,14 @@ app_launch_info->override_url = GURL(override_url); } + std::string lacros_profile_id_str; + if (GetString(app, kLacrosProfileId, &lacros_profile_id_str)) { + uint64_t lacros_profile_id = 0; + if (base::StringToUint64(lacros_profile_id_str, &lacros_profile_id)) { + app_launch_info->lacros_profile_id = lacros_profile_id; + } + } + // TODO(crbug.com/1311801): Add support for actual event_flag values. app_launch_info->event_flag = 0; @@ -970,6 +979,11 @@ app_data.Set(kOverrideUrl, app->override_url->spec()); } + if (app->lacros_profile_id.has_value()) { + app_data.Set(kLacrosProfileId, + base::NumberToString(app->lacros_profile_id.value())); + } + return base::Value(std::move(app_data)); } @@ -2144,6 +2158,8 @@ } else if (!IsValidDeskTemplateType(desk_type_string)) { return base::unexpected(SavedDeskParseError::kInvalidDeskType); } + const ash::DeskTemplateType desk_type = + GetDeskTypeFromString(desk_type_string); // If policy template set auto launch bool. bool auto_launch_on_startup = false; @@ -2158,13 +2174,21 @@ // templates after said policy templates are pushed to the device. if (auto* policy_value = value_dict.FindDict(kPolicy)) { desk_template = std::make_unique<ash::DeskTemplate>( - std::move(uuid), source, name, created_time, - GetDeskTypeFromString(desk_type_string), auto_launch_on_startup, - base::Value(policy_value->Clone())); + std::move(uuid), source, name, created_time, desk_type, + auto_launch_on_startup, base::Value(policy_value->Clone())); } else { desk_template = std::make_unique<ash::DeskTemplate>( - std::move(uuid), source, name, created_time, - GetDeskTypeFromString(desk_type_string)); + std::move(uuid), source, name, created_time, desk_type); + } + + if (desk_type == ash::DeskTemplateType::kSaveAndRecall) { + std::string lacros_profile_id_str; + if (GetString(value_dict, kLacrosProfileId, &lacros_profile_id_str)) { + uint64_t lacros_profile_id = 0; + if (base::StringToUint64(lacros_profile_id_str, &lacros_profile_id)) { + desk_template->set_lacros_profile_id(lacros_profile_id); + } + } } desk_template->set_updated_time(updated_time); @@ -2184,7 +2208,11 @@ desk_dict.Set(kUpdatedTime, base::TimeToValue(desk->GetLastUpdatedTime())); desk_dict.Set(kDeskType, SerializeDeskTypeAsString(desk->type())); desk_dict.Set(kAutoLaunchOnStartup, desk->should_launch_on_startup()); - + if (desk->type() == ash::DeskTemplateType::kSaveAndRecall && + desk->lacros_profile_id()) { + desk_dict.Set(kLacrosProfileId, + base::NumberToString(desk->lacros_profile_id())); + } desk_dict.Set( kDesk, ConvertRestoreDataToValue(desk->desk_restore_data(), app_cache));
diff --git a/components/desks_storage/core/desk_template_conversion_unittests.cc b/components/desks_storage/core/desk_template_conversion_unittests.cc index 4e044b7..bfc0d817 100644 --- a/components/desks_storage/core/desk_template_conversion_unittests.cc +++ b/components/desks_storage/core/desk_template_conversion_unittests.cc
@@ -39,6 +39,7 @@ constexpr char kBrowserUrl2[] = "https://example.com/2"; constexpr char kBrowserTemplateName[] = "BrowserTest"; constexpr char kOverrideUrl[] = "https://example.com/"; +constexpr uint64_t kTestLacrosProfileId = 12345; tab_groups::TabGroupInfo MakeSampleTabGroup() { return tab_groups::TabGroupInfo( @@ -545,10 +546,12 @@ .SetName(kBrowserTemplateName) .SetType(ash::DeskTemplateType::kSaveAndRecall) .SetCreatedTime(created_time) + .SetLacrosProfileId(kTestLacrosProfileId) .AddAppWindow( SavedDeskBrowserBuilder() .SetGenericBuilder(SavedDeskGenericAppBuilder().SetWindowId( kBrowserWindowId)) + .SetLacrosProfileId(kTestLacrosProfileId) .SetUrls({GURL(kBrowserUrl1), GURL(kBrowserUrl2)}) .Build()) .Build(); @@ -570,6 +573,8 @@ expected_browser_app_value.Set("event_flag", base::Value(0)); expected_browser_app_value.Set("window_id", base::Value(kBrowserWindowId)); expected_browser_app_value.Set("tabs", std::move(expected_tab_list)); + expected_browser_app_value.Set("lacros_profile_id", + base::NumberToString(kTestLacrosProfileId)); base::Value::List expected_app_list; expected_app_list.Append(std::move(expected_browser_app_value)); @@ -587,6 +592,8 @@ base::TimeToValue(desk_template->GetLastUpdatedTime())); expected_value.Set("desk_type", base::Value("SAVE_AND_RECALL")); expected_value.Set("desk", std::move(expected_desk_value)); + expected_value.Set("lacros_profile_id", + base::NumberToString(kTestLacrosProfileId)); EXPECT_EQ(expected_value, desk_template_value); }
diff --git a/components/desks_storage/core/saved_desk_builder.cc b/components/desks_storage/core/saved_desk_builder.cc index 234160d..0857d13 100644 --- a/components/desks_storage/core/saved_desk_builder.cc +++ b/components/desks_storage/core/saved_desk_builder.cc
@@ -253,6 +253,12 @@ return *this; } +SavedDeskBrowserBuilder& SavedDeskBrowserBuilder::SetLacrosProfileId( + uint64_t lacros_profile_id) { + lacros_profile_id_ = lacros_profile_id; + return *this; +} + SavedDeskBrowserBuilder& SavedDeskBrowserBuilder::SetIsApp(bool is_app) { is_app_ = is_app; return *this; @@ -277,6 +283,7 @@ first_non_pinned_tab_index_; generic_app.launch_info->urls = urls_; generic_app.launch_info->app_type_browser = is_app_; + generic_app.launch_info->lacros_profile_id = lacros_profile_id_; for (auto& tab_group : tab_group_builders_) { SavedDeskTabGroupBuilder::TabGroupWithStatus built_group = @@ -367,6 +374,9 @@ if (has_updated_time_) { desk_template->set_updated_time(updated_time_); } + if (lacros_profile_id_) { + desk_template->set_lacros_profile_id(*lacros_profile_id_); + } auto restore_data = std::make_unique<app_restore::RestoreData>(); @@ -424,6 +434,12 @@ return *this; } +SavedDeskBuilder& SavedDeskBuilder::SetLacrosProfileId( + uint64_t lacros_profile_id) { + lacros_profile_id_ = lacros_profile_id; + return *this; +} + SavedDeskBuilder& SavedDeskBuilder::AddAppWindow(BuiltApp built_app) { built_apps_.push_back(std::move(built_app)); return *this;
diff --git a/components/desks_storage/core/saved_desk_builder.h b/components/desks_storage/core/saved_desk_builder.h index d1ee28b..42501d72 100644 --- a/components/desks_storage/core/saved_desk_builder.h +++ b/components/desks_storage/core/saved_desk_builder.h
@@ -178,6 +178,7 @@ SavedDeskBrowserBuilder& SetActiveTabIndex(int index); SavedDeskBrowserBuilder& SetUrls(std::vector<GURL> urls); SavedDeskBrowserBuilder& SetIsLacros(bool is_lacros); + SavedDeskBrowserBuilder& SetLacrosProfileId(uint64_t lacros_profile_id); SavedDeskBrowserBuilder& AddTabGroupBuilder( SavedDeskTabGroupBuilder tab_group); @@ -194,6 +195,7 @@ std::vector<SavedDeskTabGroupBuilder> tab_group_builders_; absl::optional<int> active_tab_index_; absl::optional<int> first_non_pinned_tab_index_; + absl::optional<uint64_t> lacros_profile_id_; std::vector<GURL> urls_; }; @@ -267,6 +269,9 @@ SavedDeskBuilder& SetPolicyShouldLaunchOnStartup( bool should_launch_on_startup); + // Sets the optional lacros profile association. + SavedDeskBuilder& SetLacrosProfileId(uint64_t lacros_profile_id); + // Adds an app window. SavedDeskBuilder& AddAppWindow(BuiltApp built_app); @@ -286,6 +291,7 @@ base::Time updated_time_; base::Value policy_value_; bool policy_should_launch_on_startup_ = false; + absl::optional<uint64_t> lacros_profile_id_; std::vector<BuiltApp> built_apps_; };
diff --git a/components/enterprise/data_controls/BUILD.gn b/components/enterprise/data_controls/BUILD.gn index e56dd018..5e68605 100644 --- a/components/enterprise/data_controls/BUILD.gn +++ b/components/enterprise/data_controls/BUILD.gn
@@ -29,6 +29,8 @@ "prefs.h", "rule.cc", "rule.h", + "verdict.cc", + "verdict.h", ] deps = [ @@ -56,11 +58,13 @@ "and_condition_unittest.cc", "attributes_condition_unittest.cc", "rule_unittest.cc", + "verdict_unittest.cc", ] deps = [ ":data_controls", "//base", + "//base/test:test_support", "//testing/gtest", ] }
diff --git a/components/enterprise/data_controls/verdict.cc b/components/enterprise/data_controls/verdict.cc new file mode 100644 index 0000000..7cf949d --- /dev/null +++ b/components/enterprise/data_controls/verdict.cc
@@ -0,0 +1,63 @@ +// 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/enterprise/data_controls/verdict.h" + +#include <utility> + +namespace data_controls { + +// static +Verdict Verdict::NotSet() { + return Verdict(Rule::Level::kNotSet); +} + +// static +Verdict Verdict::Report(base::OnceClosure initial_report_closure) { + return Verdict(Rule::Level::kReport, std::move(initial_report_closure)); +} + +// static +Verdict Verdict::Warn(base::OnceClosure initial_report_closure, + base::OnceClosure bypass_report_closure) { + return Verdict(Rule::Level::kWarn, std::move(initial_report_closure), + std::move(bypass_report_closure)); +} + +// static +Verdict Verdict::Block(base::OnceClosure initial_report_closure) { + return Verdict(Rule::Level::kBlock, std::move(initial_report_closure)); +} + +// static +Verdict Verdict::Allow() { + return Verdict(Rule::Level::kAllow); +} + +Verdict::Verdict(Rule::Level level, + base::OnceClosure initial_report_closure, + base::OnceClosure bypass_report_closure) + : level_(level), + initial_report_closure_(std::move(initial_report_closure)), + bypass_report_closure_(std::move(bypass_report_closure)) { + DCHECK_EQ(level == Rule::Level::kNotSet || level == Rule::Level::kAllow, + initial_report_closure_.is_null()); + DCHECK_EQ(level == Rule::Level::kWarn, !bypass_report_closure_.is_null()); +} + +Verdict::~Verdict() = default; + +Rule::Level Verdict::level() const { + return level_; +} + +base::OnceClosure Verdict::TakeInitialReportClosure() { + return std::move(initial_report_closure_); +} + +base::OnceClosure Verdict::TakeBypassReportClosure() { + return std::move(bypass_report_closure_); +} + +} // namespace data_controls
diff --git a/components/enterprise/data_controls/verdict.h b/components/enterprise/data_controls/verdict.h new file mode 100644 index 0000000..e2bab53f --- /dev/null +++ b/components/enterprise/data_controls/verdict.h
@@ -0,0 +1,64 @@ +// 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_ENTERPRISE_DATA_CONTROLS_VERDICT_H_ +#define COMPONENTS_ENTERPRISE_DATA_CONTROLS_VERDICT_H_ + +#include "base/functional/callback.h" +#include "components/enterprise/data_controls/rule.h" + +namespace data_controls { + +// Class representing the verdict Data Controls rules should apply in a specific +// context after evaluating all rules to be applied. Instances of this class +// should be created from combining an action's context with rules by classes +// like `ChromeDlpRulesManager`, and then be considered as the source of truth +// on what UX should be shown, what should be reported, etc. +class Verdict { + public: + static Verdict NotSet(); + static Verdict Report(base::OnceClosure initial_report_closure); + static Verdict Warn(base::OnceClosure initial_report_closure, + base::OnceClosure bypass_report_closure); + static Verdict Block(base::OnceClosure initial_report_closure); + static Verdict Allow(); + + ~Verdict(); + + Rule::Level level() const; + + // Accessors that take ownership of the underlying unique closures. + base::OnceClosure TakeInitialReportClosure(); + base::OnceClosure TakeBypassReportClosure(); + + private: + explicit Verdict( + Rule::Level level, + base::OnceClosure initial_report_closure = base::OnceClosure(), + base::OnceClosure bypass_report_closure = base::OnceClosure()); + + // The highest-precedence rule level to be applied to the action potentially + // interrupted by Data Controls. + Rule::Level level_; + + // known at rule evaluation, so its type will need to change. + // The callback to be called to report the initial Data Controls rule + // triggers. + // TODO(b/303640183): This callback will likely require more information not + // known at rule evaluation, so its type will need to change. + base::OnceClosure initial_report_closure_; + + // The callback to be called when `level` is `kWarn` and the user bypasses the + // warning shown to them. This should be used to report the appropriate event, + // and should be populated with copied data of the triggered rules since those + // can change arbitrarily between the time of the warning being shown and the + // user bypassing it. + // TODO(b/303640183): This callback will likely require more information not + // known at rule evaluation, so its type will need to change. + base::OnceClosure bypass_report_closure_; +}; + +} // namespace data_controls + +#endif // COMPONENTS_ENTERPRISE_DATA_CONTROLS_VERDICT_H_
diff --git a/components/enterprise/data_controls/verdict_unittest.cc b/components/enterprise/data_controls/verdict_unittest.cc new file mode 100644 index 0000000..9bb92a5 --- /dev/null +++ b/components/enterprise/data_controls/verdict_unittest.cc
@@ -0,0 +1,64 @@ +// 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/enterprise/data_controls/verdict.h" + +#include "base/functional/callback_helpers.h" +#include "base/test/test_future.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace data_controls { + +TEST(DataControlVerdictTest, Level) { + ASSERT_EQ(Verdict::NotSet().level(), Rule::Level::kNotSet); + ASSERT_EQ(Verdict::Report(base::DoNothing()).level(), Rule::Level::kReport); + ASSERT_EQ(Verdict::Warn(base::DoNothing(), base::DoNothing()).level(), + Rule::Level::kWarn); + ASSERT_EQ(Verdict::Block(base::DoNothing()).level(), Rule::Level::kBlock); + ASSERT_EQ(Verdict::Allow().level(), Rule::Level::kAllow); +} + +TEST(DataControlVerdictTest, InitialReport) { + ASSERT_TRUE(Verdict::NotSet().TakeInitialReportClosure().is_null()); + ASSERT_TRUE(Verdict::Allow().TakeInitialReportClosure().is_null()); + + base::test::TestFuture<void> report_future; + auto report = Verdict::Report(report_future.GetCallback()); + auto report_callback = report.TakeInitialReportClosure(); + ASSERT_FALSE(report_callback.is_null()); + std::move(report_callback).Run(); + ASSERT_TRUE(report_future.Wait()); + + base::test::TestFuture<void> warn_future; + auto warn = Verdict::Warn(warn_future.GetCallback(), base::DoNothing()); + auto warn_callback = warn.TakeInitialReportClosure(); + ASSERT_FALSE(warn_callback.is_null()); + std::move(warn_callback).Run(); + ASSERT_TRUE(warn_future.Wait()); + + base::test::TestFuture<void> block_future; + auto block = Verdict::Block(block_future.GetCallback()); + auto block_callback = block.TakeInitialReportClosure(); + ASSERT_FALSE(block_callback.is_null()); + std::move(block_callback).Run(); + ASSERT_TRUE(block_future.Wait()); +} + +TEST(DataControlVerdictTest, BypassReport) { + ASSERT_TRUE(Verdict::NotSet().TakeBypassReportClosure().is_null()); + ASSERT_TRUE( + Verdict::Block(base::DoNothing()).TakeBypassReportClosure().is_null()); + ASSERT_TRUE(Verdict::Allow().TakeBypassReportClosure().is_null()); + ASSERT_TRUE( + Verdict::Report(base::DoNothing()).TakeBypassReportClosure().is_null()); + + base::test::TestFuture<void> warn_future; + auto warn = Verdict::Warn(base::DoNothing(), warn_future.GetCallback()); + auto warn_callback = warn.TakeBypassReportClosure(); + ASSERT_FALSE(warn_callback.is_null()); + std::move(warn_callback).Run(); + ASSERT_TRUE(warn_future.Wait()); +} + +} // namespace data_controls
diff --git a/components/exo/wayland/wayland_display_output_unittest.cc b/components/exo/wayland/wayland_display_output_unittest.cc index 007c5850..331ecaf 100644 --- a/components/exo/wayland/wayland_display_output_unittest.cc +++ b/components/exo/wayland/wayland_display_output_unittest.cc
@@ -127,7 +127,14 @@ // Tests to ensure exo processes added displays before removed displays for // display configuration updates. This ensures exo's clients always see a valid // Output during such configuration updates. -TEST_F(WaylandDisplayOutputTest, MaintainsNonEmptyOutputList) { +// TODO(1503560) Test consistently fails on builder Linux Chromium OS ASan LSan +// Tests. +#if defined(LEAK_SANITIZER) && defined(ADDRESS_SANITIZER) +#define MAYBE_MaintainsNonEmptyOutputList DISABLED_MaintainsNonEmptyOutputList +#else +#define MAYBE_MaintainsNonEmptyOutputList MaintainsNonEmptyOutputList +#endif +TEST_F(WaylandDisplayOutputTest, MAYBE_MaintainsNonEmptyOutputList) { // Start with 2 displays. UpdateDisplay("300x400,500x600");
diff --git a/components/global_media_controls/public/views/media_notification_view_ash_impl.cc b/components/global_media_controls/public/views/media_notification_view_ash_impl.cc index adf01f03..208c130b 100644 --- a/components/global_media_controls/public/views/media_notification_view_ash_impl.cc +++ b/components/global_media_controls/public/views/media_notification_view_ash_impl.cc
@@ -427,7 +427,7 @@ artwork_view_->SetVisible(true); artwork_view_->SetImageSize( ScaleImageSizeToFitView(image.size(), kArtworkSize)); - artwork_view_->SetImage(image); + artwork_view_->SetImage(ui::ImageModel::FromImageSkia(image)); // Draw the image with rounded corners. auto path = SkPath().addRoundRect(
diff --git a/components/metrics/generate_expired_histograms_array.gni b/components/metrics/generate_expired_histograms_array.gni index 6ea1e1c..0beb867 100644 --- a/components/metrics/generate_expired_histograms_array.gni +++ b/components/metrics/generate_expired_histograms_array.gni
@@ -198,6 +198,7 @@ "//tools/metrics/histograms/metadata/settings/histograms.xml", "//tools/metrics/histograms/metadata/sharing/histograms.xml", "//tools/metrics/histograms/metadata/side_search/histograms.xml", + "//tools/metrics/histograms/metadata/signin/enums.xml", "//tools/metrics/histograms/metadata/signin/histograms.xml", "//tools/metrics/histograms/metadata/simple/histograms.xml", "//tools/metrics/histograms/metadata/stability/histograms.xml",
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 577e3c5e..deb16255 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -167,9 +167,6 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/variations/entropy_provider.h" -// When removing the below header, also remove the friend declaration. -#include "components/variations/synthetic_trial_registry.h" -#include "components/variations/synthetic_trials.h" #if !BUILDFLAG(IS_ANDROID) #include "components/keep_alive_registry/keep_alive_types.h" @@ -426,20 +423,6 @@ // Init() has to be called after LogCrash() in order for LogCrash() to work. delegating_provider_.Init(); - // Register the synthetic trial for StatisticsRecorder. Done here instead of - // the usual place to make sure this covers all UMA-reporting platforms. - auto* synthetic_trial_registry = client_->GetSyntheticTrialRegistry(); - if (synthetic_trial_registry) { // Null in tests. - base::StringPiece group_name = - base::StatisticsRecorder::GetLockTrialGroup(); - if (!group_name.empty()) { - synthetic_trial_registry->RegisterSyntheticFieldTrial( - variations::SyntheticTrialGroup( - "StatisticsRecorderRWLock", group_name, - variations::SyntheticTrialAnnotationMode::kCurrentLog)); - } - } - state_ = INITIALIZED; }
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc index 40d2e4b..f51f4ed 100644 --- a/components/metrics/metrics_state_manager.cc +++ b/components/metrics/metrics_state_manager.cc
@@ -22,7 +22,6 @@ #include "base/memory/raw_ref.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" -#include "base/metrics/statistics_recorder.h" #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" @@ -198,11 +197,6 @@ LogClonedInstall(); } log_normal_metric_state_.LogArtificialNonUniformity(); -#ifdef ARCH_CPU_64_BITS - base::UmaHistogramMediumTimes( - "UMA.StatisticsRecorder.LockWaitTime", - base::StatisticsRecorder::GetAndClearTotalWaitTime()); -#endif // ARCH_CPU_64_BITS } // Set a random seed for the random number generator.
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index ab43bc3..9354ec9c91 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -1127,7 +1127,7 @@ UpdateAssistedQueryStats(&internal_result_); UpdateTailSuggestPrefix(&internal_result_); MaybeRemoveCompanyEntityImages(&internal_result_); - MaybeCleanSuggestionsForKeywordMode(input_.text(), &internal_result_); + MaybeCleanSuggestionsForKeywordMode(input_, &internal_result_); if (search_provider_) search_provider_->RegisterDisplayedAnswers(internal_result_); @@ -1981,15 +1981,20 @@ } void AutocompleteController::MaybeCleanSuggestionsForKeywordMode( - const std::u16string& input, + const AutocompleteInput& input, AutocompleteResult* result) { + if (input.current_page_classification() == + metrics::OmniboxEventProto::NTP_REALBOX) { + // Realbox doesn't support keyword mode yet, so keep original list intact. + return; + } if (OmniboxFieldTrial::IsKeywordModeRefreshEnabled() && - input.starts_with(u'@')) { + input.text().starts_with(u'@')) { // When the input is '@' exactly, some special filtering rules are applied. // Note: the rule preserving other matches with `associated_keyword` is // not currently necessary, but is intended to make it easy to coexist // with enterprise configured scopes when that feature is implemented. - if (input == u"@") { + if (input.text() == u"@") { result->EraseMatchesWhere([](const AutocompleteMatch& match) { return !(match.type == AutocompleteMatchType::STARTER_PACK || match.contents == u"@" || match.associated_keyword);
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h index cacffc6..e624793d9 100644 --- a/components/omnibox/browser/autocomplete_controller.h +++ b/components/omnibox/browser/autocomplete_controller.h
@@ -438,7 +438,7 @@ // May remove actions from default suggestion to avoid interference with // keyword mode refresh interaction. May clear some match text that is // repeated across multiple consecutive matches. - void MaybeCleanSuggestionsForKeywordMode(const std::u16string& input, + void MaybeCleanSuggestionsForKeywordMode(const AutocompleteInput& input, AutocompleteResult* result); // Get the experiment stats v2 entry for the omnibox position. Used on iOS.
diff --git a/components/omnibox/browser/autocomplete_controller_unittest.cc b/components/omnibox/browser/autocomplete_controller_unittest.cc index 7dd49f26..76b2dcd 100644 --- a/components/omnibox/browser/autocomplete_controller_unittest.cc +++ b/components/omnibox/browser/autocomplete_controller_unittest.cc
@@ -534,8 +534,10 @@ CreateStarterPackMatch(u"@tabs"), }); + AutocompleteInput input(u"@", 1u, metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); controller_->MaybeCleanSuggestionsForKeywordMode( - u"@", &controller_->internal_result_); + input, &controller_->internal_result_); EXPECT_EQ(controller_->internal_result_.size(), 4u); EXPECT_TRUE(
diff --git a/components/omnibox/browser/builtin_provider.cc b/components/omnibox/browser/builtin_provider.cc index 77420d84..dc51013 100644 --- a/components/omnibox/browser/builtin_provider.cc +++ b/components/omnibox/browser/builtin_provider.cc
@@ -230,7 +230,9 @@ match.fill_into_edit.substr(input.text().length()); match.destination_url = GURL(destination_url); match.transition = ui::PAGE_TRANSITION_GENERATED; - if (OmniboxFieldTrial::IsKeywordModeRefreshEnabled()) { + if (OmniboxFieldTrial::IsKeywordModeRefreshEnabled() && + input.current_page_classification() != + metrics::OmniboxEventProto::NTP_REALBOX) { match.description = l10n_util::GetStringFUTF16( IDS_OMNIBOX_INSTANT_KEYWORD_SEARCH_TEXT, template_url.short_name()); match.description_class.emplace_back(0, ACMatchClassification::NONE);
diff --git a/components/optimization_guide/core/model_execution/model_execution_manager.cc b/components/optimization_guide/core/model_execution/model_execution_manager.cc index 8d993dd31..354d61b 100644 --- a/components/optimization_guide/core/model_execution/model_execution_manager.cc +++ b/components/optimization_guide/core/model_execution/model_execution_manager.cc
@@ -5,15 +5,19 @@ #include "components/optimization_guide/core/model_execution/model_execution_manager.h" #include "base/command_line.h" +#include "base/notreached.h" #include "base/strings/stringprintf.h" #include "components/optimization_guide/core/model_execution/model_execution_fetcher.h" #include "components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h" #include "components/optimization_guide/core/model_execution/on_device_model_service_controller.h" #include "components/optimization_guide/core/model_execution/on_device_model_stream_receiver.h" #include "components/optimization_guide/core/model_execution/optimization_guide_model_execution_error.h" +#include "components/optimization_guide/core/model_quality/feature_type_map.h" +#include "components/optimization_guide/core/model_quality/model_quality_log_entry.h" #include "components/optimization_guide/core/model_util.h" #include "components/optimization_guide/core/optimization_guide_constants.h" #include "components/optimization_guide/core/optimization_guide_logger.h" +#include "components/optimization_guide/core/optimization_guide_util.h" #include "components/optimization_guide/core/optimization_metadata.h" #include "components/optimization_guide/proto/common_types.pb.h" #include "net/base/url_util.h" @@ -108,6 +112,94 @@ raw_ref<ModelExecutionManager> execution_manager_; }; +// Sets request data corresponding the feature's LogAiDataRequest. +template <typename FeatureType> +void SetExecutionRequestTemplate( + proto::LogAiDataRequest& log_ai_request, + const google::protobuf::MessageLite& request_metadata) { + typename FeatureType::LoggingData* logging_data = + FeatureType::GetLoggingData(log_ai_request); + CHECK(logging_data); + + // Request is set by the feature and should always be typed. + auto typed_request = + static_cast<const FeatureType::Request&>(request_metadata); + *(logging_data->mutable_request_data()) = typed_request; +} + +// Sets response data corresponding the feature's LogAiDataRequest. +template <typename FeatureType> +void SetExecutionResponseTemplate(proto::LogAiDataRequest& log_ai_request, + const proto::Any& response_metadata) { + typename FeatureType::LoggingData* logging_data = + FeatureType::GetLoggingData(log_ai_request); + CHECK(logging_data); + + // Deserialize any to correct feature response type. + auto response_data = + optimization_guide::ParsedAnyMetadata<typename FeatureType::Response>( + response_metadata); + + if (!response_data) { + return; + } + + // Set the response data to feature LoggingData if exists. + *(logging_data->mutable_response_data()) = std::move(*response_data); + CHECK(logging_data->has_response_data()) << "Response data is not set\n"; +} + +// Helper method matches feature to corresponding FeatureTypeMap to set +// LogAiDataRequest's request data. +void SetExecutionRequest( + proto::ModelExecutionFeature feature, + proto::LogAiDataRequest& log_ai_request, + const google::protobuf::MessageLite& request_metadata) { + switch (feature) { + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH: + SetExecutionRequestTemplate<WallpaperSearchFeatureTypeMap>( + log_ai_request, request_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TAB_ORGANIZATION: + SetExecutionRequestTemplate<TabOrganizationFeatureTypeMap>( + log_ai_request, request_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_COMPOSE: + SetExecutionRequestTemplate<ComposeFeatureTypeMap>(log_ai_request, + request_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED: + // Don't log any request data when the feature is not specified. + NOTREACHED(); + return; + } +} + +// Helper method matches feature to corresponding FeatureTypeMap to set +// LogAiDataRequest's response data. +void SetExecutionResponse(proto::ModelExecutionFeature feature, + proto::LogAiDataRequest& log_ai_request, + const proto::Any& response_metadata) { + switch (feature) { + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH: + SetExecutionResponseTemplate<WallpaperSearchFeatureTypeMap>( + log_ai_request, response_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_TAB_ORGANIZATION: + SetExecutionResponseTemplate<TabOrganizationFeatureTypeMap>( + log_ai_request, response_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_COMPOSE: + SetExecutionResponseTemplate<ComposeFeatureTypeMap>(log_ai_request, + response_metadata); + return; + case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED: + // Don't log any response data when the feature is not specified. + NOTREACHED(); + return; + } +} + } // namespace using ModelExecutionError = @@ -200,6 +292,10 @@ } } + // Set execution request in corresponding `log_ai_data_request`. + auto log_ai_data_request = std::make_unique<proto::LogAiDataRequest>(); + SetExecutionRequest(feature, *log_ai_data_request.get(), request_metadata); + auto fetcher_it = active_model_execution_fetchers_.emplace( std::piecewise_construct, std::forward_as_tuple(feature), std::forward_as_tuple(url_loader_factory_, model_execution_service_url_, @@ -208,7 +304,7 @@ feature, identity_manager_, oauth_scopes_, request_metadata, base::BindOnce(&ModelExecutionManager::OnModelExecuteResponse, weak_ptr_factory_.GetWeakPtr(), feature, - std::move(callback))); + std::move(log_ai_data_request), std::move(callback))); } std::unique_ptr<OptimizationGuideModelExecutor::Session> @@ -225,6 +321,7 @@ void ModelExecutionManager::OnModelExecuteResponse( proto::ModelExecutionFeature feature, + std::unique_ptr<proto::LogAiDataRequest> log_ai_data_request, OptimizationGuideModelExecutionResultCallback callback, base::expected<const proto::ExecuteResponse, OptimizationGuideModelExecutionError> execute_response) { @@ -238,23 +335,36 @@ return; } + // Create corresponding log entry for `log_ai_data_request` to pass it with + // the callback. + std::unique_ptr<ModelQualityLogEntry> log_entry = + std::make_unique<ModelQualityLogEntry>(std::move(log_ai_data_request)); + if (execute_response->has_error_response()) { scoped_logger.set_message("Error: No Response Metadata"); + // For unallowed error states, don't log request data. + if (!OptimizationGuideModelExecutionError::FromModelExecutionServerError( + execute_response->error_response()) + .ShouldLogModelQuality()) { + log_entry = nullptr; + } std::move(callback).Run( base::unexpected( OptimizationGuideModelExecutionError::FromModelExecutionServerError( execute_response->error_response())), - nullptr); + std::move(log_entry)); return; } if (!execute_response->has_response_metadata()) { scoped_logger.set_message("Error: No Response Metadata"); + // Log the request in case response is not present by passing the + // `log_entry`. std::move(callback).Run( base::unexpected( OptimizationGuideModelExecutionError::FromModelExecutionError( ModelExecutionError::kGenericFailure)), - nullptr); + std::move(log_entry)); return; } @@ -301,8 +411,13 @@ } } } + + // Set execution response in corresponding `log_ai_data_request`. + SetExecutionResponse(feature, *(log_entry.get()->log_ai_data_request()), + execute_response->response_metadata()); + std::move(callback).Run(base::ok(execute_response->response_metadata()), - nullptr); + std::move(log_entry)); } } // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/model_execution_manager.h b/components/optimization_guide/core/model_execution/model_execution_manager.h index d86f1cb..501b427b 100644 --- a/components/optimization_guide/core/model_execution/model_execution_manager.h +++ b/components/optimization_guide/core/model_execution/model_execution_manager.h
@@ -15,6 +15,7 @@ #include "components/optimization_guide/core/optimization_guide_features.h" #include "components/optimization_guide/core/optimization_guide_model_executor.h" #include "components/optimization_guide/proto/model_execution.pb.h" +#include "components/optimization_guide/proto/model_quality_service.pb.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/on_device_model/public/mojom/on_device_model.mojom.h" #include "url/gurl.h" @@ -59,6 +60,7 @@ // Invoked when the model execution result is available. void OnModelExecuteResponse( proto::ModelExecutionFeature feature, + std::unique_ptr<proto::LogAiDataRequest> log_ai_data_request, OptimizationGuideModelExecutionResultCallback callback, base::expected<const proto::ExecuteResponse, OptimizationGuideModelExecutionError> execute_response);
diff --git a/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc b/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc index 9a9cdff..d0c3b460 100644 --- a/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc +++ b/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc
@@ -26,17 +26,14 @@ using ::base::test::TestMessage; using ::testing::HasSubstr; -TestMessage BuildTestMessage(const std::string& test_message_str) { - TestMessage test_message; - test_message.set_test(test_message_str); - return test_message; -} - -proto::ExecuteResponse BuildTestExecuteResponse(const TestMessage& message) { +proto::ExecuteResponse BuildComposeResponse(const std::string& output) { + proto::ComposeResponse compose_response; + compose_response.set_output(output); proto::ExecuteResponse execute_response; proto::Any* any_metadata = execute_response.mutable_response_metadata(); - any_metadata->set_type_url("type.googleapis.com/" + message.GetTypeName()); - message.SerializeToString(any_metadata->mutable_value()); + any_metadata->set_type_url("type.googleapis.com/" + + compose_response.GetTypeName()); + compose_response.SerializeToString(any_metadata->mutable_value()); return execute_response; } @@ -65,7 +62,7 @@ bool SimulateSuccessfulResponse() { std::string serialized_response; proto::ExecuteResponse execute_response = - BuildTestExecuteResponse(BuildTestMessage("foo response")); + BuildComposeResponse("foo response"); execute_response.SerializeToString(&serialized_response); return SimulateResponse(serialized_response, net::HTTP_OK); } @@ -100,11 +97,11 @@ }; TEST_F(ModelExecutionManagerTest, ExecuteModelEmptyAccessToken) { - TestMessage test_message; - test_message.set_test("some test"); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); base::RunLoop run_loop; model_execution_manager()->ExecuteModel( - proto::MODEL_EXECUTION_FEATURE_COMPOSE, test_message, + proto::MODEL_EXECUTION_FEATURE_COMPOSE, request, base::BindOnce( [](base::RunLoop* run_loop, OptimizationGuideModelExecutionResult result, @@ -118,21 +115,30 @@ } TEST_F(ModelExecutionManagerTest, ExecuteModelWithUserSignIn) { - TestMessage test_message; - test_message.set_test("some test"); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); base::RunLoop run_loop; identity_test_env()->MakePrimaryAccountAvailable( "test_email", signin::ConsentLevel::kSignin); model_execution_manager()->ExecuteModel( - proto::MODEL_EXECUTION_FEATURE_COMPOSE, test_message, + proto::MODEL_EXECUTION_FEATURE_COMPOSE, request, base::BindOnce( [](base::RunLoop* run_loop, OptimizationGuideModelExecutionResult result, std::unique_ptr<ModelQualityLogEntry> log_entry) { EXPECT_TRUE(result.has_value()); - EXPECT_EQ("foo response", - ParsedAnyMetadata<TestMessage>(result.value())->test()); - EXPECT_EQ(log_entry.get(), nullptr); + auto response = + ParsedAnyMetadata<proto::ComposeResponse>(result.value()); + EXPECT_EQ("foo response", response->output()); + EXPECT_NE(log_entry.get(), nullptr); + EXPECT_TRUE(log_entry.get() + ->log_ai_data_request() + ->mutable_compose() + ->has_request_data()); + EXPECT_TRUE(log_entry.get() + ->log_ai_data_request() + ->mutable_compose() + ->has_response_data()); run_loop->Quit(); }, &run_loop)); @@ -143,27 +149,36 @@ } TEST_F(ModelExecutionManagerTest, ExecuteModelWithPassthroughSession) { - TestMessage test_message; - test_message.set_test("some test"); + proto::ComposeRequest request; + request.set_user_input("a user typed this"); base::RunLoop run_loop; identity_test_env()->MakePrimaryAccountAvailable( "test_email", signin::ConsentLevel::kSignin); auto session = model_execution_manager()->StartSession( proto::MODEL_EXECUTION_FEATURE_COMPOSE); session->ExecuteModel( - test_message, - base::BindRepeating( - [](base::RunLoop* run_loop, - OptimizationGuideModelStreamingExecutionResult result, - std::unique_ptr<ModelQualityLogEntry> log_entry) { - EXPECT_TRUE(result.has_value()); - EXPECT_EQ("foo response", - ParsedAnyMetadata<TestMessage>(result->response)->test()); - EXPECT_TRUE(result->is_complete); - EXPECT_EQ(log_entry.get(), nullptr); - run_loop->Quit(); - }, - &run_loop)); + request, base::BindRepeating( + [](base::RunLoop* run_loop, + OptimizationGuideModelStreamingExecutionResult result, + std::unique_ptr<ModelQualityLogEntry> log_entry) { + EXPECT_TRUE(result.has_value()); + EXPECT_EQ("foo response", + ParsedAnyMetadata<proto::ComposeResponse>( + result->response) + ->output()); + EXPECT_TRUE(result->is_complete); + EXPECT_NE(log_entry.get(), nullptr); + EXPECT_TRUE(log_entry.get() + ->log_ai_data_request() + ->mutable_compose() + ->has_request_data()); + EXPECT_TRUE(log_entry.get() + ->log_ai_data_request() + ->mutable_compose() + ->has_response_data()); + run_loop->Quit(); + }, + &run_loop)); identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( "access_token", base::Time::Max()); EXPECT_TRUE(SimulateSuccessfulResponse()); @@ -178,12 +193,12 @@ auto session = model_execution_manager()->StartSession( proto::MODEL_EXECUTION_FEATURE_COMPOSE); // Message is added through AddContext(). - TestMessage test_message; - test_message.set_test("some test"); - session->AddContext(test_message); + proto::ComposeRequest request; + request.set_user_input("some test"); + session->AddContext(request); // ExecuteModel() uses empty message. session->ExecuteModel( - TestMessage(), + proto::ComposeRequest(), base::BindRepeating( [](base::RunLoop* run_loop, OptimizationGuideModelStreamingExecutionResult result, @@ -205,15 +220,14 @@ "test_email", signin::ConsentLevel::kSignin); auto session = model_execution_manager()->StartSession( proto::MODEL_EXECUTION_FEATURE_COMPOSE); - TestMessage test_message; - test_message.set_test("first test"); - session->AddContext(test_message); - - test_message.set_test("second test"); - session->AddContext(test_message); + proto::ComposeRequest request; + request.set_user_input("first test"); + session->AddContext(request); + request.set_user_input("second test"); + session->AddContext(request); // ExecuteModel() uses empty message. session->ExecuteModel( - TestMessage(), + proto::ComposeRequest(), base::BindRepeating( [](base::RunLoop* run_loop, OptimizationGuideModelStreamingExecutionResult result, @@ -236,20 +250,19 @@ auto session = model_execution_manager()->StartSession( proto::MODEL_EXECUTION_FEATURE_COMPOSE); // First message is added through AddContext(). - TestMessage test_message; - test_message.set_test("some test"); - session->AddContext(test_message); + proto::ComposeRequest request; + request.set_user_input("test_message"); + session->AddContext(request); // ExecuteModel() adds a different message. - test_message.set_test("other test"); + request.set_user_input("other test"); session->ExecuteModel( - test_message, - base::BindRepeating( - [](base::RunLoop* run_loop, - OptimizationGuideModelStreamingExecutionResult result, - std::unique_ptr<ModelQualityLogEntry> log_entry) { - run_loop->Quit(); - }, - &run_loop)); + request, base::BindRepeating( + [](base::RunLoop* run_loop, + OptimizationGuideModelStreamingExecutionResult result, + std::unique_ptr<ModelQualityLogEntry> log_entry) { + run_loop->Quit(); + }, + &run_loop)); identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( "access_token", base::Time::Max()); CheckPendingRequestMessage("other test");
diff --git a/components/optimization_guide/core/model_quality/model_quality_log_entry.h b/components/optimization_guide/core/model_quality/model_quality_log_entry.h index a13e459c..861d0311 100644 --- a/components/optimization_guide/core/model_quality/model_quality_log_entry.h +++ b/components/optimization_guide/core/model_quality/model_quality_log_entry.h
@@ -30,6 +30,10 @@ ->mutable_quality_data(); } + proto::LogAiDataRequest* log_ai_data_request() { + return log_ai_data_request_.get(); + } + private: // Holds feature's model execution and quality data. std::unique_ptr<proto::LogAiDataRequest> log_ai_data_request_;
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal index f4ab40f..192f7a24 160000 --- a/components/optimization_guide/internal +++ b/components/optimization_guide/internal
@@ -1 +1 @@ -Subproject commit f4ab40f18a91c5c4ff2ac0149c4c4914bd00e661 +Subproject commit 192f7a242f1e6348842c261e22dd50852cde0885
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc index 78d5ae7..ca1d90b 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "components/page_load_metrics/renderer/page_timing_metrics_sender.h" @@ -92,9 +93,41 @@ // to legacy IPC messages. mojo::AssociatedRemote<mojom::PageLoadMetrics> page_load_metrics_; }; - } // namespace +namespace internal { +void RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + base::TimeDelta start_time_relative_to_reference, + double nav_start_to_reference) { + if (start_time_relative_to_reference.is_zero()) { + if (nav_start_to_reference == 0) { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromStartInvalidTiming, + SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsZeroAndEqNavStart); + } else { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromStartInvalidTiming, + SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsZeroAndLtNavStart); + } + } else { + if (start_time_relative_to_reference.InSecondsF() < + nav_start_to_reference) { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromStartInvalidTiming, + SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsNonZeroAndLtNavStart); + } else { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromStartInvalidTiming, + SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsNonZeroAndEqNavStart); + } + } +} +} // namespace internal + MetricsRenderFrameObserver::MetricsRenderFrameObserver( content::RenderFrame* render_frame) : content::RenderFrameObserver(render_frame), @@ -168,12 +201,21 @@ render_frame()->GetWebFrame()->PerformanceMetricsForReporting(); // Make soft navigation start time relative to navigation start. + base::TimeDelta start_time_relative_to_reference = + soft_nav_metrics.start_time; soft_nav_metrics.start_time = CreateTimeDeltaFromTimestampsInSeconds( soft_nav_metrics.start_time.InSecondsF(), metrics.NavigationStart()); // TODO(crbug.com/1489583): Avoid a crash here, while further investigating // its causes. if (soft_nav_metrics.start_time.is_zero()) { + // When soft navigation start time relative to navigation start is 0, the + // soft navigation start time relative to reference time is either less or + // equal to the navigation start. We also want to know if the start time + // relative to reference time itself is 0. That gives 4 scenarios. + internal:: + RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + start_time_relative_to_reference, metrics.NavigationStart()); return; }
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.h b/components/page_load_metrics/renderer/metrics_render_frame_observer.h index be56b63..42c8fa3 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer.h +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.h
@@ -35,6 +35,31 @@ namespace page_load_metrics { +namespace internal { +const char kPageLoadInternalSoftNavigationFromStartInvalidTiming[] = + "PageLoad.Internal.SoftNavigationFromStartInvalidTiming"; + +// These values are recorded into a UMA histogram as scenarios where the start +// time of soft navigation ends up being 0. These entries +// should not be renumbered and the numeric values should not be reused. These +// entries should be kept in sync with the definition in +// tools/metrics/histograms/enums.xml +// TODO(crbug.com/1489583): Remove the code here and related code once the bug +// is resolved. +enum class SoftNavigationFromStartInvalidTimingReasons { + kSoftNavStartTimeIsZeroAndLtNavStart = 0, + kSoftNavStartTimeIsZeroAndEqNavStart = 1, + kSoftNavStartTimeIsNonZeroAndEqNavStart = 2, + kSoftNavStartTimeIsNonZeroAndLtNavStart = 3, + kMaxValue = kSoftNavStartTimeIsNonZeroAndLtNavStart, +}; + +void RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + base::TimeDelta start_time_relative_to_reference, + double nav_start_to_reference); + +} // namespace internal + class PageTimingMetricsSender; class PageTimingSender;
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc index 72ce83c..3b02f222 100644 --- a/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc +++ b/components/page_load_metrics/renderer/metrics_render_frame_observer_unittest.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" #include "base/timer/mock_timer.h" #include "components/page_load_metrics/common/page_load_metrics.mojom-forward.h" @@ -322,4 +323,60 @@ observer.GetMockTimer()->Fire(); } +using MetricsRenderFrameObserverUmaHistogramTest = + MetricsRenderFrameObserverTest; + +TEST_F(MetricsRenderFrameObserverUmaHistogramTest, UmaHistogram) { + base::HistogramTester histogram_tester; + + // Test the case where both timings are 0. + base::TimeDelta start_time_relative_to_reference = base::TimeDelta(); + double nav_start_relative_to_reference = 0; + internal::RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + start_time_relative_to_reference, nav_start_relative_to_reference); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromStartInvalidTiming, + internal::SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsZeroAndEqNavStart, + 1); + + // Test the case where the start time is 0 and navigation start is non 0. + start_time_relative_to_reference = base::TimeDelta(); + nav_start_relative_to_reference = 1.0; + internal::RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + start_time_relative_to_reference, nav_start_relative_to_reference); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromStartInvalidTiming, + internal::SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsZeroAndLtNavStart, + 1); + + // Test the case where both timings are non 0 and they are equal. + start_time_relative_to_reference = base::TimeDelta() + base::Seconds(1); + nav_start_relative_to_reference = 1.0; + internal::RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + start_time_relative_to_reference, nav_start_relative_to_reference); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromStartInvalidTiming, + internal::SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsNonZeroAndEqNavStart, + 1); + + // Test the case where both timings are non 0 and the start time is less than + // the navigation start. + start_time_relative_to_reference = base::TimeDelta() + base::Seconds(1); + nav_start_relative_to_reference = 2.0; + internal::RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming( + start_time_relative_to_reference, nav_start_relative_to_reference); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromStartInvalidTiming, + internal::SoftNavigationFromStartInvalidTimingReasons:: + kSoftNavStartTimeIsNonZeroAndLtNavStart, + 1); +} + } // namespace page_load_metrics
diff --git a/components/password_manager/core/browser/features/password_features.cc b/components/password_manager/core/browser/features/password_features.cc index 05399afe..1dcd595 100644 --- a/components/password_manager/core/browser/features/password_features.cc +++ b/components/password_manager/core/browser/features/password_features.cc
@@ -8,14 +8,6 @@ namespace password_manager::features { -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) -// Enables attaching password manager and autofill internals logs to an Autofill -// Rater Extension Report. -BASE_FEATURE(kAttachLogsToAutofillRaterExtensionReport, - "AttachLogsToAutofillRaterExtensionReport", - base::FEATURE_DISABLED_BY_DEFAULT); -#endif - // When enabled, updates to shared existing passwords from the same sender are // auto-approved. BASE_FEATURE(kAutoApproveSharedPasswordUpdatesFromSameSender,
diff --git a/components/password_manager/core/browser/features/password_features.h b/components/password_manager/core/browser/features/password_features.h index 9ce896e..44dba81 100644 --- a/components/password_manager/core/browser/features/password_features.h +++ b/components/password_manager/core/browser/features/password_features.h
@@ -15,10 +15,6 @@ // All features in alphabetical order. The features should be documented // alongside the definition of their values in the .cc file. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) -BASE_DECLARE_FEATURE(kAttachLogsToAutofillRaterExtensionReport); -#endif - BASE_DECLARE_FEATURE(kAutoApproveSharedPasswordUpdatesFromSameSender); BASE_DECLARE_FEATURE(kBiometricTouchToFill); BASE_DECLARE_FEATURE(kClearUndecryptablePasswordsOnSync);
diff --git a/components/permissions/features.cc b/components/permissions/features.cc index 4e062232..ab72703 100644 --- a/components/permissions/features.cc +++ b/components/permissions/features.cc
@@ -40,10 +40,6 @@ "BlockRepeatedNotificationPermissionPrompts", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kPermissionElement, - "PermissionElement", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kNotificationInteractionHistory, "NotificationInteractionHistory", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/permissions/features.h b/components/permissions/features.h index 3e582527b..175cd2b 100644 --- a/components/permissions/features.h +++ b/components/permissions/features.h
@@ -29,9 +29,6 @@ BASE_DECLARE_FEATURE(kBlockRepeatedNotificationPermissionPrompts); COMPONENT_EXPORT(PERMISSIONS_COMMON) -BASE_DECLARE_FEATURE(kPermissionElement); - -COMPONENT_EXPORT(PERMISSIONS_COMMON) BASE_DECLARE_FEATURE(kNotificationInteractionHistory); COMPONENT_EXPORT(PERMISSIONS_COMMON)
diff --git a/components/permissions/pepc_initiated_permission_request_unittest.cc b/components/permissions/pepc_initiated_permission_request_unittest.cc index 92793f3c..7f81f9665 100644 --- a/components/permissions/pepc_initiated_permission_request_unittest.cc +++ b/components/permissions/pepc_initiated_permission_request_unittest.cc
@@ -7,7 +7,6 @@ #include "base/test/scoped_feature_list.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" -#include "components/permissions/features.h" #include "components/permissions/permission_context_base.h" #include "components/permissions/permissions_client.h" #include "components/permissions/test/mock_permission_prompt_factory.h" @@ -16,6 +15,7 @@ #include "components/permissions/test/test_permissions_client.h" #include "content/public/browser/permission_controller_delegate.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/common/content_features.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/render_frame_host_test_support.h" #include "content/public/test/test_browser_context.h"
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index dd41ac6..4df17c1 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -325,12 +325,15 @@ SetClientId(client_id); + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_REGISTRATION, this); + params.oauth_token = oauth_token; + params.callback = base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, + weak_ptr_factory_.GetWeakPtr()); + params.profile_id = profile_id_; + std::unique_ptr<RegistrationJobConfiguration> config = - std::make_unique<RegistrationJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_REGISTRATION, this, - DMAuth::NoAuth(), oauth_token, - base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, - weak_ptr_factory_.GetWeakPtr())); + std::make_unique<RegistrationJobConfiguration>(std::move(params)); em::DeviceRegisterRequest* request = config->request()->mutable_register_request(); @@ -390,13 +393,14 @@ SetClientId(client_id); + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_TOKEN_ENROLLMENT, this); + params.auth_data = DMAuth::FromEnrollmentToken(token); + params.callback = base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, + weak_ptr_factory_.GetWeakPtr()); + std::unique_ptr<RegistrationJobConfiguration> config = - std::make_unique<RegistrationJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_TOKEN_ENROLLMENT, - this, DMAuth::FromEnrollmentToken(token), - /*oauth_token=*/absl::nullopt, - base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, - weak_ptr_factory_.GetWeakPtr())); + std::make_unique<RegistrationJobConfiguration>(std::move(params)); // sets CBCM enrollment timeout to 30 seconds when CBCM enrollment is optional if (!is_mandatory) { @@ -423,13 +427,14 @@ return; } - std::unique_ptr<RegistrationJobConfiguration> config = std::make_unique< - RegistrationJobConfiguration>( + auto params = DMServerJobConfiguration::CreateParams::WithClient( DeviceManagementService::JobConfiguration::TYPE_CERT_BASED_REGISTRATION, - this, DMAuth::NoAuth(), - /*oauth_token=*/absl::nullopt, - base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, - weak_ptr_factory_.GetWeakPtr())); + this); + params.callback = base::BindOnce(&CloudPolicyClient::OnRegisterCompleted, + weak_ptr_factory_.GetWeakPtr()); + + std::unique_ptr<RegistrationJobConfiguration> config = + std::make_unique<RegistrationJobConfiguration>(std::move(params)); em::SignedData* signed_request = config->request() @@ -468,13 +473,15 @@ VLOG_POLICY(2, POLICY_FETCHING) << "Fetching policy type: " << type.first << " -> " << type.second; } + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_POLICY_FETCH, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.oauth_token = oauth_token_; + params.profile_id = profile_id_; + params.callback = base::BindOnce(&CloudPolicyClient::OnPolicyFetchCompleted, + weak_ptr_factory_.GetWeakPtr()); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_POLICY_FETCH, this, - /*critical=*/true, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/oauth_token_, - base::BindOnce(&CloudPolicyClient::OnPolicyFetchCompleted, - weak_ptr_factory_.GetWeakPtr())); + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::DeviceManagementRequest* request = config->request(); @@ -586,12 +593,15 @@ CHECK(is_registered()); DCHECK(auth.has_dm_token()); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_API_AUTH_CODE_FETCH, this, - /*critical=*/false, std::move(auth), - /*oauth_token=*/absl::nullopt, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_API_AUTH_CODE_FETCH, + this); + params.auth_data = std::move(auth); + params.callback = base::BindOnce(&CloudPolicyClient::OnFetchRobotAuthCodesCompleted, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::DeviceServiceApiAccessRequest* request = config->request()->mutable_service_api_access_request(); @@ -656,11 +666,15 @@ return; } - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_UPLOAD_STATUS, this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), oauth_token_, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_UPLOAD_STATUS, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.oauth_token = oauth_token_; + params.callback = base::BindOnce(&CloudPolicyClient::OnReportUploadCompleted, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::DeviceManagementRequest* request = config->request(); if (device_status) { @@ -829,12 +843,15 @@ // Unsigned commands and NONE signature are not supported. DCHECK_NE(signature_type, em::PolicyFetchRequest::NONE); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_REMOTE_COMMANDS, this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_REMOTE_COMMANDS, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.profile_id = profile_id_; + params.callback = base::BindOnce(&CloudPolicyClient::OnRemoteCommandsFetched, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::DeviceRemoteCommandRequest* const request = config->request()->mutable_remote_command_request(); @@ -877,18 +894,22 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(is_registered()); DCHECK(auth.has_oauth_token() || auth.has_dm_token()); - const bool has_oauth_token = auth.has_oauth_token(); - const std::string oauth_token = - has_oauth_token ? auth.oauth_token() : std::string(); - auto config = std::make_unique<DMServerJobConfiguration>( + + auto params = DMServerJobConfiguration::CreateParams::WithClient( DeviceManagementService::JobConfiguration:: TYPE_ATTRIBUTE_UPDATE_PERMISSION, - this, - /*critical=*/false, !has_oauth_token ? auth.Clone() : DMAuth::NoAuth(), - oauth_token, - base::BindOnce( - &CloudPolicyClient::OnDeviceAttributeUpdatePermissionCompleted, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + this); + if (auth.has_oauth_token()) { + params.oauth_token = auth.oauth_token(); + } else { + params.auth_data = auth.Clone(); + params.oauth_token = std::string(); + } + params.callback = base::BindOnce( + &CloudPolicyClient::OnDeviceAttributeUpdatePermissionCompleted, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); config->request()->mutable_device_attribute_update_permission_request(); @@ -904,15 +925,19 @@ CHECK(is_registered()); DCHECK(auth.has_oauth_token() || auth.has_dm_token()); - const bool has_oauth_token = auth.has_oauth_token(); - const std::string oauth_token = - has_oauth_token ? auth.oauth_token() : std::string(); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_ATTRIBUTE_UPDATE, this, - /*critical=*/false, !has_oauth_token ? auth.Clone() : DMAuth::NoAuth(), - oauth_token, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_ATTRIBUTE_UPDATE, this); + if (auth.has_oauth_token()) { + params.oauth_token = auth.oauth_token(); + } else { + params.auth_data = auth.Clone(); + params.oauth_token = std::string(); + } + params.callback = base::BindOnce(&CloudPolicyClient::OnDeviceAttributeUpdated, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::DeviceAttributeUpdateRequest* request = config->request()->mutable_device_attribute_update_request(); @@ -929,12 +954,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(is_registered()); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_GCM_ID_UPDATE, this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_GCM_ID_UPDATE, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.callback = base::BindOnce(&CloudPolicyClient::OnGcmIdUpdated, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); em::GcmIdUpdateRequest* const request = config->request()->mutable_gcm_id_update_request(); @@ -950,13 +976,13 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(is_registered()); - auto config = std::make_unique<DMServerJobConfiguration>( - DeviceManagementService::JobConfiguration::TYPE_UPLOAD_EUICC_INFO, - /*client=*/this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_UPLOAD_EUICC_INFO, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.callback = base::BindOnce(&CloudPolicyClient::OnEuiccInfoUploaded, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); config->request()->set_allocated_upload_euicc_info_request(request.release()); request_jobs_.push_back(service_->CreateJob(std::move(config))); @@ -983,15 +1009,15 @@ request.set_device_dm_token(device_dm_token_); } - std::unique_ptr<DMServerJobConfiguration> config = std::make_unique< - DMServerJobConfiguration>( + auto params = DMServerJobConfiguration::CreateParams::WithClient( DeviceManagementService::JobConfiguration::TYPE_CERT_PROVISIONING_REQUEST, - this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, - base::BindOnce( - &CloudPolicyClient::OnClientCertProvisioningRequestResponse, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + + params.callback = base::BindOnce( + &CloudPolicyClient::OnClientCertProvisioningRequestResponse, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + auto config = std::make_unique<DMServerJobConfiguration>(std::move(params)); *config->request()->mutable_client_certificate_provisioning_request() = std::move(request); @@ -1096,26 +1122,27 @@ CloudPolicyClient::CreateCertUploadJobConfiguration( CloudPolicyClient::ResultCallback callback) { CHECK(is_registered()); - return std::make_unique<DMServerJobConfiguration>( - service_, - DeviceManagementService::JobConfiguration::TYPE_UPLOAD_CERTIFICATE, - client_id(), - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, GetURLLoaderFactory(), + auto params = DMServerJobConfiguration::CreateParams::WithClient( + DeviceManagementService::JobConfiguration::TYPE_UPLOAD_CERTIFICATE, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.callback = base::BindOnce(&CloudPolicyClient::OnCertificateUploadCompleted, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + return std::make_unique<DMServerJobConfiguration>(std::move(params)); } std::unique_ptr<DMServerJobConfiguration> CloudPolicyClient::CreateReportUploadJobConfiguration( DeviceManagementService::JobConfiguration::JobType type, CloudPolicyClient::ResultCallback callback) { - return std::make_unique<DMServerJobConfiguration>( - type, this, - /*critical=*/false, DMAuth::FromDMToken(dm_token_), - /*oauth_token=*/absl::nullopt, + auto params = DMServerJobConfiguration::CreateParams::WithClient(type, this); + params.auth_data = DMAuth::FromDMToken(dm_token_); + params.profile_id = profile_id_; + params.callback = base::BindOnce(&CloudPolicyClient::OnReportUploadCompleted, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + return std::make_unique<DMServerJobConfiguration>(std::move(params)); } void CloudPolicyClient::ExecuteCertUploadJob(
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index b867717..1e6f6930 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -705,6 +705,7 @@ std::unique_ptr<base::Value::Dict> configuration_seed_; DeviceMode device_mode_ = DEVICE_MODE_NOT_SET; std::string client_id_; + absl::optional<std::string> profile_id_; base::Time last_policy_timestamp_; int public_key_version_ = -1; bool public_key_version_valid_ = false;
diff --git a/components/policy/core/common/cloud/dmserver_job_configurations.cc b/components/policy/core/common/cloud/dmserver_job_configurations.cc index 40d9d788..1136770 100644 --- a/components/policy/core/common/cloud/dmserver_job_configurations.cc +++ b/components/policy/core/common/cloud/dmserver_job_configurations.cc
@@ -360,18 +360,8 @@ return url; } -RegistrationJobConfiguration::RegistrationJobConfiguration( - JobType type, - CloudPolicyClient* client, - DMAuth auth_data, - absl::optional<std::string>&& oauth_token, - Callback callback) - : DMServerJobConfiguration(type, - client, - /*critical=*/false, - std::move(auth_data), - std::move(oauth_token), - std::move(callback)) {} +RegistrationJobConfiguration::RegistrationJobConfiguration(CreateParams params) + : DMServerJobConfiguration(std::move(params)) {} void RegistrationJobConfiguration::SetTimeoutDuration(base::TimeDelta timeout) { timeout_ = timeout;
diff --git a/components/policy/core/common/cloud/dmserver_job_configurations.h b/components/policy/core/common/cloud/dmserver_job_configurations.h index c6568d00..774eec4a 100644 --- a/components/policy/core/common/cloud/dmserver_job_configurations.h +++ b/components/policy/core/common/cloud/dmserver_job_configurations.h
@@ -159,11 +159,7 @@ class POLICY_EXPORT RegistrationJobConfiguration : public DMServerJobConfiguration { public: - RegistrationJobConfiguration(JobType type, - CloudPolicyClient* client, - DMAuth auth_data, - absl::optional<std::string>&& oauth_token, - Callback callback); + explicit RegistrationJobConfiguration(CreateParams params); RegistrationJobConfiguration(const RegistrationJobConfiguration&) = delete; RegistrationJobConfiguration& operator=(const RegistrationJobConfiguration&) = delete;
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index 7f84014..0006bbf 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -1182,6 +1182,7 @@ 1181: NativeHostsExecutablesLaunchDirectly 1182: FeedbackSurveysEnabled 1183: DeskAPIDeskSaveAndShareEnabled + 1184: OopPrintDriversAllowed atomic_groups: 1: Homepage 2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/Printing/OopPrintDriversAllowed.yaml b/components/policy/resources/templates/policy_definitions/Printing/OopPrintDriversAllowed.yaml new file mode 100644 index 0000000..df670d0 --- /dev/null +++ b/components/policy/resources/templates/policy_definitions/Printing/OopPrintDriversAllowed.yaml
@@ -0,0 +1,30 @@ +caption: Out-of-process print drivers allowed +default: true +desc: |- + Controls if <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> interacts with printer drivers from a separate service process. Platform printing calls to query available printers, get print driver settings, and submit documents for printing to local printers are made from a service process. Moving such calls out of the browser process helps improve stability and reduce frozen UI behavior in Print Preview. + + When this policy is set to Enabled or not set, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use a separate service process for platform printing tasks. + + When this policy is set to Disabled, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the browser process for platform printing tasks. + + This policy will be removed in the future, after the out-of-process print drivers feature has fully rolled out. +example_value: true +features: + dynamic_refresh: false + per_profile: false +future_on: +- chrome_os +items: +- caption: Platform printing uses service process. + value: true +- caption: Platform printing from browser process. + value: false +owners: +- awscreen@chromium.org +- file://printing/OWNERS +schema: + type: boolean +supported_on: +- chrome.*:120- +tags: [] +type: main \ No newline at end of file
diff --git a/components/policy/test/data/pref_mapping/OopPrintDriversAllowed.json b/components/policy/test/data/pref_mapping/OopPrintDriversAllowed.json new file mode 100644 index 0000000..2e62427 --- /dev/null +++ b/components/policy/test/data/pref_mapping/OopPrintDriversAllowed.json
@@ -0,0 +1,35 @@ +[ + { + "os": [ + "chromeos_ash", + "chromeos_lacros", + "linux", + "mac", + "win" + ], + "policy_pref_mapping_tests": [ + { + "policies": { + "OopPrintDriversAllowed": false + }, + "prefs": { + "printing.oop_print_drivers_allowed_by_policy": { + "location": "local_state", + "value": false + } + } + }, + { + "policies": { + "OopPrintDriversAllowed": true + }, + "prefs": { + "printing.oop_print_drivers_allowed_by_policy": { + "location": "local_state", + "value": true + } + } + } + ] + } +]
diff --git a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc index 76e9a8f..05467633d 100644 --- a/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc +++ b/components/safe_browsing/core/browser/realtime/url_lookup_service_base.cc
@@ -148,8 +148,6 @@ if (VerdictCacheManager::has_artificial_cached_url()) { return true; } - base::UmaHistogramBoolean("SafeBrowsing.RT.CannotCheckInvalidUrl", - !url.is_valid()); return CanGetReputationOfUrl(url); }
diff --git a/components/search_engines/search_engine_choice_utils.h b/components/search_engines/search_engine_choice_utils.h index ce9dbe8b..a8107cd3 100644 --- a/components/search_engines/search_engine_choice_utils.h +++ b/components/search_engines/search_engine_choice_utils.h
@@ -81,6 +81,8 @@ // Profile properties that need to be passed to // `ShouldShowChoiceScreen`. This is due to the fact that // the 'Profile' class is different between platforms. +// TODO(b/312115939): Rename `is_regular_profile` to something like +// `is_eligible_profile`. struct ProfileProperties { bool is_regular_profile = false; raw_ptr<PrefService> pref_service;
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb index bfd126a4..92b37055 100644 --- a/components/strings/components_strings_fil.xtb +++ b/components/strings/components_strings_fil.xtb
@@ -75,6 +75,7 @@ <translation id="1142713751288681188">Uri ng papel</translation> <translation id="1142846828089312304">I-block ang third party na cookies sa Incognito</translation> <translation id="1147769322402934017">Mga online na gallery ng larawan</translation> +<translation id="1149617035358809955">i-verify na ikaw ito para mapunan nito ang iyong impormasyon sa pagbabayad</translation> <translation id="1150565364351027703">Sunglasses</translation> <translation id="1150979032973867961">Hindi mapatunayan ng server na ito na ito ay <ph name="DOMAIN" />; hindi pinagkakatiwalaan ng operating system ng iyong computer ang certificate ng seguridad nito. Maaaring dulot ito ng maling configuration o isang umaatake na hinahadlangan ang iyong koneksyon.</translation> <translation id="1151972924205500581">Kinakailangan ang password</translation> @@ -93,6 +94,7 @@ <translation id="1175364870820465910">&I-print...</translation> <translation id="1175393348063009671">Photo (Matte)</translation> <translation id="1175875016430184367">Triple staple right</translation> +<translation id="1177548198167638471">Huwag nang Itanong Ulit</translation> <translation id="1177802847690410663">Mga web browser</translation> <translation id="1177863135347784049">Custom</translation> <translation id="1178581264944972037">I-pause</translation> @@ -355,6 +357,7 @@ <translation id="1645368109819982629">Hindi sinusuportahang protocol</translation> <translation id="1650602712345345441">Pamahalaan ang iyong mga setting ng Chrome</translation> <translation id="1652415888492971589">JIS B8</translation> +<translation id="1652862280638399816">Para magamit ang Password Manager sa macOS Keychain, ilunsad ulit ang Chromium at payagan ang access sa Keychain. Bubukas ulit ang iyong mga tab pagkatapos malunsad ulit.</translation> <translation id="1656024727720460136">Pinasimple ng Chrome ang page na ito para mas madali itong mabasa. Nakuha ng Chrome ang orihinal na page sa pamamagitan ng secure na koneksyon.</translation> <translation id="1656489000284462475">I-pick up</translation> <translation id="1658111267661135323">TV at Video</translation> @@ -988,6 +991,7 @@ <translation id="2991174974383378012">Pagbabahagi sa Mga Website</translation> <translation id="299122504639061328">Pamahalaan ang iyong default na search engine at site search</translation> <translation id="2991571918955627853">Hindi mo maaaring bisitahin ang <ph name="SITE" /> sa ngayon dahil gumagamit ng HSTS ang website. Karaniwang pansamantala lang ang mga error at pag-atake sa network, kaya malamang na gagana ang page na ito sa ibang pagkakataon.</translation> +<translation id="2991865971341174470">I-verify na ikaw ito para mapunan ng Chrome ang iyong impormasyon sa pagbabayad.</translation> <translation id="2995517112308048736">Laki ng file:</translation> <translation id="299990983510665749">Mga hatchback</translation> <translation id="3002501248619246229">Suriin ang input tray media</translation> @@ -1363,6 +1367,7 @@ <translation id="3723663469265383848">Habang ina-update, hindi mo magagamit ang iyong device sa loob ng hanggang 10 minuto.</translation> <translation id="372429172604983730">Kabilang ang antivirus, firewall, at pag-filter ng web o proxy na software sa mga application na maaaring magsanhi ng ganitong error.</translation> <translation id="3727101516080730231"><ph name="CREATE_GOOGLE_SLIDE_FOCUSED_FRIENDLY_MATCH_TEXT" />, pindutin ang Tab at pagkatapos ay ang Enter para gumawa ng bagong Google presentation sa Slides nang mabilis</translation> +<translation id="3727850735097852673">Para magamit ang Google Password Manager sa macOS Keychain, ilunsad ulit ang Chrome at payagan ang access sa Keychain. Bubukas ulit ang iyong mga tab pagkatapos malunsad ulit.</translation> <translation id="3733139489341305600">Mga autonomous na sasakyan</translation> <translation id="3736520371357197498">Kung nauunawaan mo ang mga peligro sa iyong seguridad, maaari mong <ph name="BEGIN_LINK" />bisitahin ang hindi ligtas na site na ito<ph name="END_LINK" /> bago maalis ang mga mapanganib na program.</translation> <translation id="3736739313435669994">Na-block mo ang mga site sa paggamit ng mga third-party na cookies para ma-track ka habang nagba-browse ka. Bisitahin ang mga setting para <ph name="LINK" />.</translation> @@ -1405,6 +1410,7 @@ <translation id="3807270098669886186">Mga service provider sa telepono</translation> <translation id="3807366285948165054">Pag-shift ng larawan X</translation> <translation id="3807873520724684969">Na-block ang mapaminsalang content.</translation> +<translation id="3810770279996899697">Kailangan ng Password Manager ng access sa MacOS Keychain</translation> <translation id="3810973564298564668">Pamahalaan</translation> <translation id="3812398568375898177">Isa itong mahalagang update na nagpapahusay ng performance ng mga Android app sa ChromeOS.</translation> <translation id="3815434930383843058">8 x 12 in</translation> @@ -2641,6 +2647,7 @@ <translation id="6349101878882523185">I-install ang <ph name="APP_NAME" /></translation> <translation id="6353505687280762741">{COUNT,plural, =0{Wala}=1{1 password (para sa <ph name="DOMAIN_LIST" />, naka-sync)}=2{2 password (para sa <ph name="DOMAIN_LIST" />, naka-sync)}one{# password (para sa <ph name="DOMAIN_LIST" />, naka-sync)}other{# na password (para sa <ph name="DOMAIN_LIST" />, naka-sync)}}</translation> <translation id="6355392890578844978">Hindi pinapamahalaan ng kumpanya o iba pang organisasyon ang browser na ito. Posibleng pinapamahalaan sa labas ng Chromium ang aktibidad sa device na ito. <ph name="BEGIN_LINK" />Matuto pa<ph name="END_LINK" /></translation> +<translation id="6358088212770985041">i-edit ang mga paraan ng pagbabayad</translation> <translation id="6358450015545214790">Ano ang ibig sabihin ng mga ito?</translation> <translation id="6361757823711327522">B7</translation> <translation id="6363786367719063276">Tingnan ang mga log</translation> @@ -2849,6 +2856,7 @@ <translation id="6767985426384634228">I-update ang Address?</translation> <translation id="6770747695101757579">Papel (Cotton)</translation> <translation id="6775759552199460396">JIS B2</translation> +<translation id="6779348349813025131">Kailangan ng Google Password Manager ng access sa MacOS Keychain</translation> <translation id="6784045420901191374">Komersyal na pagpapautang</translation> <translation id="6785990323398321538">Puwede mong palitan ang iyong search engine anumang oras sa mga setting ng Chrome.</translation> <translation id="6786145470008421571">Envelope 6 x 9 in</translation> @@ -2989,6 +2997,7 @@ <translation id="7023162328967545559">Babala ng admin</translation> <translation id="7024932305105294144">May mga built-in na feature na pangkaligtasan ang Chrome para maprotektahan ka habang nagba-browse ka — tulad ng Ligtas na Pag-browse sa Google na <ph name="BEGIN_LINK" />nakakita kamakailan ng phishing<ph name="END_LINK" /> sa site na sinusubukan mong bisitahin. Nagpapanggap ang mga phisihing site bilang ibang site para linlangin ka.<ph name="NEW_LINE" />Kung minsan, nakokompromiso ng mga attacker pati ang mga site na karaniwang ligtas. <ph name="BEGIN_ERROR_LINK" />Ipaalam sa amin<ph name="END_ERROR_LINK" /> kung sa palagay mo ay isa itong pagkakamali at hindi mapanganib ang site na ito.</translation> <translation id="7029809446516969842">Mga Password</translation> +<translation id="7030164307377592766">baguhin ang mga setting para sa paglalagay ng mga paraan ng pagbabayad</translation> <translation id="7030436163253143341">Hindi valid ang certificate</translation> <translation id="7031646650991750659">Aling mga Google Play app ang na-install mo</translation> <translation id="7038063300915481831"><ph name="MANAGE_GOOGLE_PRIVACY_FOCUSED_FRIENDLY_MATCH_TEXT" />, Pindutin ang Tab at pagkatapos ay ang Enter para pamahalaan ang mga setting ng privacy ng iyong Google Account</translation> @@ -3799,6 +3808,7 @@ <translation id="8555010941760982128">Gamitin ang code na ito kapag nag-checkout</translation> <translation id="8556297087315686325">Pagsubaybay at Pamamahala sa Network</translation> <translation id="8557066899867184262">Makikita ang CVC sa likod ng iyong card.</translation> +<translation id="8557412555245662180">Matuto pa tungkol sa Proteksyon sa Pag-track</translation> <translation id="8558347880669160417">Pinapayagan ang camera at mikropono sa ngayon</translation> <translation id="8559762987265718583">Hindi makapagtatag ng pribadong koneksyon sa <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> dahil mali ang petsa at oras ng iyong device (<ph name="DATE_AND_TIME" />).</translation> <translation id="8564182942834072828">Mga hiwalay na dokumento/Mga hindi naka-collate na kopya</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb index 6fdbd0f..2da75b7 100644 --- a/components/strings/components_strings_ms.xtb +++ b/components/strings/components_strings_ms.xtb
@@ -75,6 +75,7 @@ <translation id="1142713751288681188">Jenis kertas</translation> <translation id="1142846828089312304">Sekat kuki pihak ketiga dalam Inkognito</translation> <translation id="1147769322402934017">Imej galeri dalam talian</translation> +<translation id="1149617035358809955">sahkan identiti anda supaya maklumat pembayaran anda boleh diisi</translation> <translation id="1150565364351027703">Cermin mata hitam</translation> <translation id="1150979032973867961">Pelayan ini tidak dapat membuktikan bahawa domainnya ialah <ph name="DOMAIN" />; sijil keselamatannya tidak dipercayai oleh sistem pengendalian komputer anda. Ini mungkin disebabkan oleh kesilapan konfigurasi atau penyerang yang memintasi sambungan anda.</translation> <translation id="1151972924205500581">Kata laluan diperlukan</translation> @@ -93,6 +94,7 @@ <translation id="1175364870820465910">&Cetak...</translation> <translation id="1175393348063009671">Foto (Kusam)</translation> <translation id="1175875016430184367">Tiga kokot kanan</translation> +<translation id="1177548198167638471">Jangan Tanya Lagi</translation> <translation id="1177802847690410663">Penyemak imbas web</translation> <translation id="1177863135347784049">Tersuai</translation> <translation id="1178581264944972037">Jeda</translation> @@ -355,6 +357,7 @@ <translation id="1645368109819982629">Protokol tidak disokong</translation> <translation id="1650602712345345441">Urus tetapan Chrome anda</translation> <translation id="1652415888492971589">JIS B8</translation> +<translation id="1652862280638399816">Untuk menggunakan Password Manager dengan macOS Keychain, lancarkan semula Chromium dan benarkan akses Keychain. Tab anda akan dibuka semula selepas pelancaran semula.</translation> <translation id="1656024727720460136">Chrome meringkaskan halaman ini untuk memudahkan pembacaan. Chrome mengambil halaman asal melalui sambungan selamat.</translation> <translation id="1656489000284462475">Pengambilan</translation> <translation id="1658111267661135323">TV & Video</translation> @@ -988,6 +991,7 @@ <translation id="2991174974383378012">Berkongsi dengan Tapak Web</translation> <translation id="299122504639061328">Urus enjin carian lalai dan carian laman anda</translation> <translation id="2991571918955627853">Anda tidak boleh melawati <ph name="SITE" /> sekarang kerana laman web ini menggunakan HSTS. Ralat dan serangan rangkaian biasanya sementara. Oleh sebab itu, halaman ini mungkin akan berfungsi semula kemudian.</translation> +<translation id="2991865971341174470">Sahkan identiti anda supaya maklumat pembayaran anda boleh diisikan oleh Chrome.</translation> <translation id="2995517112308048736">Saiz fail:</translation> <translation id="299990983510665749">Kereta hatchback</translation> <translation id="3002501248619246229">Semak media dulang input</translation> @@ -1364,6 +1368,7 @@ <translation id="3723663469265383848">Semasa pengemaskinian, anda tidak dapat menggunakan peranti anda hingga 10 minit.</translation> <translation id="372429172604983730">Aplikasi yang boleh menyebabkan ralat ini termasuk antivirus, tembok api dan perisian penapisan web atau proksi.</translation> <translation id="3727101516080730231"><ph name="CREATE_GOOGLE_SLIDE_FOCUSED_FRIENDLY_MATCH_TEXT" />, tekan kekunci Tab kemudian Enter untuk membuat pembentangan Google baharu dalam Slides dengan pantas</translation> +<translation id="3727850735097852673">Untuk menggunakan Google Password Manager dengan macOS Keychain, lancarkan semula Chrome dan benarkan akses Keychain. Tab anda akan dibuka semula selepas pelancaran semula.</translation> <translation id="3733139489341305600">Kenderaan autonomi</translation> <translation id="3736520371357197498">Jika anda memahami risiko terhadap keselamatan anda, anda boleh <ph name="BEGIN_LINK" />melawati laman web yang tidak selamat ini<ph name="END_LINK" /> sebelum program berbahaya dialih keluar.</translation> <translation id="3736739313435669994">Anda menyekat laman daripada menggunakan kuki pihak ketiga untuk menjejaki anda semasa anda menyemak imbas. Lawati tetapan untuk <ph name="LINK" />.</translation> @@ -1406,6 +1411,7 @@ <translation id="3807270098669886186">Pembekal khidmat telefon</translation> <translation id="3807366285948165054">Anjakan X imej</translation> <translation id="3807873520724684969">Kandungan berbahaya disekat.</translation> +<translation id="3810770279996899697">Password Manager memerlukan akses kepada MacOS Keychain</translation> <translation id="3810973564298564668">Urus</translation> <translation id="3812398568375898177">Kemaskinian ini penting kerana meningkatkan prestasi apl Android pada ChromeOS.</translation> <translation id="3815434930383843058">8 x 12 in</translation> @@ -2642,6 +2648,7 @@ <translation id="6349101878882523185">Pasang <ph name="APP_NAME" /></translation> <translation id="6353505687280762741">{COUNT,plural, =0{Tiada}=1{1 kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}=2{2 kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}other{# kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}}</translation> <translation id="6355392890578844978">Penyemak imbas ini tidak diurus oleh syarikat atau organisasi lain. Aktiviti pada peranti ini mungkin diurus di luar Chromium. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> +<translation id="6358088212770985041">edit kaedah pembayaran</translation> <translation id="6358450015545214790">Apakah maksudnya?</translation> <translation id="6361757823711327522">B7</translation> <translation id="6363786367719063276">Lihat log</translation> @@ -2850,6 +2857,7 @@ <translation id="6767985426384634228">Kemas Kini Alamat?</translation> <translation id="6770747695101757579">Keras (Kapas)</translation> <translation id="6775759552199460396">JIS B2</translation> +<translation id="6779348349813025131">Google Password Manager memerlukan akses kepada MacOS Keychain</translation> <translation id="6784045420901191374">Pinjaman komersil</translation> <translation id="6785990323398321538">Anda boleh menukar enjin carian anda pada bila-bila masa dalam tetapan Chrome.</translation> <translation id="6786145470008421571">Sampul 6 x 9 inci</translation> @@ -2990,6 +2998,7 @@ <translation id="7023162328967545559">Amaran pentadbir</translation> <translation id="7024932305105294144">Chrome mengandungi ciri keselamatan terbina dalam untuk melindungi anda semasa menyemak imbas – seperti Penyemakan Imbas Selamat Google yang <ph name="BEGIN_LINK" />baru-baru ini menemukan pancingan data<ph name="END_LINK" /> pada laman yang cuba anda lawati. Laman pancingan data berpura-pura menjadi laman lain untuk memperdaya anda.<ph name="NEW_LINE" />Kadangkala, laman yang biasanya selamat juga terjejas disebabkan penyerang. <ph name="BEGIN_ERROR_LINK" />Beritahu kami<ph name="END_ERROR_LINK" /> jika anda fikir terdapat kesilapan dan laman ini tidak mendatangkan bahaya.</translation> <translation id="7029809446516969842">Kata laluan</translation> +<translation id="7030164307377592766">mengubah suai tetapan untuk pengisian kaedah pembayaran</translation> <translation id="7030436163253143341">Sijil tidak sah</translation> <translation id="7031646650991750659">Apl Google Play yang telah anda pasang</translation> <translation id="7038063300915481831"><ph name="MANAGE_GOOGLE_PRIVACY_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tekan Tab kemudian Enter untuk mengurus tetapan privasi Google Account anda</translation> @@ -3800,6 +3809,7 @@ <translation id="8555010941760982128">Gunakan kod ini semasa semak keluar</translation> <translation id="8556297087315686325">Pemantauan & Pengurusan Rangkaian</translation> <translation id="8557066899867184262">CVC terletak di belakang kad anda.</translation> +<translation id="8557412555245662180">Ketahui lebih lanjut tentang Perlindungan Penjejakan</translation> <translation id="8558347880669160417">Kamera dan mikrofon dibenarkan pada masa ini</translation> <translation id="8559762987265718583">Sambungan peribadi ke <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> tidak boleh diwujudkan kerana tarikh dan masa peranti anda (<ph name="DATE_AND_TIME" />) tidak betul.</translation> <translation id="8564182942834072828">Dokumen berasingan/Salinan berasingan</translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index f32d2b8..0d752a7 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb
@@ -75,6 +75,7 @@ <translation id="1142713751288681188">ประเภทกระดาษ</translation> <translation id="1142846828089312304">บล็อกคุกกี้ของบุคคลที่สามในโหมดไม่ระบุตัวตน</translation> <translation id="1147769322402934017">แกลเลอรีภาพออนไลน์</translation> +<translation id="1149617035358809955">ยืนยันว่าเป็นคุณจริงๆ เพื่อให้ระบบกรอกข้อมูลการชำระเงินได้</translation> <translation id="1150565364351027703">แว่นกันแดด</translation> <translation id="1150979032973867961">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปฏิบัติการของคอมพิวเตอร์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation> <translation id="1151972924205500581">ต้องมีรหัสผ่าน</translation> @@ -93,6 +94,7 @@ <translation id="1175364870820465910">&พิมพ์...</translation> <translation id="1175393348063009671">รูปภาพ (ด้าน)</translation> <translation id="1175875016430184367">เย็บด้วยลวดเย็บกระดาษด้านขวา 3 ครั้ง</translation> +<translation id="1177548198167638471">ไม่ต้องถามอีก</translation> <translation id="1177802847690410663">เว็บเบราว์เซอร์</translation> <translation id="1177863135347784049">ที่กำหนดเอง</translation> <translation id="1178581264944972037">หยุดชั่วคราว</translation> @@ -355,6 +357,7 @@ <translation id="1645368109819982629">ไม่รองรับโปรโตคอล</translation> <translation id="1650602712345345441">จัดการการตั้งค่า Chrome</translation> <translation id="1652415888492971589">JIS B8</translation> +<translation id="1652862280638399816">หากต้องการใช้เครื่องมือจัดการรหัสผ่านกับ Keychain ของ macOS ให้เปิด Chromium อีกครั้งแล้วอนุญาตให้มีการเข้าถึง Keychain แท็บจะเปิดขึ้นมาใหม่หลังจากที่เปิดอีกครั้ง</translation> <translation id="1656024727720460136">Chrome ทำให้หน้านี้อ่านง่ายขึ้น Chrome ดึงข้อมูลหน้าต้นฉบับผ่านการเชื่อมต่อที่ปลอดภัย</translation> <translation id="1656489000284462475">การรับ</translation> <translation id="1658111267661135323">ทีวีและวิดีโอ</translation> @@ -988,6 +991,7 @@ <translation id="2991174974383378012">การแชร์กับเว็บไซต์</translation> <translation id="299122504639061328">จัดการเครื่องมือค้นหาและการค้นหาเว็บไซต์เริ่มต้น</translation> <translation id="2991571918955627853">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจากเว็บไซต์ใช้ HSTS โดยปกติข้อผิดพลาดของเครือข่ายและการโจมตีจะเกิดขึ้นเพียงชั่วคราว หน้านี้จึงอาจใช้งานได้ในภายหลัง</translation> +<translation id="2991865971341174470">ยืนยันว่าเป็นคุณจริงๆ เพื่อให้ Chrome กรอกข้อมูลการชำระเงินได้</translation> <translation id="2995517112308048736">ขนาดไฟล์:</translation> <translation id="299990983510665749">รถยนต์ห้าประตู</translation> <translation id="3002501248619246229">ตรวจสอบสื่อของถาดกระดาษเข้า</translation> @@ -1362,6 +1366,7 @@ <translation id="3723663469265383848">ในระหว่างการอัปเดต คุณจะใช้อุปกรณ์ไม่ได้นานถึง 10 นาที</translation> <translation id="372429172604983730">แอปพลิเคชันที่อาจทำให้เกิดข้อผิดพลาดนี้ ได้แก่ ซอฟต์แวร์ป้องกันไวรัส ซอฟต์แวร์ไฟร์วอลล์ รวมถึงซอฟต์แวร์การกรองเว็บหรือซอฟต์แวร์พร็อกซี</translation> <translation id="3727101516080730231"><ph name="CREATE_GOOGLE_SLIDE_FOCUSED_FRIENDLY_MATCH_TEXT" /> กด Tab ตามด้วย Enter เพื่อสร้างงานนำเสนอใหม่ใน Google สไลด์อย่างรวดเร็ว</translation> +<translation id="3727850735097852673">หากต้องการใช้เครื่องมือจัดการรหัสผ่านบน Google กับ Keychain ของ macOS ให้เปิด Chrome อีกครั้งแล้วอนุญาตให้มีการเข้าถึง Keychain แท็บจะเปิดขึ้นมาใหม่หลังจากที่เปิดอีกครั้ง</translation> <translation id="3733139489341305600">ยานพาหนะแบบไร้คนขับ</translation> <translation id="3736520371357197498">หากคุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์ที่ไม่ปลอดภัยนี้<ph name="END_LINK" /> ก่อนจะมีการนำโปรแกรมอันตรายออก</translation> <translation id="3736739313435669994">คุณบล็อกเว็บไซต์ไม่ให้ใช้คุกกี้ของบุคคลที่สามเพื่อติดตามคุณขณะท่องเว็บ ไปที่การตั้งค่าเพื่อ<ph name="LINK" /></translation> @@ -1404,6 +1409,7 @@ <translation id="3807270098669886186">ผู้ให้บริการโทรศัพท์</translation> <translation id="3807366285948165054">เปลี่ยนตำแหน่งรูปภาพตามแกน X</translation> <translation id="3807873520724684969">บล็อกเนื้อหาอันตรายแล้ว</translation> +<translation id="3810770279996899697">เครื่องมือจัดการรหัสผ่านต้องการสิทธิ์เข้าถึง Keychain ของ MacOS</translation> <translation id="3810973564298564668">จัดการ</translation> <translation id="3812398568375898177">การอัปเดตนี้สำคัญต่อการปรับปรุงประสิทธิภาพของแอป Android ใน ChromeOS</translation> <translation id="3815434930383843058">8 x 12 นิ้ว</translation> @@ -2640,6 +2646,7 @@ <translation id="6349101878882523185">ติดตั้ง <ph name="APP_NAME" /></translation> <translation id="6353505687280762741">{COUNT,plural, =0{ไม่มี}=1{มีรหัสผ่าน 1 รายการ (สำหรับ <ph name="DOMAIN_LIST" />, ซิงค์แล้ว)}=2{มีรหัสผ่าน 2 รายการ (สำหรับ <ph name="DOMAIN_LIST" />, ซิงค์แล้ว)}other{มีรหัสผ่าน # รายการ (สำหรับ <ph name="DOMAIN_LIST" />, ซิงค์แล้ว)}}</translation> <translation id="6355392890578844978">เบราว์เซอร์นี้ไม่ได้จัดการโดยบริษัทหรือองค์กรอื่นๆ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chromium <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> +<translation id="6358088212770985041">แก้ไขวิธีการชำระเงิน</translation> <translation id="6358450015545214790">นี่หมายถึงอะไร</translation> <translation id="6361757823711327522">B7</translation> <translation id="6363786367719063276">ดูบันทึก</translation> @@ -2848,6 +2855,7 @@ <translation id="6767985426384634228">อัปเดตที่อยู่ไหม</translation> <translation id="6770747695101757579">กระดาษ (ใยฝ้าย)</translation> <translation id="6775759552199460396">JIS B2</translation> +<translation id="6779348349813025131">เครื่องมือจัดการรหัสผ่านบน Google ต้องการสิทธิ์เข้าถึง Keychain ของ MacOS</translation> <translation id="6784045420901191374">สินเชื่อธุรกิจ</translation> <translation id="6785990323398321538">คุณเปลี่ยนเครื่องมือค้นหาได้ตลอดเวลาในการตั้งค่าของ Chrome</translation> <translation id="6786145470008421571">Envelope 6 x 9 นิ้ว</translation> @@ -2988,6 +2996,7 @@ <translation id="7023162328967545559">คำเตือนจากผู้ดูแลระบบ</translation> <translation id="7024932305105294144">Chrome มีฟีเจอร์ความปลอดภัยในตัวเพื่อปกป้องคุณขณะท่องเว็บ เช่น Google Safe Browsing ที่<ph name="BEGIN_LINK" />พบฟิชชิง<ph name="END_LINK" />ในเว็บไซต์ที่คุณพยายามเข้าชมเมื่อเร็วๆ นี้ เว็บไซต์ฟิชชิงปลอมเป็นเว็บไซต์อื่นๆ เพื่อหลอกคุณ<ph name="NEW_LINE" />บางครั้งเว็บไซต์ที่โดยปกติจะปลอดภัยก็อาจถูกบุกรุกจากผู้โจมตีได้ โปรด<ph name="BEGIN_ERROR_LINK" />แจ้งให้เราทราบ<ph name="END_ERROR_LINK" />หากคุณคิดว่ามีข้อผิดพลาดเกิดขึ้นและเว็บไซต์นี้ไม่ก่อให้เกิดอันตราย</translation> <translation id="7029809446516969842">รหัสผ่าน</translation> +<translation id="7030164307377592766">แก้ไขการตั้งค่าสำหรับการกรอกวิธีการชำระเงิน</translation> <translation id="7030436163253143341">ใบรับรองไม่ถูกต้อง</translation> <translation id="7031646650991750659">แอปจาก Google Play ที่คุณติดตั้ง</translation> <translation id="7038063300915481831"><ph name="MANAGE_GOOGLE_PRIVACY_FOCUSED_FRIENDLY_MATCH_TEXT" /> กด Tab ตามด้วย Enter เพื่อจัดการการตั้งค่าความเป็นส่วนตัวของบัญชี Google</translation> @@ -3798,6 +3807,7 @@ <translation id="8555010941760982128">ใช้รหัสนี้เมื่อชำระเงิน</translation> <translation id="8556297087315686325">การตรวจสอบและการจัดการเครือข่าย</translation> <translation id="8557066899867184262">CVC จะอยู่ที่ด้านหลังบัตร</translation> +<translation id="8557412555245662180">ดูข้อมูลเพิ่มเติมเกี่ยวกับการป้องกันการติดตาม</translation> <translation id="8558347880669160417">อนุญาตให้ใช้กล้องและไมโครโฟนในครั้งนี้</translation> <translation id="8559762987265718583">ไม่สามารถเริ่มการเชื่อมต่อส่วนตัวกับ <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> ได้เนื่องจากวันที่และเวลาของอุปกรณ์ (<ph name="DATE_AND_TIME" />) ไม่ถูกต้อง</translation> <translation id="8564182942834072828">เอกสารแยกกัน/ไม่จัดชุดสำเนา</translation>
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.cc b/components/supervised_user/core/browser/supervised_user_preferences.cc index bcc4a269..b6de5ed 100644 --- a/components/supervised_user/core/browser/supervised_user_preferences.cc +++ b/components/supervised_user/core/browser/supervised_user_preferences.cc
@@ -185,6 +185,16 @@ return IsChildAccount(pref_service) && IsChildAccountSupervisionEnabled(); } +bool IsUrlFilteringEnabled(const PrefService& pref_service) { +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) + return IsChildAccount(pref_service); +#else + return IsChildAccount(pref_service) && + base::FeatureList::IsEnabled( + kFilterWebsitesForSupervisedUsersOnDesktopAndIOS); +#endif +} + bool AreExtensionsPermissionsEnabled(const PrefService& pref_service) { #if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.h b/components/supervised_user/core/browser/supervised_user_preferences.h index 8d85c43..f498283d 100644 --- a/components/supervised_user/core/browser/supervised_user_preferences.h +++ b/components/supervised_user/core/browser/supervised_user_preferences.h
@@ -29,7 +29,7 @@ // Returns true if the user is a type of Family Link supervised account. // This method should be preferred on gating child-specific features if there -// is no dedicated method for the feature (e.g IsURLFilteringEnabled). +// is no dedicated method for the feature (e.g IsUrlFilteringEnabled). bool IsChildAccount(const PrefService& pref_service); // Returns true if the safe sites preference is enabled and user is supervised. @@ -39,6 +39,9 @@ // parental controls and the platform supports Family Link supervision features. bool IsSubjectToParentalControls(const PrefService& pref_service); +// Returns true if the URL filtering parental control is enabled. +bool IsUrlFilteringEnabled(const PrefService& pref_service); + // Returns true if the extensions permissions parental control is enabled. bool AreExtensionsPermissionsEnabled(const PrefService& pref_service);
diff --git a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc index 5f813f6..36a9264 100644 --- a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc +++ b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
@@ -274,6 +274,22 @@ EXPECT_FALSE(supervised_user::IsSubjectToParentalControls(pref_service_)); } +TEST_P(SupervisedUserPreferencesTestWithUrlFilteringFeature, + IsUrlFilteringEnabledForSupervisedUser) { + // Set supervised user preference. + pref_service_.SetString(prefs::kSupervisedUserId, + supervised_user::kChildAccountSUID); + EXPECT_EQ(supervised_user::IsUrlFilteringEnabled(pref_service_), + IsURLFilteringEnabled()); +} + +TEST_P(SupervisedUserPreferencesTestWithUrlFilteringFeature, + IsUrlFilteringEnabledForNonSupervisedUser) { + // Set non-supervised user preference. + pref_service_.SetString(prefs::kSupervisedUserId, std::string()); + EXPECT_FALSE(supervised_user::IsUrlFilteringEnabled(pref_service_)); +} + INSTANTIATE_TEST_SUITE_P( All, SupervisedUserPreferencesTestWithUrlFilteringFeature,
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc index e9491f38..b410645 100644 --- a/components/supervised_user/core/browser/supervised_user_service.cc +++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -121,16 +121,6 @@ return name.empty() ? GetSecondCustodianEmailAddress() : name; } -bool SupervisedUserService::IsURLFilteringEnabled() const { -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) - return supervised_user::IsChildAccount(user_prefs_.get()); -#else - return supervised_user::IsChildAccount(user_prefs_.get()) && - base::FeatureList::IsEnabled( - kFilterWebsitesForSupervisedUsersOnDesktopAndIOS); -#endif -} - bool SupervisedUserService::HasACustodian() const { return !GetCustodianEmailAddress().empty() || !GetSecondCustodianEmailAddress().empty();
diff --git a/components/supervised_user/core/browser/supervised_user_service.h b/components/supervised_user/core/browser/supervised_user_service.h index a4bf55b..eaa8b00 100644 --- a/components/supervised_user/core/browser/supervised_user_service.h +++ b/components/supervised_user/core/browser/supervised_user_service.h
@@ -99,9 +99,6 @@ // is empty, or the empty string if there is no second custodian. std::string GetSecondCustodianName() const; - // Returns true if the URL filtering parental control is enabled. - bool IsURLFilteringEnabled() const; - // Returns true if there is a custodian for the child. A child can have // up to 2 custodians, and this returns true if they have at least 1. bool HasACustodian() const;
diff --git a/components/supervised_user/core/browser/supervised_user_service_unittest.cc b/components/supervised_user/core/browser/supervised_user_service_unittest.cc index 6db86e6..1fe5b44a 100644 --- a/components/supervised_user/core/browser/supervised_user_service_unittest.cc +++ b/components/supervised_user/core/browser/supervised_user_service_unittest.cc
@@ -101,21 +101,6 @@ : SupervisedUserServiceTestBase(/*is_supervised=*/true) {} }; -TEST_F(SupervisedUserServiceTest, IsURLFilteringEnabled) { -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) - ASSERT_TRUE(service_->IsURLFilteringEnabled()); -#else - ASSERT_FALSE(service_->IsURLFilteringEnabled()); -#endif - - // Enable filtering flag across platforms. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - kFilterWebsitesForSupervisedUsersOnDesktopAndIOS); - - EXPECT_TRUE(service_->IsURLFilteringEnabled()); -} - TEST_F(SupervisedUserServiceTest, ManagedSiteListTypeMetricOnPrefsChange) { base::HistogramTester histogram_tester; @@ -255,19 +240,6 @@ : SupervisedUserServiceTestBase(/*is_supervised=*/false) {} }; -TEST_F(SupervisedUserServiceTestUnsupervised, IsURLFilteringEnabled) { - ASSERT_FALSE(service_->IsURLFilteringEnabled()); - - // Enable filtering flag across platforms. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - kFilterWebsitesForSupervisedUsersOnDesktopAndIOS); - EXPECT_TRUE(base::FeatureList::IsEnabled( - kFilterWebsitesForSupervisedUsersOnDesktopAndIOS)); - - EXPECT_FALSE(service_->IsURLFilteringEnabled()); -} - // TODO(crbug.com/1364589): Failing consistently on linux-chromeos-dbg // due to failed timezone conversion assertion. #if BUILDFLAG(IS_CHROMEOS)
diff --git a/components/variations/synthetic_trial_registry.h b/components/variations/synthetic_trial_registry.h index 760c929..93b9aa4 100644 --- a/components/variations/synthetic_trial_registry.h +++ b/components/variations/synthetic_trial_registry.h
@@ -15,7 +15,6 @@ #include "components/variations/synthetic_trials.h" namespace metrics { -class MetricsService; class MetricsServiceAccessor; } // namespace metrics @@ -83,7 +82,6 @@ OverrideMode mode); private: - friend metrics::MetricsService; friend metrics::MetricsServiceAccessor; friend FieldTrialsProvider; friend FieldTrialsProviderTest;
diff --git a/components/viz/common/frame_sinks/begin_frame_source.cc b/components/viz/common/frame_sinks/begin_frame_source.cc index 39579ab6..fffc9fc 100644 --- a/components/viz/common/frame_sinks/begin_frame_source.cc +++ b/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -228,10 +228,10 @@ } UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( - "Viz.BeginFrameSource.Accuracy.AverageDelta", + "Viz.BeginFrameSource.Accuracy.AverageDelta2", total_delta_ / kFramesToEmitHistogram, /*min=*/base::Microseconds(100), - /*max=*/base::Milliseconds(8), /*bucket_count=*/20); + /*max=*/base::Milliseconds(33), /*bucket_count=*/30); frames_since_last_recording_ = 0; total_delta_ = base::TimeDelta(); }
diff --git a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/ChromeWebApkHostSignature.java b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/ChromeWebApkHostSignature.java index c6f9846c..3e714545 100644 --- a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/ChromeWebApkHostSignature.java +++ b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/ChromeWebApkHostSignature.java
@@ -7,70 +7,77 @@ /** Public key and signature for WebAPKs */ public class ChromeWebApkHostSignature { // The public key to verify whether a WebAPK is signed by WebAPK Server. - public static final byte[] EXPECTED_SIGNATURE = new byte[] {48, -126, 4, 104, 48, -126, 2, -48, - -96, 3, 2, 1, 2, 2, 20, 120, 33, -22, -36, -115, 7, 116, 66, 116, 113, -122, -126, -124, - 32, 44, 72, -43, 127, -13, -11, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, - 0, 48, 67, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 15, 48, 13, 6, 3, 85, 4, - 10, 19, 6, 71, 111, 111, 103, 108, 101, 49, 22, 48, 20, 6, 3, 85, 4, 11, 19, 13, 67, - 104, 114, 111, 109, 101, 32, 87, 101, 98, 65, 80, 75, 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, - 2, 67, 65, 48, 30, 23, 13, 49, 54, 48, 56, 50, 51, 50, 48, 48, 56, 49, 49, 90, 23, 13, - 52, 52, 48, 49, 49, 48, 50, 48, 48, 56, 49, 49, 90, 48, 67, 49, 11, 48, 9, 6, 3, 85, 4, - 6, 19, 2, 85, 83, 49, 15, 48, 13, 6, 3, 85, 4, 10, 19, 6, 71, 111, 111, 103, 108, 101, - 49, 22, 48, 20, 6, 3, 85, 4, 11, 19, 13, 67, 104, 114, 111, 109, 101, 32, 87, 101, 98, - 65, 80, 75, 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, 2, 67, 65, 48, -126, 1, -94, 48, 13, 6, - 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, -113, 0, 48, -126, 1, -118, 2, - -126, 1, -127, 0, -60, 57, -128, 54, 45, -71, -75, 1, 42, 100, 64, 111, -6, 104, -8, - -57, -45, 42, 33, 124, 43, 20, -115, -88, -100, -115, -19, 90, 25, 16, 50, -96, 27, 4, - 64, -65, 92, -74, 61, 98, 54, 88, 122, -71, -116, -86, -26, -30, -34, -16, -87, -113, - 103, -81, -76, -2, -120, -124, -70, 41, 30, 46, 75, 119, 22, 61, 92, -8, 92, 55, 8, -53, - -70, 100, 40, 77, 77, 10, -5, -74, 37, 48, -71, 108, 92, -72, -56, 17, 39, -11, 61, -86, - -52, -3, -128, 72, 68, 27, 28, -128, -126, 91, 64, -117, -67, 58, 114, -70, 112, -44, - -70, -51, -81, -95, -78, 12, -1, 123, 68, -96, -32, -76, 65, -59, 37, -31, 88, 34, -125, - -67, 58, 77, 75, -112, 23, 127, -15, -45, 56, -10, 46, -40, -82, -49, 42, 35, 127, -70, - 120, -37, 8, 24, 38, 59, -1, -39, -104, -85, 101, 43, 39, 107, -35, -7, -80, -38, -47, - -86, -53, -94, 11, 62, 86, 78, 72, 90, -54, 5, 21, -72, -122, 14, 102, 95, -81, 94, -11, - -101, 36, -31, 104, -66, -51, 24, -99, 74, 21, -106, 76, 67, 86, 49, 121, 59, -7, 79, - -87, -115, 27, -82, -98, 15, -5, 13, -90, -20, 70, 17, -68, 124, 82, 35, 53, 76, -52, - 69, 23, -97, -2, -117, 7, -27, 79, 46, -54, -99, 41, -22, -108, -25, 8, 108, 109, -23, - 13, -11, 56, 11, -71, 20, 37, -64, -13, -114, -34, -78, -49, 7, 45, 80, 7, 69, 106, 3, - -128, 70, 0, 41, -105, 76, 106, -114, 18, -22, 92, -113, -12, 109, 11, 111, 48, -63, 22, - 29, -5, -113, -2, 117, -105, 1, -21, 40, 23, -8, -36, -109, -41, -1, 92, 94, 51, 122, - -67, -116, -64, 28, 38, 112, 4, -25, -18, -92, 53, -119, -37, 58, -28, 62, -88, 126, - -66, -113, -101, 57, -66, -48, -88, -47, -65, -65, 108, -116, -52, -87, -33, 30, 121, - -6, -50, -97, 99, -102, 106, -31, 119, -26, -49, 63, 90, -19, 119, 103, -83, 125, 29, - -32, -102, -97, -99, -45, 59, 36, 30, 58, 28, 59, 2, 48, 0, -76, 108, 98, 62, 68, -11, - -82, -74, -38, 93, -22, -79, -110, 73, 13, 2, 3, 1, 0, 1, -93, 84, 48, 82, 48, 14, 6, 3, - 85, 29, 15, 1, 1, -1, 4, 4, 3, 2, 2, -92, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, 6, 8, - 43, 6, 1, 5, 5, 7, 3, 1, 48, 12, 6, 3, 85, 29, 19, 1, 1, -1, 4, 2, 48, 0, 48, 29, 6, 3, - 85, 29, 14, 4, 22, 4, 20, 62, -89, -113, -1, -62, -65, -19, 4, 56, -51, 41, -53, 51, 41, - -28, -42, -36, 31, -89, -19, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, - 3, -126, 1, -127, 0, 27, -3, -41, -125, 123, -93, 20, -83, -83, -13, -120, -13, -123, - 29, 107, -9, 77, -75, -118, 106, 5, 113, -11, 40, -84, 98, -126, -55, 39, 77, -87, -53, - -5, 122, -63, -108, 23, 112, -88, 17, 28, 15, -103, 75, 75, 123, -21, 119, 125, -78, - -125, 87, 78, 41, -103, 6, 9, 91, 89, 42, 86, 25, -62, -30, 117, 22, -107, 53, 66, 56, - -23, -115, 16, -85, -38, 77, -117, -87, 106, -4, -91, 36, 81, 40, -31, 123, -40, 69, - -119, -69, -83, -78, 64, 123, 46, 36, 31, -29, 64, 36, -8, -22, -93, 22, -48, -49, 11, - -67, 48, -1, 26, 94, -82, 65, 6, 82, 18, 91, -56, 118, -55, 111, -18, -114, -86, -98, - -3, 40, -48, -46, -102, -120, 20, 101, -60, 91, -103, -92, 43, 12, -104, -10, -60, 10, - -31, -26, 111, -125, 103, 102, -105, 116, -66, -89, -58, 11, 34, 1, 22, 112, 126, 81, - 115, -104, -120, 115, -43, -59, 50, -67, -42, -42, 122, -66, 57, 121, 30, -22, -8, 96, - 114, -110, -98, 102, 41, -64, 115, -44, -84, 10, 63, 19, -105, 118, -2, 98, 45, -49, 94, - 114, 81, -84, -111, -34, -23, 49, 73, 91, 76, 81, 90, 86, 112, 12, -87, -41, -61, -82, - 32, -87, -7, 95, -28, -25, -9, -38, -102, 54, -81, -109, -126, 59, -82, 103, 126, -92, - -51, -81, 44, 61, 103, 127, -1, -23, -84, -35, -43, -88, 41, 120, 76, 120, 39, -124, 81, - 90, 64, 69, 112, 18, 54, -115, -7, 12, -110, 105, 48, -44, 88, 35, -104, 107, -83, -4, - -16, 123, 59, -13, 121, 63, -89, 118, 100, 38, 118, -30, 9, -57, -54, -108, -26, -45, - 29, -22, 57, -81, 83, -124, -114, -50, 16, 78, 23, -41, -4, 119, -13, -68, 38, -23, 56, - 22, -96, -63, -27, 70, -94, -35, 111, -45, -9, 59, -90, -27, 103, 95, 16, 127, -118, - -98, -75, -52, 7, 32, 65, -27, -68, 62, -81, 98, -54, -80, -23, 59, 38, -127, 96, 71, - 123, 34, -113, -23, -80, 32, -97, -55, -100, 121, 120, 50, -48, 58, 69, -105, 26, 126, - 30, -1, -112, -41, -18, -16, 62, 48, -22, -2, 19, 117, -6, 59, 74, -13, 92, -1}; + public static final byte[] EXPECTED_SIGNATURE = + new byte[] { + 48, -126, 4, 104, 48, -126, 2, -48, -96, 3, 2, 1, 2, 2, 20, 120, 33, -22, -36, -115, + 7, 116, 66, 116, 113, -122, -126, -124, 32, 44, 72, -43, 127, -13, -11, 48, 13, 6, + 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 67, 49, 11, 48, 9, 6, 3, 85, 4, + 6, 19, 2, 85, 83, 49, 15, 48, 13, 6, 3, 85, 4, 10, 19, 6, 71, 111, 111, 103, 108, + 101, 49, 22, 48, 20, 6, 3, 85, 4, 11, 19, 13, 67, 104, 114, 111, 109, 101, 32, 87, + 101, 98, 65, 80, 75, 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, 2, 67, 65, 48, 30, 23, 13, + 49, 54, 48, 56, 50, 51, 50, 48, 48, 56, 49, 49, 90, 23, 13, 52, 52, 48, 49, 49, 48, + 50, 48, 48, 56, 49, 49, 90, 48, 67, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, + 49, 15, 48, 13, 6, 3, 85, 4, 10, 19, 6, 71, 111, 111, 103, 108, 101, 49, 22, 48, 20, + 6, 3, 85, 4, 11, 19, 13, 67, 104, 114, 111, 109, 101, 32, 87, 101, 98, 65, 80, 75, + 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, 2, 67, 65, 48, -126, 1, -94, 48, 13, 6, 9, 42, + -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, -113, 0, 48, -126, 1, -118, 2, + -126, 1, -127, 0, -60, 57, -128, 54, 45, -71, -75, 1, 42, 100, 64, 111, -6, 104, -8, + -57, -45, 42, 33, 124, 43, 20, -115, -88, -100, -115, -19, 90, 25, 16, 50, -96, 27, + 4, 64, -65, 92, -74, 61, 98, 54, 88, 122, -71, -116, -86, -26, -30, -34, -16, -87, + -113, 103, -81, -76, -2, -120, -124, -70, 41, 30, 46, 75, 119, 22, 61, 92, -8, 92, + 55, 8, -53, -70, 100, 40, 77, 77, 10, -5, -74, 37, 48, -71, 108, 92, -72, -56, 17, + 39, -11, 61, -86, -52, -3, -128, 72, 68, 27, 28, -128, -126, 91, 64, -117, -67, 58, + 114, -70, 112, -44, -70, -51, -81, -95, -78, 12, -1, 123, 68, -96, -32, -76, 65, + -59, 37, -31, 88, 34, -125, -67, 58, 77, 75, -112, 23, 127, -15, -45, 56, -10, 46, + -40, -82, -49, 42, 35, 127, -70, 120, -37, 8, 24, 38, 59, -1, -39, -104, -85, 101, + 43, 39, 107, -35, -7, -80, -38, -47, -86, -53, -94, 11, 62, 86, 78, 72, 90, -54, 5, + 21, -72, -122, 14, 102, 95, -81, 94, -11, -101, 36, -31, 104, -66, -51, 24, -99, 74, + 21, -106, 76, 67, 86, 49, 121, 59, -7, 79, -87, -115, 27, -82, -98, 15, -5, 13, -90, + -20, 70, 17, -68, 124, 82, 35, 53, 76, -52, 69, 23, -97, -2, -117, 7, -27, 79, 46, + -54, -99, 41, -22, -108, -25, 8, 108, 109, -23, 13, -11, 56, 11, -71, 20, 37, -64, + -13, -114, -34, -78, -49, 7, 45, 80, 7, 69, 106, 3, -128, 70, 0, 41, -105, 76, 106, + -114, 18, -22, 92, -113, -12, 109, 11, 111, 48, -63, 22, 29, -5, -113, -2, 117, + -105, 1, -21, 40, 23, -8, -36, -109, -41, -1, 92, 94, 51, 122, -67, -116, -64, 28, + 38, 112, 4, -25, -18, -92, 53, -119, -37, 58, -28, 62, -88, 126, -66, -113, -101, + 57, -66, -48, -88, -47, -65, -65, 108, -116, -52, -87, -33, 30, 121, -6, -50, -97, + 99, -102, 106, -31, 119, -26, -49, 63, 90, -19, 119, 103, -83, 125, 29, -32, -102, + -97, -99, -45, 59, 36, 30, 58, 28, 59, 2, 48, 0, -76, 108, 98, 62, 68, -11, -82, + -74, -38, 93, -22, -79, -110, 73, 13, 2, 3, 1, 0, 1, -93, 84, 48, 82, 48, 14, 6, 3, + 85, 29, 15, 1, 1, -1, 4, 4, 3, 2, 2, -92, 48, 19, 6, 3, 85, 29, 37, 4, 12, 48, 10, + 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 12, 6, 3, 85, 29, 19, 1, 1, -1, 4, 2, 48, 0, 48, + 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 62, -89, -113, -1, -62, -65, -19, 4, 56, -51, + 41, -53, 51, 41, -28, -42, -36, 31, -89, -19, 48, 13, 6, 9, 42, -122, 72, -122, -9, + 13, 1, 1, 11, 5, 0, 3, -126, 1, -127, 0, 27, -3, -41, -125, 123, -93, 20, -83, -83, + -13, -120, -13, -123, 29, 107, -9, 77, -75, -118, 106, 5, 113, -11, 40, -84, 98, + -126, -55, 39, 77, -87, -53, -5, 122, -63, -108, 23, 112, -88, 17, 28, 15, -103, 75, + 75, 123, -21, 119, 125, -78, -125, 87, 78, 41, -103, 6, 9, 91, 89, 42, 86, 25, -62, + -30, 117, 22, -107, 53, 66, 56, -23, -115, 16, -85, -38, 77, -117, -87, 106, -4, + -91, 36, 81, 40, -31, 123, -40, 69, -119, -69, -83, -78, 64, 123, 46, 36, 31, -29, + 64, 36, -8, -22, -93, 22, -48, -49, 11, -67, 48, -1, 26, 94, -82, 65, 6, 82, 18, 91, + -56, 118, -55, 111, -18, -114, -86, -98, -3, 40, -48, -46, -102, -120, 20, 101, -60, + 91, -103, -92, 43, 12, -104, -10, -60, 10, -31, -26, 111, -125, 103, 102, -105, 116, + -66, -89, -58, 11, 34, 1, 22, 112, 126, 81, 115, -104, -120, 115, -43, -59, 50, -67, + -42, -42, 122, -66, 57, 121, 30, -22, -8, 96, 114, -110, -98, 102, 41, -64, 115, + -44, -84, 10, 63, 19, -105, 118, -2, 98, 45, -49, 94, 114, 81, -84, -111, -34, -23, + 49, 73, 91, 76, 81, 90, 86, 112, 12, -87, -41, -61, -82, 32, -87, -7, 95, -28, -25, + -9, -38, -102, 54, -81, -109, -126, 59, -82, 103, 126, -92, -51, -81, 44, 61, 103, + 127, -1, -23, -84, -35, -43, -88, 41, 120, 76, 120, 39, -124, 81, 90, 64, 69, 112, + 18, 54, -115, -7, 12, -110, 105, 48, -44, 88, 35, -104, 107, -83, -4, -16, 123, 59, + -13, 121, 63, -89, 118, 100, 38, 118, -30, 9, -57, -54, -108, -26, -45, 29, -22, 57, + -81, 83, -124, -114, -50, 16, 78, 23, -41, -4, 119, -13, -68, 38, -23, 56, 22, -96, + -63, -27, 70, -94, -35, 111, -45, -9, 59, -90, -27, 103, 95, 16, 127, -118, -98, + -75, -52, 7, 32, 65, -27, -68, 62, -81, 98, -54, -80, -23, 59, 38, -127, 96, 71, + 123, 34, -113, -23, -80, 32, -97, -55, -100, 121, 120, 50, -48, 58, 69, -105, 26, + 126, 30, -1, -112, -41, -18, -16, 62, 48, -22, -2, 19, 117, -6, 59, 74, -13, 92, -1 + }; // The public key for comment signed WebAPK's. Elliptic Curve, NIST P-256 in ASN.1 format. - public static final byte[] PUBLIC_KEY = new byte[] {48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, - 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, -25, 45, 2, 49, 44, -60, 107, - -108, -45, 27, -40, -8, -116, 44, 7, -38, -103, 52, -81, 33, -90, -80, -94, 125, -3, - -67, 51, -125, -63, 6, -127, 89, 32, 53, 83, -120, -106, -113, -121, -39, 115, -50, 15, - 117, 66, 78, -89, -124, -120, 4, -61, 8, -90, -67, -6, 71, -120, -120, 23, 23, 77, 75, - 103, -28}; + public static final byte[] PUBLIC_KEY = + new byte[] { + 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, + 1, 7, 3, 66, 0, 4, -25, 45, 2, 49, 44, -60, 107, -108, -45, 27, -40, -8, -116, 44, + 7, -38, -103, 52, -81, 33, -90, -80, -94, 125, -3, -67, 51, -125, -63, 6, -127, 89, + 32, 53, 83, -120, -106, -113, -121, -39, 115, -50, 15, 117, 66, 78, -89, -124, -120, + 4, -61, 8, -90, -67, -6, 71, -120, -120, 23, 23, 77, 75, 103, -28 + }; }
diff --git a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java index 7c96512..f63631c 100644 --- a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java +++ b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkValidator.java
@@ -55,8 +55,12 @@ private static PublicKey sCommentSignedPublicKey; private static boolean sOverrideValidation; - @IntDef({ValidationResult.FAILURE, ValidationResult.V1_WEB_APK, ValidationResult.MAPS_LITE, - ValidationResult.COMMENT_SIGNED}) + @IntDef({ + ValidationResult.FAILURE, + ValidationResult.V1_WEB_APK, + ValidationResult.MAPS_LITE, + ValidationResult.COMMENT_SIGNED + }) @Retention(RetentionPolicy.SOURCE) private @interface ValidationResult { int FAILURE = 0; @@ -66,16 +70,14 @@ } /** - * Queries the PackageManager to determine whether one or more WebAPKs can handle - * the URL. Ignores whether the user has selected a default handler for the URL and - * whether the default handler is a WebAPK. + * Queries the PackageManager to determine whether one or more WebAPKs can handle the URL. + * Ignores whether the user has selected a default handler for the URL and whether the default + * handler is a WebAPK. * * @param context The application context. * @param url The url to check. - * @return Package name for one of the WebAPKs which can handle the URL. If there - * are several - * matching WebAPKs an arbitrary one is returned. Null if there is no matching - * WebAPK. + * @return Package name for one of the WebAPKs which can handle the URL. If there are several + * matching WebAPKs an arbitrary one is returned. Null if there is no matching WebAPK. */ public static @Nullable String queryFirstWebApkPackage(Context context, String url) { return findFirstWebApkPackage(context, resolveInfosForUrl(context, url)); @@ -83,13 +85,13 @@ /** * Queries the PackageManager to determine whether one or more WebAPKs can handle the URL. - * Ignores whether the user has selected a default handler for the URL and whether the - * default handler is a WebAPK. + * Ignores whether the user has selected a default handler for the URL and whether the default + * handler is a WebAPK. * * @param context The application context. * @param url The url to check. * @return ResolveInfo for one of the WebAPKs which can handle the URL. If there are several - * matching ResolveInfos an arbitrary one is returned. Null if there is no matching WebAPK. + * matching ResolveInfos an arbitrary one is returned. Null if there is no matching WebAPK. */ public static @Nullable ResolveInfo queryFirstWebApkResolveInfo(Context context, String url) { return findFirstWebApkResolveInfo(context, resolveInfosForUrl(context, url)); @@ -97,14 +99,14 @@ /** * Queries the PackageManager to determine whether one or more WebAPKs can handle the URL. - * Ignores whether the user has selected a default handler for the URL and whether the - * default handler is a WebAPK. + * Ignores whether the user has selected a default handler for the URL and whether the default + * handler is a WebAPK. * * @param context The application context. * @param url The url to check. * @param packageName The optional package name. * @return ResolveInfo for one of the WebAPKs which can handle the URL. If there are several - * matching ResolveInfos an arbitrary one is returned. Null if there is no matching WebAPK. + * matching ResolveInfos an arbitrary one is returned. Null if there is no matching WebAPK. */ public static @Nullable ResolveInfo queryFirstWebApkResolveInfo( Context context, String url, @Nullable String packageName) { @@ -113,8 +115,9 @@ } /** - * Searches {@link infos} and returns the package name of the first {@link ResolveInfo} - * which corresponds to a WebAPK. + * Searches {@link infos} and returns the package name of the first {@link ResolveInfo} which + * corresponds to a WebAPK. + * * @param context The context to use to check whether WebAPK is valid. * @param infos The {@link ResolveInfo}s to search. * @return WebAPK package name of the match. Null if there are no matches. @@ -130,6 +133,7 @@ /** * Whether the given package corresponds to a WebAPK that can handle the URL. + * * @param context The application context. * @param webApkPackage The package to consider. * @param url The URL the package must be able to handle. @@ -148,6 +152,7 @@ /** * Fetches a list of {@link ResolveInfo}s from the PackageManager that can handle the URL. + * * @param context The application context. * @param url The URL to check. * @return The list of {@link ResolveInfo}s found that can handle the URL. @@ -172,8 +177,8 @@ // StrictMode is relaxed due to https://crbug.com/843092. StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads(); try { - return context.getPackageManager().queryIntentActivities( - intent, PackageManager.GET_RESOLVED_FILTER); + return context.getPackageManager() + .queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER); } catch (Exception e) { // We used to catch only java.util.MissingResourceException, but we need to catch // more exceptions to handle "Package manager has died" exception. @@ -187,6 +192,7 @@ /** * Searches {@link infos} and returns the first {@link ResolveInfo} which corresponds to a * WebAPK. + * * @param context The context to use to check whether WebAPK is valid. * @param infos The {@link ResolveInfo}s to search. * @return The matching {@link ResolveInfo}. Null if there are no matches. @@ -204,6 +210,7 @@ /** * Returns whether the provided WebAPK is installed and passes signature checks. + * * @param context A context * @param webappPackageName The package name to check * @return true iff the WebAPK is installed and passes security checks @@ -213,9 +220,9 @@ } /** - * Returns whether the provided WebAPK is installed and is valid V1 WebAPK. - * This is similar to |isValidWebApk| but only checks V1 WebApks, does not checks MapsLite - * and comment signed WebAPK. + * Returns whether the provided WebAPK is installed and is valid V1 WebAPK. This is similar to + * |isValidWebApk| but only checks V1 WebApks, does not checks MapsLite and comment signed + * WebAPK. * * @param context A context * @param webappPackageName The package name to check @@ -230,15 +237,19 @@ private static @ValidationResult int isValidWebApkInternal( Context context, String webappPackageName) { if (sExpectedSignature == null || sCommentSignedPublicKeyBytes == null) { - Log.wtf(TAG, + Log.wtf( + TAG, "WebApk validation failure - expected signature not set - " + "missing call to WebApkValidator.init"); return ValidationResult.FAILURE; } PackageInfo packageInfo; try { - packageInfo = context.getPackageManager().getPackageInfo(webappPackageName, - PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA); + packageInfo = + context.getPackageManager() + .getPackageInfo( + webappPackageName, + PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA); } catch (Exception e) { if (DEBUG) { e.printStackTrace(); @@ -274,9 +285,9 @@ /** * @param url A Url that might launch a WebApk. * @param applicationPackage The package of the WebApk to restrict the launch to. - * @return An intent that could launch a WebApk for the provided URL (and package), if such - * a WebApk exists. If package isn't specified, the intent may create a - * disambiguation dialog when started. + * @return An intent that could launch a WebApk for the provided URL (and package), if such a + * WebApk exists. If package isn't specified, the intent may create a disambiguation dialog + * when started. */ public static Intent createWebApkIntentForUrlAndOptionalPackage( String url, @Nullable String applicationPackage) { @@ -313,7 +324,8 @@ } private static boolean verifyV1WebApk(PackageInfo packageInfo, String webappPackageName) { - if (packageInfo.signatures == null || packageInfo.signatures.length != 2 + if (packageInfo.signatures == null + || packageInfo.signatures.length != 2 || !webappPackageName.startsWith(WEBAPK_PACKAGE_PREFIX)) { return false; } @@ -381,8 +393,7 @@ buf.load(); WebApkVerifySignature v = new WebApkVerifySignature(buf); - @WebApkVerifySignature.Error - int result = v.read(); + @WebApkVerifySignature.Error int result = v.read(); if (result != WebApkVerifySignature.Error.OK) { Log.e(TAG, String.format("Failure reading %s: %s", packageFilename, result)); return false; @@ -416,6 +427,7 @@ /** * Determines if a bound WebAPK generated from |manifestUrl| is installed on the device. + * * @param context The context to use to check whether WebAPK is valid. * @param manifestUrl The URL of the manifest that was used to generate the WebAPK. * @return The WebAPK's package name if installed, or null otherwise. @@ -425,8 +437,10 @@ Context context, String manifestUrl) { assert manifestUrl != null; - List<PackageInfo> packages = context.getPackageManager().getInstalledPackages( - PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA); + List<PackageInfo> packages = + context.getPackageManager() + .getInstalledPackages( + PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA); // Filter out unbound & invalid WebAPKs. for (int i = 0; i < packages.size(); i++) { @@ -451,6 +465,7 @@ /** * Initializes the WebApkValidator. + * * @param expectedSignature V1 WebAPK RSA signature. * @param v2PublicKeyBytes New comment signed public key bytes as x509 encoded public key. */ @@ -464,8 +479,8 @@ } /** - * Sets whether validation performed by this class should be disabled. This is meant only - * for development with unsigned WebApks and should never be enabled in a real build. + * Sets whether validation performed by this class should be disabled. This is meant only for + * development with unsigned WebApks and should never be enabled in a real build. */ public static void setDisableValidationForTesting(boolean disable) { var oldValue = sOverrideValidation; @@ -474,16 +489,16 @@ } /** - * Sets whether validation performed by this class should be disabled. This is meant only - * for development with unsigned WebApks and should never be enabled in a real build. + * Sets whether validation performed by this class should be disabled. This is meant only for + * development with unsigned WebApks and should never be enabled in a real build. */ public static void setDisableValidation(boolean disable) { sOverrideValidation = disable; } /** - * Lazy evaluate the creation of the Public Key as the KeyFactories may not yet be - * initialized. + * Lazy evaluate the creation of the Public Key as the KeyFactories may not yet be initialized. + * * @return The decoded PublicKey or null */ private static PublicKey getCommentSignedPublicKey() throws Exception {
diff --git a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkVerifySignature.java b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkVerifySignature.java index c5c73b8..b65a789 100644 --- a/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkVerifySignature.java +++ b/components/webapk/android/libs/client/src/org/chromium/components/webapk/lib/client/WebApkVerifySignature.java
@@ -27,9 +27,17 @@ */ public class WebApkVerifySignature { /** Errors codes. */ - @IntDef({Error.OK, Error.BAD_APK, Error.EXTRA_FIELD_TOO_LARGE, Error.FILE_COMMENT_TOO_LARGE, - Error.INCORRECT_SIGNATURE, Error.SIGNATURE_NOT_FOUND, Error.TOO_MANY_META_INF_FILES, - Error.BAD_BLANK_SPACE, Error.BAD_V2_SIGNING_BLOCK}) + @IntDef({ + Error.OK, + Error.BAD_APK, + Error.EXTRA_FIELD_TOO_LARGE, + Error.FILE_COMMENT_TOO_LARGE, + Error.INCORRECT_SIGNATURE, + Error.SIGNATURE_NOT_FOUND, + Error.TOO_MANY_META_INF_FILES, + Error.BAD_BLANK_SPACE, + Error.BAD_V2_SIGNING_BLOCK + }) @SuppressWarnings("JavaLangClash") @Retention(RetentionPolicy.SOURCE) public @interface Error { @@ -77,10 +85,9 @@ private static final String V2_SIGNING_MAGIC = "APK Sig Block 42"; /** - * The pattern we look for in the APK/zip comment for signing key. - * An example is "webapk:0000:<hexvalues>". This pattern can appear anywhere - * in the comment but must be separated from any other parts with a - * separator that doesn't look like a hex character. + * The pattern we look for in the APK/zip comment for signing key. An example is + * "webapk:0000:<hexvalues>". This pattern can appear anywhere in the comment but must be + * separated from any other parts with a separator that doesn't look like a hex character. */ private static final Pattern WEBAPK_COMMENT_PATTERN = Pattern.compile("webapk:\\d+:([a-fA-F0-9]+)"); @@ -130,12 +137,13 @@ } /** Comparator for sorting the list by position ascending. */ - public static Comparator<Block> positionComparator = new Comparator<Block>() { - @Override - public int compare(Block b1, Block b2) { - return b1.mPosition - b2.mPosition; - } - }; + public static Comparator<Block> positionComparator = + new Comparator<Block>() { + @Override + public int compare(Block b1, Block b2) { + return b1.mPosition - b2.mPosition; + } + }; @Override public boolean equals(Object o) { @@ -159,12 +167,12 @@ * Read in the comment and directory. If there is no parseable comment we won't read the * directory as there is no point (for speed). On success, all of our private variables will be * set. + * * @return OK on success. */ public @Error int read() { try { - @Error - int err = readEOCD(); + @Error int err = readEOCD(); if (err != Error.OK) { return err; } @@ -184,6 +192,7 @@ /** * verifySignature hashes all the files and then verifies the signature. + * * @param pub The public key that it should be verified against. * @return Error.OK if the public key signature verifies. */ @@ -209,6 +218,7 @@ /** * calculateHash goes through each file listed in blocks and calculates the SHA-256 * cryptographic hash. + * * @param sig Signature object you can call update on. */ public @Error int calculateHash(Signature sig) throws Exception { @@ -246,6 +256,7 @@ /** * intToLittleEndian converts an integer to a little endian array of bytes. + * * @param value Integer value to convert. * @return Array of bytes. */ @@ -257,9 +268,9 @@ } /** - * Extract the bytes of the signature from the comment. We expect - * "webapk:0000:<hexvalues>" comment followed by hex values. Currently we ignore the - * "key id" which is always "0000". + * Extract the bytes of the signature from the comment. We expect "webapk:0000:<hexvalues>" + * comment followed by hex values. Currently we ignore the "key id" which is always "0000". + * * @return the bytes of the signature. */ static byte[] parseCommentSignature(String comment) { @@ -273,6 +284,7 @@ /** * Reads the End of Central Directory Record. + * * @return Error.OK on success. */ private @Error int readEOCD() { @@ -298,6 +310,7 @@ /** * Reads the central directory and populates {@link mBlocks} with data about each entry. + * * @return Error.OK on success. */ @Error @@ -394,10 +407,11 @@ /** * We search buffer for EOCD_SIG and return the location where we found it. If the file has no * comment it should seek only once. - * TODO(scottkirkwood): Use a Boyer-Moore search algorithm. + * * @return Offset from start of buffer or -1 if not found. */ private int findEOCDStart() { + // TODO(scottkirkwood): Use a Boyer-Moore search algorithm. int offset = mBuffer.limit() - MIN_EOCD_SIZE; int minSearchOffset = Math.max(0, offset - MAX_EOCD_SIZE); for (; offset >= minSearchOffset; offset--) { @@ -412,6 +426,7 @@ /** * Seek to this position. + * * @param offset offset from start of file. */ private void seek(int offset) { @@ -420,6 +435,7 @@ /** * Skip forward this number of bytes. + * * @param delta number of bytes to seek forward. */ private void seekDelta(int delta) { @@ -428,6 +444,7 @@ /** * Reads two bytes in little endian format. + * * @return short value read (as an int). */ private int read2() { @@ -436,6 +453,7 @@ /** * Reads four bytes in little endian format. + * * @return value read. */ private int read4() { @@ -453,8 +471,8 @@ } /** - * Convert a hex string into bytes. We store hex in the signature as zip - * tools often don't like binary strings. + * Convert a hex string into bytes. We store hex in the signature as zip tools often don't like + * binary strings. */ static byte[] hexToBytes(String s) { int len = s.length(); @@ -464,8 +482,10 @@ } byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) - + Character.digit(s.charAt(i + 1), 16)); + data[i / 2] = + (byte) + ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); } return data; }
diff --git a/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkConstants.java b/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkConstants.java index 603be0f..1cd7583 100644 --- a/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkConstants.java +++ b/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkConstants.java
@@ -4,9 +4,7 @@ package org.chromium.components.webapk.lib.common; -/** - * Stores WebAPK related constants. - */ +/** Stores WebAPK related constants. */ public final class WebApkConstants { public static final String WEBAPK_PACKAGE_PREFIX = "org.chromium.webapk"; }
diff --git a/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkMetaDataKeys.java b/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkMetaDataKeys.java index 9e0b525..b5a6d7b3 100644 --- a/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkMetaDataKeys.java +++ b/components/webapk/android/libs/common/src/org/chromium/components/webapk/lib/common/WebApkMetaDataKeys.java
@@ -4,9 +4,7 @@ package org.chromium.components.webapk.lib.common; -/** - * <meta-data> keys for WebAPK Android Manifest. - */ +/** <meta-data> keys for WebAPK Android Manifest. */ public final class WebApkMetaDataKeys { public static final String SHELL_APK_VERSION = "org.chromium.webapk.shell_apk.shellApkVersion"; public static final String RUNTIME_HOST = "org.chromium.webapk.shell_apk.runtimeHost";
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenCoordinator.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenCoordinator.java index 8697b5d3..7e6b672 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenCoordinator.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenCoordinator.java
@@ -23,7 +23,7 @@ * This class is responsible for setting up and coordinating everything related to the * add-to-homescreen UI component. * - * The {@link #showForAppMenu} method is used to show the add-to-homescreen UI when the user + * <p>The {@link #showForAppMenu} method is used to show the add-to-homescreen UI when the user * chooses the "Add to Home screen" option from the app menu. */ @JNINamespace("webapps") @@ -35,8 +35,11 @@ private WebContents mWebContents; @VisibleForTesting - public AddToHomescreenCoordinator(WebContents webContents, Context activityContext, - WindowAndroid windowAndroid, ModalDialogManager modalDialogManager) { + public AddToHomescreenCoordinator( + WebContents webContents, + Context activityContext, + WindowAndroid windowAndroid, + ModalDialogManager modalDialogManager) { mActivityContext = activityContext; mWindowAndroid = windowAndroid; mModalDialogManager = modalDialogManager; @@ -45,14 +48,18 @@ /** * Starts and shows the add-to-homescreen UI component for the given {@link WebContents}. + * * @return whether add-to-homescreen UI was started successfully. */ - public static void showForAppMenu(Context activityContext, WindowAndroid windowAndroid, - ModalDialogManager modalDialogManager, WebContents webContents, Bundle menuItemData) { - @StringRes - int titleId = menuItemData.getInt(AppBannerManager.MENU_TITLE_KEY); + public static void showForAppMenu( + Context activityContext, + WindowAndroid windowAndroid, + ModalDialogManager modalDialogManager, + WebContents webContents, + Bundle menuItemData) { + @StringRes int titleId = menuItemData.getInt(AppBannerManager.MENU_TITLE_KEY); new AddToHomescreenCoordinator( - webContents, activityContext, windowAndroid, modalDialogManager) + webContents, activityContext, windowAndroid, modalDialogManager) .showForAppMenu(titleId); } @@ -69,10 +76,11 @@ /** * Constructs all MVC components on request from the C++ side. + * * @param webContents The {@link WebContents} that initiated the add to homescreen request. Used - * for accessing activity {@link Context} and {@link ModalDialogManager}. + * for accessing activity {@link Context} and {@link ModalDialogManager}. * @return A C++ pointer to the associated add_to_homescreen_mediator.cc object. This will be - * used by add_to_homescreen_coordinator.cc to complete the initialization of the mediator. + * used by add_to_homescreen_coordinator.cc to complete the initialization of the mediator. */ @CalledByNative private static long initMvcAndReturnMediator(WebContents webContents) { @@ -83,33 +91,41 @@ if (modalDialogManager == null) return 0; - AddToHomescreenCoordinator coordinator = new AddToHomescreenCoordinator( - webContents, windowAndroid.getContext().get(), windowAndroid, modalDialogManager); + AddToHomescreenCoordinator coordinator = + new AddToHomescreenCoordinator( + webContents, + windowAndroid.getContext().get(), + windowAndroid, + modalDialogManager); return coordinator.buildMediatorAndShowDialog().getNativeMediator(); } /** * Constructs all MVC components. {@link AddToHomescreenDialogView} is shown as soon as it's * constructed. + * * @return The instance of {@link AddToHomescreenMediator} that was constructed. */ private AddToHomescreenMediator buildMediatorAndShowDialog() { PropertyModel model = new PropertyModel.Builder(AddToHomescreenProperties.ALL_KEYS).build(); AddToHomescreenMediator addToHomescreenMediator = new AddToHomescreenMediator(model, mWindowAndroid); - PropertyModelChangeProcessor.create(model, - initView(AppBannerManager.getHomescreenLanguageOption(mWebContents), + PropertyModelChangeProcessor.create( + model, + initView( + AppBannerManager.getHomescreenLanguageOption(mWebContents), addToHomescreenMediator), AddToHomescreenViewBinder::bind); return addToHomescreenMediator; } /** - * Creates and returns a {@link AddToHomescreenDialogView}. - * Extracted into a separate method for easier testing. + * Creates and returns a {@link AddToHomescreenDialogView}. Extracted into a separate method for + * easier testing. */ @VisibleForTesting - protected AddToHomescreenDialogView initView(AppBannerManager.InstallStringPair installStrings, + protected AddToHomescreenDialogView initView( + AppBannerManager.InstallStringPair installStrings, AddToHomescreenViewDelegate delegate) { return new AddToHomescreenDialogView( mActivityContext, mModalDialogManager, installStrings, delegate);
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenDialogView.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenDialogView.java index d5112844..e4fca66 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenDialogView.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenDialogView.java
@@ -35,7 +35,7 @@ * Displays the "Add to Homescreen" dialog, which contains a (possibly editable) title, icon, and * possibly an origin. * - * When the constructor is called, the dialog is shown immediately. A spinner is displayed if any + * <p>When the constructor is called, the dialog is shown immediately. A spinner is displayed if any * data is not yet fetched, and accepting the dialog is disabled until all data is available and in * its place on the screen. */ @@ -43,15 +43,16 @@ implements View.OnClickListener, ModalDialogProperties.Controller { private PropertyModel mDialogModel; private ModalDialogManager mModalDialogManager; - @VisibleForTesting - protected AddToHomescreenViewDelegate mDelegate; + @VisibleForTesting protected AddToHomescreenViewDelegate mDelegate; private View mParentView; + /** * {@link #mShortcutTitleInput} and the {@link #mAppLayout} are mutually exclusive, depending on * whether the home screen item is a bookmark shortcut or a web/native app. */ private EditText mShortcutTitleInput; + private LinearLayout mAppLayout; private TextView mAppNameView; private TextView mAppOriginView; @@ -64,7 +65,9 @@ private boolean mCanSubmit; @VisibleForTesting - public AddToHomescreenDialogView(Context context, ModalDialogManager modalDialogManager, + public AddToHomescreenDialogView( + Context context, + ModalDialogManager modalDialogManager, AppBannerManager.InstallStringPair installStrings, AddToHomescreenViewDelegate delegate) { assert delegate != null; @@ -86,51 +89,70 @@ mAppNameView.setOnClickListener(this); mIconView.setOnClickListener(this); - mParentView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - if (mProgressBarView.getMeasuredHeight() == mShortcutTitleInput.getMeasuredHeight() - && mShortcutTitleInput.getBackground() != null) { - // Force the text field to align better with the icon by accounting for the - // padding introduced by the background drawable. - mShortcutTitleInput.getLayoutParams().height = - mProgressBarView.getMeasuredHeight() - + mShortcutTitleInput.getPaddingBottom(); - ViewUtils.requestLayout(v, - "AddToHomescreenDialogView.<init>.OnLayoutChangeListener.onLayoutChange"); - v.removeOnLayoutChangeListener(this); - } - } - }); + mParentView.addOnLayoutChangeListener( + new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange( + View v, + int left, + int top, + int right, + int bottom, + int oldLeft, + int oldTop, + int oldRight, + int oldBottom) { + if (mProgressBarView.getMeasuredHeight() + == mShortcutTitleInput.getMeasuredHeight() + && mShortcutTitleInput.getBackground() != null) { + // Force the text field to align better with the icon by accounting for + // the padding introduced by the background drawable. + mShortcutTitleInput.getLayoutParams().height = + mProgressBarView.getMeasuredHeight() + + mShortcutTitleInput.getPaddingBottom(); + String caller = + "AddToHomescreenDialogView.<init>." + + "OnLayoutChangeListener.onLayoutChange"; + ViewUtils.requestLayout(v, caller); + v.removeOnLayoutChangeListener(this); + } + } + }); // The "Add" button should be disabled if the dialog's text field is empty. - mShortcutTitleInput.addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + mShortcutTitleInput.addTextChangedListener( + new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} - @Override - public void afterTextChanged(Editable editableText) { - updateInstallButton(); - } - }); + @Override + public void afterTextChanged(Editable editableText) { + updateInstallButton(); + } + }); Resources resources = context.getResources(); mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) .with(ModalDialogProperties.CONTROLLER, this) .with(ModalDialogProperties.TITLE, resources, installStrings.titleTextId) - .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + .with( + ModalDialogProperties.POSITIVE_BUTTON_TEXT, + resources, installStrings.buttonTextId) .with(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true) - .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + .with( + ModalDialogProperties.NEGATIVE_BUTTON_TEXT, + resources, R.string.cancel) .with(ModalDialogProperties.CUSTOM_VIEW, mParentView) .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) - .with(ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS, + .with( + ModalDialogProperties.BUTTON_TAP_PROTECTION_PERIOD_MS, UiUtils.PROMPT_INPUT_PROTECTION_SHORT_DELAY_MS) .build(); mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.TAB); @@ -176,10 +198,12 @@ void setNativeInstallButtonText(String installButtonText) { mDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_TEXT, installButtonText); - mDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_CONTENT_DESCRIPTION, - ContextUtils.getApplicationContext().getString( - R.string.app_banner_view_native_app_install_accessibility, - installButtonText)); + mDialogModel.set( + ModalDialogProperties.POSITIVE_BUTTON_CONTENT_DESCRIPTION, + ContextUtils.getApplicationContext() + .getString( + R.string.app_banner_view_native_app_install_accessibility, + installButtonText)); } void setNativeAppRating(float rating) { @@ -195,8 +219,9 @@ } private void updateInstallButton() { - boolean missingTitle = mShortcutTitleInput.getVisibility() == View.VISIBLE - && TextUtils.isEmpty(mShortcutTitleInput.getText()); + boolean missingTitle = + mShortcutTitleInput.getVisibility() == View.VISIBLE + && TextUtils.isEmpty(mShortcutTitleInput.getText()); mDialogModel.set( ModalDialogProperties.POSITIVE_BUTTON_DISABLED, !mCanSubmit || missingTitle); } @@ -218,7 +243,7 @@ } /** - * From {@link ModalDialogProperties.Controller}. Called when a dialog button is clicked. + * From {@link ModalDialogProperties.Controller}. Called when a dialog button is clicked. * * @param model The dialog model that is associated with this click event. * @param buttonType The type of the button.
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenMediator.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenMediator.java index 16481a0..00cadde 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenMediator.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenMediator.java
@@ -20,8 +20,8 @@ /** * The mediator class in the MVC architecture of the add-to-homescreen component. The C++ - * counterpart of this class calls various Java set methods ({@link #setIcon}, - * {@link #setWebAppInfo}, {@link #setWebAppInfoWithIcon}, and {@link #setNativeAppInfo}) when more + * counterpart of this class calls various Java set methods ({@link #setIcon}, {@link + * #setWebAppInfo}, {@link #setWebAppInfoWithIcon}, and {@link #setNativeAppInfo}) when more * information about the app is available. These methods modify the model that lives on the Java * side. */ @@ -41,8 +41,8 @@ void startForAppMenu(@NonNull WebContents webContents, @StringRes int titleId) { if (mNativeAddToHomescreenMediator == 0) return; - AddToHomescreenMediatorJni.get().startForAppMenu( - mNativeAddToHomescreenMediator, webContents, titleId); + AddToHomescreenMediatorJni.get() + .startForAppMenu(mNativeAddToHomescreenMediator, webContents, titleId); } @CalledByNative @@ -70,7 +70,8 @@ mModel.set(AddToHomescreenProperties.TYPE, AppType.NATIVE); mModel.set(AddToHomescreenProperties.NATIVE_APP_RATING, nativeAppData.rating()); mModel.set(AddToHomescreenProperties.CAN_SUBMIT, true); - mModel.set(AddToHomescreenProperties.NATIVE_INSTALL_BUTTON_TEXT, + mModel.set( + AddToHomescreenProperties.NATIVE_INSTALL_BUTTON_TEXT, nativeAppData.installButtonText()); } @@ -118,11 +119,18 @@ @NativeMethods interface Natives { long initialize(AddToHomescreenMediator instance); - void startForAppMenu(long nativeAddToHomescreenMediator, WebContents webContents, + + void startForAppMenu( + long nativeAddToHomescreenMediator, + WebContents webContents, @StringRes int titleId); + void addToHomescreen(long nativeAddToHomescreenMediator, String title); + void onNativeDetailsShown(long nativeAddToHomescreenMediator); + void onUiDismissed(long nativeAddToHomescreenMediator); + void destroy(long nativeAddToHomescreenMediator); } }
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenProperties.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenProperties.java index 0c869fa..94581f1 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenProperties.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenProperties.java
@@ -11,9 +11,7 @@ import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; -/** - * Contains the properties that an add-to-homescreen {@link PropertyModel} can have. - */ +/** Contains the properties that an add-to-homescreen {@link PropertyModel} can have. */ public class AddToHomescreenProperties { public static final PropertyModel.WritableObjectPropertyKey<String> TITLE = new PropertyModel.WritableObjectPropertyKey<>(); @@ -34,6 +32,15 @@ public static final PropertyModel.WritableFloatPropertyKey NATIVE_APP_RATING = new PropertyModel.WritableFloatPropertyKey(); - public static final PropertyKey[] ALL_KEYS = {TITLE, URL, DESCRIPTION, ICON, TYPE, CAN_SUBMIT, - CLICK_LISTENER, NATIVE_INSTALL_BUTTON_TEXT, NATIVE_APP_RATING}; + public static final PropertyKey[] ALL_KEYS = { + TITLE, + URL, + DESCRIPTION, + ICON, + TYPE, + CAN_SUBMIT, + CLICK_LISTENER, + NATIVE_INSTALL_BUTTON_TEXT, + NATIVE_APP_RATING + }; }
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewBinder.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewBinder.java index a70d7354..b664e5ac 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewBinder.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewBinder.java
@@ -10,9 +10,7 @@ import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; -/** - * Binds an add-to-homescreen {@link PropertyModel} with a {@link AddToHomescreenDialogView}. - */ +/** Binds an add-to-homescreen {@link PropertyModel} with a {@link AddToHomescreenDialogView}. */ class AddToHomescreenViewBinder { static void bind(PropertyModel model, AddToHomescreenDialogView view, PropertyKey propertyKey) { if (propertyKey.equals(AddToHomescreenProperties.TITLE)) {
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewDelegate.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewDelegate.java index 1cec17d..3a2fabe 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewDelegate.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AddToHomescreenViewDelegate.java
@@ -9,13 +9,12 @@ * AddToHomescreenMediator}. */ public interface AddToHomescreenViewDelegate { - /** - * Called when the user accepts adding the item to home screen with the provided title. - */ + /** Called when the user accepts adding the item to home screen with the provided title. */ void onAddToHomescreen(String title); /** * Called when the user requests app details. + * * @return Whether the view should be dismissed. */ boolean onAppDetailsRequested();
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java index accddc4..b3ba79f 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppBannerManager.java
@@ -22,15 +22,15 @@ /** * Manages an AppBannerInfoBar for a WebContents. * - * The AppBannerManager is responsible for fetching details about native apps to display in the + * <p>The AppBannerManager is responsible for fetching details about native apps to display in the * banner. The actual observation of the WebContents (which triggers the automatic creation and * removal of banners, among other things) is done by the native-side AppBannerManagerAndroid. */ @JNINamespace("webapps") public class AppBannerManager { /** - * A struct containing the string resources IDs for the strings to show in the install - * dialog (both the dialog title and the accept button). + * A struct containing the string resources IDs for the strings to show in the install dialog + * (both the dialog title and the accept button). */ public static class InstallStringPair { public final @StringRes int titleTextId; @@ -61,6 +61,7 @@ /** * Checks if the add to home screen intent is supported. + * * @return true if add to home screen is supported, false otherwise. */ @CalledByNative @@ -79,7 +80,8 @@ /** * Sets the delegate that provides information about a given package. - * @param delegate Delegate to use. Previously set ones are destroyed. + * + * @param delegate Delegate to use. Previously set ones are destroyed. */ public static void setAppDetailsDelegate(AppDetailsDelegate delegate) { if (sAppDetailsDelegate != null) sAppDetailsDelegate.destroy(); @@ -88,6 +90,7 @@ /** * Constructs an AppBannerManager. + * * @param nativePointer the native-side object that owns this AppBannerManager. */ private AppBannerManager(long nativePointer) { @@ -106,7 +109,8 @@ /** * Grabs package information for the banner asynchronously. - * @param url URL for the page that is triggering the banner. + * + * @param url URL for the page that is triggering the banner. * @param packageName Name of the package that is being advertised. */ @CalledByNative @@ -131,7 +135,8 @@ /** * Called when data about the package has been retrieved, which includes the url for the * app's icon but not the icon Bitmap itself. - * @param data Data about the app. Null if the task failed. + * + * @param data Data about the app. Null if the task failed. */ @Override public void onAppDetailsRetrieved(AppData data) { @@ -140,9 +145,14 @@ String imageUrl = data.imageUrl(); if (TextUtils.isEmpty(imageUrl)) return; - AppBannerManagerJni.get().onAppDetailsRetrieved(mNativePointer, - AppBannerManager.this, data, data.title(), data.packageName(), - data.imageUrl()); + AppBannerManagerJni.get() + .onAppDetailsRetrieved( + mNativePointer, + AppBannerManager.this, + data, + data.title(), + data.packageName(), + data.imageUrl()); } }; } @@ -211,6 +221,7 @@ /** * Checks whether the renderer has navigated to a PWA. + * * @param contents The web contents to check. * @return true if the site has been determined to contain a PWA. */ @@ -225,17 +236,32 @@ @NativeMethods public interface Natives { AppBannerManager getJavaBannerManagerForWebContents(WebContents webContents); + String getInstallableWebAppName(WebContents webContents); + String getInstallableWebAppManifestId(WebContents webContents); - boolean onAppDetailsRetrieved(long nativeAppBannerManagerAndroid, AppBannerManager caller, - AppData data, String title, String packageName, String imageUrl); + + boolean onAppDetailsRetrieved( + long nativeAppBannerManagerAndroid, + AppBannerManager caller, + AppData data, + String title, + String packageName, + String imageUrl); + // Testing methods. void ignoreChromeChannelForTesting(); + boolean isRunningForTesting(long nativeAppBannerManagerAndroid, AppBannerManager caller); + int getPipelineStatusForTesting(long nativeAppBannerManagerAndroid); + int getBadgeStatusForTesting(long nativeAppBannerManagerAndroid); + void setDaysAfterDismissAndIgnoreToTrigger(int dismissDays, int ignoreDays); + void setTimeDeltaForTesting(int days); + void setTotalEngagementToTrigger(double engagement); } }
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppData.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppData.java index e31f8ff..c500d9b9 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppData.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppData.java
@@ -7,9 +7,7 @@ import android.app.PendingIntent; import android.content.Intent; -/** - * Stores information about a particular app. - */ +/** Stores information about a particular app. */ public class AppData { // Immutable data about this app. private final String mSiteUrl; @@ -25,7 +23,8 @@ /** * Creates a new AppData for the given page and package. - * @param siteUrl URL for the site requesting the banner. + * + * @param siteUrl URL for the site requesting the banner. * @param packageName Name of the package associated with the app. */ public AppData(String siteUrl, String packageName) { @@ -35,6 +34,7 @@ /** * Returns the URL of the website requesting the banner. + * * @return The URL of the website. */ public String siteUrl() { @@ -43,6 +43,7 @@ /** * Returns the package name of the app. + * * @return The String containing the package name. */ public String packageName() { @@ -51,6 +52,7 @@ /** * Returns the title to display for the app in the banner. + * * @return The String to display. */ public String title() { @@ -59,6 +61,7 @@ /** * Returns the URL where the app icon can be retrieved from. + * * @return The URL to grab the icon from. */ public String imageUrl() { @@ -67,6 +70,7 @@ /** * Returns how well the app was rated, on a scale from 0 to 5. + * * @return The rating of the app. */ public float rating() { @@ -75,6 +79,7 @@ /** * Returns text to display on the install button when the app is not installed on the system. + * * @return The String to display. */ public String installButtonText() { @@ -82,8 +87,9 @@ } /** - * Returns the Intent used to send a user to a details page about the app. - * The IntentSender stored inside dictates what package needs to be launched. + * Returns the Intent used to send a user to a details page about the app. The IntentSender + * stored inside dictates what package needs to be launched. + * * @return Intent that triggers the details page. */ public PendingIntent detailsIntent() { @@ -92,6 +98,7 @@ /** * Returns the Intent that triggers the install. + * * @return Intent used to trigger the install. */ public Intent installIntent() { @@ -100,15 +107,21 @@ /** * Stores all of the data about the given app after it's been retrieved. - * @param title App title. - * @param imageUrl URL where the icon is located. - * @param rating Rating of the app. + * + * @param title App title. + * @param imageUrl URL where the icon is located. + * @param rating Rating of the app. * @param installButtonText Text to display on the install button if it's not installed yet. - * @param detailsIntent Intent to fire to launch the details page for the app - * @param installIntent Intent to fire to trigger the purchase/install process. + * @param detailsIntent Intent to fire to launch the details page for the app + * @param installIntent Intent to fire to trigger the purchase/install process. */ - public void setPackageInfo(String title, String imageUrl, float rating, - String installButtonText, PendingIntent detailsIntent, Intent installIntent) { + public void setPackageInfo( + String title, + String imageUrl, + float rating, + String installButtonText, + PendingIntent detailsIntent, + Intent installIntent) { mTitle = title; mImageUrl = imageUrl; mRating = rating;
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppDetailsDelegate.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppDetailsDelegate.java index a0ebedd..1b739d6 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppDetailsDelegate.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/AppDetailsDelegate.java
@@ -4,35 +4,31 @@ package org.chromium.components.webapps; -/** - * Fetches data about the given app. - */ +/** Fetches data about the given app. */ public abstract class AppDetailsDelegate { - /** - * Class to inform when the app's details have been retrieved. - */ + /** Class to inform when the app's details have been retrieved. */ public interface Observer { /** * Called when the task has finished. - * @param data Data about the requested package. Will be null if retrieval failed. + * + * @param data Data about the requested package. Will be null if retrieval failed. */ public void onAppDetailsRetrieved(AppData data); } /** - * Retrieves information about the given package asynchronously. When details have been + * Retrieves information about the given package asynchronously. When details have been * retrieved, the observer is alerted. - * @param observer Informed when the app details have been received. - * @param url URL of the page requesting a banner. + * + * @param observer Informed when the app details have been received. + * @param url URL of the page requesting a banner. * @param packageName Name of the app's package. - * @param referrer Referrer specified by the page requesting a banner. - * @param iconSize Size of the icon to retrieve. + * @param referrer Referrer specified by the page requesting a banner. + * @param iconSize Size of the icon to retrieve. */ public abstract void getAppDetailsAsynchronously( Observer observer, String url, String packageName, String referrer, int iconSize); - /** - * Destroy the delegate, cleaning up any open hooks. - */ + /** Destroy the delegate, cleaning up any open hooks. */ public abstract void destroy(); }
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java index 9472f25..32a72021 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java
@@ -29,9 +29,8 @@ import org.chromium.url.GURL; /** - * This class contains functions related to adding shortcuts to the Android Home - * screen. These shortcuts are used to either open a page in the main browser - * or open a web app. + * This class contains functions related to adding shortcuts to the Android Home screen. These + * shortcuts are used to either open a page in the main browser or open a web app. */ public class WebappsIconUtils { private static final String TAG = "WebappsIconUtils"; @@ -76,11 +75,14 @@ Bitmap padded = createHomeScreenIconFromWebIcon(bitmap, true); Icon adaptiveIcon = Icon.createWithAdaptiveBitmap(padded); AdaptiveIconDrawable adaptiveIconDrawable = - (AdaptiveIconDrawable) adaptiveIcon.loadDrawable( - ContextUtils.getApplicationContext()); + (AdaptiveIconDrawable) + adaptiveIcon.loadDrawable(ContextUtils.getApplicationContext()); - Bitmap result = Bitmap.createBitmap(adaptiveIconDrawable.getIntrinsicWidth(), - adaptiveIconDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + Bitmap result = + Bitmap.createBitmap( + adaptiveIconDrawable.getIntrinsicWidth(), + adaptiveIconDrawable.getIntrinsicHeight(), + Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); adaptiveIconDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); adaptiveIconDrawable.draw(canvas); @@ -138,8 +140,9 @@ } /** - * Returns the ideal size for an icon representing a web app. This size is used on app banners, + * Returns the ideal size for an icon representing a web app. This size is used on app banners, * the Android Home screen, and in Android's recent tasks list, among other places. + * * @param context Context to pull resources from. * @return the dimensions in pixels which the icon should have. */ @@ -148,8 +151,9 @@ } /** - * Returns the minimum size for an icon representing a web app. This size is used on app + * Returns the minimum size for an icon representing a web app. This size is used on app * banners, the Android Home screen, and in Android's recent tasks list, among other places. + * * @param context Context to pull resources from. * @return the lower bound of the size which the icon should have in pixels. */ @@ -163,6 +167,7 @@ /** * Returns the ideal size for an image displayed on a web app's splash screen. + * * @param context Context to pull resources from. * @return the dimensions in pixels which the image should have. */ @@ -172,6 +177,7 @@ /** * Returns the minimum size for an image displayed on a web app's splash screen. + * * @param context Context to pull resources from. * @return the lower bound of the size which the image should have in pixels. */ @@ -181,6 +187,7 @@ /** * Returns the ideal size for a monochrome icon of a WebAPK. + * * @param context Context to pull resources from. * @return the dimensions in pixels which the monochrome icon should have. */ @@ -190,6 +197,7 @@ /** * Returns the ideal size for an adaptive launcher icon of a WebAPK. + * * @param context Context to pull resources from. * @return the dimensions in pixels which the adaptive launcher icon should have. */ @@ -199,6 +207,7 @@ /** * Returns the ideal size for prompt UI icon corner radius. + * * @return the dimensions in pixels which the prompt UI should use as the corner radius. */ @CalledByNative @@ -207,16 +216,15 @@ return context.getResources().getDimensionPixelSize(R.dimen.webapk_prompt_ui_icon_radius); } - /** - * Check the running Android version supports adaptive icon (i.e. API level >= 26) - */ + /** Check the running Android version supports adaptive icon (i.e. API level >= 26) */ public static boolean doesAndroidSupportMaskableIcons() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; } /** * Returns whether the given icon matches the size requirements to be used on the home screen. - * @param width Icon width, in pixels. + * + * @param width Icon width, in pixels. * @param height Icon height, in pixels. * @return whether the given icon matches the size requirements to be used on the home screen. */ @@ -229,13 +237,13 @@ } /** - * Generates a generic icon to be used in the launcher. This is just a rounded rectangle with - * a letter in the middle taken from the website's domain name. + * Generates a generic icon to be used in the launcher. This is just a rounded rectangle with a + * letter in the middle taken from the website's domain name. * - * @param url URL of the shortcut. - * @param red Red component of the dominant icon color. + * @param url URL of the shortcut. + * @param red Red component of the dominant icon color. * @param green Green component of the dominant icon color. - * @param blue Blue component of the dominant icon color. + * @param blue Blue component of the dominant icon color. * @return Bitmap Either the touch-icon or the newly created favicon. */ @CalledByNative @@ -285,11 +293,15 @@ private static int[] getIconSizes() { Context context = ContextUtils.getApplicationContext(); // This ordering must be kept up to date with the C++ WebappsIconUtils. - return new int[] {getIdealHomescreenIconSizeInPx(context), - getMinimumHomescreenIconSizeInPx(context), getIdealSplashImageSizeInPx(context), - getMinimumSplashImageSizeInPx(context), getIdealMonochromeIconSizeInPx(context), - getIdealAdaptiveLauncherIconSizeInPx(context), - ViewUtils.dpToPx(context, SHORTCUT_ICON_IDEAL_SIZE_DP)}; + return new int[] { + getIdealHomescreenIconSizeInPx(context), + getMinimumHomescreenIconSizeInPx(context), + getIdealSplashImageSizeInPx(context), + getMinimumSplashImageSizeInPx(context), + getIdealMonochromeIconSizeInPx(context), + getIdealAdaptiveLauncherIconSizeInPx(context), + ViewUtils.dpToPx(context, SHORTCUT_ICON_IDEAL_SIZE_DP) + }; } /** @@ -301,7 +313,8 @@ int maxX = icon.getWidth() - 1; int maxY = icon.getHeight() - 1; - if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixel(maxX, maxY)) != 0) + if ((Color.alpha(icon.getPixel(0, 0)) != 0) + && (Color.alpha(icon.getPixel(maxX, maxY)) != 0) && (Color.alpha(icon.getPixel(0, maxY)) != 0) && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) { return true;
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java index 7a5b0fe..e0a5546 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsUtils.java
@@ -28,9 +28,7 @@ import java.util.List; -/** - * Contains utilities for Web Apps and homescreen shortcuts. - */ +/** Contains utilities for Web Apps and homescreen shortcuts. */ public class WebappsUtils { private static final String TAG = "WebappsUtils"; @@ -44,8 +42,9 @@ /** * Creates an intent that will add a shortcut to the home screen. - * @param title Title of the shortcut. - * @param icon Image that represents the shortcut. + * + * @param title Title of the shortcut. + * @param icon Image that represents the shortcut. * @param shortcutIntent Intent to fire when the shortcut is activated. * @return Intent for the shortcut. */ @@ -59,6 +58,7 @@ /** * Request Android to add a shortcut to the home screen. + * * @param id The generated GUID of the shortcut. * @param title Title of the shortcut. * @param icon Image that represents the shortcut. @@ -86,28 +86,30 @@ Log.e(TAG, "Failed to find an icon for " + title + ", not adding."); return; } - Icon icon = isMaskableIcon ? Icon.createWithAdaptiveBitmap(bitmap) - : Icon.createWithBitmap(bitmap); + Icon icon = + isMaskableIcon + ? Icon.createWithAdaptiveBitmap(bitmap) + : Icon.createWithBitmap(bitmap); - ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(context, id) - .setShortLabel(title) - .setLongLabel(title) - .setIcon(icon) - .setIntent(shortcutIntent) - .build(); + ShortcutInfo shortcutInfo = + new ShortcutInfo.Builder(context, id) + .setShortLabel(title) + .setLongLabel(title) + .setIcon(icon) + .setIntent(shortcutIntent) + .build(); try { ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class); shortcutManager.requestPinShortcut(shortcutInfo, null); } catch (IllegalStateException e) { - Log.d(TAG, + Log.d( + TAG, "Could not create pinned shortcut: device is locked, or " + "activity is backgrounded."); } } - /** - * Show toast to alert user that the shortcut was added to the home screen. - */ + /** Show toast to alert user that the shortcut was added to the home screen. */ private static void showAddedToHomescreenToast(final String title) { Context applicationContext = ContextUtils.getApplicationContext(); String toastText = applicationContext.getString(R.string.added_to_homescreen, title); @@ -138,6 +140,7 @@ /** * Utility method to check if a shortcut can be added to the home screen. + * * @return if a shortcut can be added to the home screen under the current profile. */ @SuppressLint("WrongConstant") @@ -182,6 +185,7 @@ /** * Override whether shortcuts are considered supported for testing. + * * @param supported Whether shortcuts are supported. Pass null to reset. */ public static void setAddToHomeIntentSupportedForTesting(Boolean supported) {
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/bottomsheet/ImageZoomView.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/bottomsheet/ImageZoomView.java index 263d681..b6dc27a2 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/bottomsheet/ImageZoomView.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/bottomsheet/ImageZoomView.java
@@ -13,9 +13,7 @@ import org.chromium.components.browser_ui.widget.FullscreenAlertDialog; import org.chromium.components.webapps.R; -/** - * UI for the zoomed image view used for screenshots in the bottom-sheet UI for PWA installs. - */ +/** UI for the zoomed image view used for screenshots in the bottom-sheet UI for PWA installs. */ public class ImageZoomView extends FullscreenAlertDialog { public ImageZoomView(Context context, Bitmap bitmap) { super(context);
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/installable/InstallableAmbientBadgeInfoBar.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/installable/InstallableAmbientBadgeInfoBar.java index 4f6ae84a..8d0049e 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/installable/InstallableAmbientBadgeInfoBar.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/installable/InstallableAmbientBadgeInfoBar.java
@@ -24,9 +24,7 @@ import org.chromium.components.webapps.R; import org.chromium.components.webapps.WebappsIconUtils; -/** - * An ambient infobar to tell the user that the current site they are visiting is a PWA. - */ +/** An ambient infobar to tell the user that the current site they are visiting is a PWA. */ @JNINamespace("webapps") public class InstallableAmbientBadgeInfoBar extends InfoBar implements View.OnClickListener { private String mMessageText; @@ -83,15 +81,16 @@ public void onClick(View v) { if (getNativeInfoBarPtr() == 0 || mIsHiding) return; - InstallableAmbientBadgeInfoBarJni.get().addToHomescreen( - getNativeInfoBarPtr(), InstallableAmbientBadgeInfoBar.this); + InstallableAmbientBadgeInfoBarJni.get() + .addToHomescreen(getNativeInfoBarPtr(), InstallableAmbientBadgeInfoBar.this); } /** * Creates the infobar. - * @param iconDrawableId Drawable ID corresponding to the icon that the infobar will show. - * @param iconBitmap Bitmap of the icon to display in the infobar. - * @param messageText String to display + * + * @param iconDrawableId Drawable ID corresponding to the icon that the infobar will show. + * @param iconBitmap Bitmap of the icon to display in the infobar. + * @param messageText String to display */ private InstallableAmbientBadgeInfoBar( int iconDrawableId, Bitmap iconBitmap, String messageText, String url) {
diff --git a/content/browser/DEPS b/content/browser/DEPS index 1e79dbf1..24551ef 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -13,9 +13,6 @@ "+components/file_access", "+components/filename_generation", "+components/grit", - # TODO(crbug.com/1501507): Remove illegal dependency of content/browser/ to - # components/permissions/features.h - "!components/permissions/features.h", "+components/power_monitor", "+components/services/font", "+components/services/filesystem",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index dff0ff8..c3911c00 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -202,6 +202,7 @@ DumpAccessibilityTreeTestPassToString()); // TODO(crbug.com/1428967): Flaky on asan of linux, chromeos and win. +// This is not fixed by rebuilding the subtree when parsing is complete. IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, MAYBE_ASAN(AccessibilityCSSAltText)) { RunCSSTest(FILE_PATH_LITERAL("alt-text.html")); @@ -226,10 +227,13 @@ RunCSSTest(FILE_PATH_LITERAL("content-visibility-auto-crash.html")); } -// TODO(https://crbug.com/1367886): Flaky on ASan builders. -IN_PROC_BROWSER_TEST_P( - DumpAccessibilityTreeTest, - MAYBE_ASAN(AccessibilityCSSContentVisibilityAutoAriaHidden)) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + AccessibilityCSSContentVisibilityAutoAriaHidden) { + RunCSSTest(FILE_PATH_LITERAL("content-visibility-auto-aria-hidden.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityCSSContentVisibilityAutoAriaHidden) { RunCSSTest(FILE_PATH_LITERAL("content-visibility-auto-aria-hidden.html")); } @@ -247,9 +251,13 @@ RunCSSTest(FILE_PATH_LITERAL("counter-text.html")); } -// TODO(crbug.com/1480429): Flaky IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_ASAN(AccessibilityCSSDisplayContents)) { + AccessibilityCSSDisplayContents) { + RunCSSTest(FILE_PATH_LITERAL("display-contents.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityCSSDisplayContents) { RunCSSTest(FILE_PATH_LITERAL("display-contents.html")); } @@ -270,10 +278,14 @@ RunCSSTest(FILE_PATH_LITERAL("head-style-script-display-block.html")); } -// TODO(https://crbug.com/1367886): Flaky on ASan builders. -IN_PROC_BROWSER_TEST_P( - DumpAccessibilityTreeTest, - MAYBE_ASAN(AccessibilityCSSHeadStyleScriptContentVisibilityHidden)) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + AccessibilityCSSHeadStyleScriptContentVisibilityHidden) { + RunCSSTest( + FILE_PATH_LITERAL("head-style-script-content-visibility-hidden.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityCSSHeadStyleScriptContentVisibilityHidden) { RunCSSTest( FILE_PATH_LITERAL("head-style-script-content-visibility-hidden.html")); } @@ -1552,6 +1564,11 @@ RunHtmlTest(FILE_PATH_LITERAL("table-canvas-fallback.html")); } +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityTableCanvasFallback) { + RunHtmlTest(FILE_PATH_LITERAL("table-canvas-fallback.html")); +} + IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityTableColumnHidden) { RunAriaTest(FILE_PATH_LITERAL("table-column-hidden.html")); @@ -1599,13 +1616,7 @@ RunHtmlTest(FILE_PATH_LITERAL("a-with-before.html")); } -// TODO(crbug.com/1479326): Fix flaky test on Linux and Mac. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) -#define MAYBE_AccessibilityAWithImg DISABLED_AccessibilityAWithImg -#else -#define MAYBE_AccessibilityAWithImg AccessibilityAWithImg -#endif -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, MAYBE_AccessibilityAWithImg) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAWithImg) { RunHtmlTest(FILE_PATH_LITERAL("a-with-img.html")); } @@ -1702,6 +1713,11 @@ RunHtmlTest(FILE_PATH_LITERAL("canvas-fallback.html")); } +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityCanvasFallback) { + RunHtmlTest(FILE_PATH_LITERAL("canvas-fallback.html")); +} + // TODO(crbug.com/1193963): fails on Windows. #if BUILDFLAG(IS_WIN) #define MAYBE_AccessibilityCaption DISABLED_AccessibilityCaption @@ -1829,15 +1845,20 @@ } // TODO(https://crbug.com/1367886): Flaky on asan builder on multiple platforms. +// This is not fixed by rebuilding the subtree when parsing is complete. IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, MAYBE_ASAN(AccessibilityContenteditableDocsLi)) { RunHtmlTest(FILE_PATH_LITERAL("contenteditable-docs-li.html")); } -// TODO(https://crbug.com/1367886): Flaky on asan builder on multiple platforms. -IN_PROC_BROWSER_TEST_P( - DumpAccessibilityTreeTest, - MAYBE_ASAN(AccessibilityContenteditableLiContainsPresentation)) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + AccessibilityContenteditableLiContainsPresentation) { + RunHtmlTest( + FILE_PATH_LITERAL("contenteditable-li-contains-presentation.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityContenteditableLiContainsPresentation) { RunHtmlTest( FILE_PATH_LITERAL("contenteditable-li-contains-presentation.html")); } @@ -1915,6 +1936,7 @@ } // TODO(crbug.com/1485244): Fails on ASAN/LSAN bots. +// This is not fixed by rebuilding the subtree when parsing is complete. #if defined(ADDRESS_SANITIZER) #define MAYBE_AccessibilityCustomElementWithAriaOwnsOutside \ DISABLED_AccessibilityCustomElementWithAriaOwnsOutside @@ -2291,15 +2313,13 @@ RunHtmlTest(FILE_PATH_LITERAL("input-checkbox.html")); } -// TODO(crbug.com/1428967): Flaky on asan and linux-chromeos-dbg. -#if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER) || BUILDFLAG(IS_CHROMEOS) -#define MAYBE_AccessibilityInputCheckBoxInMenu \ - DISABLED_AccessibilityInputCheckBoxInMenu -#else -#define MAYBE_AccessibilityInputCheckBoxInMenu AccessibilityInputCheckBoxInMenu -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilityInputCheckBoxInMenu) { + AccessibilityInputCheckBoxInMenu) { + RunHtmlTest(FILE_PATH_LITERAL("input-checkbox-in-menu.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityInputCheckBoxInMenu) { RunHtmlTest(FILE_PATH_LITERAL("input-checkbox-in-menu.html")); } @@ -2922,9 +2942,12 @@ RunHtmlTest(FILE_PATH_LITERAL("param.html")); } -// TODO(crbug.com/1476950) Disabled due to flakiness. -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - DISABLED_AccessibilityPopoverApi) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityPopoverApi) { + RunHtmlTest(FILE_PATH_LITERAL("popover-api.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityPopoverApi) { RunHtmlTest(FILE_PATH_LITERAL("popover-api.html")); } @@ -2938,14 +2961,12 @@ RunHtmlTest(FILE_PATH_LITERAL("popover-collapsed.html")); } -// TODO(https://crbug.com/1367886): Flaky on ASan and chromeos builders. -#if BUILDFLAG(IS_CHROMEOS) || defined(ADDRESS_SANITIZER) -#define MAYBE_AccessibilityPopoverHint DISABLED_AccessibilityPopoverHint -#else -#define MAYBE_AccessibilityPopoverHint AccessibilityPopoverHint -#endif -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilityPopoverHint) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityPopoverHint) { + RunPopoverHintTest(FILE_PATH_LITERAL("popover-hint.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityPopoverHint) { RunPopoverHintTest(FILE_PATH_LITERAL("popover-hint.html")); } @@ -3068,14 +3089,12 @@ RunHtmlTest(FILE_PATH_LITERAL("select.html")); } -// Flaky on Android and linux-chromeos-dbg - crbug.com/1367886 -#if BUILDFLAG(IS_CHROMEOS) -#define MAYBE_AccessibilitySelectInCanvas DISABLED_AccessibilitySelectInCanvas -#else -#define MAYBE_AccessibilitySelectInCanvas AccessibilitySelectInCanvas -#endif -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilitySelectInCanvas) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilitySelectInCanvas) { + RunHtmlTest(FILE_PATH_LITERAL("select-in-canvas.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilitySelectInCanvas) { RunHtmlTest(FILE_PATH_LITERAL("select-in-canvas.html")); } @@ -3137,6 +3156,7 @@ } // TODO(https://crbug.com/1367886): Flaky on asan builder on multiple platforms. +// This is not fixed by rebuilding the subtree when parsing is complete. IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, MAYBE_ASAN(AccessibilitySpanLineBreak)) { RunHtmlTest(FILE_PATH_LITERAL("span-line-break.html")); @@ -3206,22 +3226,23 @@ RunHtmlTest(FILE_PATH_LITERAL("svg-desc-in-group.html")); } -// TODO(crbug.com/1480429): Flaky -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) -#define MAYBE_AccessibilitySvgElementsNotMapped \ - DISABLED_AccessibilitySvgElementsNotMapped -#else -#define MAYBE_AccessibilitySvgElementsNotMapped \ - AccessibilitySvgElementsNotMapped -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilitySvgElementsNotMapped) { + AccessibilitySvgElementsNotMapped) { RunHtmlTest(FILE_PATH_LITERAL("svg-elements-not-mapped.html")); } -// TODO(crbug.com/1367886): Enable once thread flakiness is resolved. +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilitySvgElementsNotMapped) { + RunHtmlTest(FILE_PATH_LITERAL("svg-elements-not-mapped.html")); +} + IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - DISABLED_AccessibilitySvgTextAlternativeComputation) { + AccessibilitySvgTextAlternativeComputation) { + RunHtmlTest(FILE_PATH_LITERAL("svg-text-alternative-computation.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilitySvgTextAlternativeComputation) { RunHtmlTest(FILE_PATH_LITERAL("svg-text-alternative-computation.html")); } @@ -3276,6 +3297,11 @@ RunHtmlTest(FILE_PATH_LITERAL("table-layout.html")); } +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + AccessibilityTableLayout) { + RunHtmlTest(FILE_PATH_LITERAL("table-layout.html")); +} + IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityTablePresentation) { RunHtmlTest(FILE_PATH_LITERAL("table-presentation.html")); @@ -3320,17 +3346,14 @@ RunHtmlTest(FILE_PATH_LITERAL("table-headers-row-role-dynamic.html")); } -// TODO(https://crbug.com/1367886): Flaky on ASan builders. -// TODO(https://crbug.com/1503056): Flaky on linux-chromeos-dbg. -#if BUILDFLAG(IS_CHROMEOS) || defined(ADDRESS_SANITIZER) -#define MAYBE_AccessibilityTableMultipleRowAndColumnHeaders \ - DISABLED_AccessibilityTableMultipleRowAndColumnHeaders -#else -#define MAYBE_AccessibilityTableMultipleRowAndColumnHeaders \ - AccessibilityTableMultipleRowAndColumnHeaders -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilityTableMultipleRowAndColumnHeaders) { + AccessibilityTableMultipleRowAndColumnHeaders) { + RunHtmlTest(FILE_PATH_LITERAL("table-multiple-row-and-column-headers.html")); +} + +// TODO(https://crbug.com/1367886): De-flake and reenable. +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + DISABLED_AccessibilityTableMultipleRowAndColumnHeaders) { RunHtmlTest(FILE_PATH_LITERAL("table-multiple-row-and-column-headers.html")); } @@ -3534,9 +3557,12 @@ // DisplayLocking tests // -// TODO(https://crbug.com/1367886): Flaky on ASan builders. -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_ASAN(DisplayLockingActivatable)) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DisplayLockingActivatable) { + RunDisplayLockingTest(FILE_PATH_LITERAL("activatable.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + DisplayLockingActivatable) { RunDisplayLockingTest(FILE_PATH_LITERAL("activatable.html")); } @@ -3550,9 +3576,12 @@ RunDisplayLockingTest(FILE_PATH_LITERAL("viewport-activation.html")); } -// TODO(https://crbug.com/1367886): Flaky on ASan builders. -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_ASAN(DisplayLockingAll)) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DisplayLockingAll) { + RunDisplayLockingTest(FILE_PATH_LITERAL("all.html")); +} + +IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest, + DisplayLockingAll) { RunDisplayLockingTest(FILE_PATH_LITERAL("all.html")); }
diff --git a/content/browser/attribution_reporting/attribution_report.cc b/content/browser/attribution_reporting/attribution_report.cc index cbf6c27..c09faac 100644 --- a/content/browser/attribution_reporting/attribution_report.cc +++ b/content/browser/attribution_reporting/attribution_report.cc
@@ -54,7 +54,7 @@ } // namespace -AttributionReport::EventLevelData::EventLevelData(uint64_t trigger_data, +AttributionReport::EventLevelData::EventLevelData(uint32_t trigger_data, int64_t priority, StoredSource source) : trigger_data(trigger_data),
diff --git a/content/browser/attribution_reporting/attribution_report.h b/content/browser/attribution_reporting/attribution_report.h index 851ee6e4..ce9a8ad 100644 --- a/content/browser/attribution_reporting/attribution_report.h +++ b/content/browser/attribution_reporting/attribution_report.h
@@ -44,9 +44,7 @@ // Struct that contains the data specific to the event-level report. struct CONTENT_EXPORT EventLevelData { - EventLevelData(uint64_t trigger_data, - int64_t priority, - StoredSource); + EventLevelData(uint32_t trigger_data, int64_t priority, StoredSource); EventLevelData(const EventLevelData&); EventLevelData& operator=(const EventLevelData&); EventLevelData(EventLevelData&&); @@ -56,8 +54,7 @@ // Data provided at trigger time by the attribution destination. Depending // on the source type, this contains the associated data in the trigger // redirect. - // TODO(apaseltiner): Change this to `uint32_t`. - uint64_t trigger_data; + uint32_t trigger_data; // Priority specified in conversion redirect. int64_t priority;
diff --git a/content/browser/attribution_reporting/attribution_reporting.proto b/content/browser/attribution_reporting/attribution_reporting.proto index 116a240..4ab7253 100644 --- a/content/browser/attribution_reporting/attribution_reporting.proto +++ b/content/browser/attribution_reporting/attribution_reporting.proto
@@ -48,7 +48,7 @@ } message AttributionEventLevelMetadata { - optional uint64 trigger_data = 1; + optional uint32 trigger_data = 1; optional int64 priority = 2; }
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 6f7718e..7bf69325 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -787,7 +787,7 @@ continue; } - uint64_t trigger_data; + uint32_t trigger_data; int64_t priority; if (!DeserializeReportMetadata(metadata, trigger_data, priority)) { continue; @@ -1503,7 +1503,7 @@ ReportCorruptionStatus::kSourceDataMissingEventLevel); break; } - uint64_t trigger_data; + uint32_t trigger_data; int64_t priority; if (!DeserializeReportMetadata(metadata, trigger_data, priority)) { corruption_causes.Put(ReportCorruptionStatus::kInvalidMetadata);
diff --git a/content/browser/attribution_reporting/privacy_math.cc b/content/browser/attribution_reporting/privacy_math.cc index 1ea60bd..1c25727 100644 --- a/content/browser/attribution_reporting/privacy_math.cc +++ b/content/browser/attribution_reporting/privacy_math.cc
@@ -9,6 +9,7 @@ #include <algorithm> #include <cmath> #include <functional> +#include <iterator> #include <map> #include <tuple> #include <utility> @@ -437,15 +438,20 @@ } std::vector<FakeEventLevelReport> GetFakeReportsForSequenceIndex( - int trigger_data_cardinality, - const attribution_reporting::EventReportWindows& event_report_windows, + const attribution_reporting::TriggerSpecs& specs, int max_reports, int64_t random_stars_and_bars_sequence_index) { + const attribution_reporting::TriggerSpec* single_spec = + specs.SingleSharedSpec(); + CHECK(single_spec); + + const int trigger_data_cardinality = specs.size(); + const std::vector<int> bars_preceding_each_star = GetBarsPrecedingEachStar(GetStarIndices( /*num_stars=*/max_reports, /*num_bars=*/trigger_data_cardinality * - event_report_windows.end_times().size(), + single_spec->event_report_windows().end_times().size(), /*sequence_index=*/random_stars_and_bars_sequence_index)); std::vector<FakeEventLevelReport> fake_reports; @@ -462,12 +468,16 @@ auto result = std::div(num_bars - 1, trigger_data_cardinality); - const int trigger_data = result.rem; - DCHECK_GE(trigger_data, 0); - DCHECK_LT(trigger_data, trigger_data_cardinality); + const int trigger_data_index = result.rem; + DCHECK_GE(trigger_data_index, 0); + DCHECK_LT(trigger_data_index, trigger_data_cardinality); - fake_reports.push_back({.trigger_data = static_cast<uint64_t>(trigger_data), - .window_index = result.quot}); + fake_reports.push_back({ + .trigger_data = + std::next(specs.trigger_data_indices().begin(), trigger_data_index) + ->first, + .window_index = result.quot, + }); } DCHECK_LE(fake_reports.size(), static_cast<size_t>(max_reports)); return fake_reports; @@ -489,15 +499,12 @@ // spec if all of the specs have the same # of windows and reports. We can // consider further optimizing if it's useful. The existing code will cover // the default specs for navigation / event sources. - const attribution_reporting::TriggerSpec* single_spec = - specs.SingleSharedSpec(); const absl::uint128 sequence_index = RandGenerator(num_states); DCHECK_GE(sequence_index, 0); DCHECK_LT(sequence_index, kMaxNumCombinations); - fake_reports = single_spec + fake_reports = specs.SingleSharedSpec() ? internal::GetFakeReportsForSequenceIndex( - /*trigger_data_cardinality=*/specs.size(), - single_spec->event_report_windows(), max_reports, + specs, max_reports, base::checked_cast<int64_t>( absl::Uint128Low64(sequence_index))) : internal::GetFakeReportsForSequenceIndex(
diff --git a/content/browser/attribution_reporting/privacy_math.h b/content/browser/attribution_reporting/privacy_math.h index b84df95..e314f780 100644 --- a/content/browser/attribution_reporting/privacy_math.h +++ b/content/browser/attribution_reporting/privacy_math.h
@@ -17,15 +17,17 @@ #include "third_party/abseil-cpp/absl/types/optional.h" namespace attribution_reporting { -class EventReportWindows; class MaxEventLevelReports; class TriggerSpecs; } namespace content { +// TODO(apaseltiner): Use `uint8_t` as the type of both fields here, as the +// trigger data *index* is guaranteed to be < 32 and the window index is +// guaranteed to be < 5. struct FakeEventLevelReport { - uint64_t trigger_data; + uint32_t trigger_data; int window_index; friend std::strong_ordering operator<=>(const FakeEventLevelReport&, @@ -77,7 +79,7 @@ attribution_reporting::MaxEventLevelReports); // Determines the randomized response flip probability for the given API -// configuration, and performs randomized response on that otutput space. +// configuration, and performs randomized response on that output space. // // Returns `absl::nullopt` if the output should be determined truthfully. // Otherwise will return a vector of fake reports. @@ -144,9 +146,10 @@ // 2. For all other stars, count the number of bars that precede them. Each // star represents a report where the reporting window and trigger data is // uniquely determined by that number. +// +// `CHECK()`s `TriggerSpecs::SingleSharedSpec()`. CONTENT_EXPORT std::vector<FakeEventLevelReport> GetFakeReportsForSequenceIndex( - int trigger_data_cardinality, - const attribution_reporting::EventReportWindows&, + const attribution_reporting::TriggerSpecs&, int max_event_level_reports, int64_t random_stars_and_bars_sequence_index);
diff --git a/content/browser/attribution_reporting/privacy_math_unittest.cc b/content/browser/attribution_reporting/privacy_math_unittest.cc index 961db46..850b440 100644 --- a/content/browser/attribution_reporting/privacy_math_unittest.cc +++ b/content/browser/attribution_reporting/privacy_math_unittest.cc
@@ -13,7 +13,6 @@ #include "base/containers/flat_map.h" #include "base/time/time.h" -#include "components/attribution_reporting/constants.h" #include "components/attribution_reporting/event_report_windows.h" #include "components/attribution_reporting/max_event_level_reports.h" #include "components/attribution_reporting/source_type.mojom.h" @@ -366,16 +365,14 @@ }; for (const auto& test_case : kTestCases) { - int trigger_data_cardinality = - attribution_reporting::DefaultTriggerDataCardinality( - test_case.source_type); - int max_reports = test_case.source_type == SourceType::kEvent ? 1 : 3; EXPECT_EQ(test_case.expected, internal::GetFakeReportsForSequenceIndex( - trigger_data_cardinality, - *EventReportWindows::FromDefaults(base::Days(30), - test_case.source_type), - max_reports, test_case.sequence_index)) + attribution_reporting::TriggerSpecs::Default( + test_case.source_type, + *EventReportWindows::FromDefaults(base::Days(30), + test_case.source_type)), + MaxEventLevelReports(test_case.source_type), + test_case.sequence_index)) << test_case.sequence_index; } } @@ -564,5 +561,32 @@ } } +// Regression test for http://crbug.com/1503728 in which the optimized +// randomized-response incorrectly returned the trigger data *index* rather than +// the trigger data *value* in the fake reports. +TEST(PrivacyMathTest, NonDefaultTriggerDataForSingleSharedSpec) { + // Note that the trigger data does not start at 0. + const auto kSpecs = attribution_reporting::TriggerSpecs::CreateForTesting( + {{/*trigger_data=*/123, /*index=*/0}}, + {attribution_reporting::TriggerSpec()}); + + ASSERT_TRUE(kSpecs.SingleSharedSpec()); + + // There are only 2 states (0 reports or 1 report with trigger data 123), so + // loop until we hit the non-empty case. + + RandomizedResponse response; + do { + internal::StateMap map; + + response = + internal::DoRandomizedResponseWithCache(kSpecs, /*max_reports=*/1, + /*epsilon=*/0, map) + .response(); + } while (!response.has_value() || response->empty()); + + ASSERT_EQ(uint64_t{123u}, response->front().trigger_data); +} + } // namespace } // namespace content
diff --git a/content/browser/attribution_reporting/sql_utils.cc b/content/browser/attribution_reporting/sql_utils.cc index 368fd621..a34da07 100644 --- a/content/browser/attribution_reporting/sql_utils.cc +++ b/content/browser/attribution_reporting/sql_utils.cc
@@ -285,7 +285,7 @@ } bool DeserializeReportMetadata(const std::string& str, - uint64_t& trigger_data, + uint32_t& trigger_data, int64_t& priority) { proto::AttributionEventLevelMetadata msg; if (!msg.ParseFromString(str) || !msg.has_trigger_data() ||
diff --git a/content/browser/attribution_reporting/sql_utils.h b/content/browser/attribution_reporting/sql_utils.h index e71bea6..04e9a00 100644 --- a/content/browser/attribution_reporting/sql_utils.h +++ b/content/browser/attribution_reporting/sql_utils.h
@@ -81,7 +81,7 @@ const AttributionReport::NullAggregatableData&); [[nodiscard]] bool DeserializeReportMetadata(const std::string&, - uint64_t& trigger_data, + uint32_t& trigger_data, int64_t& priority); [[nodiscard]] bool DeserializeReportMetadata(
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc index ea0dcae..058df8d 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl_unittest.cc
@@ -10,6 +10,7 @@ #include <vector> #include "base/functional/callback.h" +#include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" #include "content/public/browser/storage_partition_config.h" #include "content/public/test/browser_task_environment.h" @@ -167,8 +168,10 @@ {"https://website.sp.nom.br", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, EmptyDelete) { @@ -187,8 +190,9 @@ {"http://192.168.1.1:80", false}, }; - for (TestCase test_case : test_cases) { - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); } } @@ -243,8 +247,10 @@ {"https://sp.nom.br", false}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, RegistrableDomainGURLPreserveList) { @@ -287,8 +293,10 @@ {"https://sp.nom.br", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, @@ -337,8 +345,10 @@ {"https://subdomain.second-level-domain.fileserver", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, builder.BuildCookieDeletionFilter()); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], builder.BuildCookieDeletionFilter()); + } } TEST(BrowsingDataFilterBuilderImplTest, EmptyCookieDeletionFilter) { @@ -395,8 +405,10 @@ {"https://subdomain.second-level-domain.fileserver", false}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, builder.BuildCookieDeletionFilter()); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], builder.BuildCookieDeletionFilter()); + } } TEST(BrowsingDataFilterBuilderImplTest, PartitionedCookies) { @@ -666,8 +678,10 @@ {"website.fileserver", false}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, @@ -701,8 +715,10 @@ {"website.fileserver", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, OriginDeleteList) { @@ -732,8 +748,10 @@ {"https://www.chromium.org", false}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, OriginPreserveList) { @@ -763,8 +781,10 @@ {"https://www.youtube.com", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, CombinedDeleteList) { @@ -786,8 +806,10 @@ {"https://www.example.com/?q=test", true}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, CombinedPreserveList) { @@ -809,8 +831,10 @@ {"https://www.example.com/?q=test", false}, }; - for (TestCase test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, PartitionedDeleteList) { @@ -842,8 +866,10 @@ {origin3, origin3, blink::mojom::AncestorChainBit::kCrossSite, true}, }; - for (auto test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, PartitionedPreserveList) { @@ -875,8 +901,10 @@ {origin3, origin3, blink::mojom::AncestorChainBit::kCrossSite, false}, }; - for (auto test_case : test_cases) - RunTestCase(test_case, filter); + for (size_t i = 0; i < std::size(test_cases); i++) { + SCOPED_TRACE(base::StringPrintf("Test case %zu", i)); + RunTestCase(test_cases[i], filter); + } } TEST(BrowsingDataFilterBuilderImplTest, GetOrigins) {
diff --git a/content/browser/browsing_data/clear_site_data_handler_unittest.cc b/content/browser/browsing_data/clear_site_data_handler_unittest.cc index 099405f..d00ee75 100644 --- a/content/browser/browsing_data/clear_site_data_handler_unittest.cc +++ b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
@@ -12,6 +12,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" +#include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -668,6 +669,8 @@ const GURL kTestURL("https://example.com"); for (const auto partitioned_state_allowed_only : test_cases) { + SCOPED_TRACE(base::StringPrintf("partitioned_state_allowed_only: %d", + partitioned_state_allowed_only)); auto context = net::CreateTestURLRequestContextBuilder()->Build(); std::unique_ptr<net::URLRequest> request( context->CreateRequest(kTestURL, net::DEFAULT_PRIORITY, nullptr,
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index bee8f8c3..afe951f 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -186,7 +186,7 @@ .SetSecure(cookie.IsSecure()) .SetSession(!cookie.IsPersistent()) .SetPriority(BuildCookiePriority(cookie.Priority())) - .SetSameParty(cookie.IsSameParty()) + .SetSameParty(false) .SetSourceScheme(BuildCookieSourceScheme(cookie.SourceScheme())) .SetSourcePort(cookie.SourcePort()) .Build();
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index d5e8338..e99d75a 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -12,7 +12,6 @@ #include "base/functional/bind.h" #include "base/memory/ptr_util.h" -#include "components/permissions/features.h" #include "content/browser/bad_message.h" #include "content/browser/permissions/permission_controller_impl.h" #include "content/browser/permissions/permission_util.h" @@ -20,6 +19,7 @@ #include "content/public/browser/permission_request_description.h" #include "content/public/browser/permission_result.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/common/content_features.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-shared.h" @@ -129,8 +129,7 @@ void PermissionServiceImpl::RegisterPageEmbeddedPermissionControl( std::vector<blink::mojom::PermissionDescriptorPtr> permissions, RegisterPageEmbeddedPermissionControlCallback callback) { - if (!base::FeatureList::IsEnabled( - permissions::features::kPermissionElement)) { + if (!base::FeatureList::IsEnabled(features::kPermissionElement)) { bad_message::ReceivedBadMessage( context_->render_frame_host()->GetProcess(), bad_message::PSI_REGISTER_PERMISSION_ELEMENT_WITHOUT_FEATURE); @@ -150,8 +149,7 @@ void PermissionServiceImpl::RequestPageEmbeddedPermission( EmbeddedPermissionRequestDescriptorPtr descriptor, RequestPageEmbeddedPermissionCallback callback) { - if (!base::FeatureList::IsEnabled( - permissions::features::kPermissionElement)) { + if (!base::FeatureList::IsEnabled(features::kPermissionElement)) { bad_message::ReceivedBadMessage( context_->render_frame_host()->GetProcess(), bad_message::PSI_REQUEST_EMBEDDED_PERMISSION_WITHOUT_FEATURE);
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager.cc b/content/browser/preloading/prefetch/prefetch_document_manager.cc index e810c30..ef201f1 100644 --- a/content/browser/preloading/prefetch/prefetch_document_manager.cc +++ b/content/browser/preloading/prefetch/prefetch_document_manager.cc
@@ -67,6 +67,8 @@ WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), document_token_( static_cast<RenderFrameHostImpl*>(rfh)->GetDocumentToken()), + no_vary_search_support_enabled_( + network::features::kPrefetchNoVarySearchShippedByDefault.Get()), prefetch_destruction_callback_(base::DoNothing()) {} PrefetchDocumentManager::~PrefetchDocumentManager() { @@ -389,10 +391,16 @@ } } -void PrefetchDocumentManager::EnableNoVarySearchSupport() { +void PrefetchDocumentManager::EnableNoVarySearchSupportFromOriginTrial() { no_vary_search_support_enabled_ = true; } +// In order to ship No-Vary-Search header and keep the Origin Trial and be +// able to remotely go back to Origin Trial in case we unship, we use +// the suggested approach at +// go/graduating-from-finch#optional-leave-a-finch-hook of using a separate +// base feature to control shipping - in our case we will continue to use the +// existing base feature kPrefetchNoVarySearch. bool PrefetchDocumentManager::NoVarySearchSupportEnabled() const { return no_vary_search_support_enabled_ && base::FeatureList::IsEnabled(network::features::kPrefetchNoVarySearch);
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager.h b/content/browser/preloading/prefetch/prefetch_document_manager.h index 903c27a..f8e54e7 100644 --- a/content/browser/preloading/prefetch/prefetch_document_manager.h +++ b/content/browser/preloading/prefetch/prefetch_document_manager.h
@@ -103,7 +103,7 @@ // Whether the prefetch attempt for target |url| failed or discarded bool IsPrefetchAttemptFailedOrDiscarded(const GURL& url); - void EnableNoVarySearchSupport(); + void EnableNoVarySearchSupportFromOriginTrial(); bool NoVarySearchSupportEnabled() const; // Returns a tuple: (can_prefetch_now, prefetch_to_evict). 'can_prefetch_now'
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc index 2a2d3af..a458a77a 100644 --- a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
@@ -111,7 +111,6 @@ auto* prefetch_document_manager = PrefetchDocumentManager::GetOrCreateForCurrentDocument( &GetPrimaryMainFrame()); - prefetch_document_manager->EnableNoVarySearchSupport(); // Create list of SpeculationCandidatePtrs. std::vector<blink::mojom::SpeculationCandidatePtr> candidates; @@ -453,5 +452,53 @@ GetCrossOriginUrl("/candidate1.html"))); } +// Struct describing the settings for No-Vary-Search experiment's flags used to +// support shipping and origin trial. +struct NoVarySearchExperimentConfigTestInfo { + bool shipped_by_default; + bool origin_trial_enabled; + bool experiment_expected_status; +}; + +class PrefetchDocumentManagerNoVarySearchTest + : public PrefetchDocumentManagerTest, + public testing::WithParamInterface<NoVarySearchExperimentConfigTestInfo> { +}; + +// Tests that the NoVarySearch feature is properly enabled/disabled when +// setting shipping and Origin Trial flags. +TEST_P(PrefetchDocumentManagerNoVarySearchTest, + NoVarySearchFeatureStatusCheck) { + base::test::ScopedFeatureList scoped_feature_list; + + bool shipped_by_default = GetParam().shipped_by_default; + bool origin_trial_enabled = GetParam().origin_trial_enabled; + bool experiment_expected_status = GetParam().experiment_expected_status; + + scoped_feature_list.InitAndEnableFeatureWithParameters( + network::features::kPrefetchNoVarySearch, + {{network::features::kPrefetchNoVarySearchShippedByDefault.name, + shipped_by_default ? "true" : "false"}}); + + auto* prefetch_document_manager = + PrefetchDocumentManager::GetOrCreateForCurrentDocument( + &GetPrimaryMainFrame()); + + if (origin_trial_enabled) { + prefetch_document_manager->EnableNoVarySearchSupportFromOriginTrial(); + } + + EXPECT_EQ(prefetch_document_manager->NoVarySearchSupportEnabled(), + experiment_expected_status); +} + +INSTANTIATE_TEST_SUITE_P( + PrefetchDocumentManagerTest, + PrefetchDocumentManagerNoVarySearchTest, + ::testing::Values(NoVarySearchExperimentConfigTestInfo{false, false, false}, + NoVarySearchExperimentConfigTestInfo{false, true, true}, + NoVarySearchExperimentConfigTestInfo{true, false, true}, + NoVarySearchExperimentConfigTestInfo{true, true, true})); + } // namespace } // namespace content
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc index 7fd2243..3cd0f2a1 100644 --- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -366,7 +366,7 @@ PrefetchDocumentManager* prefetch_document_manager = PrefetchDocumentManager::GetOrCreateForCurrentDocument(main_rfh()); if (enable_no_vary_search_header) - prefetch_document_manager->EnableNoVarySearchSupport(); + prefetch_document_manager->EnableNoVarySearchSupportFromOriginTrial(); prefetch_document_manager->PrefetchUrl( prefetch_url, prefetch_type, referrer, no_vary_search_hint, nullptr); @@ -2374,7 +2374,8 @@ {{"ineligible_decoy_request_probability", "0"}, {"prefetch_container_lifetime_s", "-1"}, {"max_srp_prefetches", "2"}}}}, - {network::features::kPrefetchNoVarySearch}); + {network::features::kPrefetchNoVarySearch, + ::features::kPrefetchNewLimits}); } }; @@ -5301,7 +5302,7 @@ }}, // For this test class we need to enable kPrefetchNoVarySearch. {network::features::kPrefetchNoVarySearch, {}}}, - {}); + {::features::kPrefetchNewLimits}); } };
diff --git a/content/browser/preloading/preloading_decider_unittest.cc b/content/browser/preloading/preloading_decider_unittest.cc index 7fdc089..cd02b90 100644 --- a/content/browser/preloading/preloading_decider_unittest.cc +++ b/content/browser/preloading/preloading_decider_unittest.cc
@@ -57,12 +57,7 @@ ASSERT_TRUE(prefetches_[index]); base::WeakPtr<PrefetchContainer> prefetch_container = prefetches_[index]; prefetches_.erase(prefetches_.begin() + index); - PreloadingDecider::GetForCurrentDocument( - RenderFrameHost::FromID( - prefetch_container->GetReferringRenderFrameHostId())) - ->OnPreloadDiscarded({prefetch_container->GetURL(), - blink::mojom::SpeculationAction::kPrefetch}); - ResetPrefetch(std::move(prefetch_container)); + ResetPrefetch(prefetch_container); } std::vector<base::WeakPtr<PrefetchContainer>> prefetches_; @@ -792,9 +787,6 @@ // Tests that candidate removal causes a prefetch to be destroyed, and that // a reinserted candidate with the same url is re-processed. TEST_F(PreloadingDeciderTest, ProcessCandidates_EagerCandidateRemoval) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({::features::kPrefetchNewLimits}, {}); - auto* preloading_decider = PreloadingDecider::GetOrCreateForCurrentDocument(&GetPrimaryMainFrame()); ASSERT_TRUE(preloading_decider); @@ -844,9 +836,6 @@ // Tests that candidate removal works correctly for non-eager candidates, and // that a non-eager candidate is reprocessed correctly after re-insertion. TEST_F(PreloadingDeciderTest, ProcessCandidates_NonEagerCandidateRemoval) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({::features::kPrefetchNewLimits}, {}); - auto* preloading_decider = PreloadingDecider::GetOrCreateForCurrentDocument(&GetPrimaryMainFrame()); ASSERT_TRUE(preloading_decider); @@ -908,9 +897,6 @@ // URL. TEST_F(PreloadingDeciderTest, ProcessCandidates_SecondCandidateWithSameUrlKeepsPrefetchAlive) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures({::features::kPrefetchNewLimits}, {}); - auto* preloading_decider = PreloadingDecider::GetOrCreateForCurrentDocument(&GetPrimaryMainFrame()); ASSERT_TRUE(preloading_decider);
diff --git a/content/browser/preloading/speculation_rules/speculation_host_impl.cc b/content/browser/preloading/speculation_rules/speculation_host_impl.cc index 4980eda..49f41c5 100644 --- a/content/browser/preloading/speculation_rules/speculation_host_impl.cc +++ b/content/browser/preloading/speculation_rules/speculation_host_impl.cc
@@ -81,7 +81,7 @@ PrefetchDocumentManager::GetOrCreateForCurrentDocument( &render_frame_host()); CHECK(prefetch_document_manager); - prefetch_document_manager->EnableNoVarySearchSupport(); + prefetch_document_manager->EnableNoVarySearchSupportFromOriginTrial(); } void SpeculationHostImpl::InitiatePreview(const GURL& url) {
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 9fa8eddf..7ec96a4 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -640,6 +640,12 @@ desired_fallback); } +viz::SurfaceId DelegatedFrameHost::GetFirstSurfaceIdAfterNavigationForTesting() + const { + return viz::SurfaceId(frame_sink_id_, + first_local_surface_id_after_navigation_); +} + void DelegatedFrameHost::SetIsFrameSinkIdOwner(bool is_owner) { if (is_owner == owns_frame_sink_id_) { return;
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index bafee8c..275fc7d 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -205,6 +205,8 @@ return GetPreNavigationSurfaceId(); } + viz::SurfaceId GetFirstSurfaceIdAfterNavigationForTesting() const; + void SetIsFrameSinkIdOwner(bool is_owner); private:
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index f55fe3a1..cc85035 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -129,6 +129,16 @@ #include "content/browser/renderer_host/render_widget_host_view_aura.h" #endif // defined(USE_AURA) +#if BUILDFLAG(IS_MAC) +#include "content/browser/renderer_host/browser_compositor_view_mac.h" +#include "content/browser/renderer_host/test_render_widget_host_view_mac_factory.h" +#endif + +#if BUILDFLAG(IS_IOS) +#include "content/browser/renderer_host/browser_compositor_ios.h" +#include "content/browser/renderer_host/test_render_widget_host_view_ios_factory.h" +#endif + namespace content { namespace { @@ -7667,6 +7677,7 @@ } namespace { + class RenderFrameHostImplBrowserTestWithBFCacheAndViewTransition : public RenderFrameHostImplBrowserTestWithBFCache { public: @@ -7701,6 +7712,55 @@ } } } + +bool IsChildFrame(RenderWidgetHostView* view) { + CHECK(view); + return static_cast<RenderWidgetHostViewBase*>(view) + ->IsRenderWidgetHostViewChildFrame(); +} + +#if BUILDFLAG(IS_ANDROID) +ui::DelegatedFrameHostAndroid* GetDelegatedFrameHost( + RenderWidgetHostView* view) { + CHECK(!IsChildFrame(view)); + return static_cast<RenderWidgetHostViewAndroid*>(view) + ->delegated_frame_host_for_testing(); +} +#else +DelegatedFrameHost* GetDelegatedFrameHost(RenderWidgetHostView* view) { + CHECK(!IsChildFrame(view)); + DelegatedFrameHost* dfh = nullptr; +#if BUILDFLAG(IS_MAC) + auto* compositor = GetBrowserCompositorMacForTesting(view); + dfh = compositor->GetDelegatedFrameHost(); +#elif BUILDFLAG(IS_IOS) + auto* compositor = GetBrowserCompositorIOSForTesting(view); + dfh = compositor->GetDelegatedFrameHost(); +#elif defined(USE_AURA) + dfh = static_cast<RenderWidgetHostViewAura*>(view) + ->GetDelegatedFrameHostForTesting(); +#endif // BUILDFLAG(IS_MAC) + return dfh; +} +#endif // BUILDFLAG(IS_ANDROID) + +viz::SurfaceId GetCurrentSurfaceIdOnDelegatedFrameHost( + RenderWidgetHostView* view) { + auto* dfh = GetDelegatedFrameHost(view); + CHECK(dfh); +#if BUILDFLAG(IS_ANDROID) + return dfh->GetCurrentSurfaceIdForTesting(); +#else + return dfh->GetCurrentSurfaceId(); +#endif // BUILDFLAG(IS_ANDROID) +} + +viz::SurfaceId GetFirstSurfaceIdAfterNavigation(RenderWidgetHostView* view) { + auto* dfh = GetDelegatedFrameHost(view); + CHECK(dfh); + return dfh->GetFirstSurfaceIdAfterNavigationForTesting(); +} + } // namespace // https://crbug.com/1415340: For a page with ViewTransition being restored from @@ -7728,6 +7788,8 @@ // Navigate to Red. ASSERT_TRUE(NavigateToURL(shell(), url_red)); RenderFrameHostWrapper rfh_red(web_contents()->GetPrimaryMainFrame()); + const auto first_surface_id_after_nav_before_bfcache_restore = + GetFirstSurfaceIdAfterNavigation(rfh_red->GetView()); // Navigate to Green. ASSERT_TRUE(NavigateToURL(shell(), url_green)); @@ -7744,10 +7806,41 @@ ASSERT_EQ(rfh_red.get(), web_contents()->GetPrimaryMainFrame()); ASSERT_TRUE(rwhi_red->IsContentRenderingTimeoutRunning()); - gfx::Image screenshot; - ui::GrabViewSnapshot(web_contents()->GetView()->GetNativeView(), - gfx::Rect(web_contents()->GetSize()), &screenshot); - AssertBitmapOfColor(screenshot.AsBitmap(), SK_ColorGREEN); + const auto first_surface_id_after_nav_after_bfcache_restore = + GetFirstSurfaceIdAfterNavigation(rfh_red->GetView()); + // The `first_surface_id_after_nav_` of the DelegatedFrameHost{Android}, after + // the BFCache restore, should have a different value than before. + ASSERT_NE(first_surface_id_after_nav_after_bfcache_restore, + first_surface_id_after_nav_before_bfcache_restore); + // The first call to `DelegatedFrameHost{Android}::EmbedSurface` will set + // `first_surface_id_after_nav_` to the new current `viz::SurfaceId`; if there + // are subsequent `EmbedSurface` calls (i.e., Android), the current surface id + // will be newer than `first_surface_id_after_nav_`. + ASSERT_TRUE( + GetCurrentSurfaceIdOnDelegatedFrameHost(rfh_red->GetView()) + .IsSameOrNewerThan(first_surface_id_after_nav_after_bfcache_restore)); + + { + gfx::Image screenshot; + ui::GrabViewSnapshot(web_contents()->GetView()->GetNativeView(), + gfx::Rect(web_contents()->GetSize()), &screenshot); + AssertBitmapOfColor(screenshot.AsBitmap(), SK_ColorGREEN); + } + + ASSERT_TRUE(rwhi_red->IsContentRenderingTimeoutRunning()); + rwhi_red->ForceFirstFrameAfterNavigationTimeout(); + + WaitForBrowserCompositorFramePresented(web_contents()); + + // `ForceFirstFrameAfterNavigationTimeout` resets the fallback surface id to + // `first_surface_id_after_nav_` of the `DelegatedFrameHost{Android}`. This + // should have no effects on the screen. + { + gfx::Image screenshot; + ui::GrabViewSnapshot(web_contents()->GetView()->GetNativeView(), + gfx::Rect(web_contents()->GetSize()), &screenshot); + AssertBitmapOfColor(screenshot.AsBitmap(), SK_ColorGREEN); + } } // Tests that when a RenderFrameHost is stored in BFCache, that the visibility
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc index 401e65a..9ced2dff 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -536,6 +536,8 @@ blink::WebGestureEvent fling_cancel = gesture; fling_cancel.SetType(blink::WebInputEvent::Type::kGestureFlingCancel); fling_cancel.SetSourceDevice(blink::WebGestureDevice::kTouchscreen); + fling_cancel.data.fling_cancel.prevent_boosting = false; + fling_cancel.data.fling_cancel.target_viewport = false; if (ShouldRouteEvents()) { host_->delegate()->GetInputEventRouter()->RouteGestureEvent( host_view_, &fling_cancel,
diff --git a/content/browser/webauth/authenticator_common_impl.cc b/content/browser/webauth/authenticator_common_impl.cc index 12c627d1..63e5418 100644 --- a/content/browser/webauth/authenticator_common_impl.cc +++ b/content/browser/webauth/authenticator_common_impl.cc
@@ -604,7 +604,10 @@ req_state_->caller_origin, req_state_->relying_party_id, RequestSource(), device::FidoRequestType::kMakeCredential, req_state_->make_credential_options->resident_key, - base::span<const device::CableDiscoveryData>(), discovery_factory()); + base::span<const device::CableDiscoveryData>(), + GetWebAuthenticationDelegate()->IsEnclaveAuthenticatorAvailable( + GetBrowserContext()), + discovery_factory()); req_state_->make_credential_options->allow_skipping_pin_touch = allow_skipping_pin_touch; @@ -654,6 +657,8 @@ req_state_->caller_origin, req_state_->relying_party_id, RequestSource(), device::FidoRequestType::kGetAssertion, /*resident_key_requirement=*/absl::nullopt, cable_pairings, + GetWebAuthenticationDelegate()->IsEnclaveAuthenticatorAvailable( + GetBrowserContext()), discovery_factory()); #if BUILDFLAG(IS_CHROMEOS) discovery_factory()->set_get_assertion_request_for_legacy_credential_check(
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index 975845fa..654e5da 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -9161,6 +9161,7 @@ device::FidoRequestType request_type, absl::optional<device::ResidentKeyRequirement> resident_key_requirement, base::span<const device::CableDiscoveryData> pairings_from_extension, + bool is_enclave_authenticator_available, device::FidoDiscoveryFactory* fido_discovery_factory) override { // nswindow must be set for the iCloud Keychain authenticator to be // discovered.
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 140ca5b9b..fb0dcd02 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -961,16 +961,16 @@ auto network_manager = IdpNetworkRequestManager::Create( static_cast<RenderFrameHostImpl*>(&render_frame_host())); auto user_info_request = FederatedAuthUserInfoRequest::Create( - std::move(network_manager), permission_delegate_.get(), - &render_frame_host(), fedcm_metrics_.get(), std::move(provider)); + std::move(network_manager), permission_delegate_, + api_permission_delegate_, &render_frame_host(), fedcm_metrics_.get(), + std::move(provider)); FederatedAuthUserInfoRequest* user_info_request_ptr = user_info_request.get(); user_info_requests_.insert(std::move(user_info_request)); user_info_request_ptr->SetCallbackAndStart( base::BindOnce(&FederatedAuthRequestImpl::CompleteUserInfoRequest, weak_ptr_factory_.GetWeakPtr(), user_info_request_ptr, - std::move(callback)), - api_permission_delegate_.get()); + std::move(callback))); } void FederatedAuthRequestImpl::CancelTokenRequest() { @@ -2488,13 +2488,10 @@ // `approved_clients` list provided by IDP. However, in this case we have // to trust the browser observed sign-in unless the IDP can be exempted. // For example, they have third party cookies access on the RP site. - if (!permission_delegate_->HasSharingPermission( - origin(), GetEmbeddingOrigin(), - url::Origin::Create(idp_info.first), account.id) && - !webid::IdpHasThirdPartyCookiesAccess(render_frame_host(), - /*provider_url=*/idp_info.first, - GetEmbeddingOrigin(), - api_permission_delegate_)) { + if (!webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( + render_frame_host(), /*provider_url=*/idp_info.first, + GetEmbeddingOrigin(), origin(), account.id, permission_delegate_, + api_permission_delegate_)) { continue; } @@ -2544,15 +2541,11 @@ } bool has_sharing_permission_for_any_account = - permission_delegate_->HasSharingPermission( - origin(), GetEmbeddingOrigin(), url::Origin::Create(config_url), - absl::nullopt); + webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( + render_frame_host(), config_url, GetEmbeddingOrigin(), origin(), + /*account_id=*/absl::nullopt, permission_delegate_, + api_permission_delegate_); - // The ExemptIdPWithThirdPartyCookie feature does not apply to `mediation: - // silent` to avoid unexpected conversion rate drop. Because if an IdP loses - // 3PC access on an RP, the request will fail silently. In contrast, with - // `mediation: optional`, users can still grant explicit permission on the - // account UI if the IdP loses 3PC access. if (!has_sharing_permission_for_any_account) { render_frame_host().AddMessageToConsole( blink::mojom::ConsoleMessageLevel::kError, @@ -2666,15 +2659,15 @@ auto network_manager = CreateNetworkManager(); revoke_request_ = FederatedAuthRevokeRequest::Create( - std::move(network_manager), permission_delegate_.get(), - &render_frame_host(), fedcm_metrics_.get(), std::move(options), + std::move(network_manager), permission_delegate_, &render_frame_host(), + fedcm_metrics_.get(), std::move(options), should_complete_request_immediately_); FederatedAuthRevokeRequest* revoke_request_ptr = revoke_request_.get(); revoke_request_ptr->SetCallbackAndStart( base::BindOnce(&FederatedAuthRequestImpl::CompleteRevokeRequest, weak_ptr_factory_.GetWeakPtr(), std::move(callback)), - api_permission_delegate_.get()); + api_permission_delegate_); } void FederatedAuthRequestImpl::RecordErrorMetrics(
diff --git a/content/browser/webid/federated_auth_revoke_request.cc b/content/browser/webid/federated_auth_revoke_request.cc index 4ff97e3..cff8be1 100644 --- a/content/browser/webid/federated_auth_revoke_request.cc +++ b/content/browser/webid/federated_auth_revoke_request.cc
@@ -109,9 +109,12 @@ /*should_delay_callback=*/true); return; } - // Reject if we know that there are no sharing permissions with the given IdP. - if (!permission_delegate_->HasSharingPermission( - origin_, embedding_origin_, config_origin, absl::nullopt)) { + // Reject if we know that there are no sharing permissions with the given IdP + // and the IdP doesn't have third party cookies access on the RP site. + if (!webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( + *render_frame_host_, options_->config->config_url, embedding_origin_, + origin_, /*account_id=*/absl::nullopt, permission_delegate_, + api_permission_delegate)) { Complete(RevokeStatus::kError, RevokeStatusForMetrics::kNoAccountToRevoke, /*should_delay_callback=*/true); return;
diff --git a/content/browser/webid/federated_auth_revoke_request_unittest.cc b/content/browser/webid/federated_auth_revoke_request_unittest.cc index 9823956..d7b1799d 100644 --- a/content/browser/webid/federated_auth_revoke_request_unittest.cc +++ b/content/browser/webid/federated_auth_revoke_request_unittest.cc
@@ -37,6 +37,7 @@ using ::testing::Return; using FedCmEntry = ukm::builders::Blink_FedCm; +using LoginState = content::IdentityRequestAccount::LoginState; using RevokeResponse = content::IdpNetworkRequestManager::RevokeResponse; using RevokeStatusForMetrics = content::FedCmRevokeStatus; using blink::mojom::RevokeStatus; @@ -186,13 +187,34 @@ const url::Origin& relying_party_embedder, const url::Origin& identity_provider, const absl::optional<std::string>& account_id) override { - return true; + url::Origin rp_origin_with_data = url::Origin::Create(GURL(kRpUrl)); + url::Origin idp_origin_with_data = url::Origin::Create(GURL(kProviderUrl)); + bool has_granted_permission_per_profile = + relying_party_requester == rp_origin_with_data && + relying_party_embedder == rp_origin_with_data && + identity_provider == idp_origin_with_data; + return has_granted_permission_per_profile && + (account_id + ? accounts_with_sharing_permission_.count(account_id.value()) + : !accounts_with_sharing_permission_.empty()); } absl::optional<bool> GetIdpSigninStatus( const url::Origin& idp_origin) override { return true; } + + void SetConfig(const Config& config) { + accounts_with_sharing_permission_.clear(); + for (const AccountConfig& account_config : config.accounts) { + if (account_config.was_granted_sharing_permission) { + accounts_with_sharing_permission_.insert(account_config.id); + } + } + } + + private: + std::set<std::string> accounts_with_sharing_permission_; }; } // namespace @@ -222,6 +244,8 @@ void RunRevokeTest(const Config& config, RevokeStatus expected_revoke_status) { + permission_delegate_->SetConfig(config); + auto network_manager = std::make_unique<TestIdpNetworkRequestManager>(config); network_manager_ = network_manager.get(); @@ -320,4 +344,32 @@ FedCmEntry::kEntryName); } +TEST_F(FederatedAuthRevokeRequestTest, + NoSharingPermissionButIdpHasThirdPartyCookiesAccessAndClaimsSignin) { + base::test::ScopedFeatureList list; + list.InitAndEnableFeature(features::kFedCmExemptIdpWithThirdPartyCookies); + + const char kAccountId[] = "account"; + + Config config = kValidConfig; + config.accounts = {{kAccountId, /*login_state=*/LoginState::kSignIn, + /*was_granted_sharing_permission=*/false}}; + + // Pretend the IdP was given third-party cookies access. + EXPECT_CALL(*api_permission_delegate_, + HasThirdPartyCookiesAccess(_, GURL(kProviderUrl), + url::Origin::Create(GURL(kRpUrl)))) + .WillOnce(Return(true)); + + RunRevokeTest(config, RevokeStatus::kSuccess); + EXPECT_TRUE(network_manager_->has_fetched_well_known_); + EXPECT_TRUE(network_manager_->has_fetched_config_); + EXPECT_TRUE(network_manager_->has_fetched_revoke_); + + histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.Revoke2", + RevokeStatusForMetrics::kSuccess, 1); + ExpectRevokeStatusUKM(RevokeStatusForMetrics::kSuccess, + FedCmEntry::kEntryName); +} + } // namespace content
diff --git a/content/browser/webid/federated_auth_user_info_request.cc b/content/browser/webid/federated_auth_user_info_request.cc index 35f0fb9c..ca6d576d 100644 --- a/content/browser/webid/federated_auth_user_info_request.cc +++ b/content/browser/webid/federated_auth_user_info_request.cc
@@ -73,6 +73,7 @@ FederatedAuthUserInfoRequest::Create( std::unique_ptr<IdpNetworkRequestManager> network_manager, FederatedIdentityPermissionContextDelegate* permission_delegate, + FederatedIdentityApiPermissionContextDelegate* api_permission_delegate, RenderFrameHost* render_frame_host, FedCmMetrics* metrics, blink::mojom::IdentityProviderConfigPtr provider) { @@ -80,7 +81,8 @@ base::WrapUnique<FederatedAuthUserInfoRequest>( new FederatedAuthUserInfoRequest( std::move(network_manager), permission_delegate, - render_frame_host, metrics, std::move(provider))); + api_permission_delegate, render_frame_host, metrics, + std::move(provider))); return request; } @@ -91,11 +93,13 @@ FederatedAuthUserInfoRequest::FederatedAuthUserInfoRequest( std::unique_ptr<IdpNetworkRequestManager> network_manager, FederatedIdentityPermissionContextDelegate* permission_delegate, + FederatedIdentityApiPermissionContextDelegate* api_permission_delegate, RenderFrameHost* render_frame_host, FedCmMetrics* metrics, blink::mojom::IdentityProviderConfigPtr provider) : network_manager_(std::move(network_manager)), permission_delegate_(permission_delegate), + api_permission_delegate_(api_permission_delegate), metrics_(metrics), render_frame_host_(render_frame_host), client_id_(provider->client_id), @@ -111,8 +115,7 @@ } void FederatedAuthUserInfoRequest::SetCallbackAndStart( - blink::mojom::FederatedAuthRequest::RequestUserInfoCallback callback, - FederatedIdentityApiPermissionContextDelegate* api_permission_delegate) { + blink::mojom::FederatedAuthRequest::RequestUserInfoCallback callback) { callback_ = std::move(callback); request_start_time_ = base::TimeTicks::Now(); @@ -138,7 +141,7 @@ } FederatedApiPermissionStatus permission_status = - api_permission_delegate->GetApiPermissionStatus(embedding_origin_); + api_permission_delegate_->GetApiPermissionStatus(embedding_origin_); if (permission_status != FederatedApiPermissionStatus::GRANTED) { CompleteWithError(FederatedAuthUserInfoRequestResult::kNoApiPermission); return; @@ -152,11 +155,12 @@ return; } - if (!permission_delegate_->HasSharingPermission( - parent_frame_origin_, embedding_origin_, - url::Origin::Create(idp_config_url_), /*account_id=*/absl::nullopt)) { - // If there is no sharing permission, we can abort before performing any - // fetch. + if (!webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( + *render_frame_host_, idp_config_url_, embedding_origin_, + parent_frame_origin_, /*account_id=*/absl::nullopt, + permission_delegate_, api_permission_delegate_)) { + // If there is no sharing permission or the IdP does not have third party + // cookies access, we can abort before performing any fetch. CompleteWithError( FederatedAuthUserInfoRequestResult::kNoAccountSharingPermission); return; @@ -224,6 +228,27 @@ FederatedAuthUserInfoRequestResult::kInvalidAccountsResponse); return; } + + // Populate the accounts login state. + for (auto& account : accounts) { + // We set the login state based on the IDP response if it sends + // back an approved_clients list. If it does not, we need to set + // it here based on browser state. + if (account.login_state) { + continue; + } + + LoginState login_state = LoginState::kSignUp; + // Consider this a sign-in if we have seen a successful sign-up for + // this account before. + if (permission_delegate_->HasSharingPermission( + parent_frame_origin_, embedding_origin_, + url::Origin::Create(idp_config_url_), account.id)) { + login_state = LoginState::kSignIn; + } + account.login_state = login_state; + } + MaybeReturnAccounts(std::move(accounts)); } @@ -288,9 +313,10 @@ return false; } - return permission_delegate_->HasSharingPermission( - parent_frame_origin_, embedding_origin_, - url::Origin::Create(idp_config_url_), account.id); + return webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( + *render_frame_host_, idp_config_url_, embedding_origin_, + parent_frame_origin_, account.id, permission_delegate_, + api_permission_delegate_); } void FederatedAuthUserInfoRequest::Complete(
diff --git a/content/browser/webid/federated_auth_user_info_request.h b/content/browser/webid/federated_auth_user_info_request.h index 9dd1db9..a97994e 100644 --- a/content/browser/webid/federated_auth_user_info_request.h +++ b/content/browser/webid/federated_auth_user_info_request.h
@@ -36,6 +36,7 @@ static std::unique_ptr<FederatedAuthUserInfoRequest> Create( std::unique_ptr<IdpNetworkRequestManager> network_manager, FederatedIdentityPermissionContextDelegate* permission_delegate, + FederatedIdentityApiPermissionContextDelegate* api_permission_delegate, RenderFrameHost* render_frame_host, FedCmMetrics* metrics, blink::mojom::IdentityProviderConfigPtr provider); @@ -49,13 +50,13 @@ // on having a pointer to this object, hence cannot be passed in the // constructor. Once the callback is set, start fetching. void SetCallbackAndStart( - blink::mojom::FederatedAuthRequest::RequestUserInfoCallback callback, - FederatedIdentityApiPermissionContextDelegate* api_permission_delegate); + blink::mojom::FederatedAuthRequest::RequestUserInfoCallback callback); private: FederatedAuthUserInfoRequest( std::unique_ptr<IdpNetworkRequestManager> network_manager, FederatedIdentityPermissionContextDelegate* permission_delegate, + FederatedIdentityApiPermissionContextDelegate* api_permission_delegate, RenderFrameHost* render_frame_host, FedCmMetrics* metrics, blink::mojom::IdentityProviderConfigPtr provider); @@ -85,6 +86,8 @@ // Owned by |BrowserContext| raw_ptr<FederatedIdentityPermissionContextDelegate> permission_delegate_ = nullptr; + raw_ptr<FederatedIdentityApiPermissionContextDelegate> + api_permission_delegate_ = nullptr; // Owned by |FederatedAuthRequestImpl| raw_ptr<FedCmMetrics> metrics_; raw_ptr<RenderFrameHost, DanglingUntriaged> render_frame_host_;
diff --git a/content/browser/webid/federated_auth_user_info_request_unittest.cc b/content/browser/webid/federated_auth_user_info_request_unittest.cc index bd64d40..3c5c0efd 100644 --- a/content/browser/webid/federated_auth_user_info_request_unittest.cc +++ b/content/browser/webid/federated_auth_user_info_request_unittest.cc
@@ -15,6 +15,7 @@ #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "content/browser/webid/fedcm_metrics.h" #include "content/browser/webid/test/mock_api_permission_delegate.h" @@ -223,9 +224,10 @@ relying_party_requester == rp_origin_with_data && relying_party_embedder == rp_origin_with_data && identity_provider == idp_origin_with_data; - return has_granted_permission_per_profile && account_id - ? accounts_with_sharing_permission_.count(account_id.value()) - : !accounts_with_sharing_permission_.empty(); + return has_granted_permission_per_profile && + (account_id + ? accounts_with_sharing_permission_.count(account_id.value()) + : !accounts_with_sharing_permission_.empty()); } absl::optional<bool> GetIdpSigninStatus( @@ -293,9 +295,9 @@ UserInfoCallbackHelper callback_helper; request_ = FederatedAuthUserInfoRequest::Create( std::move(network_manager), permission_delegate_.get(), - iframe_render_frame_host_, metrics_.get(), std::move(idp_ptr)); - request_->SetCallbackAndStart(callback_helper.callback(), - api_permission_delegate_.get()); + api_permission_delegate_.get(), iframe_render_frame_host_, + metrics_.get(), std::move(idp_ptr)); + request_->SetCallbackAndStart(callback_helper.callback()); callback_helper.WaitForCallback(); EXPECT_EQ(expected_user_info_status, callback_helper.user_info_status_); @@ -434,6 +436,55 @@ {kAccount1Id, kAccount2Id}); } +TEST_F(FederatedAuthUserInfoRequestTest, + NoSharingPermissionButIdpHasThirdPartyCookiesAccessAndClaimsSignin) { + base::test::ScopedFeatureList list; + list.InitAndEnableFeature(features::kFedCmExemptIdpWithThirdPartyCookies); + + const char kAccountId[] = "account"; + + Config config = kValidConfig; + config.accounts = {{kAccountId, /*login_state=*/LoginState::kSignIn, + /*was_granted_sharing_permission=*/false}}; + + // Pretend the IdP was given third-party cookies access. + EXPECT_CALL(*api_permission_delegate_, + HasThirdPartyCookiesAccess(_, GURL(kProviderUrl), + url::Origin::Create(GURL(kRpUrl)))) + .WillRepeatedly(Return(true)); + + RunUserInfoTest(config, RequestUserInfoStatus::kSuccess, {kAccountId}); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequestResult::kSuccess, 1); +} + +TEST_F(FederatedAuthUserInfoRequestTest, + NoSharingPermissionButIdpHasThirdPartyCookiesAccessButNotSignin) { + base::test::ScopedFeatureList list; + list.InitAndEnableFeature(features::kFedCmExemptIdpWithThirdPartyCookies); + + const char kAccountId[] = "account"; + + Config config = kValidConfig; + config.accounts = {{kAccountId, /*login_state=*/absl::nullopt, + /*was_granted_sharing_permission=*/false}}; + + // Pretend the IdP was given third-party cookies access. + EXPECT_CALL(*api_permission_delegate_, + HasThirdPartyCookiesAccess(_, GURL(kProviderUrl), + url::Origin::Create(GURL(kRpUrl)))) + .WillRepeatedly(Return(true)); + + RunUserInfoTest(config, RequestUserInfoStatus::kError, {}); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequestResult::kNoReturningUserFromFetchedAccounts, + 1); +} + TEST_F(FederatedAuthUserInfoRequestTest, ConfigFetchFailed) { Config config = kValidConfig; config.config_fetch_status = {ParseStatus::kHttpNotFoundError, 404};
diff --git a/content/browser/webid/webid_utils.cc b/content/browser/webid/webid_utils.cc index 5fe11c5..bdeaebe 100644 --- a/content/browser/webid/webid_utils.cc +++ b/content/browser/webid/webid_utils.cc
@@ -337,14 +337,21 @@ base::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); } -bool IdpHasThirdPartyCookiesAccess( +bool HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( RenderFrameHost& host, const GURL& provider_url, const url::Origin& embedder_origin, + const url::Origin& requester_origin, + const absl::optional<std::string>& account_id, + FederatedIdentityPermissionContextDelegate* sharing_permission_delegate, FederatedIdentityApiPermissionContextDelegate* api_permission_delegate) { - return IsFedCmExemptIdpWithThirdPartyCookiesEnabled() && - api_permission_delegate->HasThirdPartyCookiesAccess(host, provider_url, - embedder_origin); + bool has_access = IsFedCmExemptIdpWithThirdPartyCookiesEnabled() && + api_permission_delegate->HasThirdPartyCookiesAccess( + host, provider_url, embedder_origin); + return sharing_permission_delegate->HasSharingPermission( + requester_origin, embedder_origin, + url::Origin::Create(provider_url), account_id) || + has_access; } } // namespace content::webid
diff --git a/content/browser/webid/webid_utils.h b/content/browser/webid/webid_utils.h index b16b2a7..3a4a88e 100644 --- a/content/browser/webid/webid_utils.h +++ b/content/browser/webid/webid_utils.h
@@ -82,11 +82,17 @@ // Returns the eTLD+1 for a given url. For localhost, returns the host. std::string FormatUrlWithDomain(const GURL& url, bool for_display); -// Returns true if the IdP has third-party cookies access on the RP top frame. -bool IdpHasThirdPartyCookiesAccess( +// Returns true if the user has used FedCM to login to the RP via the IdP +// account or if the IdP has third party cookies access. For the former, if +// |account| is provided, we look for the specific account. Otherwise we look +// for *any* account. +bool HasSharingPermissionOrIdpHasThirdPartyCookiesAccess( RenderFrameHost& host, const GURL& provider_url, const url::Origin& embedder_origin, + const url::Origin& requester_origin, + const absl::optional<std::string>& account_id, + FederatedIdentityPermissionContextDelegate* sharing_permission_delegate, FederatedIdentityApiPermissionContextDelegate* api_permission_delegate); } // namespace webid
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index de31ade5..3b0f190 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -19,7 +19,6 @@ #include "build/chromeos_buildflags.h" #include "cc/base/features.h" #include "components/attribution_reporting/features.h" -#include "components/permissions/features.h" #include "content/common/content_navigation_policy.h" #include "content/common/content_switches_internal.h" #include "content/common/features.h" @@ -342,64 +341,78 @@ // TODO(crbug/832393): Cleanup the inconsistency between custom WRF enabler // function and using feature string name with EnableFeatureFromString. const RuntimeFeatureToChromiumFeatureMap<const char*> - runtimeFeatureNameToChromiumFeatureMapping[] = - { {"AllowContentInitiatedDataUrlNavigations", - raw_ref(features::kAllowContentInitiatedDataUrlNavigations)}, - {"AllowURNsInIframes", raw_ref(blink::features::kAllowURNsInIframes)}, - {"AllowURNsInIframes", raw_ref(features::kPrivacySandboxAdsAPIsOverride), - kSetOnlyIfOverridden}, - {"AllowURNsInIframes", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), - kSetOnlyIfOverridden}, - {"AttributionReporting", raw_ref(features::kPrivacySandboxAdsAPIsOverride), - kSetOnlyIfOverridden}, - {"AttributionReporting", - raw_ref(features::kPrivacySandboxAdsAPIsM1Override), kSetOnlyIfOverridden}, - {"AttributionReportingCrossAppWeb", - raw_ref(features::kPrivacySandboxAdsAPIsOverride), kSetOnlyIfOverridden}, - {"AndroidDownloadableFontsMatching", - raw_ref(features::kAndroidDownloadableFontsMatching)}, + runtimeFeatureNameToChromiumFeatureMapping[] = { + {"AllowContentInitiatedDataUrlNavigations", + raw_ref(features::kAllowContentInitiatedDataUrlNavigations)}, + {"AllowURNsInIframes", raw_ref(blink::features::kAllowURNsInIframes)}, + {"AllowURNsInIframes", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AllowURNsInIframes", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, + {"AttributionReporting", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AttributionReporting", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, + {"AttributionReportingCrossAppWeb", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AndroidDownloadableFontsMatching", + raw_ref(features::kAndroidDownloadableFontsMatching)}, #if BUILDFLAG(IS_ANDROID) - {"CCTNewRFMPushBehavior", raw_ref(blink::features::kCCTNewRFMPushBehavior)}, + {"CCTNewRFMPushBehavior", + raw_ref(blink::features::kCCTNewRFMPushBehavior)}, #endif - {"CompressionDictionaryTransport", - raw_ref(network::features::kCompressionDictionaryTransport)}, - {"CompressionDictionaryTransportBackend", - raw_ref(network::features::kCompressionDictionaryTransportBackend)}, - {"CookieDeprecationFacilitatedTesting", - raw_ref(features::kCookieDeprecationFacilitatedTesting)}, - {"Database", raw_ref(blink::features::kWebSQLAccess), kSetOnlyIfOverridden}, - {"Fledge", raw_ref(blink::features::kFledge), kSetOnlyIfOverridden}, - {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsOverride), - kSetOnlyIfOverridden}, - {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), - kSetOnlyIfOverridden}, + {"CompressionDictionaryTransport", + raw_ref(network::features::kCompressionDictionaryTransport)}, + {"CompressionDictionaryTransportBackend", + raw_ref(network::features::kCompressionDictionaryTransportBackend)}, + {"CookieDeprecationFacilitatedTesting", + raw_ref(features::kCookieDeprecationFacilitatedTesting)}, + {"Database", raw_ref(blink::features::kWebSQLAccess), + kSetOnlyIfOverridden}, + {"Fledge", raw_ref(blink::features::kFledge), kSetOnlyIfOverridden}, + {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, #if BUILDFLAG(USE_FONTATIONS_BACKEND) - {"FontationsFontBackend", raw_ref(blink::features::kFontationsFontBackend)}, + {"FontationsFontBackend", + raw_ref(blink::features::kFontationsFontBackend)}, #endif - {"FontSrcLocalMatching", raw_ref(features::kFontSrcLocalMatching)}, - {"LegacyWindowsDWriteFontFallback", - raw_ref(features::kLegacyWindowsDWriteFontFallback)}, - {"OriginIsolationHeader", raw_ref(features::kOriginIsolationHeader)}, - {"PartitionedCookies", raw_ref(net::features::kPartitionedCookies)}, - {"ReduceAcceptLanguage", raw_ref(network::features::kReduceAcceptLanguage)}, - {"StorageAccessAPI", raw_ref(features::kFirstPartySets)}, - {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsOverride), - kSetOnlyIfOverridden}, - {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), - kSetOnlyIfOverridden}, - {"TopicsDocumentAPI", raw_ref(features::kPrivacySandboxAdsAPIsOverride), - kSetOnlyIfOverridden}, - {"TopicsDocumentAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), - kSetOnlyIfOverridden}, - {"TouchTextEditingRedesign", raw_ref(features::kTouchTextEditingRedesign)}, - {"TrustedTypesFromLiteral", raw_ref(features::kTrustedTypesFromLiteral)}, - {"WebSerialBluetooth", - raw_ref(features::kEnableBluetoothSerialPortProfileInSerialApi)}, - {"MediaStreamTrackTransfer", raw_ref(features::kMediaStreamTrackTransfer)}, - {"PrivateNetworkAccessPermissionPrompt", - raw_ref(network::features::kPrivateNetworkAccessPermissionPrompt), - kSetOnlyIfOverridden}, - {"PermissionElement", raw_ref(permissions::features::kPermissionElement)} }; + {"FontSrcLocalMatching", raw_ref(features::kFontSrcLocalMatching)}, + {"LegacyWindowsDWriteFontFallback", + raw_ref(features::kLegacyWindowsDWriteFontFallback)}, + {"OriginIsolationHeader", raw_ref(features::kOriginIsolationHeader)}, + {"PartitionedCookies", raw_ref(net::features::kPartitionedCookies)}, + {"ReduceAcceptLanguage", + raw_ref(network::features::kReduceAcceptLanguage)}, + {"StorageAccessAPI", raw_ref(features::kFirstPartySets)}, + {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, + {"TopicsDocumentAPI", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"TopicsDocumentAPI", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, + {"TouchTextEditingRedesign", + raw_ref(features::kTouchTextEditingRedesign)}, + {"TrustedTypesFromLiteral", + raw_ref(features::kTrustedTypesFromLiteral)}, + {"WebSerialBluetooth", + raw_ref(features::kEnableBluetoothSerialPortProfileInSerialApi)}, + {"MediaStreamTrackTransfer", + raw_ref(features::kMediaStreamTrackTransfer)}, + {"PrivateNetworkAccessPermissionPrompt", + raw_ref(network::features::kPrivateNetworkAccessPermissionPrompt), + kSetOnlyIfOverridden}, + {"PermissionElement", raw_ref(features::kPermissionElement)}}; for (const auto& mapping : runtimeFeatureNameToChromiumFeatureMapping) { SetRuntimeFeatureFromChromiumFeature( *mapping.chromium_feature, mapping.option, [&mapping](bool enabled) {
diff --git a/content/public/browser/authenticator_request_client_delegate.cc b/content/public/browser/authenticator_request_client_delegate.cc index 46af20b..0991f2f 100644 --- a/content/public/browser/authenticator_request_client_delegate.cc +++ b/content/public/browser/authenticator_request_client_delegate.cc
@@ -96,6 +96,11 @@ return nullptr; } +bool WebAuthenticationDelegate::IsEnclaveAuthenticatorAvailable( + BrowserContext* browser_context) { + return false; +} + #if BUILDFLAG(IS_MAC) absl::optional<WebAuthenticationDelegate::TouchIdAuthenticatorConfig> WebAuthenticationDelegate::GetTouchIdAuthenticatorConfig( @@ -153,6 +158,7 @@ device::FidoRequestType request_type, absl::optional<device::ResidentKeyRequirement> resident_key_requirement, base::span<const device::CableDiscoveryData> pairings_from_extension, + bool is_enclave_authenticator_available, device::FidoDiscoveryFactory* fido_discovery_factory) {} void AuthenticatorRequestClientDelegate::SelectAccount(
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h index b883fd5..ad5e851 100644 --- a/content/public/browser/authenticator_request_client_delegate.h +++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -132,6 +132,9 @@ BrowserContext* browser_context, const url::Origin& caller_origin); + // Returns true when the cloud enclave authenticator is available for use. + virtual bool IsEnclaveAuthenticatorAvailable(BrowserContext* browser_context); + #if BUILDFLAG(IS_MAC) using TouchIdAuthenticatorConfig = device::fido::mac::AuthenticatorConfig; @@ -276,6 +279,9 @@ // be functional and |pairings_from_extension| contains any caBLEv1 pairings // that have been provided in an extension to the WebAuthn get() call. // + // When `is_enclave_authenticator_available` is true, the embedder will + // provide a cloud enclave authenticator option. + // // Other FidoDiscoveryFactory fields (e.g. the `LAContextDropbox`) can also be // configured by this function. virtual void ConfigureDiscoveries( @@ -285,6 +291,7 @@ device::FidoRequestType request_type, absl::optional<device::ResidentKeyRequirement> resident_key_requirement, base::span<const device::CableDiscoveryData> pairings_from_extension, + bool is_enclave_authenticator_available, device::FidoDiscoveryFactory* fido_discovery_factory); // SelectAccount is called to allow the embedder to select between one or more
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 7636998..f87f3b4 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -661,6 +661,12 @@ "PepperCrossOriginRedirectRestriction", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables an in-content element that interacts with the permissions +// infrastructure. +BASE_FEATURE(kPermissionElement, + "PermissionElement", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables Persistent Origin Trials. It causes tokens for an origin to be stored // and persisted for the next navigation. This way, an origin trial can affect // things before receiving the response, for instance it can affect the next @@ -673,7 +679,7 @@ // separates eager and non-eager prefetches, and allows for evictions. BASE_FEATURE(kPrefetchNewLimits, "PrefetchNewLimits", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables exposure of ads APIs in the renderer: Attribution Reporting, // FLEDGE, Topics, along with a number of other features actively in development
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 7430e31..c31fce24 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -167,6 +167,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kPeriodicBackgroundSync); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFeaturePolicyHeader); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPepperCrossOriginRedirectRestriction); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kPermissionElement); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPersistentOriginTrials); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrefetchNewLimits); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrivacySandboxAdsAPIsOverride);
diff --git a/content/test/data/accessibility/html/a-with-img-expected-android-assist-data.txt b/content/test/data/accessibility/html/a-with-img-expected-android-assist-data.txt index a6db5b34..4b83765 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-android-assist-data.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-android-assist-data.txt
@@ -6,7 +6,7 @@ ++++TextView text:" " textSize:16.00 style:0 bundle:[display="", htmlTag=""] ++++View textSize:16.00 style:4 fgColor:-16776978 bundle:[display="inline", href="http://www.google.com", htmlTag="a"] ++++++TextView text:"Link with " textSize:16.00 style:4 fgColor:-16776978 bundle:[display="", htmlTag=""] -++++++Image text:"image" textSize:16.00 style:4 fgColor:-16776978 bundle:[alt="image", display="inline", htmlTag="img", src="bullet.png"] +++++++Image text:"bullet image" textSize:16.00 style:4 fgColor:-16776978 bundle:[alt="bullet image", display="inline", htmlTag="img", src="bullet.png"] ++++++TextView text:" in the middle." textSize:16.00 style:4 fgColor:-16776978 bundle:[display="", htmlTag=""] ++++TextView text:" " textSize:16.00 style:0 bundle:[display="", htmlTag=""] ++++View textSize:16.00 style:4 fgColor:-16776978 bundle:[display="inline", href="http://www.google.com", htmlTag="a"] @@ -16,4 +16,4 @@ ++++TextView text:" " textSize:16.00 style:0 bundle:[display="", htmlTag=""] ++++View textSize:16.00 style:4 fgColor:-16776978 bundle:[display="inline", href="http://www.google.com", htmlTag="a"] ++++++TextView text:"Link with image at the " textSize:16.00 style:4 fgColor:-16776978 bundle:[display="", htmlTag=""] -++++++Image text:"end" textSize:16.00 style:4 fgColor:-16776978 bundle:[alt="end", display="inline", htmlTag="img", src="bullet.png"] \ No newline at end of file +++++++Image text:"end, it's a bullet" textSize:16.00 style:4 fgColor:-16776978 bundle:[alt="end, it's a bullet", display="inline", htmlTag="img", src="bullet.png"]
diff --git a/content/test/data/accessibility/html/a-with-img-expected-android-external.txt b/content/test/data/accessibility/html/a-with-img-expected-android-external.txt index 82f8c30..2bb9703 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-android-external.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-android-external.txt
@@ -4,9 +4,9 @@ ++++++Image text:"Link" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/bullet.png"] ++++++TextView text:" with image at start." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText", clickableScore="100"] ++++TextView text:" " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"] -++++View text:"null" contentDescription:"Link with image in the middle." clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="link", clickableScore="300", hasImage="true", roleDescription="link", targetUrl="http://www.google.com/"] +++++View text:"null" contentDescription:"Link with bullet image in the middle." clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="link", clickableScore="300", hasImage="true", roleDescription="link", targetUrl="http://www.google.com/"] ++++++TextView text:"Link with " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText", clickableScore="100"] -++++++Image text:"image" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/bullet.png"] +++++++Image text:"bullet image" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/bullet.png"] ++++++TextView text:" in the middle." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText", clickableScore="100"] ++++TextView text:" " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"] ++++View text:"null" contentDescription:"Link with broken in the middle." clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="link", clickableScore="300", hasImage="true", roleDescription="link", targetUrl="http://www.google.com/"] @@ -14,6 +14,6 @@ ++++++Image text:"broken" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/broken.png"] ++++++TextView text:" in the middle." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText", clickableScore="100"] ++++TextView text:" " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"] -++++View text:"null" contentDescription:"Link with image at the end" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="link", clickableScore="300", hasImage="true", roleDescription="link", targetUrl="http://www.google.com/"] +++++View text:"null" contentDescription:"Link with image at the end, it's a bullet" clickable focusable actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="link", clickableScore="300", hasImage="true", roleDescription="link", targetUrl="http://www.google.com/"] ++++++TextView text:"Link with image at the " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText", clickableScore="100"] -++++++Image text:"end" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/bullet.png"] \ No newline at end of file +++++++Image text:"end, it's a bullet" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="image", clickableScore="100", hasImage="true", roleDescription="graphic", targetUrl="file:///storage/emulated/0/chromium_tests_root/content/test/data/accessibility/html/bullet.png"]
diff --git a/content/test/data/accessibility/html/a-with-img-expected-android.txt b/content/test/data/accessibility/html/a-with-img-expected-android.txt index 60a573da..5d6dbc10 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-android.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-android.txt
@@ -4,9 +4,9 @@ ++++++android.widget.Image role_description='graphic' name='Link' ++++++android.widget.TextView name=' with image at start.' ++++android.widget.TextView name=' ' -++++android.view.View role_description='link' clickable focusable link name='Link with image in the middle.' +++++android.view.View role_description='link' clickable focusable link name='Link with bullet image in the middle.' ++++++android.widget.TextView name='Link with ' -++++++android.widget.Image role_description='graphic' name='image' +++++++android.widget.Image role_description='graphic' name='bullet image' ++++++android.widget.TextView name=' in the middle.' ++++android.widget.TextView name=' ' ++++android.view.View role_description='link' clickable focusable link name='Link with broken in the middle.' @@ -14,6 +14,6 @@ ++++++android.widget.Image role_description='graphic' name='broken' ++++++android.widget.TextView name=' in the middle.' ++++android.widget.TextView name=' ' -++++android.view.View role_description='link' clickable focusable link name='Link with image at the end' +++++android.view.View role_description='link' clickable focusable link name='Link with image at the end, it's a bullet' ++++++android.widget.TextView name='Link with image at the ' -++++++android.widget.Image role_description='graphic' name='end' +++++++android.widget.Image role_description='graphic' name='end, it's a bullet'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-auralinux.txt b/content/test/data/accessibility/html/a-with-img-expected-auralinux.txt index a440378e..518632e 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-auralinux.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-auralinux.txt
@@ -4,9 +4,9 @@ ++++++[image] name='Link' ++++++[static] name=' with image at start.' ++++[static] name=' ' -++++[link] name='Link with image in the middle.' +++++[link] name='Link with bullet image in the middle.' ++++++[static] name='Link with ' -++++++[image] name='image. To get missing image descriptions, open the context menu.' +++++++[image] name='bullet image' ++++++[static] name=' in the middle.' ++++[static] name=' ' ++++[link] name='Link with broken in the middle.' @@ -14,6 +14,6 @@ ++++++[image] name='broken' ++++++[static] name=' in the middle.' ++++[static] name=' ' -++++[link] name='Link with image at the end' +++++[link] name='Link with image at the end, it's a bullet' ++++++[static] name='Link with image at the ' -++++++[image] name='end' \ No newline at end of file +++++++[image] name='end, it's a bullet'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-blink.txt b/content/test/data/accessibility/html/a-with-img-expected-blink.txt index a4f4ca5..703a649 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-blink.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-blink.txt
@@ -7,10 +7,10 @@ ++++++++++inlineTextBox name=' with image at start.' ++++++staticText name=' ' ++++++++inlineTextBox name=' ' -++++++link linked name='Link with image in the middle.' +++++++link linked name='Link with bullet image in the middle.' ++++++++staticText linked name='Link with ' ++++++++++inlineTextBox name='Link with ' -++++++++image linked name='image' +++++++++image linked name='bullet image' ++++++++staticText linked name=' in the middle.' ++++++++++inlineTextBox name=' in the middle.' ++++++staticText name=' ' @@ -23,7 +23,7 @@ ++++++++++inlineTextBox name=' in the middle.' ++++++staticText name=' ' ++++++++inlineTextBox name=' ' -++++++link linked name='Link with image at the end' +++++++link linked name='Link with image at the end, it's a bullet' ++++++++staticText linked name='Link with image at the ' ++++++++++inlineTextBox name='Link with image at the ' -++++++++image linked name='end' +++++++++image linked name='end, it's a bullet'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-fuchsia.txt b/content/test/data/accessibility/html/a-with-img-expected-fuchsia.txt index cdcd2a5..276b148 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-fuchsia.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-fuchsia.txt
@@ -7,10 +7,10 @@ ++++++++++UNKNOWN label=' with image at start.' ++++++STATIC_TEXT label=' ' ++++++++UNKNOWN label=' ' -++++++LINK focusable label='Link with image in the middle.' actions='{DEFAULT}' +++++++LINK focusable label='Link with bullet image in the middle.' actions='{DEFAULT}' ++++++++STATIC_TEXT label='Link with ' actions='{DEFAULT}' ++++++++++UNKNOWN label='Link with ' -++++++++IMAGE label='image' actions='{DEFAULT}' +++++++++IMAGE label='bullet image' actions='{DEFAULT}' ++++++++STATIC_TEXT label=' in the middle.' actions='{DEFAULT}' ++++++++++UNKNOWN label=' in the middle.' ++++++STATIC_TEXT label=' ' @@ -23,7 +23,7 @@ ++++++++++UNKNOWN label=' in the middle.' ++++++STATIC_TEXT label=' ' ++++++++UNKNOWN label=' ' -++++++LINK focusable label='Link with image at the end' actions='{DEFAULT}' +++++++LINK focusable label='Link with image at the end, it's a bullet' actions='{DEFAULT}' ++++++++STATIC_TEXT label='Link with image at the ' actions='{DEFAULT}' ++++++++++UNKNOWN label='Link with image at the ' -++++++++IMAGE label='end' actions='{DEFAULT}' +++++++++IMAGE label='end, it's a bullet' actions='{DEFAULT}'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-mac.txt b/content/test/data/accessibility/html/a-with-img-expected-mac.txt index 3a03e7d..bd3fa30 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-mac.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-mac.txt
@@ -4,9 +4,9 @@ ++++++AXImage AXDescription='Link' ++++++AXStaticText AXValue=' with image at start.' ++++AXStaticText AXValue=' ' -++++AXLink AXDescription='Link with image in the middle.' +++++AXLink AXDescription='Link with bullet image in the middle.' ++++++AXStaticText AXValue='Link with ' -++++++AXImage AXDescription='image. To get missing image descriptions, open the context menu.' +++++++AXImage AXDescription='bullet image' ++++++AXStaticText AXValue=' in the middle.' ++++AXStaticText AXValue=' ' ++++AXLink AXDescription='Link with broken in the middle.' @@ -14,6 +14,6 @@ ++++++AXImage AXDescription='broken' ++++++AXStaticText AXValue=' in the middle.' ++++AXStaticText AXValue=' ' -++++AXLink AXDescription='Link with image at the end' +++++AXLink AXDescription='Link with image at the end, it's a bullet' ++++++AXStaticText AXValue='Link with image at the ' -++++++AXImage AXDescription='end' \ No newline at end of file +++++++AXImage AXDescription='end, it's a bullet'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt index aa69f507..3e4617b 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt
@@ -4,9 +4,9 @@ ++++++Image Name='Link' ++++++Text Name=' with image at start.' IsControlElement=false ++++Text Name=' ' -++++Hyperlink Name='Link with image in the middle.' +++++Hyperlink Name='Link with bullet image in the middle.' ++++++Text Name='Link with ' IsControlElement=false -++++++Image Name='image. To get missing image descriptions, open the context menu.' +++++++Image Name='bullet image' ++++++Text Name=' in the middle.' IsControlElement=false ++++Text Name=' ' ++++Hyperlink Name='Link with broken in the middle.' @@ -14,6 +14,6 @@ ++++++Image Name='broken' ++++++Text Name=' in the middle.' IsControlElement=false ++++Text Name=' ' -++++Hyperlink Name='Link with image at the end' +++++Hyperlink Name='Link with image at the end, it's a bullet' ++++++Text Name='Link with image at the ' IsControlElement=false -++++++Image Name='end' +++++++Image Name='end, it's a bullet'
diff --git a/content/test/data/accessibility/html/a-with-img-expected-win.txt b/content/test/data/accessibility/html/a-with-img-expected-win.txt index 1c61474..d010197 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-win.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-win.txt
@@ -4,9 +4,9 @@ ++++++ROLE_SYSTEM_GRAPHIC name='Link' READONLY ++++++ROLE_SYSTEM_STATICTEXT name=' with image at start.' ++++ROLE_SYSTEM_STATICTEXT name=' ' -++++ROLE_SYSTEM_LINK name='Link with image in the middle.' FOCUSABLE +++++ROLE_SYSTEM_LINK name='Link with bullet image in the middle.' FOCUSABLE ++++++ROLE_SYSTEM_STATICTEXT name='Link with ' -++++++ROLE_SYSTEM_GRAPHIC name='image. To get missing image descriptions, open the context menu.' READONLY +++++++ROLE_SYSTEM_GRAPHIC name='bullet image' READONLY ++++++ROLE_SYSTEM_STATICTEXT name=' in the middle.' ++++ROLE_SYSTEM_STATICTEXT name=' ' ++++ROLE_SYSTEM_LINK name='Link with broken in the middle.' FOCUSABLE @@ -14,6 +14,6 @@ ++++++ROLE_SYSTEM_GRAPHIC name='broken' READONLY ++++++ROLE_SYSTEM_STATICTEXT name=' in the middle.' ++++ROLE_SYSTEM_STATICTEXT name=' ' -++++ROLE_SYSTEM_LINK name='Link with image at the end' FOCUSABLE +++++ROLE_SYSTEM_LINK name='Link with image at the end, it's a bullet' FOCUSABLE ++++++ROLE_SYSTEM_STATICTEXT name='Link with image at the ' -++++++ROLE_SYSTEM_GRAPHIC name='end' READONLY \ No newline at end of file +++++++ROLE_SYSTEM_GRAPHIC name='end, it's a bullet' READONLY
diff --git a/content/test/data/accessibility/html/a-with-img.html b/content/test/data/accessibility/html/a-with-img.html index 27ac858..b4b5a6c 100644 --- a/content/test/data/accessibility/html/a-with-img.html +++ b/content/test/data/accessibility/html/a-with-img.html
@@ -5,8 +5,8 @@ <html> <body> <a href="http://www.google.com"><img src="bullet.png" alt="Link"/> with image at start.</a> - <a href="http://www.google.com">Link with <img src="bullet.png" alt="image"/> in the middle.</a> + <a href="http://www.google.com">Link with <img src="bullet.png" alt="bullet image"/> in the middle.</a> <a href="http://www.google.com">Link with <img src="broken.png" alt="broken"/> in the middle.</a> - <a href="http://www.google.com">Link with image at the <img src="bullet.png" alt="end"/></a> + <a href="http://www.google.com">Link with image at the <img src="bullet.png" alt="end, it's a bullet"/></a> </body> </html>
diff --git a/content/test/data/gpu/webcodecs/convert-to-rgb.js b/content/test/data/gpu/webcodecs/convert-to-rgb.js index ac4220c..20d16e2 100644 --- a/content/test/data/gpu/webcodecs/convert-to-rgb.js +++ b/content/test/data/gpu/webcodecs/convert-to-rgb.js
@@ -5,7 +5,7 @@ 'use strict'; async function validateFourColorsBytes(frame) { - const tolerance = 5; + const tolerance = 8; const m = 4; let expected_xy_color = [ // Left-top yellow
diff --git a/content/test/data/view_transitions/green.html b/content/test/data/view_transitions/green.html index e6505fe..8b18f9f 100644 --- a/content/test/data/view_transitions/green.html +++ b/content/test/data/view_transitions/green.html
@@ -1,12 +1,6 @@ <!DOCTYPE html> <html> <head> - <!-- - "width=device-width" tag helps avoiding the ViewTransition screenshot size - becomes less than the size of the frame. - TODO(https://crbug.com/1495157): Remove this tag if we can get pass the - DCHECKs. - --> <meta name="viewport" content="width=device-width"> <meta name="view-transition" content="same-origin"> </head>
diff --git a/content/web_test/renderer/test_plugin.cc b/content/web_test/renderer/test_plugin.cc index e25e944..50c15f7e7 100644 --- a/content/web_test/renderer/test_plugin.cc +++ b/content/web_test/renderer/test_plugin.cc
@@ -21,6 +21,10 @@ #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/shared_image_format.h" #include "content/web_test/renderer/test_runner.h" +#include "gin/handle.h" +#include "gin/interceptor.h" +#include "gin/object_template_builder.h" +#include "gin/wrappable.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/client_shared_image.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -116,24 +120,50 @@ return blink::WebPluginContainer::kTouchEventRequestTypeNone; } +class ScriptableObject : public gin::Wrappable<ScriptableObject>, + public gin::NamedPropertyInterceptor { + public: + static gin::WrapperInfo kWrapperInfo; + + static v8::Local<v8::Object> Create(v8::Isolate* isolate) { + ScriptableObject* scriptable_object = new ScriptableObject(isolate); + return gin::CreateHandle(isolate, scriptable_object) + .ToV8() + .As<v8::Object>(); + } + + // gin::NamedPropertyInterceptor + v8::Local<v8::Value> GetNamedProperty( + v8::Isolate* isolate, + const std::string& identifier) override { + if (identifier == "loaded") { + return v8::True(isolate); + } + return v8::Local<v8::Value>(); + } + + private: + explicit ScriptableObject(v8::Isolate* isolate) + : gin::NamedPropertyInterceptor(isolate, this) {} + + // gin::Wrappable + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override { + return gin::Wrappable<ScriptableObject>::GetObjectTemplateBuilder(isolate) + .AddNamedPropertyInterceptor(); + } +}; + +// static +gin::WrapperInfo ScriptableObject::kWrapperInfo = {gin::kEmbedderNativeGin}; + } // namespace TestPlugin::TestPlugin(const blink::WebPluginParams& params, TestRunner* test_runner, blink::WebLocalFrame* frame) : test_runner_(test_runner), - container_(nullptr), web_local_frame_(frame), - gl_(nullptr), - content_changed_(false), - framebuffer_(0), - touch_event_request_( - blink::WebPluginContainer::kTouchEventRequestTypeNone), - re_request_touch_events_(false), - print_event_details_(false), - print_user_gesture_status_(false), - can_process_drag_(false), - supports_keyboard_focus_(false), is_persistent_(params.mime_type == PluginPersistsMimeType()) { DCHECK_EQ(params.attribute_names.size(), params.attribute_values.size()); size_t size = params.attribute_names.size(); @@ -212,6 +242,7 @@ gl_ = nullptr; context_provider_.reset(); + scriptable_object_.Reset(); container_ = nullptr; @@ -301,6 +332,13 @@ return false; } +v8::Local<v8::Object> TestPlugin::V8ScriptableObject(v8::Isolate* isolate) { + if (scriptable_object_.IsEmpty()) { + scriptable_object_.Reset(isolate, ScriptableObject::Create(isolate)); + } + return scriptable_object_.Get(isolate); +} + // static void TestPlugin::ReleaseSharedMemory( scoped_refptr<cc::CrossThreadSharedBitmap> shared_bitmap,
diff --git a/content/web_test/renderer/test_plugin.h b/content/web_test/renderer/test_plugin.h index 43327f2..c9022ca3 100644 --- a/content/web_test/renderer/test_plugin.h +++ b/content/web_test/renderer/test_plugin.h
@@ -100,6 +100,7 @@ void DidFinishLoading() override {} void DidFailLoading(const blink::WebURLError& error) override {} bool IsPlaceholder() override; + v8::Local<v8::Object> V8ScriptableObject(v8::Isolate*) override; // cc::TextureLayerClient methods: bool PrepareTransferableResource( @@ -181,22 +182,24 @@ gpu::Mailbox mailbox_; gpu::SyncToken sync_token_; scoped_refptr<cc::CrossThreadSharedBitmap> shared_bitmap_; - bool content_changed_; - GLuint framebuffer_; + bool content_changed_ = false; + GLuint framebuffer_ = 0; Scene scene_; scoped_refptr<cc::TextureLayer> layer_; - blink::WebPluginContainer::TouchEventRequestType touch_event_request_; + v8::Persistent<v8::Object> scriptable_object_; + + blink::WebPluginContainer::TouchEventRequestType touch_event_request_ = + blink::WebPluginContainer::kTouchEventRequestTypeNone; // Requests touch events from the WebPluginContainerImpl multiple times to // tickle webkit.org/b/108381 - bool re_request_touch_events_; - bool print_event_details_; - bool print_user_gesture_status_; - bool can_process_drag_; - bool supports_keyboard_focus_; + bool re_request_touch_events_ = false; + bool print_event_details_ = false; + bool print_user_gesture_status_ = false; + bool can_process_drag_ = false; + bool supports_keyboard_focus_ = false; bool is_persistent_; - bool can_create_without_renderer_; }; } // namespace content
diff --git a/device/fido/features.cc b/device/fido/features.cc index 71fbad2..8eb9307 100644 --- a/device/fido/features.cc +++ b/device/fido/features.cc
@@ -128,11 +128,6 @@ "WebAuthenticationSkipSingleAccountMacOS", base::FEATURE_ENABLED_BY_DEFAULT); -// Enabled in M116. Remove in or after M119. -BASE_FEATURE(kWebAuthnWindowsUIv6, - "WebAuthenticationWindowsUIv6", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enabled in M117. Remove in or after M120. BASE_FEATURE(kWebAuthConditionalUIExperimentation, "WebAuthenticationConditionalUIExperimentation",
diff --git a/device/fido/features.h b/device/fido/features.h index 2051de1..4b9a9317 100644 --- a/device/fido/features.h +++ b/device/fido/features.h
@@ -102,10 +102,6 @@ COMPONENT_EXPORT(DEVICE_FIDO) BASE_DECLARE_FEATURE(kWebAuthnSkipSingleAccountMacOS); -// Delegate to Windows UI with webauthn.dll version six. -COMPONENT_EXPORT(DEVICE_FIDO) -BASE_DECLARE_FEATURE(kWebAuthnWindowsUIv6); - // Allow sites to opt into experimenting with conditional UI presentations. COMPONENT_EXPORT(DEVICE_FIDO) BASE_DECLARE_FEATURE(kWebAuthConditionalUIExperimentation);
diff --git a/device/fido/win/webauthn_api.cc b/device/fido/win/webauthn_api.cc index 55309d83..1e185f3 100644 --- a/device/fido/win/webauthn_api.cc +++ b/device/fido/win/webauthn_api.cc
@@ -316,8 +316,7 @@ WinWebAuthnApi::~WinWebAuthnApi() = default; bool WinWebAuthnApi::SupportsHybrid() { - return base::FeatureList::IsEnabled(device::kWebAuthnWindowsUIv6) && - IsAvailable() && Version() >= WEBAUTHN_API_VERSION_6; + return IsAvailable() && Version() >= WEBAUTHN_API_VERSION_6; } std::pair<CtapDeviceResponseCode,
diff --git a/docs/speed/startup/android_startup.md b/docs/speed/startup/android_startup.md index 3d33aa3..2e4b6bc 100644 --- a/docs/speed/startup/android_startup.md +++ b/docs/speed/startup/android_startup.md
@@ -59,8 +59,14 @@ Some start-up changes can improve start-up for high-end devices but degrade it for low-end ones (or vice versa). It is important to test both. +For small regressions (e.g. ~1%), it can help to add `--pageset-repeat 10` +or `--pageset-repeat 20` in order to increase the number of samples collected. +A single repeat produces 8 samples, then Pinpoint normally runs it 10 times +(total 80). With `--pageset-repeat=20` the total number of samples is 1600. + * Use `android-go-*` devices to test low-end. * Use `android-pixel6-*` to test high-end. They set `is_high_end_android=true`. +* The full list of bots [is here](/docs/speed/perf_lab_platforms.md). [Pinpoint]: https://pinpoint-dot-chromeperf.appspot.com/
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index 745518a5..29b5aa0 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -47,16 +47,12 @@ AutomationInternalCustomBindings::AutomationInternalCustomBindings( ScriptContext* context, - NativeExtensionBindingsSystem* bindings_system, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - int worker_thread_id) + NativeExtensionBindingsSystem* bindings_system) : ObjectBackedNativeHandler(context), bindings_system_(bindings_system), should_ignore_context_(false), automation_v8_bindings_( - std::make_unique<ui::AutomationV8Bindings>(this, this)), - io_task_runner_(io_task_runner), - worker_thread_id_(worker_thread_id) { + std::make_unique<ui::AutomationV8Bindings>(this, this)) { // We will ignore this instance if the extension has a background page and // this context is not that background page. In all other cases, we will have // multiple instances floating around in the same process. @@ -173,25 +169,8 @@ void AutomationInternalCustomBindings::DispatchEvent( const std::string& event_name, const base::Value::List& event_args) const { - if (worker_thread_id_ == kMainThreadId) { - bindings_system_->DispatchEventInContext(event_name, event_args, nullptr, - context()); - return; - } - - // If the extension is a service worker, post the task to that thread. - // This includes all manifest v3 extensions, as they are required to be - // service workers. - content::WorkerThread::PostTask( - worker_thread_id_, - base::BindOnce( - [](NativeExtensionBindingsSystem* bindings, - const std::string& event_name, const base::Value::List& event_args, - ScriptContext* context) { - bindings->DispatchEventInContext(event_name, event_args, nullptr, - context); - }, - bindings_system_, event_name, event_args.Clone(), context())); + bindings_system_->DispatchEventInContext(event_name, event_args, nullptr, + context()); } std::string @@ -243,11 +222,22 @@ } void AutomationInternalCustomBindings::NotifyTreeEventListenersChanged() { - io_task_runner_->PostTask( - FROM_HERE, + // This task is posted because we need to wait for any pending mutations + // to be processed before sending the event. + auto callback = base::BindOnce(&AutomationInternalCustomBindings:: MaybeSendOnAllAutomationEventListenersRemoved, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr()); + + if (context()->IsForServiceWorker()) { + content::WorkerThread::PostTask(content::WorkerThread::GetCurrentId(), + std::move(callback)); + } else { + context() + ->web_frame() + ->GetTaskRunner(blink::TaskType::kInternalDefault) + ->PostTask(FROM_HERE, std::move(callback)); + } } } // namespace extensions
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.h b/extensions/renderer/api/automation/automation_internal_custom_bindings.h index 2f99f70..475f355d 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.h +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.h
@@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/task/single_thread_task_runner.h" #include "extensions/common/api/automation.h" #include "extensions/renderer/object_backed_native_handler.h" #include "ui/accessibility/ax_enums.mojom-shared.h" @@ -38,9 +37,7 @@ public: AutomationInternalCustomBindings( ScriptContext* context, - NativeExtensionBindingsSystem* bindings_system, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - int worker_thread_id); + NativeExtensionBindingsSystem* bindings_system); AutomationInternalCustomBindings(const AutomationInternalCustomBindings&) = delete; @@ -98,9 +95,6 @@ std::unique_ptr<ui::AutomationV8Bindings> automation_v8_bindings_; - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - const int worker_thread_id_; - base::WeakPtrFactory<AutomationInternalCustomBindings> weak_ptr_factory_{ this}; };
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc index d894404..7cb36e8 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
@@ -38,15 +38,10 @@ script_context->set_url(extension->url()); bindings_system()->UpdateBindingsForContext(script_context); - // Currently the TaskRunner is not used, because the thread ID is - // kMainThreadId. - // When testing with a different thread ID, a runloop will be needed to - // allow the TaskRunner to complete. // TODO(crbug/1487002) Add tests for service worker. auto automation_internal_bindings = - std::make_unique<AutomationInternalCustomBindings>( - script_context, bindings_system(), - base::SingleThreadTaskRunner::GetCurrentDefault(), kMainThreadId); + std::make_unique<AutomationInternalCustomBindings>(script_context, + bindings_system()); automation_internal_bindings_ = automation_internal_bindings.get(); script_context->module_system()->RegisterNativeHandler( "automationInternal", std::move(automation_internal_bindings));
diff --git a/extensions/renderer/bindings/api_binding.cc b/extensions/renderer/bindings/api_binding.cc index c9cb407d..d36f2ba 100644 --- a/extensions/renderer/bindings/api_binding.cc +++ b/extensions/renderer/bindings/api_binding.cc
@@ -536,9 +536,6 @@ } // static -bool APIBinding::enable_promise_support_for_testing = false; - -// static void APIBinding::GetEventObject( v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
diff --git a/extensions/renderer/bindings/api_binding.h b/extensions/renderer/bindings/api_binding.h index 1dee126..f4be942d 100644 --- a/extensions/renderer/bindings/api_binding.h +++ b/extensions/renderer/bindings/api_binding.h
@@ -84,11 +84,6 @@ APIBindingHooks* hooks() { return binding_hooks_.get(); } - // Global bool to allow for testing of promise support. - // TODO(tjudkins): Replace this with a runtime determined condition gated on - // MV3. - static bool enable_promise_support_for_testing; - private: // Initializes the object_template_ for this API. Called lazily when the // first instance is created.
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index e08f1e3..6e42ecd 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -1004,18 +1004,9 @@ "runtime", std::unique_ptr<NativeHandler>(new RuntimeCustomBindings(context))); - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr; - // RenderThread::Get() returns nullptr from some tests. - if (context->IsForServiceWorker() && RenderThread::Get()) { - io_task_runner = RenderThread::Get()->GetIOTaskRunner(); - } else if (context->web_frame()) { - io_task_runner = - context->web_frame()->GetTaskRunner(blink::TaskType::kInternalDefault); - } module_system->RegisterNativeHandler( "automationInternal", std::make_unique<AutomationInternalCustomBindings>( - context, bindings_system, io_task_runner, - content::WorkerThread::GetCurrentId())); + context, bindings_system)); } #if BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
diff --git a/extensions/shell/browser/shell_desktop_controller_aura_browsertest.cc b/extensions/shell/browser/shell_desktop_controller_aura_browsertest.cc index 6bde319..c65a7c6 100644 --- a/extensions/shell/browser/shell_desktop_controller_aura_browsertest.cc +++ b/extensions/shell/browser/shell_desktop_controller_aura_browsertest.cc
@@ -67,6 +67,7 @@ void TearDownOnMainThread() override { EXPECT_FALSE(KeepAliveRegistry::GetInstance()->IsKeepingAlive()); + desktop_controller_ = nullptr; ShellApiTest::TearDownOnMainThread(); } @@ -83,8 +84,7 @@ scoped_refptr<const Extension> app_; private: - raw_ptr<ShellDesktopControllerAura, DanglingUntriaged> desktop_controller_ = - nullptr; + raw_ptr<ShellDesktopControllerAura> desktop_controller_ = nullptr; }; // Test that closing the app window stops the DesktopController.
diff --git a/google_apis/gaia/oauth_multilogin_result_unittest.cc b/google_apis/gaia/oauth_multilogin_result_unittest.cc index 11457e8..777add8 100644 --- a/google_apis/gaia/oauth_multilogin_result_unittest.cc +++ b/google_apis/gaia/oauth_multilogin_result_unittest.cc
@@ -166,14 +166,6 @@ Property(&CanonicalCookie::Priority, Eq(net::CookiePriority::COOKIE_PRIORITY_HIGH)))); - // SameParty is not set, so all these cookies should have IsSameParty() set - // to false (the default value). - EXPECT_THAT(result.cookies(), - ElementsAre(Property(&CanonicalCookie::IsSameParty, Eq(false)), - Property(&CanonicalCookie::IsSameParty, Eq(false)), - Property(&CanonicalCookie::IsSameParty, Eq(false)), - Property(&CanonicalCookie::IsSameParty, Eq(false)))); - EXPECT_THAT(result.cookies()[0].CreationDate().InSecondsFSinceUnixEpoch(), DoubleNear(now, 0.5)); EXPECT_THAT(result.cookies()[0].LastAccessDate().InSecondsFSinceUnixEpoch(),
diff --git a/google_apis/gcm/engine/gcm_unregistration_request_handler.cc b/google_apis/gcm/engine/gcm_unregistration_request_handler.cc index c656a83..7c480a9 100644 --- a/google_apis/gcm/engine/gcm_unregistration_request_handler.cc +++ b/google_apis/gcm/engine/gcm_unregistration_request_handler.cc
@@ -5,7 +5,6 @@ #include "google_apis/gcm/engine/gcm_unregistration_request_handler.h" #include "base/logging.h" -#include "base/metrics/histogram_macros.h" #include "google_apis/gcm/base/gcm_util.h" namespace gcm { @@ -50,11 +49,4 @@ return UnregistrationRequest::RESPONSE_PARSING_FAILED; } -void GCMUnregistrationRequestHandler::ReportUMAs( - UnregistrationRequest::Status status) { - UMA_HISTOGRAM_ENUMERATION("GCM.UnregistrationRequestStatus", - status, - UnregistrationRequest::UNREGISTRATION_STATUS_COUNT); -} - } // namespace gcm
diff --git a/google_apis/gcm/engine/gcm_unregistration_request_handler.h b/google_apis/gcm/engine/gcm_unregistration_request_handler.h index 6a6da7a..c26cd1e 100644 --- a/google_apis/gcm/engine/gcm_unregistration_request_handler.h +++ b/google_apis/gcm/engine/gcm_unregistration_request_handler.h
@@ -14,7 +14,7 @@ class GCM_EXPORT GCMUnregistrationRequestHandler : public UnregistrationRequest::CustomRequestHandler { public: - GCMUnregistrationRequestHandler(const std::string& app_id); + explicit GCMUnregistrationRequestHandler(const std::string& app_id); GCMUnregistrationRequestHandler(const GCMUnregistrationRequestHandler&) = delete; @@ -27,7 +27,7 @@ void BuildRequestBody(std::string* body) override; UnregistrationRequest::Status ParseResponse( const std::string& response) override; - void ReportUMAs(UnregistrationRequest::Status status) override; + void ReportUMAs(UnregistrationRequest::Status status) override {} private: std::string app_id_;
diff --git a/google_apis/internal b/google_apis/internal index 5e58468..8c0bf6a 160000 --- a/google_apis/internal +++ b/google_apis/internal
@@ -1 +1 @@ -Subproject commit 5e58468fff99dbb1482cb9a211e30bd7ca71fb03 +Subproject commit 8c0bf6a2b3aa247b0fbb15ab114e0ac78fbcbf0f
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index b2bde21..4b3ea707 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2921,6 +2921,7 @@ GLboolean visible, GLfloat hdr_headroom, const volatile GLbyte* key) { + TRACE_EVENT0("gpu", "RasterDecoderImpl::DoBeginRasterCHROMIUM"); // Workaround for https://crbug.com/906453: Flush before BeginRaster (the // commands between BeginRaster and EndRaster will not flush). FlushToWorkAroundMacCrashes();
diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc index 676db8d8..4a1fcb8 100644 --- a/gpu/command_buffer/service/service_utils.cc +++ b/gpu/command_buffer/service/service_utils.cc
@@ -251,8 +251,7 @@ VulkanImplementationName ParseVulkanImplementationName( const base::CommandLine* command_line) { #if BUILDFLAG(IS_ANDROID) - if (command_line->HasSwitch(switches::kWebViewDrawFunctorUsesVulkan) && - base::FeatureList::IsEnabled(features::kWebViewVulkan)) { + if (command_line->HasSwitch(switches::kWebViewDrawFunctorUsesVulkan)) { return VulkanImplementationName::kForcedNative; } #endif
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index f9985026..d0b5a51c 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -108,10 +108,6 @@ // Use AImageReader for MediaCodec and MediaPlyer on android. BASE_FEATURE(kAImageReader, "AImageReader", base::FEATURE_ENABLED_BY_DEFAULT); -// If webview-draw-functor-uses-vulkan is set, use vulkan for composite and -// raster. -BASE_FEATURE(kWebViewVulkan, "WebViewVulkan", base::FEATURE_ENABLED_BY_DEFAULT); - // Used to limit AImageReader max queue size to 1 since many devices especially // android Tv devices do not support more than 1 images. BASE_FEATURE(kLimitAImageReaderMaxSizeToOne, @@ -254,7 +250,7 @@ // Enable Vulkan graphics backend for compositing and rasterization. Defaults to // native implementation if --use-vulkan flag is not used. Otherwise // --use-vulkan will be followed. -// Note Android WebView uses kWebViewVulkan instead of this. +// Note Android WebView uses kWebViewDrawFunctorUsesVulkan instead of this. BASE_FEATURE(kVulkan, "Vulkan", #if BUILDFLAG(IS_ANDROID) @@ -472,8 +468,7 @@ // WebView checks, which do not use (and disables) kVulkan. // Do this above the Android version check because there are test devices if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kWebViewDrawFunctorUsesVulkan) && - base::FeatureList::IsEnabled(kWebViewVulkan)) { + switches::kWebViewDrawFunctorUsesVulkan)) { return true; }
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h index da9a6ee..dfce763 100644 --- a/gpu/config/gpu_finch_features.h +++ b/gpu/config/gpu_finch_features.h
@@ -27,7 +27,6 @@ GPU_EXPORT BASE_DECLARE_FEATURE(kAndroidSurfaceControl); GPU_EXPORT BASE_DECLARE_FEATURE(kWebViewSurfaceControl); GPU_EXPORT BASE_DECLARE_FEATURE(kAImageReader); -GPU_EXPORT BASE_DECLARE_FEATURE(kWebViewVulkan); GPU_EXPORT BASE_DECLARE_FEATURE(kLimitAImageReaderMaxSizeToOne); GPU_EXPORT BASE_DECLARE_FEATURE(kWebViewThreadSafeMediaDefault); GPU_EXPORT BASE_DECLARE_FEATURE(kIncreaseBufferCountForHighFrameRate);
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index c9d7ef6a..f047b7e 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc
@@ -875,8 +875,7 @@ gl::GLDisplay* gl_display = InitializeGLThreadSafe( command_line, gpu_preferences_, &gpu_info_, &gpu_feature_info_); - if (command_line->HasSwitch(switches::kWebViewDrawFunctorUsesVulkan) && - base::FeatureList::IsEnabled(features::kWebViewVulkan)) { + if (command_line->HasSwitch(switches::kWebViewDrawFunctorUsesVulkan)) { bool result = InitializeVulkan(); // There is no fallback for webview. CHECK(result);
diff --git a/infra/config/dev/subprojects/chromium/ci.star b/infra/config/dev/subprojects/chromium/ci.star index 32bf7e9..64a863e 100644 --- a/infra/config/dev/subprojects/chromium/ci.star +++ b/infra/config/dev/subprojects/chromium/ci.star
@@ -159,6 +159,7 @@ ), ), builderless = False, + ssd = True, ) ci_builder(
diff --git a/infra/config/generated/builders/try/linux-wpt-chromium-rel/properties.json b/infra/config/generated/builders/try/linux-wpt-chromium-rel/properties.json index d5aa2a9..f82b19e6 100644 --- a/infra/config/generated/builders/try/linux-wpt-chromium-rel/properties.json +++ b/infra/config/generated/builders/try/linux-wpt-chromium-rel/properties.json
@@ -35,7 +35,7 @@ "project": "chromium" } ], - "retry_failed_shards": false + "retry_failed_shards": true } }, "$build/reclient": {
diff --git a/infra/config/generated/luci/cr-buildbucket-dev.cfg b/infra/config/generated/luci/cr-buildbucket-dev.cfg index 9d767da..4e42fae2 100644 --- a/infra/config/generated/luci/cr-buildbucket-dev.cfg +++ b/infra/config/generated/luci/cr-buildbucket-dev.cfg
@@ -74,6 +74,7 @@ dimensions: "builder:linux-local-ssd-rel-dev" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-22.04" + dimensions: "ssd:1" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index e7c4743..b6eed54 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -57037,7 +57037,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57122,7 +57122,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57207,7 +57207,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57291,7 +57291,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57376,7 +57376,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57457,7 +57457,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57541,7 +57541,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57626,7 +57626,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -57710,7 +57710,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62356,7 +62356,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62440,7 +62440,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62525,7 +62525,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62621,7 +62621,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62716,7 +62716,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62811,7 +62811,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -62910,7 +62910,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63005,7 +63005,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63100,7 +63100,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63195,7 +63195,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63368,7 +63368,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63463,7 +63463,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63558,7 +63558,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63661,7 +63661,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63756,7 +63756,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63851,7 +63851,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -63946,7 +63946,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64041,7 +64041,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64136,7 +64136,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64243,7 +64243,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64358,7 +64358,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64454,7 +64454,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64549,7 +64549,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64637,7 +64637,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64731,7 +64731,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64827,7 +64827,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -64922,7 +64922,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65018,7 +65018,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65114,7 +65114,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65210,7 +65210,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65306,7 +65306,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65402,7 +65402,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65498,7 +65498,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65594,7 +65594,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65690,7 +65690,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65786,7 +65786,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65882,7 +65882,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -65978,7 +65978,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66074,7 +66074,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66171,7 +66171,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66267,7 +66267,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66363,7 +66363,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66459,7 +66459,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66555,7 +66555,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66651,7 +66651,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66748,7 +66748,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66844,7 +66844,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -66940,7 +66940,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67036,7 +67036,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67132,7 +67132,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67228,7 +67228,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67322,7 +67322,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67416,7 +67416,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67505,7 +67505,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67592,7 +67592,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67686,7 +67686,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67781,7 +67781,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67877,7 +67877,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -67972,7 +67972,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68067,7 +68067,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68162,7 +68162,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68257,7 +68257,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68352,7 +68352,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68447,7 +68447,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68542,7 +68542,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68637,7 +68637,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68732,7 +68732,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68827,7 +68827,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -68922,7 +68922,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69017,7 +69017,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69112,7 +69112,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69207,7 +69207,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69306,7 +69306,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69402,7 +69402,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69498,7 +69498,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69593,7 +69593,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69688,7 +69688,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69784,7 +69784,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69881,7 +69881,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -69977,7 +69977,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70072,7 +70072,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70168,7 +70168,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70263,7 +70263,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70346,7 +70346,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70441,7 +70441,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70536,7 +70536,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70632,7 +70632,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70727,7 +70727,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70822,7 +70822,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -70923,7 +70923,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71018,7 +71018,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71114,7 +71114,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71215,7 +71215,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71316,7 +71316,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71416,7 +71416,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71516,7 +71516,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71611,7 +71611,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71706,7 +71706,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71801,7 +71801,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71896,7 +71896,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -71991,7 +71991,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72086,7 +72086,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72182,7 +72182,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72278,7 +72278,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72373,7 +72373,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72461,7 +72461,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72554,7 +72554,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72649,7 +72649,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72744,7 +72744,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72839,7 +72839,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -72934,7 +72934,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73028,7 +73028,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73122,7 +73122,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73216,7 +73216,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73310,7 +73310,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73405,7 +73405,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73500,7 +73500,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73595,7 +73595,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73690,7 +73690,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73784,7 +73784,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73879,7 +73879,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -73974,7 +73974,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74109,7 +74109,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74205,7 +74205,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74305,7 +74305,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } experiments { key: "weetbix.enable_weetbix_exonerations" @@ -74413,7 +74413,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74521,7 +74521,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74610,7 +74610,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74704,7 +74704,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74800,7 +74800,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74888,7 +74888,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -74982,7 +74982,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75077,7 +75077,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75173,7 +75173,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75268,7 +75268,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75364,7 +75364,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75460,7 +75460,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75563,7 +75563,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75658,7 +75658,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75757,7 +75757,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } experiments { key: "weetbix.enable_weetbix_exonerations" @@ -75852,7 +75852,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -75948,7 +75948,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76039,7 +76039,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76131,7 +76131,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76223,7 +76223,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76315,7 +76315,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76407,7 +76407,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76499,7 +76499,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76591,7 +76591,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76683,7 +76683,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76775,7 +76775,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76867,7 +76867,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -76959,7 +76959,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77051,7 +77051,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77143,7 +77143,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77235,7 +77235,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77327,7 +77327,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77419,7 +77419,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77510,7 +77510,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77601,7 +77601,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77692,7 +77692,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77783,7 +77783,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77874,7 +77874,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -77965,7 +77965,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78056,7 +78056,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78147,7 +78147,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78238,7 +78238,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78329,7 +78329,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78420,7 +78420,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78511,7 +78511,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78602,7 +78602,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78693,7 +78693,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78785,7 +78785,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78877,7 +78877,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -78969,7 +78969,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79061,7 +79061,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79153,7 +79153,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79245,7 +79245,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79337,7 +79337,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79429,7 +79429,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79521,7 +79521,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79613,7 +79613,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79705,7 +79705,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79797,7 +79797,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79888,7 +79888,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -79979,7 +79979,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80071,7 +80071,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80250,7 +80250,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80347,7 +80347,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80444,7 +80444,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80541,7 +80541,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80638,7 +80638,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80735,7 +80735,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80832,7 +80832,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -80931,7 +80931,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81028,7 +81028,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81125,7 +81125,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81223,7 +81223,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81320,7 +81320,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81418,7 +81418,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81517,7 +81517,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81616,7 +81616,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81714,7 +81714,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81811,7 +81811,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -81908,7 +81908,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82005,7 +82005,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82102,7 +82102,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82197,7 +82197,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82293,7 +82293,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82389,7 +82389,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82485,7 +82485,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82580,7 +82580,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82676,7 +82676,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82771,7 +82771,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82867,7 +82867,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -82962,7 +82962,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83049,7 +83049,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83259,7 +83259,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83354,7 +83354,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83450,7 +83450,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83545,7 +83545,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83640,7 +83640,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83735,7 +83735,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83830,7 +83830,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -83925,7 +83925,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84020,7 +84020,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84115,7 +84115,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84210,7 +84210,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84305,7 +84305,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84400,7 +84400,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84495,7 +84495,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84582,7 +84582,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84677,7 +84677,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84772,7 +84772,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84867,7 +84867,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -84954,7 +84954,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85048,7 +85048,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85143,7 +85143,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85239,7 +85239,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85335,7 +85335,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85438,7 +85438,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85533,7 +85533,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85620,7 +85620,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85714,7 +85714,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85810,7 +85810,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85903,7 +85903,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -85999,7 +85999,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86094,7 +86094,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86189,7 +86189,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86284,7 +86284,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86379,7 +86379,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86474,7 +86474,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86569,7 +86569,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86665,7 +86665,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86760,7 +86760,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86856,7 +86856,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -86951,7 +86951,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87039,7 +87039,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87133,7 +87133,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87228,7 +87228,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87323,7 +87323,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87422,7 +87422,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87517,7 +87517,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87612,7 +87612,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87707,7 +87707,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87797,7 +87797,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87891,7 +87891,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -87986,7 +87986,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88081,7 +88081,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88176,7 +88176,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88272,7 +88272,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88375,7 +88375,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88470,7 +88470,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88569,7 +88569,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88664,7 +88664,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88759,7 +88759,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88858,7 +88858,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -88953,7 +88953,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89045,7 +89045,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89137,7 +89137,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89265,7 +89265,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89357,7 +89357,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89449,7 +89449,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89544,7 +89544,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89639,7 +89639,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89734,7 +89734,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89829,7 +89829,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -89924,7 +89924,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90019,7 +90019,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90114,7 +90114,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90209,7 +90209,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90305,7 +90305,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90400,7 +90400,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90494,7 +90494,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90589,7 +90589,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90684,7 +90684,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90779,7 +90779,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90874,7 +90874,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -90970,7 +90970,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91065,7 +91065,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91160,7 +91160,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91255,7 +91255,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91351,7 +91351,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91446,7 +91446,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91549,7 +91549,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91644,7 +91644,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91743,7 +91743,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91838,7 +91838,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -91934,7 +91934,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92029,7 +92029,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92124,7 +92124,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92212,7 +92212,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92310,7 +92310,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92405,7 +92405,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92505,7 +92505,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92606,7 +92606,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92701,7 +92701,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92800,7 +92800,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92895,7 +92895,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -92994,7 +92994,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93089,7 +93089,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93184,7 +93184,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93270,7 +93270,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93356,7 +93356,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93568,7 +93568,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93662,7 +93662,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93756,7 +93756,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93849,7 +93849,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -93942,7 +93942,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94036,7 +94036,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94128,7 +94128,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94221,7 +94221,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94315,7 +94315,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94408,7 +94408,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94503,7 +94503,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94597,7 +94597,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94690,7 +94690,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94784,7 +94784,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94878,7 +94878,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -94977,7 +94977,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95070,7 +95070,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95163,7 +95163,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95256,7 +95256,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95355,7 +95355,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95450,7 +95450,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95541,7 +95541,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95635,7 +95635,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95729,7 +95729,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95823,7 +95823,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -95916,7 +95916,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96010,7 +96010,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96104,7 +96104,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96198,7 +96198,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96292,7 +96292,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96385,7 +96385,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96478,7 +96478,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96572,7 +96572,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96666,7 +96666,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96760,7 +96760,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96854,7 +96854,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -96947,7 +96947,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97041,7 +97041,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97135,7 +97135,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97229,7 +97229,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97323,7 +97323,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97416,7 +97416,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97510,7 +97510,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97604,7 +97604,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97697,7 +97697,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97791,7 +97791,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97885,7 +97885,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -97980,7 +97980,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98074,7 +98074,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98168,7 +98168,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98262,7 +98262,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98347,7 +98347,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98432,7 +98432,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98517,7 +98517,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98602,7 +98602,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98683,7 +98683,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98779,7 +98779,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98874,7 +98874,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -98956,7 +98956,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99039,7 +99039,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99130,7 +99130,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99216,7 +99216,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99302,7 +99302,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99388,7 +99388,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99598,7 +99598,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99732,7 +99732,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99827,7 +99827,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -99922,7 +99922,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100017,7 +100017,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100112,7 +100112,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100204,7 +100204,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100298,7 +100298,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100392,7 +100392,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100488,7 +100488,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100580,7 +100580,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100674,7 +100674,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100769,7 +100769,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100857,7 +100857,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -100959,7 +100959,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101054,7 +101054,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101149,7 +101149,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101244,7 +101244,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101339,7 +101339,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101438,7 +101438,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101533,7 +101533,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101625,7 +101625,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101753,7 +101753,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101881,7 +101881,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -101973,7 +101973,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102065,7 +102065,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102161,7 +102161,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102257,7 +102257,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102345,7 +102345,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102439,7 +102439,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102534,7 +102534,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102629,7 +102629,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102724,7 +102724,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102818,7 +102818,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -102912,7 +102912,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103006,7 +103006,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103102,7 +103102,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103197,7 +103197,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103293,7 +103293,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103389,7 +103389,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103484,7 +103484,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103579,7 +103579,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103674,7 +103674,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103754,7 +103754,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true @@ -103834,7 +103834,7 @@ } experiments { key: "swarming.prpc.cli" - value: 5 + value: 50 } resultdb { enable: true
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 67fdc8e4..9777cbc 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -2216,6 +2216,11 @@ short_name: "perf-arm" } builders { + name: "buildbucket/luci.chrome.ci/fuchsia-arm64-rel-ready" + category: "gardener|p/chrome|arm64" + short_name: "rel-ready" + } + builders { name: "buildbucket/luci.chrome.ci/fuchsia-fyi-arm64-size" category: "gardener|p/chrome|arm64" short_name: "size"
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl index 81a42ab..659d807 100644 --- a/infra/config/generated/testing/test_suites.pyl +++ b/infra/config/generated/testing/test_suites.pyl
@@ -3890,6 +3890,13 @@ }, 'components_browsertests': {}, 'components_unittests': {}, + 'compositor_unittests': { + 'test': 'compositor_unittests', + 'args': [ + '--test-launcher-bot-mode', + '--test-launcher-filter-file=testing/buildbot/filters/ios.compositor_unittests.filter', + ], + }, 'content_browsertests': { 'args': [ '--test-launcher-bot-mode',
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index ea191b9..75e4cfc 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 121.0.6137.0', + 'description': 'Run with ash-chrome version 121.0.6138.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v121.0.6137.0', - 'revision': 'version:121.0.6137.0', + 'location': 'lacros_version_skew_tests_v121.0.6138.0', + 'revision': 'version:121.0.6138.0', }, ], },
diff --git a/infra/config/lib/try.star b/infra/config/lib/try.star index 4014c24..31849ab 100644 --- a/infra/config/lib/try.star +++ b/infra/config/lib/try.star
@@ -233,7 +233,7 @@ experiments.setdefault("chromium_swarming.expose_merge_script_failures", 100) # TODO(crbug.com/1466962): Remove when the experiment is the default. - experiments.setdefault("swarming.prpc.cli", 5) + experiments.setdefault("swarming.prpc.cli", 50) merged_resultdb_bigquery_exports = [ resultdb.export_test_results(
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 7f6cfa5..9a33a18 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -177,6 +177,7 @@ category = category, short_name = short_name, ) for name, category, short_name in ( + ("fuchsia-arm64-rel-ready", "gardener|p/chrome|arm64", "rel-ready"), ("fuchsia-arm64-nest-sd", "gardener|p/chrome|arm64", "nest-arm"), ("fuchsia-builder-perf-arm64", "gardener|p/chrome|arm64", "perf-arm"), ("fuchsia-cast-astro", "gardener|hardware|cast", "ast"),
diff --git a/infra/config/subprojects/chromium/try/tryserver.blink.star b/infra/config/subprojects/chromium/try/tryserver.blink.star index 96f3d2f..659284a 100644 --- a/infra/config/subprojects/chromium/try/tryserver.blink.star +++ b/infra/config/subprojects/chromium/try/tryserver.blink.star
@@ -72,7 +72,7 @@ """, mirrors = ["ci/linux-wpt-fyi-rel"], try_settings = builder_config.try_settings( - retry_failed_shards = False, + retry_failed_shards = True, ), os = os.LINUX_DEFAULT, contact_team_email = "chrome-blink-engprod@google.com",
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star index 82d5ce94e..8c63194 100644 --- a/infra/config/targets/basic_suites.star +++ b/infra/config/targets/basic_suites.star
@@ -4544,6 +4544,13 @@ ), "components_browsertests": None, "components_unittests": None, + "compositor_unittests": targets.legacy_test_config( + test = "compositor_unittests", + args = [ + "--test-launcher-bot-mode", + "--test-launcher-filter-file=testing/buildbot/filters/ios.compositor_unittests.filter", + ], + ), "content_browsertests": targets.legacy_test_config( args = [ "--test-launcher-bot-mode",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index 0b1d1dd1..4fd4ed2 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.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_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ] }
diff --git a/internal b/internal index a745a52..57f20f5 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit a745a52bdcff739fdbd370e7fb7da57c8111786e +Subproject commit 57f20f590e37501b247262add777c9ec78fd696b
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index 40443b2..ec3365a 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -258,7 +258,6 @@ "//base/test:test_support", "//components/version_info", "//ios/chrome/app", - "//ios/chrome/app:app_internal", "//ios/chrome/app:mode", "//ios/chrome/browser/url_loading/model", "//net",
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_fil.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_fil.xtb index 222dc66..cd8c2bca 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_fil.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_fil.xtb
@@ -87,6 +87,7 @@ <translation id="4195557071150719219">Tingnan ang Mga Kamakailang Tab sa Chromium</translation> <translation id="4408912345039114853">Magpatakbo ng Pag-check sa Kaligtasan sa Chromium</translation> <translation id="4432744876818348753">Mag-sign in para masulit ang Chromium.</translation> +<translation id="4498832288620833153">Idaragdag ang mga in-input na URL sa iyong listahan ng babasahin sa Chromium.</translation> <translation id="452436063477828504">Tiyaking magagamit mo sa anumang oras ang data ng Chromium sa iyong Google Account</translation> <translation id="4555020257205549924">Kapag naka-on ang feature na ito, mag-aalok ang Chromium na magsalin ng mga page na nakasulat sa ibang mga wika gamit ang Google Translate. <ph name="BEGIN_LINK" />Matuto pa<ph name="END_LINK" /></translation> <translation id="4576283463017113841">Bubuksan ang Page ng Setting ng Mga Paraan ng Pagbabayad sa Chromium.</translation> @@ -197,6 +198,7 @@ <translation id="7928628054454574139">Buksan ang Chromium sa tuwing magta-tap ka sa mga link sa iba pang app</translation> <translation id="7931842119211730154">I-lock ang Mga Tab na Incognito Kapag Isinara Mo ang Chromium</translation> <translation id="7934404985878918282">Tingnan ang Listahan ng Babasahin sa Chromium</translation> +<translation id="7971753607796745700">Magdagdag ng Item sa Listahan ng Babasahin sa Chromium</translation> <translation id="7980860476903281594">Ibabahagi ng Chromium ang iyong lokasyon sa mga site na pinapayagan mo.</translation> <translation id="7995166854192397899">Batay ang mga suhestyon sa iyong aktibidad sa pag-browse sa iba mo pang device. Para makatanggap ng mga suhestyon, mag-sign in sa Chromium sa lahat ng iyong device.</translation> <translation id="800195749539500647">Sulitin ang Chromium</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb index 6d22c271..954807df 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
@@ -87,6 +87,7 @@ <translation id="4195557071150719219">Lihat Tab Terbaharu Chromium</translation> <translation id="4408912345039114853">Jalankan Pemeriksaan Keselamatan Chromium</translation> <translation id="4432744876818348753">Log masuk untuk memanfaatkan Chromium sepenuhnya</translation> +<translation id="4498832288620833153">Menambahkan URL yang diinput pada senarai bacaan anda dalam Chromium.</translation> <translation id="452436063477828504">Pastikan anda dapat menggunakan data Chromium pada bila-bila masa dalam Google Account anda</translation> <translation id="4555020257205549924">Apabila ciri ini dihidupkan, Chromium akan menawarkan untuk menterjemah halaman yang ditulis dalam bahasa lain menggunakan Terjemahan Google. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> <translation id="4576283463017113841">Buka Halaman Tetapan Kaedah Pembayaran dalam Chromium.</translation> @@ -197,6 +198,7 @@ <translation id="7928628054454574139">Buka Chromium pada bila-bila masa anda mengetik pautan dalam apl lain</translation> <translation id="7931842119211730154">Kunci Tab Inkognito Apabila Anda Menutup Chromium</translation> <translation id="7934404985878918282">Lihat Senarai Bacaan Chromium</translation> +<translation id="7971753607796745700">Tambahkan Item Senarai Bacaan pada Chromium</translation> <translation id="7980860476903281594">Chromium berkongsi lokasi anda dengan laman yang anda benarkan.</translation> <translation id="7995166854192397899">Cadangan adalah berdasarkan aktiviti penyemakan imbas anda pada peranti anda yang lain. Untuk mendapatkan cadangan, log masuk ke Chromium pada semua peranti anda.</translation> <translation id="800195749539500647">Manfaat Chromium sepenuhnya</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_th.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_th.xtb index 4c02d886..7ca633f0 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_th.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_th.xtb
@@ -87,6 +87,7 @@ <translation id="4195557071150719219">ดูแท็บล่าสุดใน Chromium</translation> <translation id="4408912345039114853">เรียกใช้การตรวจสอบความปลอดภัยใน Chromium</translation> <translation id="4432744876818348753">ลงชื่อเข้าใช้เพื่อรับประโยชน์สูงสุดจาก Chromium</translation> +<translation id="4498832288620833153">เพิ่ม URL ที่ป้อนลงในเรื่องรออ่านใน Chromium</translation> <translation id="452436063477828504">ตรวจสอบว่าคุณใช้ข้อมูล Chromium ในบัญชี Google ได้เสมอ</translation> <translation id="4555020257205549924">เมื่อเปิดฟีเจอร์นี้ Chromium จะเสนอให้แปลหน้าต่างๆ ที่เขียนด้วยภาษาอื่นโดยใช้ Google แปลภาษา <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> <translation id="4576283463017113841">เปิดหน้าการตั้งค่าวิธีการชำระเงินใน Chromium</translation> @@ -197,6 +198,7 @@ <translation id="7928628054454574139">คุณแตะลิงก์ในแอปอื่นๆ เพื่อเปิด Chromium ได้ทุกเมื่อ</translation> <translation id="7931842119211730154">ล็อกแท็บที่ไม่ระบุตัวตนเมื่อปิด Chromium</translation> <translation id="7934404985878918282">ดูเรื่องรออ่านใน Chromium</translation> +<translation id="7971753607796745700">เพิ่มรายการเรื่องรออ่านใน Chromium</translation> <translation id="7980860476903281594">Chromium แชร์ตำแหน่งกับเว็บไซต์ที่คุณอนุญาต</translation> <translation id="7995166854192397899">คำแนะนำต่างๆ จะอิงตามกิจกรรมการท่องเว็บในอุปกรณ์อื่นๆ ของคุณ หากต้องการรับคำแนะนำ ให้ลงชื่อเข้าใช้ Chromium ในอุปกรณ์ทั้งหมดของคุณ</translation> <translation id="800195749539500647">รับประโยชน์สูงสุดจาก Chromium</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_fil.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_fil.xtb index c5e13ce..fbbef0d 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_fil.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_fil.xtb
@@ -58,6 +58,7 @@ <translation id="2671426118752779020">Puwede mong gamitin ang mga password na na-save mo sa Google Password Manager sa iba pang app sa iyong iPhone.</translation> <translation id="2689064829982324496">Para mag-sign out sa iyong Google Account sa lahat ng website, <ph name="BEGIN_LINK" />mag-sign out sa Chrome<ph name="END_LINK" />.</translation> <translation id="2695886661449553974">Hindi matingnan ng Chrome kung may mga update. Subukan ulit sa ibang pagkakataon.</translation> +<translation id="2702250627063295552">Magdagdag ng Item sa Listahan ng Babasahin sa Chrome</translation> <translation id="2736805085127235148">Kasalukuyang naka-off ang mga notification sa Chrome sa mga setting ng iyong device.</translation> <translation id="2767464022270041271">Walang naka-save na password. Masusuri ng Google Password Manager ang iyong mga password kapag na-save mo ang mga ito.</translation> <translation id="2868822340714096138">I-clear ang Data Mula sa Pagba-browse sa Chrome</translation> @@ -83,6 +84,7 @@ <translation id="3744018071945602754">Pamahalaan ang Mga Password sa Chrome</translation> <translation id="3827545470516145620">Mayroon kang standard na proteksyon sa seguridad sa device na ito</translation> <translation id="384394811301901750">Hindi magamit ng Google Chrome ang camera mo ngayon</translation> +<translation id="3863841106411295595">Idaragdag ang mga in-input na URL sa iyong listahan ng babasahin sa Chrome.</translation> <translation id="3901001113120561395">Sulitin ang Chrome.</translation> <translation id="3967382818307165056">Mamahala ng Mga Paraan ng Pagbabayad sa Chrome</translation> <translation id="3980220367029651214">Lumilipat ka mula sa naka-sync na account na <ph name="USER_EMAIL1" /> papunta sa <ph name="USER_EMAIL2" />. Pinamamahalaan ng <ph name="DOMAIN" /> ang kasalukuyan mong data sa Chrome. Ide-delete nito ang data mo sa device na ito, ngunit mananatili ang iyong data sa <ph name="USER_EMAIL1" />.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb index 73fa6ca..badae43 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
@@ -58,6 +58,7 @@ <translation id="2671426118752779020">Anda boleh menggunakan kata laluan yang anda simpan pada Pengurus Kata Laluan Google dalam apl lain pada iPhone anda.</translation> <translation id="2689064829982324496">Untuk log keluar daripada Google Account dalam semua laman web, <ph name="BEGIN_LINK" />log keluar daripada Chrome<ph name="END_LINK" />.</translation> <translation id="2695886661449553974">Chrome tidak dapat menyemak kemaskinian. Cuba lagi nanti.</translation> +<translation id="2702250627063295552">Tambahkan Item Senarai Bacaan pada Chrome</translation> <translation id="2736805085127235148">Pemberitahuan Chrome dimatikan dalam tetapan peranti anda pada masa ini.</translation> <translation id="2767464022270041271">Tiada kata laluan yang disimpan. Google Password Manager boleh menyemak kata laluan anda yang disimpan.</translation> <translation id="2868822340714096138">Kosongkan Data Semakan Imbas dalam Chrome</translation> @@ -83,6 +84,7 @@ <translation id="3744018071945602754">Urus Kata Laluan dalam Chrome</translation> <translation id="3827545470516145620">Anda mendapat perlindungan keselamatan standard pada peranti ini</translation> <translation id="384394811301901750">Google Chrome tidak dapat menggunakan kamera anda sekarang</translation> +<translation id="3863841106411295595">Menambahkan URL yang diinput pada senarai bacaan anda dalam Chrome.</translation> <translation id="3901001113120561395">Manfaatkan Chrome sepenuhnya.</translation> <translation id="3967382818307165056">Urus Kaedah Pembayaran dalam Chrome</translation> <translation id="3980220367029651214">Anda bertukar akaun penyegerakan daripada <ph name="USER_EMAIL1" /> kepada <ph name="USER_EMAIL2" />. Data Chrome sedia ada anda diurus oleh <ph name="DOMAIN" />. Ini akan memadamkan data anda daripada peranti ini, tetapi data anda akan kekal dalam <ph name="USER_EMAIL1" />.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_th.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_th.xtb index 13a3b534..83c6ca2 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_th.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_th.xtb
@@ -58,6 +58,7 @@ <translation id="2671426118752779020">คุณใช้รหัสผ่านที่บันทึกอยู่ในเครื่องมือจัดการรหัสผ่านบน Google ในแอปอื่นๆ บน iPhone ได้</translation> <translation id="2689064829982324496">หากต้องการออกจากระบบบัญชี Google ในเว็บไซต์ทั้งหมด ให้<ph name="BEGIN_LINK" />ออกจากระบบ Chrome<ph name="END_LINK" /></translation> <translation id="2695886661449553974">Chrome ตรวจหาอัปเดตไม่ได้ โปรดลองอีกครั้งภายหลัง</translation> +<translation id="2702250627063295552">เพิ่มรายการเรื่องรออ่านใน Chrome</translation> <translation id="2736805085127235148">ตอนนี้การแจ้งเตือนของ Chrome ปิดอยู่ในการตั้งค่าอุปกรณ์</translation> <translation id="2767464022270041271">ไม่มีรหัสผ่านที่บันทึกไว้ เครื่องมือจัดการรหัสผ่านบน Google จะตรวจสอบรหัสผ่านได้เมื่อคุณบันทึกไว้</translation> <translation id="2868822340714096138">ล้างข้อมูลการท่องเว็บใน Chrome</translation> @@ -83,6 +84,7 @@ <translation id="3744018071945602754">จัดการรหัสผ่านใน Chrome</translation> <translation id="3827545470516145620">คุณกำลังได้รับการรักษาความปลอดภัยแบบมาตรฐานในอุปกรณ์นี้</translation> <translation id="384394811301901750">Google Chrome ไม่สามารถใช้กล้องถ่ายรูปได้ในขณะนี้</translation> +<translation id="3863841106411295595">เพิ่ม URL ที่ป้อนลงในเรื่องรออ่านใน Chrome</translation> <translation id="3901001113120561395">รับประโยชน์สูงสุดจาก Chrome</translation> <translation id="3967382818307165056">จัดการวิธีการชำระเงินใน Chrome</translation> <translation id="3980220367029651214">คุณกำลังเปลี่ยนบัญชีในการซิงค์จาก <ph name="USER_EMAIL1" /> เป็น <ph name="USER_EMAIL2" /> ข้อมูล Chrome ที่มีอยู่ของคุณจัดการโดย <ph name="DOMAIN" /> การเปลี่ยนบัญชีจะลบข้อมูลจากอุปกรณ์นี้ แต่ข้อมูลจะยังคงอยู่ใน <ph name="USER_EMAIL1" /></translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_af.xtb b/ios/chrome/app/strings/resources/ios_strings_af.xtb index 0766eba..c6b2a313 100644 --- a/ios/chrome/app/strings/resources/ios_strings_af.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_af.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Slimrangskikingkieslysbalk</translation> <translation id="4860895144060829044">Bel</translation> <translation id="4881695831933465202">Maak oop</translation> +<translation id="4883824756452868502">Bespeur eenhede</translation> <translation id="488785315393301722">Wys besonderhede</translation> <translation id="4894963374040315706">Dit maak dit vir jou moontlik om met jou stem te soek</translation> <translation id="489903206070130262">Jou laaste oop oortjie</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Merk as gelees</translation> <translation id="4908869848243824489">Ontdek deur Google</translation> <translation id="4913626501929406101">Jy kan veilig ’n kopie van jou wagwoord met iemand in jou gesinsgroep deel. <ph name="BEGIN_LINK" />Kom meer te wete<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Aanvaar</translation> <translation id="4922154083994158612">Nog sekuriteit?</translation> <translation id="4930714375720679147">Skakel aan</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Aanbieding om te vertaal</translation> <translation id="5556459405103347317">Herlaai</translation> <translation id="555749644339804659">Gaan tans wagwoorde na …</translation> +<translation id="5559567453458728487">Skakel metingeenhede om wat op die web gevind word</translation> <translation id="556042886152191864">Knoppie</translation> <translation id="5572684875078967866">Inligtingberging</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Spoor hierdie pakkie na}other{Spoor alle pakkies na}}</translation> <translation id="5597915316964418992">Maak die oortjierooster oop</translation> <translation id="560322036295180549">Afgeskakel deur jou organisasie</translation> <translation id="5614553682702429503">Stoor wagwoord?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Skakel sinkronisering aan?</translation> <translation id="6781405765516175232">Tik op “Kry rigtingaanwysings” vir roete-opsies.</translation> <translation id="6785453220513215166">Stuur tans omvalverslag …</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Stop nasporing van hierdie pakkie}other{Stop nasporing van hierdie pakkies}}</translation> <translation id="6790502149545262384">Jy sal binnekort stories van <ph name="CHANNEL_NAME" /> af sien wanneer jy ’n nuwe oortjie oopmaak.</translation> <translation id="6797885426782475225">Stemsoektog</translation> <translation id="6800349425672670802">Jy kan vanaf die Oortjiewisselaar toegang tot al jou oop oortjies kry.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_am.xtb b/ios/chrome/app/strings/resources/ios_strings_am.xtb index 04f0913..712d03ea 100644 --- a/ios/chrome/app/strings/resources/ios_strings_am.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_am.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">የዘመናዊ ድርድር የምናሌ አሞሌ</translation> <translation id="4860895144060829044">ደውል</translation> <translation id="4881695831933465202">ክፍት የሚሆንባቸው</translation> +<translation id="4883824756452868502">አሃዶችን ይወቁ</translation> <translation id="488785315393301722">ዝርዝሮችን አሳይ</translation> <translation id="4894963374040315706">ይህ እርስዎ ድምጽዎን ተጠቅመው እንዲፈልጉ ያስችልዎታል</translation> <translation id="489903206070130262">የእርስዎ መጨረሻ የተከፈተ ትር</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">እንደተነበበ ምልክት አድርግ</translation> <translation id="4908869848243824489">ምርምር በGoogle</translation> <translation id="4913626501929406101">የይለፍ ቃልዎ ቅጂ ደህንነቱ በተጠበቀ ሁኔታ በቤተሰብ ቡድንዎ ውስጥ ካለ ሰው ጋር ማጋራት ይችላሉ። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ሌንስ</translation> <translation id="4918086044614829423">ይቀበሉ</translation> <translation id="4922154083994158612">ተጨማሪ ደህንነት?</translation> <translation id="4930714375720679147">አብራ</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">ለመተርጎም ሐሳብ አቅርብ</translation> <translation id="5556459405103347317">ዳግም ጫን</translation> <translation id="555749644339804659">የይለፍ ቃላትን በመፈተሽ ላይ…</translation> +<translation id="5559567453458728487">በድር ላይ የተገኙ የልወጣ መለኪያ አሃዶችን ይቀይሩ</translation> <translation id="556042886152191864">አዘራር</translation> <translation id="5572684875078967866">የመረጃ ማከማቻ</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{ይህን ጥቅል ተከታተል}one{ሁሉንም ጥቅል ተከታተል}other{ሁሉንም ጥቅል ተከታተል}}</translation> <translation id="5597915316964418992">የትር ፍርግርግን ይክፈቱ</translation> <translation id="560322036295180549">በድርጅትዎ ጠፍቷል</translation> <translation id="5614553682702429503">የይለፍ ቃል ይቀመጥ?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">ስምረት ይብራ?</translation> <translation id="6781405765516175232">ለአቅጣጫ አማራጮች «አቅጣጫዎችን ያግኙ» የሚለው ላይ መታ ያድርጉ።</translation> <translation id="6785453220513215166">የብልሽት ሪፖርት በመላክ ላይ...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{ይህን ጥቅል መከታተል አቁም}one{ሁሉም ጥቅሎች መከታተል አቁም}other{ሁሉም ጥቅሎች መከታተል አቁም}}</translation> <translation id="6790502149545262384">በቅርቡ አዲስ ትር ሲከፍቱ ከ<ph name="CHANNEL_NAME" /> የመጡ ታሪኮችን ይመለከታሉ።</translation> <translation id="6797885426782475225">የድምፅ ፍለጋ</translation> <translation id="6800349425672670802">የእርስዎን ሁሉንም ክፍት ትሮች ከትር መቀያየሪያው መድረስ ይችላሉ።</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_strings_ar.xtb index 8636f76..e1ce131 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ar.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ar.xtb
@@ -743,7 +743,6 @@ <translation id="4904877109095351937">وضع علامة كمقروءة</translation> <translation id="4908869848243824489">اقتراحات من Google</translation> <translation id="4913626501929406101">يمكنك مشاركة نسخة من كلمة المرور بأمان مع أي فرد في مجموعة عائلتك. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">العدسة</translation> <translation id="4918086044614829423">قبول</translation> <translation id="4922154083994158612">هل تريد الحصول على مزيد من الحماية؟</translation> <translation id="4930714375720679147">تفعيل</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_as.xtb b/ios/chrome/app/strings/resources/ios_strings_as.xtb index ca0e989a..62c743d3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_as.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_as.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">পঢ়া হিচাপে চিহ্নিত কৰক</translation> <translation id="4908869848243824489">Googleৰ Discover</translation> <translation id="4913626501929406101">আপুনি আপোনাৰ পাছৱৰ্ডৰ এটা প্ৰতিলিপি আপোনাৰ পৰিয়ালৰ গোটৰ যিকোনো ব্যক্তিৰ সৈতে সুৰক্ষিতভাৱে শ্বেয়াৰ কৰিব পাৰে। <ph name="BEGIN_LINK" />অধিক জানক<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">লেন্স</translation> <translation id="4918086044614829423">গ্ৰহণ কৰক</translation> <translation id="4922154083994158612">অধিক সুৰক্ষা লাগে নেকি?</translation> <translation id="4930714375720679147">অন কৰক</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_az.xtb b/ios/chrome/app/strings/resources/ios_strings_az.xtb index b2d084f..6a831062 100644 --- a/ios/chrome/app/strings/resources/ios_strings_az.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_az.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Oxunmuş Kimi Qeyd Edin</translation> <translation id="4908869848243824489">Google Təkliflər</translation> <translation id="4913626501929406101">Parol kopyasını ailə qrupunun üzvü ilə təhlükəsiz paylaşa bilərsiniz. <ph name="BEGIN_LINK" />Ətraflı məlumat<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Obyektiv</translation> <translation id="4918086044614829423">Qəbul edin</translation> <translation id="4922154083994158612">Daha Çox Güvənlik İstəyirsiniz?</translation> <translation id="4930714375720679147">Aktiv Edin</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_be.xtb b/ios/chrome/app/strings/resources/ios_strings_be.xtb index 2149decf..93c79b0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_be.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_be.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Пазначыць як прачытанае</translation> <translation id="4908869848243824489">Рэкамендацыі ад Google</translation> <translation id="4913626501929406101">Вы можаце бяспечна абагуліць копію свайго пароля з іншым удзельнікам сямейнай групы. <ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Аб'ектыў</translation> <translation id="4918086044614829423">Прыняць</translation> <translation id="4922154083994158612">Патрабуецца дадатковая бяспека?</translation> <translation id="4930714375720679147">Уключыць</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_bg.xtb b/ios/chrome/app/strings/resources/ios_strings_bg.xtb index 61dd8f1e..02f3b3b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bg.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bg.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Означаване като прочетено</translation> <translation id="4908869848243824489">Discover от Google</translation> <translation id="4913626501929406101">Можете по сигурен начин да споделите копие на паролата си с някого в семейната си група. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Лупа</translation> <translation id="4918086044614829423">Приемам</translation> <translation id="4922154083994158612">Искате по-високо ниво на сигурност?</translation> <translation id="4930714375720679147">Включване</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_bn.xtb b/ios/chrome/app/strings/resources/ios_strings_bn.xtb index e109c30..4686065 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bn.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">পঠিত হিসেবে চিহ্নিত করুন</translation> <translation id="4908869848243824489">Google-এর ডিসকভার</translation> <translation id="4913626501929406101">নিজের ফ্যামিলি গ্রুপে কারও সাথে সুরক্ষিতভাবে আপনি পাসওয়ার্ডের কপি শেয়ার করতে পারবেন। <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">লেন্স</translation> <translation id="4918086044614829423">স্বীকার</translation> <translation id="4922154083994158612">আরও নিরাপত্তা?</translation> <translation id="4930714375720679147">চালু করুন</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_strings_bs.xtb index 218dc78..c4e096f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bs.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Označi kao pročitano</translation> <translation id="4908869848243824489">Googleov Discover</translation> <translation id="4913626501929406101">Možete sigurno podijeliti kopiju lozinke s nekim iz porodične grupe. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objektiv</translation> <translation id="4918086044614829423">Prihvati</translation> <translation id="4922154083994158612">Više sigurnosti?</translation> <translation id="4930714375720679147">Uključi</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ca.xtb b/ios/chrome/app/strings/resources/ios_strings_ca.xtb index f294151..292c932 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ca.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ca.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Marca com a llegit</translation> <translation id="4908869848243824489">Discover de Google</translation> <translation id="4913626501929406101">Pots compartir de manera segura una còpia de la teva contrasenya amb algú del teu grup familiar. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objectiu</translation> <translation id="4918086044614829423">Accepta</translation> <translation id="4922154083994158612">Més seguretat?</translation> <translation id="4930714375720679147">Activa</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_cs.xtb b/ios/chrome/app/strings/resources/ios_strings_cs.xtb index 4899e0d2..b02240ac 100644 --- a/ios/chrome/app/strings/resources/ios_strings_cs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_cs.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Označit jako přečtené</translation> <translation id="4908869848243824489">Kanál Objevit od Googlu</translation> <translation id="4913626501929406101">Kopii svého hesla můžete bezpečně sdílet s někým ve vaší rodinné skupině. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Přijmout</translation> <translation id="4922154083994158612">Chcete lepší zabezpečení?</translation> <translation id="4930714375720679147">Zapnout</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_cy.xtb b/ios/chrome/app/strings/resources/ios_strings_cy.xtb index 96eb39c..680ca73 100644 --- a/ios/chrome/app/strings/resources/ios_strings_cy.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_cy.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Bar Dewislen Trefnu Clyfar</translation> <translation id="4860895144060829044">Galw</translation> <translation id="4881695831933465202">Agor</translation> +<translation id="4883824756452868502">Canfod Unedau</translation> <translation id="488785315393301722">Dangos Manylion</translation> <translation id="4894963374040315706">Mae hyn yn eich galluogi i chwilio gan ddefnyddio'ch llais</translation> <translation id="489903206070130262">Eich Tab Agored Diwethaf</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Marcio fel wedi'i Ddarllen</translation> <translation id="4908869848243824489">Darganfod gan Google</translation> <translation id="4913626501929406101">Gallwch rannu copi o'ch cyfrinair yn ddiogel gyda rhywun yn eich grŵp teulu. <ph name="BEGIN_LINK" />Dysgu rhagor<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Derbyn</translation> <translation id="4922154083994158612">Rhagor o Ddiogelwch?</translation> <translation id="4930714375720679147">Troi Ymlaen</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Cynnig Cyfieithu</translation> <translation id="5556459405103347317">Ail-lwytho</translation> <translation id="555749644339804659">Wrthi'n gwirio cyfrineiriau…</translation> +<translation id="5559567453458728487">Trosi unedau mesur a ddarganfyddir ar y we</translation> <translation id="556042886152191864">Botwm</translation> <translation id="5572684875078967866">Storfa Gwybodaeth</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Olrhain y Pecyn Hwn}zero{Olrhain Pob Pecyn}two{Olrhain Pob Pecyn}few{Olrhain Pob Pecyn}many{Olrhain Pob Pecyn}other{Olrhain Pob Pecyn}}</translation> <translation id="5597915316964418992">Agorwch y Grid Tabiau</translation> <translation id="560322036295180549">Wedi'i ddiffodd gan eich sefydliad</translation> <translation id="5614553682702429503">Cadw'r cyfrinair?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Troi Cysoni Ymlaen?</translation> <translation id="6781405765516175232">Ar gyfer opsiynau llwybr, tapiwch "Cael Cyfarwyddiadau."</translation> <translation id="6785453220513215166">Anfon adroddiad am y toriad...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Dadolrhain y Pecyn Hwn}zero{Dadolrhain Pob Pecyn}two{Dadolrhain Pob Pecyn}few{Dadolrhain Pob Pecyn}many{Dadolrhain Pob Pecyn}other{Dadolrhain Pob Pecyn}}</translation> <translation id="6790502149545262384">Yn fuan, byddwch yn gweld straeon o <ph name="CHANNEL_NAME" /> pan fyddwch yn agor tab newydd.</translation> <translation id="6797885426782475225">Chwilio â Llais</translation> <translation id="6800349425672670802">Gallwch gael mynediad at eich holl dabiau agored o'r Newidiwr Tabiau.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_da.xtb b/ios/chrome/app/strings/resources/ios_strings_da.xtb index 3e8cebe..5aeb82d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_da.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_da.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Menulinje for smartsortering</translation> <translation id="4860895144060829044">Ring op</translation> <translation id="4881695831933465202">Åbn</translation> +<translation id="4883824756452868502">Registrer enheder</translation> <translation id="488785315393301722">Se info</translation> <translation id="4894963374040315706">Det giver dig mulighed for at søge ved hjælp af stemmen</translation> <translation id="489903206070130262">Din seneste åbne fane</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Markér som læst</translation> <translation id="4908869848243824489">Discover fra Google</translation> <translation id="4913626501929406101">Du kan på sikker vis dele en kopi af din adgangskode med en anden i din familiegruppe. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objektiv</translation> <translation id="4918086044614829423">Accepter</translation> <translation id="4922154083994158612">Større sikkerhed?</translation> <translation id="4930714375720679147">Aktivér</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Tilbyd at oversætte</translation> <translation id="5556459405103347317">Genindlæs</translation> <translation id="555749644339804659">Tjekker adgangskoder…</translation> +<translation id="5559567453458728487">Konverter måleenheder, du finder på nettet</translation> <translation id="556042886152191864">Knap</translation> <translation id="5572684875078967866">Datamængde</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Spor denne pakke}one{Spor denne pakke}other{Spor alle pakker}}</translation> <translation id="5597915316964418992">Åbn fanegitteret</translation> <translation id="560322036295180549">Deaktiveret af din organisation</translation> <translation id="5614553682702429503">Vil du gemme adgangskoden?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Vil du aktivere synkronisering?</translation> <translation id="6781405765516175232">Tryk på "Få rutevejledning" for at få vist rutemuligheder.</translation> <translation id="6785453220513215166">Der sendes en nedbrudsrapport...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Fjern sporing af denne pakke}one{Fjern sporing af denne pakke}other{Fjern sporing af alle pakker}}</translation> <translation id="6790502149545262384">Du får snart vist historier fra <ph name="CHANNEL_NAME" />, når du åbner en ny fane.</translation> <translation id="6797885426782475225">Talesøgning</translation> <translation id="6800349425672670802">Du kan få adgang til alle dine åbne faner via Faneskift.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_de.xtb b/ios/chrome/app/strings/resources/ios_strings_de.xtb index 70f6879c..7611bce 100644 --- a/ios/chrome/app/strings/resources/ios_strings_de.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_de.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Als gelesen markieren</translation> <translation id="4908869848243824489">Discover von Google</translation> <translation id="4913626501929406101">Du kannst eine Kopie deines Passworts sicher mit Personen in deiner Familiengruppe teilen. <ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupe</translation> <translation id="4918086044614829423">Annehmen</translation> <translation id="4922154083994158612">Mehr Sicherheit?</translation> <translation id="4930714375720679147">Aktivieren</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_el.xtb b/ios/chrome/app/strings/resources/ios_strings_el.xtb index dd7e3fd..10beb61 100644 --- a/ios/chrome/app/strings/resources/ios_strings_el.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_el.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Επισήμ. ως αναγνωσμένων</translation> <translation id="4908869848243824489">Discover από την Google</translation> <translation id="4913626501929406101">Μπορείτε να κοινοποιήσετε με ασφάλεια ένα αντίγραφο του κωδικού πρόσβασής σας σε κάποιο άτομο στην ομάδα οικογένειάς σας. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Φακός</translation> <translation id="4918086044614829423">Αποδοχή</translation> <translation id="4922154083994158612">Περισσότερη ασφάλεια;</translation> <translation id="4930714375720679147">Ενεργοποίηση</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb index 87b7f215..4c02b5424 100644 --- a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Mark Read</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">You can securely share a copy of your password with someone in your family group. <ph name="BEGIN_LINK" />Learn more<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Accept</translation> <translation id="4922154083994158612">More security?</translation> <translation id="4930714375720679147">Turn On</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_es-419.xtb b/ios/chrome/app/strings/resources/ios_strings_es-419.xtb index ea35fd1..447fab5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_es-419.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_es-419.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Marcar como leídas</translation> <translation id="4908869848243824489">Descubre de Google</translation> <translation id="4913626501929406101">Puedes compartir de forma segura una copia de tu contraseña con un miembro de tu grupo familiar. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Aceptar</translation> <translation id="4922154083994158612">¿Quieres obtener más seguridad?</translation> <translation id="4930714375720679147">Activar</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_es.xtb b/ios/chrome/app/strings/resources/ios_strings_es.xtb index 6374126..820556f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_es.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_es.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Marcar como leídas</translation> <translation id="4908869848243824489">Discover de Google</translation> <translation id="4913626501929406101">Puedes compartir de forma segura una copia de tu contraseña con un miembro de tu grupo familiar. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lente</translation> <translation id="4918086044614829423">Aceptar</translation> <translation id="4922154083994158612">¿Más seguridad?</translation> <translation id="4930714375720679147">Activar</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_et.xtb b/ios/chrome/app/strings/resources/ios_strings_et.xtb index fcbd78a..f423ec2 100644 --- a/ios/chrome/app/strings/resources/ios_strings_et.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_et.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Nutika sortimise menüüriba</translation> <translation id="4860895144060829044">Helistage</translation> <translation id="4881695831933465202">Ava</translation> +<translation id="4883824756452868502">Ühikute tuvastamine</translation> <translation id="488785315393301722">Üksikasjade kuvamine</translation> <translation id="4894963374040315706">See võimaldab hääle abil otsida</translation> <translation id="489903206070130262">Teie viimane avatud vaheleht</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Märgi loetuks</translation> <translation id="4908869848243824489">Discover Google'ilt</translation> <translation id="4913626501929406101">Saate mõne oma peregrupi liikmega turvaliselt oma parooli koopiat jagada. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objektiiv</translation> <translation id="4918086044614829423">Nõustu</translation> <translation id="4922154083994158612">Kas soovite paremat turvalisust?</translation> <translation id="4930714375720679147">Lülita sisse</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Paku tõlkimist</translation> <translation id="5556459405103347317">Laadi uuesti</translation> <translation id="555749644339804659">Paroolide kontrollimine …</translation> +<translation id="5559567453458728487">Veebist leitavate mõõtühikute teisendamine</translation> <translation id="556042886152191864">Nupp</translation> <translation id="5572684875078967866">Infoühikud</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Jälgi seda saadetist}other{Jälgi kõiki saadetisi}}</translation> <translation id="5597915316964418992">Vahelehtede ruudustiku avamine</translation> <translation id="560322036295180549">Teie organisatsioon on välja lülitanud</translation> <translation id="5614553682702429503">Kas salvestada parool?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Kas lülitada sünkroonimine sisse?</translation> <translation id="6781405765516175232">Marsruudivalikute nägemiseks puudutage valikut „Hankige juhiseid“.</translation> <translation id="6785453220513215166">Krahhiaruande saatmine ...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Peata selle saadetise jälgimine}other{Peata kõigi saadetiste jälgimine}}</translation> <translation id="6790502149545262384">Varsti näete uue vahelehe avamisel lugusid saidilt <ph name="CHANNEL_NAME" />.</translation> <translation id="6797885426782475225">Häälotsing</translation> <translation id="6800349425672670802">Kõikide avatud vahelehtede juurde pääsete funktsiooniga Vahelehtede vaheti.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_eu.xtb b/ios/chrome/app/strings/resources/ios_strings_eu.xtb index 4f413ef..5d1a01c 100644 --- a/ios/chrome/app/strings/resources/ios_strings_eu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_eu.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Markatu irakurritako gisa</translation> <translation id="4908869848243824489">Google-ren Discover</translation> <translation id="4913626501929406101">Pasahitzaren kopia bat era seguruan parteka dezakezu zure familia-taldeko beste norbaitekin. <ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Leiarra</translation> <translation id="4918086044614829423">Onartu</translation> <translation id="4922154083994158612">Segurtasuna areagotu nahi duzu?</translation> <translation id="4930714375720679147">Aktibatu</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fa.xtb b/ios/chrome/app/strings/resources/ios_strings_fa.xtb index febc7d0..f83987a 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fa.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">علامتگذاری بهعنوان خواندهشده</translation> <translation id="4908869848243824489">«یافتهها» از Google</translation> <translation id="4913626501929406101">میتوانید نسخهای از گذرواژهتان را بهطور ایمن با فردی در گروه خانوادهتان همرسانی کنید. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">لنز</translation> <translation id="4918086044614829423">میپذیرم</translation> <translation id="4922154083994158612">امنیت بیشتری میخواهید؟</translation> <translation id="4930714375720679147">روشن کردن</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fi.xtb b/ios/chrome/app/strings/resources/ios_strings_fi.xtb index 1c4c17e..c93db75 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fi.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Älykkään lajittelun valikkopalkki</translation> <translation id="4860895144060829044">Soita</translation> <translation id="4881695831933465202">Avaa</translation> +<translation id="4883824756452868502">Tunnista yksiköt</translation> <translation id="488785315393301722">Näytä tiedot</translation> <translation id="4894963374040315706">Tämän avulla voit tehdä hakuja puhumalla</translation> <translation id="489903206070130262">Viimeisin avoin välilehti</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Merkitse luetuksi</translation> <translation id="4908869848243824489">Google Discover</translation> <translation id="4913626501929406101">Voit jakaa kopion salasanastasi perheryhmäsi jäsenille. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Linssi</translation> <translation id="4918086044614829423">Hyväksy</translation> <translation id="4922154083994158612">Parempi tietoturva?</translation> <translation id="4930714375720679147">Ota käyttöön</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Tarjoudu kääntämään</translation> <translation id="5556459405103347317">Lataa uudelleen</translation> <translation id="555749644339804659">Tarkistetaan salasanoja…</translation> +<translation id="5559567453458728487">Muunna verkosta löytyneet mittayksiköt</translation> <translation id="556042886152191864">Painike</translation> <translation id="5572684875078967866">Tietojen tallennus</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Seuraa tätä pakettia}other{Seuraa kaikkia paketteja}}</translation> <translation id="5597915316964418992">Avaa välilehtiruudukko</translation> <translation id="560322036295180549">Organisaatiosi on laittanut tämän pois päältä</translation> <translation id="5614553682702429503">Tallennetaanko salasana?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Laitetaanko synkronointi päälle?</translation> <translation id="6781405765516175232">Näet reittivaihtoehdot valitsemalla "Hae reittiohjeet".</translation> <translation id="6785453220513215166">Lähetetään virheraporttia…</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Lopeta tämän paketin seuraaminen}other{Lopeta kaikkien pakettien seuraaminen}}</translation> <translation id="6790502149545262384">Näet pian tarinoita täältä avatessasi uuden välilehden: <ph name="CHANNEL_NAME" />.</translation> <translation id="6797885426782475225">Puhehaku</translation> <translation id="6800349425672670802">Voit käyttää kaikkia avoimia välilehtiä Välilehtien vaihtajasta.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fil.xtb b/ios/chrome/app/strings/resources/ios_strings_fil.xtb index 436d7b5..7c7e103 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fil.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fil.xtb
@@ -410,6 +410,7 @@ <translation id="3080525922482950719">Puwede kang mag-save ng mga page para basahin sa ibang pagkakataon o nang offline</translation> <translation id="3081338492074632642">Tiyaking tumutugma ang password na sine-save mo sa iyong password para sa <ph name="WEBSITE" /></translation> <translation id="3087734570205094154">Sa ilalim</translation> +<translation id="3090455602619185166">Mag-sign In sa Pinapamahalaang Account</translation> <translation id="309710370695886264">Mayroon kang 1 password na ginamit ulit. Ayusin ito ngayon para manatiling ligtas.</translation> <translation id="3112556859945124369">Markahan…</translation> <translation id="3122484138405575719"><ph name="BEGIN_LINK" />Tingnan Kung Ano ang Puwede Mong I-sync<ph name="END_LINK" /></translation> @@ -574,6 +575,7 @@ <translation id="4002066346123236978">Pamagat</translation> <translation id="4004204301268239848">Sine-save ang mga password sa iyong Google Account para magamit mo ang mga ito sa anumang device.</translation> <translation id="4018310736049373830">Pamahalaan ang Aktibidad</translation> +<translation id="4021931095789478915">Idagdag ang ${url} sa listahan ng babasahin</translation> <translation id="4038354071007134711">Walang application sa device ang makakabukas nito.</translation> <translation id="4042870976416480368">Hanapin sa Page</translation> <translation id="40433179647657191">Gumawa at magbahagi ng direktang link sa isang bahagi ng page na na-highlight mo.</translation> @@ -741,7 +743,6 @@ <translation id="4904877109095351937">Markahan Bilang Nabasa Na</translation> <translation id="4908869848243824489">Discover ng Google</translation> <translation id="4913626501929406101">Puwede kang secure na mag-share ng kopya ng iyong password sa isang tao sa grupo ng pamilya mo. <ph name="BEGIN_LINK" />Matuto pa<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Tanggapin</translation> <translation id="4922154083994158612">Higit pang Seguridad?</translation> <translation id="4930714375720679147">I-on</translation> @@ -1448,6 +1449,7 @@ <translation id="8556590991644167667">{count,plural, =1{Nag-dismiss ka ng {count} babala}one{Nag-dismiss ka ng {count} babala}other{Nag-dismiss ka ng {count} na babala}}</translation> <translation id="8558480467877843976">Magagamit mo na ngayon ang Chrome sa tuwing magbo-browse o magta-tap ka ng mga link sa mga mensahe, dokumento, at iba pang app.</translation> <translation id="8560253818350321773">Unang ipakita ang mga item na madalas gamitin.</translation> +<translation id="8569721750632860947">Anong URL ang gusto mong idagdag sa iyong listahan ng babasahin?</translation> <translation id="8588404856427128947">Naka-off</translation> <translation id="8591976964826315682">I-block ang Third-Party na Cookies sa Incognito</translation> <translation id="8593565399399144771">Puwede kang magbukas ng bagong tab dito.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb b/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb index 94d07e1..cd0d2034 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Marquer comme lu</translation> <translation id="4908869848243824489">Découvertes par Google</translation> <translation id="4913626501929406101">Vous pouvez partager en toute sécurité une copie de votre mot de passe avec un membre de votre groupe familial. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objectif</translation> <translation id="4918086044614829423">Accepter</translation> <translation id="4922154083994158612">Plus de sécurité?</translation> <translation id="4930714375720679147">Activer</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fr.xtb b/ios/chrome/app/strings/resources/ios_strings_fr.xtb index cd9e6ea2..64e522c3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fr.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Marquer comme lues</translation> <translation id="4908869848243824489">Discover de Google</translation> <translation id="4913626501929406101">Vous pouvez partager de façon sécurisée une copie de votre mot de passe avec un membre de votre groupe familial. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Loupe</translation> <translation id="4918086044614829423">Accepter</translation> <translation id="4922154083994158612">Renforcer la sécurité ?</translation> <translation id="4930714375720679147">Activer</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_gl.xtb b/ios/chrome/app/strings/resources/ios_strings_gl.xtb index 81ea4dde..9d08c5d5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_gl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_gl.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Barra de menú con orde intelixente</translation> <translation id="4860895144060829044">Chamar</translation> <translation id="4881695831933465202">Abrir</translation> +<translation id="4883824756452868502">Detectar unidades</translation> <translation id="488785315393301722">Mostrar detalles</translation> <translation id="4894963374040315706">Permíteche buscar de forma máis rápida usando a voz</translation> <translation id="489903206070130262">A túa última pestana aberta</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Marcar como lidos</translation> <translation id="4908869848243824489">Discover, de Google</translation> <translation id="4913626501929406101">Podes compartir de maneira segura unha copia do teu contrasinal con calquera persoa do teu grupo familiar. <ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Obxectivo</translation> <translation id="4918086044614829423">Aceptar</translation> <translation id="4922154083994158612">Queres aumentar a seguranza?</translation> <translation id="4930714375720679147">Activar</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Ofrecer a tradución</translation> <translation id="5556459405103347317">Volver cargar</translation> <translation id="555749644339804659">Comprobando contrasinais…</translation> +<translation id="5559567453458728487">Converte as unidades de medida que se atopen na Web</translation> <translation id="556042886152191864">Botón</translation> <translation id="5572684875078967866">Almacenamento de información</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Facer seguimento deste paquete}other{Facer seguimento de todos os paquetes}}</translation> <translation id="5597915316964418992">Abre a grade de pestanas</translation> <translation id="560322036295180549">Opción desactivada pola túa organización</translation> <translation id="5614553682702429503">Queres gardar o contrasinal?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Queres activar a sincronización?</translation> <translation id="6781405765516175232">Para consultar as opcións de ruta, toca Obter indicacións.</translation> <translation id="6785453220513215166">Enviando informe de erros...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Deixar de facer seguimento deste paquete}other{Deixar de facer seguimento de todos os paquetes}}</translation> <translation id="6790502149545262384">Dentro de pouco verás as historias de <ph name="CHANNEL_NAME" /> cando abras unha pestana nova.</translation> <translation id="6797885426782475225">Busca por voz</translation> <translation id="6800349425672670802">Podes acceder todas as pestanas abertas desde o selector de pestanas.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_gu.xtb b/ios/chrome/app/strings/resources/ios_strings_gu.xtb index bdf798e..d848dfa 100644 --- a/ios/chrome/app/strings/resources/ios_strings_gu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_gu.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">વાંચેલ તરીકે ચિહ્નિત કરો</translation> <translation id="4908869848243824489">Googleનું Discover</translation> <translation id="4913626501929406101">તમે તમારા ફૅમિલી ગ્રૂપમાં કોઈ વ્યક્તિ સાથે તમારા પાસવર્ડની કૉપિ સુરક્ષિત રીતે શેર કરી શકો છો. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">લેન્સ</translation> <translation id="4918086044614829423">સ્વીકારો</translation> <translation id="4922154083994158612">વધુ સુરક્ષાની જરૂર છે?</translation> <translation id="4930714375720679147">ચાલુ કરો</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hi.xtb b/ios/chrome/app/strings/resources/ios_strings_hi.xtb index 3ef2c2a..16b24a4 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hi.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">पढ़ी गईं चिह्नित करें</translation> <translation id="4908869848243824489">Google का 'डिस्कवर'</translation> <translation id="4913626501929406101">अपने फ़ैमिली ग्रुप के किसी सदस्य के साथ, पासवर्ड की कॉपी सुरक्षित तरीके से शेयर की जा सकती है. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">लैंस</translation> <translation id="4918086044614829423">स्वीकार करें</translation> <translation id="4922154083994158612">क्या आपको बेहतर सुरक्षा चाहिए?</translation> <translation id="4930714375720679147">चालू करें</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_strings_hr.xtb index 58cc7e8..3978eb3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hr.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Označi kao pročitano</translation> <translation id="4908869848243824489">Googleov Discover</translation> <translation id="4913626501929406101">Kopiju svoje zaporke možete na siguran način dijeliti s nekim u obiteljskoj grupi. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Leća</translation> <translation id="4918086044614829423">Prihvati</translation> <translation id="4922154083994158612">Dodatna zaštita?</translation> <translation id="4930714375720679147">Uključi</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hu.xtb b/ios/chrome/app/strings/resources/ios_strings_hu.xtb index 1b3400c..a1d8531 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hu.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Intelligens rendezés menüsora</translation> <translation id="4860895144060829044">Hívás</translation> <translation id="4881695831933465202">Megnyitás</translation> +<translation id="4883824756452868502">Mértékegységek észlelése</translation> <translation id="488785315393301722">Részletek megjelenítése</translation> <translation id="4894963374040315706">Lehetővé teszi a hangalapú keresés használatát</translation> <translation id="489903206070130262">A legutóbb megnyitott lap</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Megjelölés olvasottként</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">Biztonságosan megoszthatja jelszavának másolatát a családi csoportja tagjaival. <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation> -<translation id="4916679969857390442">Lencse</translation> <translation id="4918086044614829423">Elfogadás</translation> <translation id="4922154083994158612">Nagyobb biztonságot szeretne?</translation> <translation id="4930714375720679147">Bekapcsolás</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Fordítás felajánlása</translation> <translation id="5556459405103347317">Újratöltés</translation> <translation id="555749644339804659">Jelszavak ellenőrzése…</translation> +<translation id="5559567453458728487">Az interneten talált mértékegységek konvertálása</translation> <translation id="556042886152191864">Gomb</translation> <translation id="5572684875078967866">Adattárolás</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Csomag nyomon követése}other{Az összes csomag nyomon követése}}</translation> <translation id="5597915316964418992">Nyissa meg a laprácsot</translation> <translation id="560322036295180549">Kikapcsolta a szervezete</translation> <translation id="5614553682702429503">Szeretné elmenteni a jelszót?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Bekapcsolja a szinkronizálást?</translation> <translation id="6781405765516175232">A lehetséges útvonalak megtekintéséhez koppintson az „Útvonaltervezés” lehetőségre.</translation> <translation id="6785453220513215166">Hibajelentés küldése…</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Csomag nyomon követésének megszüntetése}other{Az összes csomag nyomon követésének megszüntetése}}</translation> <translation id="6790502149545262384">Új lap megnyitásakor hamarosan látni fogja a(z) <ph name="CHANNEL_NAME" /> webhely történeteit.</translation> <translation id="6797885426782475225">Hangalapú keresés</translation> <translation id="6800349425672670802">A Lapváltóból az összes megnyitott laphoz hozzáférhet.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hy.xtb b/ios/chrome/app/strings/resources/ios_strings_hy.xtb index 27e8618..e83958c 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hy.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hy.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Խելացի դասավորման ընտրացանկի գոտի</translation> <translation id="4860895144060829044">Զանգեք</translation> <translation id="4881695831933465202">Բացել</translation> +<translation id="4883824756452868502">Հայտնաբերել չափման միավորներ</translation> <translation id="488785315393301722">Ցույց տալ մանրամասները</translation> <translation id="4894963374040315706">Սա անհրաժեշտ է ձայնային որոնումն օգտագործելու համար</translation> <translation id="489903206070130262">Ձեր վերջին բաց ներդիրը</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Նշել որպես կարդացված</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">Դուք կարող եք կիսվել ձեր գաղտնաբառի պատճենով ընտանեկան խմբի անդամի հետ։ Դա անվտանգ է։ <ph name="BEGIN_LINK" />Իմանալ ավելին<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Ոսպնապակի</translation> <translation id="4918086044614829423">Ընդունել</translation> <translation id="4922154083994158612">Ուզո՞ւմ եք ուժեղացնել հաշվի պաշտպանությունը</translation> <translation id="4930714375720679147">Միացնել</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Առաջարկել թարգմանություն</translation> <translation id="5556459405103347317">Վերաբեռնել</translation> <translation id="555749644339804659">Գաղտնաբառերի ստուգում…</translation> +<translation id="5559567453458728487">Փոխարկել չափման միավորները վեբ էջերում</translation> <translation id="556042886152191864">Կոճակ</translation> <translation id="5572684875078967866">Տեղեկությունների ծավալ</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Հետևել այս առաքանուն}one{Հետևել առաքանուն}other{Հետևել բոլոր առաքանիներին}}</translation> <translation id="5597915316964418992">Բացեք ներդիրների ցանցը</translation> <translation id="560322036295180549">Անջատվել է կազմակերպության կողմից</translation> <translation id="5614553682702429503">Պահե՞լ գաղտնաբառը</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Միացնե՞լ համաժամացումը</translation> <translation id="6781405765516175232">Հնարավոր երթուղիները տեսնելու համար հպեք «Ստանալ երթուղիներ»։</translation> <translation id="6785453220513215166">Խափանման հաշվետվության ուղարկում…</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Դադարեցնել այս առաքանու հետագծումը}one{Դադարեցնել առաքանու հետագծումը}other{Դադարեցնել բոլոր առաքանիների հետագծումը}}</translation> <translation id="6790502149545262384">Շուտով, երբ նոր ներդիր բացեք, կտեսնեք նորություններ <ph name="CHANNEL_NAME" /> կայքից։</translation> <translation id="6797885426782475225">Ձայնային որոնում</translation> <translation id="6800349425672670802">Բոլոր բացված ներդիրները կարող եք օգտագործել ներդիրների փոխանջատիչից։</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_id.xtb b/ios/chrome/app/strings/resources/ios_strings_id.xtb index 5a581240..201a91d9 100644 --- a/ios/chrome/app/strings/resources/ios_strings_id.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_id.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Panel Menu Urutkan Pintar</translation> <translation id="4860895144060829044">Telepon</translation> <translation id="4881695831933465202">Buka</translation> +<translation id="4883824756452868502">Deteksi Unit</translation> <translation id="488785315393301722">Tampilkan Detail</translation> <translation id="4894963374040315706">Hal ini memungkinkan Anda menelusuri menggunakan suara</translation> <translation id="489903206070130262">Tab Terakhir yang Dibuka</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Tandai Sudah Dibaca</translation> <translation id="4908869848243824489">Discover oleh Google</translation> <translation id="4913626501929406101">Anda dapat membagikan salinan sandi Anda dengan aman kepada seseorang dalam grup keluarga Anda. <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lensa</translation> <translation id="4918086044614829423">Terima</translation> <translation id="4922154083994158612">Keamanan yang Lebih Baik?</translation> <translation id="4930714375720679147">Aktifkan</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Tawarkan Penerjemahan</translation> <translation id="5556459405103347317">Muat ulang</translation> <translation id="555749644339804659">Memeriksa sandi…</translation> +<translation id="5559567453458728487">Mengonversi unit pengukuran yang ditemukan di web</translation> <translation id="556042886152191864">Tombol</translation> <translation id="5572684875078967866">Penyimpanan Informasi</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Lacak Paket Ini}other{Lacak Semua Paket}}</translation> <translation id="5597915316964418992">Buka Petak Tab</translation> <translation id="560322036295180549">Dinonaktifkan oleh organisasi Anda</translation> <translation id="5614553682702429503">Simpan sandi?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Aktifkan Sinkronisasi?</translation> <translation id="6781405765516175232">Untuk opsi rute, ketuk “Dapatkan Rute”.</translation> <translation id="6785453220513215166">Mengirim laporan kerusakan...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Batalkan Pelacakan Paket Ini}other{Batalkan Pelacakan Semua Paket}}</translation> <translation id="6790502149545262384">Sebentar lagi, Anda akan melihat artikel dari <ph name="CHANNEL_NAME" /> saat membuka tab baru.</translation> <translation id="6797885426782475225">Penelusuran Suara</translation> <translation id="6800349425672670802">Anda dapat mengakses semua tab yang terbuka dari Pengalih Tab.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_is.xtb b/ios/chrome/app/strings/resources/ios_strings_is.xtb index 3b4ec41..41bc8645 100644 --- a/ios/chrome/app/strings/resources/ios_strings_is.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_is.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Merkja sem lesið</translation> <translation id="4908869848243824489">Tillögur frá Google</translation> <translation id="4913626501929406101">Þú getur núna örugglega deilt afriti að aðgangsorðinu þínu með einhverjum í fjölskylduhópnum. <ph name="BEGIN_LINK" />Nánar<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Linsa</translation> <translation id="4918086044614829423">Samþykkja</translation> <translation id="4922154083994158612">Meira öryggi?</translation> <translation id="4930714375720679147">Kveikja</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_it.xtb b/ios/chrome/app/strings/resources/ios_strings_it.xtb index 97c589f..78c68e4 100644 --- a/ios/chrome/app/strings/resources/ios_strings_it.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_it.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Barra dei menu con ordine intelligente</translation> <translation id="4860895144060829044">Chiama</translation> <translation id="4881695831933465202">Apri</translation> +<translation id="4883824756452868502">Rileva unità</translation> <translation id="488785315393301722">Mostra dettagli</translation> <translation id="4894963374040315706">In questo modo puoi eseguire ricerche con i comandi vocali</translation> <translation id="489903206070130262">Ultima scheda aperta</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Segna come già letti</translation> <translation id="4908869848243824489">Discover di Google</translation> <translation id="4913626501929406101">Puoi condividere in sicurezza una copia della tua password con un membro del tuo gruppo Famiglia. <ph name="BEGIN_LINK" />Scopri di più<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lente</translation> <translation id="4918086044614829423">Accetto</translation> <translation id="4922154083994158612">Vuoi maggiore sicurezza?</translation> <translation id="4930714375720679147">Attiva</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Proponi di tradurre</translation> <translation id="5556459405103347317">Ricarica</translation> <translation id="555749644339804659">Controllo delle password…</translation> +<translation id="5559567453458728487">Converti le unità di misura trovate sul web</translation> <translation id="556042886152191864">Pulsante</translation> <translation id="5572684875078967866">Archiviazione delle informazioni</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Monitora questo pacchetto}other{Monitora tutti i pacchetti}}</translation> <translation id="5597915316964418992">Apri la griglia delle schede</translation> <translation id="560322036295180549">Opzione disattivata dall'organizzazione</translation> <translation id="5614553682702429503">Salvare la password?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Vuoi attivare la sincronizzazione?</translation> <translation id="6781405765516175232">Per conoscere le opzioni per il percorso, tocca "Indicazioni stradali".</translation> <translation id="6785453220513215166">Invio report sugli arresti anomali...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Annulla monitoraggio del pacchetto}other{Annulla monitoraggio di tutti i pacchetti}}</translation> <translation id="6790502149545262384">A breve vedrai storie di <ph name="CHANNEL_NAME" /> quando aprirai una nuova scheda.</translation> <translation id="6797885426782475225">Ricerca vocale</translation> <translation id="6800349425672670802">Puoi accedere a tutte le schede aperte dal Selettore di schede.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_strings_iw.xtb index 823a9cc..b768225e 100644 --- a/ios/chrome/app/strings/resources/ios_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_iw.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">סימון כ'נקרא'</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">אפשר לשתף באופן מאובטח עותק של הסיסמה עם מישהו בקבוצה המשפחתית שלך. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">עדשה</translation> <translation id="4918086044614829423">אישור</translation> <translation id="4922154083994158612">רוצה לשפר את רמת האבטחה?</translation> <translation id="4930714375720679147">הפעלה</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ja.xtb b/ios/chrome/app/strings/resources/ios_strings_ja.xtb index 5398849..2e583a7 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ja.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ja.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">既読にする</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">パスワードのコピーをファミリー グループのユーザーと安全に共有できます。<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">レンズ</translation> <translation id="4918086044614829423">同意する</translation> <translation id="4922154083994158612">セキュリティを強化しますか?</translation> <translation id="4930714375720679147">ON にする</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ka.xtb b/ios/chrome/app/strings/resources/ios_strings_ka.xtb index 9ce1d49c..850647d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ka.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ka.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">წაკითხულად მონიშვნა</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">შეგიძლიათ უსაფრთხოდ გააზიაროთ თქვენი პაროლის ასლი თქვენი ოჯახის ჯგუფის წევრთან. <ph name="BEGIN_LINK" />შეიტყვეთ მეტი<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ლინზა</translation> <translation id="4918086044614829423">მიღება</translation> <translation id="4922154083994158612">გსურთ მეტი უსაფრთხოება?</translation> <translation id="4930714375720679147">ჩართვა</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_kk.xtb b/ios/chrome/app/strings/resources/ios_strings_kk.xtb index f05468a..7ac63b0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_kk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_kk.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Оқылған етіп белгілеу</translation> <translation id="4908869848243824489">Google ұсынатын Discover</translation> <translation id="4913626501929406101">Құпия сөзіңіздің көшірмесін отбасылық топтағы адамдармен қауіпсіз түрде бөлісе аласыз. <ph name="BEGIN_LINK" />Толық ақпарат<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Үлкейткіш әйнек</translation> <translation id="4918086044614829423">Қабылдау</translation> <translation id="4922154083994158612">Қауіпсіздікті күшейткіңіз келе ме?</translation> <translation id="4930714375720679147">Қосу</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_km.xtb b/ios/chrome/app/strings/resources/ios_strings_km.xtb index 8b6113684..de5646f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_km.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_km.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">សម្គាល់ថាបានអាន</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">អ្នកអាចចែករំលែកច្បាប់ចម្លងពាក្យសម្ងាត់របស់អ្នកដោយសុវត្ថិភាពជាមួយនរណាម្នាក់នៅក្នុងក្រុមគ្រួសាររបស់អ្នក។ <ph name="BEGIN_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">លែន</translation> <translation id="4918086044614829423">ទទួល</translation> <translation id="4922154083994158612">សុវត្ថិភាពច្រើនទៀត?</translation> <translation id="4930714375720679147">បើក</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_kn.xtb b/ios/chrome/app/strings/resources/ios_strings_kn.xtb index 16bb4c6..8066fa2a 100644 --- a/ios/chrome/app/strings/resources/ios_strings_kn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_kn.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">ಓದಿದೆ ಎಂದು ಗುರುತಿಸಿ</translation> <translation id="4908869848243824489">Google ನಿಂದ Discover</translation> <translation id="4913626501929406101">ನಿಮ್ಮ ಕುಟುಂಬ ಗುಂಪಿನಲ್ಲಿರುವ ಯಾರೊಂದಿಗಾದರೂ ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ನ ಕಾಪಿಯನ್ನು ನೀವು ಸುರಕ್ಷಿತವಾಗಿ ಹಂಚಿಕೊಳ್ಳಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ಲೆನ್ಸ್</translation> <translation id="4918086044614829423">ಸಮ್ಮತಿಸು</translation> <translation id="4922154083994158612">ಹೆಚ್ಚಿನ ಭದ್ರತೆಯನ್ನು ಪಡೆಯಲು ಬಯಸುತ್ತೀರಾ?</translation> <translation id="4930714375720679147">ಆನ್ ಮಾಡಿ</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ko.xtb b/ios/chrome/app/strings/resources/ios_strings_ko.xtb index 2c58594..d122b76 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ko.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ko.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">스마트 정렬 메뉴 바</translation> <translation id="4860895144060829044">전화걸기</translation> <translation id="4881695831933465202">열기</translation> +<translation id="4883824756452868502">단위 감지</translation> <translation id="488785315393301722">세부정보 표시</translation> <translation id="4894963374040315706">액세스를 허용하면 음성으로 검색할 수 있습니다.</translation> <translation id="489903206070130262">마지막으로 연 탭</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">읽음으로 표시</translation> <translation id="4908869848243824489">Google 디스커버</translation> <translation id="4913626501929406101">가족 그룹의 다른 사용자와 비밀번호 사본을 안전하게 공유할 수 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">렌즈</translation> <translation id="4918086044614829423">수락</translation> <translation id="4922154083994158612">보안을 강화하시겠습니까?</translation> <translation id="4930714375720679147">사용 설정</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">번역 옵션 제공</translation> <translation id="5556459405103347317">새로고침</translation> <translation id="555749644339804659">비밀번호 확인 중…</translation> +<translation id="5559567453458728487">웹에서 찾은 측정 단위 변환</translation> <translation id="556042886152191864">버튼</translation> <translation id="5572684875078967866">정보 저장소</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{이 택배 추적}other{모든 배송 추적}}</translation> <translation id="5597915316964418992">탭 그리드 열기</translation> <translation id="560322036295180549">조직에서 사용 중지했습니다.</translation> <translation id="5614553682702429503">비밀번호를 저장하시겠습니까?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">동기화를 사용하시겠습니까?</translation> <translation id="6781405765516175232">경로 옵션을 보려면 '길찾기'를 탭합니다.</translation> <translation id="6785453220513215166">비정상 종료 보고서 보내는 중...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{이 택배 추적 취소}other{모든 택배 추적 취소}}</translation> <translation id="6790502149545262384">곧 새 탭을 열 때 <ph name="CHANNEL_NAME" /> 스토리가 표시됩니다</translation> <translation id="6797885426782475225">음성검색</translation> <translation id="6800349425672670802">탭 전환 도구에서 열려 있는 모든 탭에 액세스할 수 있습니다.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ky.xtb b/ios/chrome/app/strings/resources/ios_strings_ky.xtb index aa141e1e..e8d528b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ky.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ky.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Окулган деп белгилөө</translation> <translation id="4908869848243824489">Google сунуштары</translation> <translation id="4913626501929406101">Сырсөзүңүздүн көчүрмөсүн үй-бүлөлүк тобуңуздагы киши менен коопсуз түрдө бөлүшө аласыз. <ph name="BEGIN_LINK" />Кеңири маалымат<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Линза</translation> <translation id="4918086044614829423">Кабыл алуу</translation> <translation id="4922154083994158612">Кошумча коопсуздук керекпи?</translation> <translation id="4930714375720679147">Күйгүзүү</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_lo.xtb b/ios/chrome/app/strings/resources/ios_strings_lo.xtb index 56689005..a9be098 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lo.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lo.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">ໝາຍວ່າອ່ານແລ້ວ</translation> <translation id="4908869848243824489">Discover ໂດຍ Google</translation> <translation id="4913626501929406101">ທ່ານສາມາດແບ່ງປັນສຳເນົາລະຫັດຜ່ານຂອງທ່ານກັບຄົນໃນກຸ່ມຄອບຄົວຂອງທ່ານໄດ້ຢ່າງປອດໄພ. <ph name="BEGIN_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ເລນສ໌</translation> <translation id="4918086044614829423">ຍອມຮັບ</translation> <translation id="4922154083994158612">ຕ້ອງການຄວາມປອດໄພເພີ່ມເຕີມບໍ?</translation> <translation id="4930714375720679147">ເປີດ</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_lt.xtb b/ios/chrome/app/strings/resources/ios_strings_lt.xtb index 5ab28e9b..704f984 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lt.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lt.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Pažymėti kaip skaitytus</translation> <translation id="4908869848243824489">„Google“ funkcija „Discover“</translation> <translation id="4913626501929406101">Galite saugiai bendrinti slaptažodžio kopiją su kitu šeimos grupės nariu. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objektyvas</translation> <translation id="4918086044614829423">Priimti</translation> <translation id="4922154083994158612">Daugiau saugumo?</translation> <translation id="4930714375720679147">Įjungti</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_lv.xtb b/ios/chrome/app/strings/resources/ios_strings_lv.xtb index 5d91fe4..534a976 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lv.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lv.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Atzīmēt kā izlasītus</translation> <translation id="4908869848243824489">Google funkcija Discover</translation> <translation id="4913626501929406101">Varat droši kopīgot paroles kopiju ar kādu ģimenes grupas dalībnieku. <ph name="BEGIN_LINK" />Uzziniet vairāk<ph name="END_LINK" />.</translation> -<translation id="4916679969857390442">Lēca</translation> <translation id="4918086044614829423">Pieņemt</translation> <translation id="4922154083994158612">Vai uzlabot drošību?</translation> <translation id="4930714375720679147">Ieslēgt</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_mk.xtb b/ios/chrome/app/strings/resources/ios_strings_mk.xtb index 1c40bd30..bf90cbc 100644 --- a/ios/chrome/app/strings/resources/ios_strings_mk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_mk.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Означи како прочитано</translation> <translation id="4908869848243824489">Discover од Google</translation> <translation id="4913626501929406101">Може безбедно да споделите копија од вашата лозинка со некого во вашата семејна група. <ph name="BEGIN_LINK" />Дознајте повеќе<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Објектив</translation> <translation id="4918086044614829423">Прифати</translation> <translation id="4922154083994158612">Поголема безбедност?</translation> <translation id="4930714375720679147">Вклучи</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ml.xtb b/ios/chrome/app/strings/resources/ios_strings_ml.xtb index 5e670fd..e9b30b0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ml.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ml.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">വായിച്ചതായി അടയാളപ്പെടുത്തുക</translation> <translation id="4908869848243824489">Google-ന്റെ Discover</translation> <translation id="4913626501929406101">നിങ്ങളുടെ കുടുംബ ഗ്രൂപ്പിലെ ആരെങ്കിലുമായി പാസ്വേഡിന്റെ ഒരു പകർപ്പ് സുരക്ഷിതമായി പങ്കിടാം. <ph name="BEGIN_LINK" />കൂടുതലറിയുക<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ലെന്സ്</translation> <translation id="4918086044614829423">സ്വീകരിക്കുക</translation> <translation id="4922154083994158612">കൂടുതൽ സുരക്ഷ വേണോ?</translation> <translation id="4930714375720679147">ഓണാക്കുക</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_mn.xtb b/ios/chrome/app/strings/resources/ios_strings_mn.xtb index 2fe1733c..47411145 100644 --- a/ios/chrome/app/strings/resources/ios_strings_mn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_mn.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Уншсан гэж тэмдэглэх</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">Та нууц үгнийхээ хуулбарыг гэр бүлийн бүлэгтээ байгаа хэн нэгэнтэй аюулгүй хуваалцах боломжтой. <ph name="BEGIN_LINK" />Нэмэлт мэдээлэл авах<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Хүлээн зөвшөөрөх</translation> <translation id="4922154083994158612">Илүү аюулгүй байдал?</translation> <translation id="4930714375720679147">Асаах</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_mr.xtb b/ios/chrome/app/strings/resources/ios_strings_mr.xtb index fd369037..b46932cd 100644 --- a/ios/chrome/app/strings/resources/ios_strings_mr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_mr.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">वाचले चिन्हांकित करा</translation> <translation id="4908869848243824489">Google चे Discover</translation> <translation id="4913626501929406101">तुम्ही तुमच्या पासवर्डची प्रत तुमच्या कुटुंब गटातील एखाद्या व्यक्तीशी सुरक्षितपणे शेअर करू शकता. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">लेन्स</translation> <translation id="4918086044614829423">स्वीकारा</translation> <translation id="4922154083994158612">आणखी सुरक्षा हवी आहे का?</translation> <translation id="4930714375720679147">सुरू करा</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_strings_ms.xtb index 59a0b90..7930670 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ms.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ms.xtb
@@ -410,6 +410,7 @@ <translation id="3080525922482950719">Anda boleh menyimpan halaman untuk dibaca kemudian atau secara luar talian</translation> <translation id="3081338492074632642">Pastikan kata laluan yang anda simpan sepadan dengan kata laluan anda untuk <ph name="WEBSITE" /></translation> <translation id="3087734570205094154">Bawah</translation> +<translation id="3090455602619185166">Log Masuk dengan Akaun Terurus</translation> <translation id="309710370695886264">Anda mempunyai 1 kata laluan yang digunakan semula. Betulkan sekarang untuk kekal selamat.</translation> <translation id="3112556859945124369">Tandakan...</translation> <translation id="3122484138405575719"><ph name="BEGIN_LINK" />Lihat Item Yang Boleh Anda Segerakkan<ph name="END_LINK" />.</translation> @@ -574,6 +575,7 @@ <translation id="4002066346123236978">Tajuk</translation> <translation id="4004204301268239848">Kata laluan disimpan dalam Google Account anda supaya anda dapat menggunakannya pada mana-mana peranti.</translation> <translation id="4018310736049373830">Urus Aktiviti</translation> +<translation id="4021931095789478915">Tambahkan ${url} pada senarai bacaan</translation> <translation id="4038354071007134711">Tiada aplikasi pada peranti ini yang dapat membuka fail itu.</translation> <translation id="4042870976416480368">Cari dalam Halaman</translation> <translation id="40433179647657191">Buat dan kongsi pautan terus ke bahagian halaman yang telah anda serlahkan.</translation> @@ -741,7 +743,6 @@ <translation id="4904877109095351937">Tandakan Dibaca</translation> <translation id="4908869848243824489">Discover oleh Google</translation> <translation id="4913626501929406101">Anda boleh berkongsi salinan kata laluan anda dengan selamat dengan seseorang dalam kumpulan keluarga anda. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lensa</translation> <translation id="4918086044614829423">Terima</translation> <translation id="4922154083994158612">Lagi Keselamatan?</translation> <translation id="4930714375720679147">Hidupkan</translation> @@ -1448,6 +1449,7 @@ <translation id="8556590991644167667">{count,plural, =1{Anda mengetepikan {count} amaran}other{Anda mengetepikan {count} amaran}}</translation> <translation id="8558480467877843976">Kini anda boleh menggunakan Chrome pada bila-bila masa anda menyemak imbas atau mengetik pautan dalam mesej, dokumen dan apl lain.</translation> <translation id="8560253818350321773">Menunjukkan item yang sering digunakan dahulu.</translation> +<translation id="8569721750632860947">Apakah URL yang mahu ditambahkan pada senarai bacaan anda?</translation> <translation id="8588404856427128947">Mati</translation> <translation id="8591976964826315682">Sekat Kuki Pihak Ketiga dalam Inkognito</translation> <translation id="8593565399399144771">Anda boleh membuka tab baharu di sini.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_my.xtb b/ios/chrome/app/strings/resources/ios_strings_my.xtb index c44bac9e..8512076d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_my.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_my.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">ဖတ်ပြီးကြောင်း အမှတ်အသားလုပ်ရန်</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">သင့်မိသားစုအဖွဲ့အတွင်းရှိ တစ်စုံတစ်ဦးနှင့် သင့်စကားဝှက်မိတ္တူကို လုံခြုံစွာ မျှဝေနိုင်သည်။ <ph name="BEGIN_LINK" />ပိုမိုလေ့လာရန်<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">မှန်ဘီလူး</translation> <translation id="4918086044614829423">လက်ခံရန်</translation> <translation id="4922154083994158612">နောက်ထပ်လုံခြုံရေး ရယူမလား။</translation> <translation id="4930714375720679147">ဖွင့်ရန်</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ne.xtb b/ios/chrome/app/strings/resources/ios_strings_ne.xtb index 78887ae..094d54d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ne.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ne.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">पढिसकिएको भनी चिन्ह लगाउनुहोस्</translation> <translation id="4908869848243824489">Google को Discover</translation> <translation id="4913626501929406101">तपाईं आफ्नो पारिवारिक समूहका कुनै पनि सदस्यसँग आफ्नो पासवर्डको कपी सुरक्षित तरिकाले सेयर गर्न सक्नुहुन्छ। <ph name="BEGIN_LINK" />थप जान्नुहोस्<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">लेन्सहरू</translation> <translation id="4918086044614829423">स्वीकार्नुहोस्</translation> <translation id="4922154083994158612">थप सुरक्षा चाहनुहुन्छ?</translation> <translation id="4930714375720679147">अन गर्नुहोस्</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_nl.xtb b/ios/chrome/app/strings/resources/ios_strings_nl.xtb index e439e32..fcb3e8e 100644 --- a/ios/chrome/app/strings/resources/ios_strings_nl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_nl.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Markeren als gelezen</translation> <translation id="4908869848243824489">Discover van Google</translation> <translation id="4913626501929406101">Je kunt een kopie van je wachtwoord beveiligd delen met iemand in je gezinsgroep. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Accepteren</translation> <translation id="4922154083994158612">Sterkere beveiliging?</translation> <translation id="4930714375720679147">Aanzetten</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_no.xtb b/ios/chrome/app/strings/resources/ios_strings_no.xtb index 09a4c31..8cebc634 100644 --- a/ios/chrome/app/strings/resources/ios_strings_no.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_no.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Merk som lest</translation> <translation id="4908869848243824489">Discover fra Google</translation> <translation id="4913626501929406101">Du kan dele en kopi av passordet ditt med andre i familiegruppen din på en sikker måte. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Forstørrelsesglass</translation> <translation id="4918086044614829423">Godta</translation> <translation id="4922154083994158612">Vil du ha mer sikkerhet?</translation> <translation id="4930714375720679147">Slå på</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_or.xtb b/ios/chrome/app/strings/resources/ios_strings_or.xtb index 1483db62..f0823b3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_or.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_or.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">"ପଢ଼ାଯାଇଛି" ଭାବରେ ଚିହ୍ନିତ କରନ୍ତୁ</translation> <translation id="4908869848243824489">Googleର Discover</translation> <translation id="4913626501929406101">ଆପଣ ଆପଣଙ୍କ ପରିବାର ଗୋଷ୍ଠୀରେ ଥିବା କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ସହିତ ଆପଣଙ୍କ ପାସୱାର୍ଡର ଏକ କପିକୁ ସୁରକ୍ଷିତ ଭାବେ ସେୟାର କରିପାରିବେ। <ph name="BEGIN_LINK" />ଅଧିକ ଜାଣନ୍ତୁ<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ଲେନ୍ସ</translation> <translation id="4918086044614829423">ସ୍ୱୀକାର କରନ୍ତୁ</translation> <translation id="4922154083994158612">ଅଧିକ ସୁରକ୍ଷା ଆବଶ୍ୟକ?</translation> <translation id="4930714375720679147">ଚାଲୁ କରନ୍ତୁ</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_pa.xtb b/ios/chrome/app/strings/resources/ios_strings_pa.xtb index 2344ace7..6867a8b0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pa.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pa.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">ਪੜ੍ਹੇ ਇੰਦਰਾਜ਼ਾਂ ਨੂੰ ਨਿਸ਼ਾਨਦੇਹ ਕਰੋ</translation> <translation id="4908869848243824489">Google ਵੱਲੋਂ Discover</translation> <translation id="4913626501929406101">ਤੁਸੀਂ ਆਪਣੇ ਪਰਿਵਾਰ ਗਰੁੱਪ ਵਿੱਚ ਕਿਸੇ ਨਾਲ ਆਪਣੇ ਪਾਸਵਰਡ ਦੀ ਇੱਕ ਕਾਪੀ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਾਂਝਾ ਕਰ ਸਕਦੇ ਹੋ। <ph name="BEGIN_LINK" />ਹੋਰ ਜਾਣੋ<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">ਲੈਂਸ</translation> <translation id="4918086044614829423">ਸਵੀਕਾਰ ਕਰੋ</translation> <translation id="4922154083994158612">ਕੀ ਹੋਰ ਸੁਰੱਖਿਆ ਦੀ ਲੋੜ ਹੈ?</translation> <translation id="4930714375720679147">ਚਾਲੂ ਕਰੋ</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_pl.xtb b/ios/chrome/app/strings/resources/ios_strings_pl.xtb index d3708fc..1e8775ed 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pl.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Oznacz jako przeczytane</translation> <translation id="4908869848243824489">Discover od Google</translation> <translation id="4913626501929406101">Możesz bezpiecznie udostępnić kopię hasła innej osobie w grupie rodzinnej. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Akceptuj</translation> <translation id="4922154083994158612">Więcej ustawień bezpieczeństwa?</translation> <translation id="4930714375720679147">Włącz</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb b/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb index 8466b400..7e4c49a1 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Marcar como lidas</translation> <translation id="4908869848243824489">Discover do Google</translation> <translation id="4913626501929406101">Você pode compartilhar uma cópia da sua senha de forma segura com alguém do grupo familiar. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Aceitar</translation> <translation id="4922154083994158612">Mais segurança?</translation> <translation id="4930714375720679147">Ativar</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb b/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb index f6eb666..b430c2e2 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Marcar como lidas</translation> <translation id="4908869848243824489">Discover da Google</translation> <translation id="4913626501929406101">Pode partilhar de forma segura uma cópia da sua palavra-passe com alguém no seu grupo familiar. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lente</translation> <translation id="4918086044614829423">Aceitar</translation> <translation id="4922154083994158612">Mais segurança?</translation> <translation id="4930714375720679147">Ativar</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ro.xtb b/ios/chrome/app/strings/resources/ios_strings_ro.xtb index da77f15..1909b9f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ro.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ro.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Bara de meniu pentru sortare inteligentă</translation> <translation id="4860895144060829044">Apelează</translation> <translation id="4881695831933465202">Deschide</translation> +<translation id="4883824756452868502">Detectează unități</translation> <translation id="488785315393301722">Afișați detaliile</translation> <translation id="4894963374040315706">Astfel, cauți mai rapid folosind vocea</translation> <translation id="489903206070130262">Ultima filă deschisă</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Marchează ca citite</translation> <translation id="4908869848243824489">Discover de la Google</translation> <translation id="4913626501929406101">Poți trimite în siguranță o copie a parolei unui membru al grupului de familie. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupă</translation> <translation id="4918086044614829423">Acceptă</translation> <translation id="4922154083994158612">Mai multă securitate?</translation> <translation id="4930714375720679147">Activează</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Oferă traducerea</translation> <translation id="5556459405103347317">Reîncarcă</translation> <translation id="555749644339804659">Se verifică parolele…</translation> +<translation id="5559567453458728487">Convertește unitățile de măsură găsite pe web</translation> <translation id="556042886152191864">Buton</translation> <translation id="5572684875078967866">Stocarea informațiilor</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Urmărește coletul}few{Urmăriți toate pachetele}other{Urmăriți toate pachetele}}</translation> <translation id="5597915316964418992">Deschide grila cu file</translation> <translation id="560322036295180549">Dezactivată de organizație</translation> <translation id="5614553682702429503">Salvezi parola?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Activezi sincronizarea?</translation> <translation id="6781405765516175232">Pentru opțiunile de traseu, atinge Obține indicații de orientare.</translation> <translation id="6785453220513215166">Se trimite raportul de blocare...</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Anulează urmărirea coletului}few{Anulează urmărirea tuturor coletelor}other{Anulează urmărirea tuturor coletelor}}</translation> <translation id="6790502149545262384">În curând, vei vedea articole de la <ph name="CHANNEL_NAME" /> când deschizi o filă nouă.</translation> <translation id="6797885426782475225">Căutare vocală</translation> <translation id="6800349425672670802">Poți accesa toate filele deschise din Comutatorul de file.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ru.xtb b/ios/chrome/app/strings/resources/ios_strings_ru.xtb index 84e4c37..e582db38 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ru.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ru.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">Умная сортировка для строки меню</translation> <translation id="4860895144060829044">Позвонить</translation> <translation id="4881695831933465202">Открыть</translation> +<translation id="4883824756452868502">Определять единицы измерения</translation> <translation id="488785315393301722">Показать сведения</translation> <translation id="4894963374040315706">Это нужно, чтобы использовать голосовой поиск.</translation> <translation id="489903206070130262">Последняя открытая вкладка</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">Отметить как прочитанное</translation> <translation id="4908869848243824489">Рекомендации от Google</translation> <translation id="4913626501929406101">Вы можете поделиться копией пароля с участником семейной группы. Это безопасно. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Лупа</translation> <translation id="4918086044614829423">Принять</translation> <translation id="4922154083994158612">Хотите усилить защиту аккаунта?</translation> <translation id="4930714375720679147">Включить</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">Предлагать перевести</translation> <translation id="5556459405103347317">Перезагрузить</translation> <translation id="555749644339804659">Проверка паролей…</translation> +<translation id="5559567453458728487">Конвертировать единицы измерения в Сети.</translation> <translation id="556042886152191864">Кнопка</translation> <translation id="5572684875078967866">Объем данных</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{Отслеживать эту посылку}one{Отслеживать все посылки}few{Отслеживать все посылки}many{Отслеживать все посылки}other{Отслеживать все посылки}}</translation> <translation id="5597915316964418992">Откройте сетку таблицы.</translation> <translation id="560322036295180549">Функция отключена вашей организацией</translation> <translation id="5614553682702429503">Сохранить пароль?</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">Включить синхронизацию?</translation> <translation id="6781405765516175232">Чтобы узнать, как добраться до места, нажмите "Проложить маршрут".</translation> <translation id="6785453220513215166">Отправка отчета об ошибке…</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{Перестать отслеживать посылку}one{Перестать отслеживать все посылки}few{Перестать отслеживать все посылки}many{Перестать отслеживать все посылки}other{Перестать отслеживать все посылки}}</translation> <translation id="6790502149545262384">Скоро, открывая новую вкладку, вы будете видеть статьи с сайта "<ph name="CHANNEL_NAME" />".</translation> <translation id="6797885426782475225">Голосовой поиск</translation> <translation id="6800349425672670802">Все открытые вкладки можно найти в переключателе вкладок.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_si.xtb b/ios/chrome/app/strings/resources/ios_strings_si.xtb index cd136b8..506b636 100644 --- a/ios/chrome/app/strings/resources/ios_strings_si.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_si.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">කියවූ ලෙස ලකුණු කරන්න</translation> <translation id="4908869848243824489">Google වෙතින් Discover</translation> <translation id="4913626501929406101">ඔබට ඔබේ මුරපදයෙහි පිටපතක් ඔබේ පවුලේ සමූහයේ සිටින කෙනෙකු සමග සුරක්ෂිතව බෙදා ගත හැක. <ph name="BEGIN_LINK" />තව දැන ගන්න<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">කාච</translation> <translation id="4918086044614829423">පිළිගන්න</translation> <translation id="4922154083994158612">තව ආරක්ෂාවක්?</translation> <translation id="4930714375720679147">ක්රියාත්මක කරන්න</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sk.xtb b/ios/chrome/app/strings/resources/ios_strings_sk.xtb index 00685ee..8e031f3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sk.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Označiť ako prečítané</translation> <translation id="4908869848243824489">Kanál Objaviť od Googlu</translation> <translation id="4913626501929406101">Kópiu svojho hesla môžete bezpečne zdieľať s členom svojej rodinnej skupiny. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Prijať</translation> <translation id="4922154083994158612">Chcete zvýšiť zabezpečenie?</translation> <translation id="4930714375720679147">Zapnúť</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sl.xtb b/ios/chrome/app/strings/resources/ios_strings_sl.xtb index 450bff4..c52a483 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sl.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Označi kot prebrano</translation> <translation id="4908869848243824489">Googlovo Odkrivanje</translation> <translation id="4913626501929406101">Kopijo gesla lahko varno delite z osebo v skupini družinskih članov. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Sprejmi</translation> <translation id="4922154083994158612">Več varnosti?</translation> <translation id="4930714375720679147">Vklop</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sq.xtb b/ios/chrome/app/strings/resources/ios_strings_sq.xtb index 0ee15b1..ed89f3d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sq.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sq.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Shëno si të lexuara</translation> <translation id="4908869848243824489">"Zbulo" nga Google</translation> <translation id="4913626501929406101">Mund të ndash në mënyrë të sigurt një kopje të fjalëkalimit tënd me dikë në grupin tënd të familjes. <ph name="BEGIN_LINK" />Mëso më shumë<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lente</translation> <translation id="4918086044614829423">Prano</translation> <translation id="4922154083994158612">Më shumë siguri?</translation> <translation id="4930714375720679147">Aktivizo</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb index 1eea952..52dba20 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Označi kao pročitano</translation> <translation id="4908869848243824489">Google Discover</translation> <translation id="4913626501929406101">Možete bezbedno da delite kopiju lozinke sa nekim u grupi za porodicu. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Objektiv</translation> <translation id="4918086044614829423">Prihvati</translation> <translation id="4922154083994158612">Više bezbednosti?</translation> <translation id="4930714375720679147">Uključi</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sr.xtb b/ios/chrome/app/strings/resources/ios_strings_sr.xtb index e881558..57d871fa 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sr.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Означи као прочитано</translation> <translation id="4908869848243824489">Google Discover</translation> <translation id="4913626501929406101">Можете безбедно да делите копију лозинке са неким у групи за породицу. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Објектив</translation> <translation id="4918086044614829423">Прихвати</translation> <translation id="4922154083994158612">Више безбедности?</translation> <translation id="4930714375720679147">Укључи</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sv.xtb b/ios/chrome/app/strings/resources/ios_strings_sv.xtb index 3567129..0f4deefb 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sv.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sv.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Markera som läst</translation> <translation id="4908869848243824489">Förslag från Google</translation> <translation id="4913626501929406101">Du kan tryggt och säkert dela en kopia av ditt lösenord med någon i familjegruppen. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lins</translation> <translation id="4918086044614829423">Acceptera</translation> <translation id="4922154083994158612">Vill du ha bättre säkerhet?</translation> <translation id="4930714375720679147">Aktivera</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sw.xtb b/ios/chrome/app/strings/resources/ios_strings_sw.xtb index d2a9897..2677df6 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sw.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Tia Alama Kuwa Umesoma</translation> <translation id="4908869848243824489">Dokezo kutoka Google</translation> <translation id="4913626501929406101">Unaweza kushiriki nakala ya nenosiri lako kwa usalama na mtu aliye katika kikundi cha familia yako. <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lensi</translation> <translation id="4918086044614829423">Kubali</translation> <translation id="4922154083994158612">Je, Unahitaji Usalama Zaidi?</translation> <translation id="4930714375720679147">Washa</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ta.xtb b/ios/chrome/app/strings/resources/ios_strings_ta.xtb index a425882..4ff4218 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ta.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ta.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">படித்ததாகக் குறி</translation> <translation id="4908869848243824489">Discover by Google</translation> <translation id="4913626501929406101">குடும்பக் குழுவிலுள்ள ஒருவருக்கு உங்கள் கடவுச்சொல்லின் நகலைப் பாதுகாப்பாகப் பகிரலாம். <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">லென்ஸ்</translation> <translation id="4918086044614829423">ஏற்கிறேன்</translation> <translation id="4922154083994158612">கூடுதல் பாதுகாப்பு வேண்டுமா?</translation> <translation id="4930714375720679147">இயக்கு</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_te.xtb b/ios/chrome/app/strings/resources/ios_strings_te.xtb index 9ab55fce5..f5d3b34 100644 --- a/ios/chrome/app/strings/resources/ios_strings_te.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_te.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">చదివినట్లు గుర్తు పెట్టు</translation> <translation id="4908869848243824489">Google ద్వారా Discover</translation> <translation id="4913626501929406101">మీ పాస్వర్డ్ కాపీని మీ ఫ్యామిలీ గ్రూప్లోని ఎవరితోనైనా మీరు సురక్షితంగా షేర్ చేయవచ్చు. <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">లెన్స్</translation> <translation id="4918086044614829423">ఆమోదించు</translation> <translation id="4922154083994158612">మరింత సెక్యూరిటీ కావాలా?</translation> <translation id="4930714375720679147">ఆన్ చేయి</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_th.xtb b/ios/chrome/app/strings/resources/ios_strings_th.xtb index 27f2503a..418f513 100644 --- a/ios/chrome/app/strings/resources/ios_strings_th.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_th.xtb
@@ -410,6 +410,7 @@ <translation id="3080525922482950719">คุณบันทึกหน้าเว็บไว้อ่านภายหลังหรืออ่านขณะออฟไลน์ได้</translation> <translation id="3081338492074632642">ตรวจสอบว่ารหัสผ่านที่คุณจะบันทึกตรงกับรหัสผ่านสำหรับ <ph name="WEBSITE" /></translation> <translation id="3087734570205094154">ด้านล่าง</translation> +<translation id="3090455602619185166">ลงชื่อเข้าใช้ด้วยบัญชีที่จัดการ</translation> <translation id="309710370695886264">คุณมีรหัสผ่านที่ใช้ซ้ำ 1 รายการ แก้ไขเลยเพื่อความปลอดภัย</translation> <translation id="3112556859945124369">ทำเครื่องหมาย…</translation> <translation id="3122484138405575719"><ph name="BEGIN_LINK" />ดูสิ่งที่คุณซิงค์ได้<ph name="END_LINK" /></translation> @@ -574,6 +575,7 @@ <translation id="4002066346123236978">ชื่อ</translation> <translation id="4004204301268239848">ระบบจะบันทึกรหัสผ่านไว้ในบัญชี Google เพื่อให้คุณใช้ในอุปกรณ์เครื่องใดก็ได้</translation> <translation id="4018310736049373830">จัดการกิจกรรม</translation> +<translation id="4021931095789478915">เพิ่ม ${url} ลงในเรื่องรออ่าน</translation> <translation id="4038354071007134711">ไม่มีแอปพลิเคชันใดบนอุปกรณ์นี้ที่สามารถเปิดไฟล์ได้</translation> <translation id="4042870976416480368">ค้นหาในหน้าเว็บ</translation> <translation id="40433179647657191">สร้างและแชร์ลิงก์โดยตรงของหน้าที่คุณไฮไลต์</translation> @@ -741,7 +743,6 @@ <translation id="4904877109095351937">ทำเครื่องหมายว่าอ่านแล้ว</translation> <translation id="4908869848243824489">ฟีเจอร์สำรวจโดย Google</translation> <translation id="4913626501929406101">คุณแชร์สำเนารหัสผ่านกับคนในกลุ่มครอบครัวได้อย่างปลอดภัย <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">เลนส์</translation> <translation id="4918086044614829423">ยอมรับ</translation> <translation id="4922154083994158612">หากต้องการความปลอดภัยมากขึ้น</translation> <translation id="4930714375720679147">เปิด</translation> @@ -1448,6 +1449,7 @@ <translation id="8556590991644167667">{count,plural, =1{คุณได้ปิดคำเตือน {count} รายการ}other{คุณได้ปิดคําเตือน {count} รายการ}}</translation> <translation id="8558480467877843976">ตอนนี้คุณจะใช้ Chrome ทุกครั้งที่เรียกดูหรือแตะลิงก์ในข้อความ เอกสาร และแอปอื่นๆ ได้</translation> <translation id="8560253818350321773">แสดงรายการที่ใช้บ่อยก่อน</translation> +<translation id="8569721750632860947">คุณต้องการเพิ่ม URL ใดลงในเรื่องรออ่าน</translation> <translation id="8588404856427128947">ปิด</translation> <translation id="8591976964826315682">บล็อกคุกกี้ของบุคคลที่สามในโหมดไม่ระบุตัวตน</translation> <translation id="8593565399399144771">คุณเปิดแท็บใหม่ได้ที่นี่</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_tr.xtb b/ios/chrome/app/strings/resources/ios_strings_tr.xtb index 31e950cc..483db3c5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_tr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_tr.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Okundu Olarak İşaretle</translation> <translation id="4908869848243824489">Google'dan Keşfet</translation> <translation id="4913626501929406101">Şifrenizin kopyasını, aile grubunuzdaki kişilerle güvenli bir şekilde paylaşabilirsiniz. <ph name="BEGIN_LINK" />Daha fazla bilgi<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lens</translation> <translation id="4918086044614829423">Kabul et</translation> <translation id="4922154083994158612">Daha fazla güvenlik mi istiyorsunuz?</translation> <translation id="4930714375720679147">Etkinleştir</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_uk.xtb b/ios/chrome/app/strings/resources/ios_strings_uk.xtb index 115dcbb..fbf97576 100644 --- a/ios/chrome/app/strings/resources/ios_strings_uk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_uk.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Позначити як прочитані</translation> <translation id="4908869848243824489">Рекомендації від Google</translation> <translation id="4913626501929406101">Ви можете безпечно надіслати копію пароля учасникам сімейної групи. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Лупа</translation> <translation id="4918086044614829423">Прийняти</translation> <translation id="4922154083994158612">Посилити захист?</translation> <translation id="4930714375720679147">Увімкнути</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ur.xtb b/ios/chrome/app/strings/resources/ios_strings_ur.xtb index 4fe9f8f..5ab8614 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ur.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ur.xtb
@@ -733,6 +733,7 @@ <translation id="4856841893565072365">اسمارٹ ترتیب کا مینو بار</translation> <translation id="4860895144060829044">کال کریں</translation> <translation id="4881695831933465202">کھولیں</translation> +<translation id="4883824756452868502">یونٹس کی شناخت کریں</translation> <translation id="488785315393301722">تفصیلات دکھائیں</translation> <translation id="4894963374040315706">یہ آپ کو اپنی آواز کا استعمال کر کے تلاش کرنے کی اجازت دیتا ہے</translation> <translation id="489903206070130262">آپ کا آخری کھلا ہوا ٹیب</translation> @@ -740,7 +741,6 @@ <translation id="4904877109095351937">پڑھے ہوئے کے بطور نشان زد کریں</translation> <translation id="4908869848243824489">Discover منجانب Google</translation> <translation id="4913626501929406101">آپ اپنے فیملی گروپ میں کسی کے ساتھ اپنے پاس ورڈ کی کاپی کا اشتراک محفوظ طریقے سے کر سکتے ہیں۔ <ph name="BEGIN_LINK" />مزید جانیں<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">لینز</translation> <translation id="4918086044614829423">قبول کریں</translation> <translation id="4922154083994158612">مزید سیکیورٹی؟</translation> <translation id="4930714375720679147">آن کریں</translation> @@ -855,8 +855,10 @@ <translation id="5551897871312988470">ترجمہ کی پیشکش کریں</translation> <translation id="5556459405103347317">دوبارہ لوڈ کریں</translation> <translation id="555749644339804659">پاس ورڈز چیک ہو رہے ہیں…</translation> +<translation id="5559567453458728487">ویب پر تبدیلی کی پیمائش کے یونٹس ملے</translation> <translation id="556042886152191864">بٹن</translation> <translation id="5572684875078967866">معلوماتی اسٹوریج</translation> +<translation id="5591792606924434384">{COUNT,plural, =1{اس پیکیج کو ٹریک کریں}other{تمام پیکیجز کو ٹریک کریں}}</translation> <translation id="5597915316964418992">ٹیب گرڈ کھولیں</translation> <translation id="560322036295180549">آپ کی تنظیم کے ذریعے اف کر دیا گیا</translation> <translation id="5614553682702429503">پاس ورڈ کو محفوظ کریں؟</translation> @@ -1119,6 +1121,7 @@ <translation id="6781260999953472352">مطابقت پذیری آن کریں؟</translation> <translation id="6781405765516175232">راستے کے اختیارات کے لیے، "ڈائریکشنز حاصل کریں" پر تھپتھپائیں۔</translation> <translation id="6785453220513215166">کریش رپورٹ بھیج رہا ہے…</translation> +<translation id="6788698206356268539">{COUNT,plural, =1{اس پیکیج کو ٹریک کرنا بند کریں}other{تمام پیکیجز کو ٹریک کرنا بند کریں}}</translation> <translation id="6790502149545262384">جلد ہی، نیا ٹیب کھولنے پر آپ کو <ph name="CHANNEL_NAME" /> سے کہانیاں دکھائی دیں گی۔</translation> <translation id="6797885426782475225">صوتی تلاش</translation> <translation id="6800349425672670802">آپ ٹیب سوئچر سے اپنے تمام کھلے ہوئے ٹیبز تک رسائی حاصل کر سکتے ہیں۔</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_strings_uz.xtb index 28eb191..9c93ac0 100644 --- a/ios/chrome/app/strings/resources/ios_strings_uz.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">O‘qildi deb belgilash</translation> <translation id="4908869848243824489">Google Discover</translation> <translation id="4913626501929406101">Parolingiz nusxasini oilaviy guruhingizdagilarga xavfsiz ulashishingiz mumkin. <ph name="BEGIN_LINK" />Batafsil<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Lupa</translation> <translation id="4918086044614829423">Qabul qilish</translation> <translation id="4922154083994158612">Himoya kuchaytirilsinmi?</translation> <translation id="4930714375720679147">Yoqish</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_vi.xtb b/ios/chrome/app/strings/resources/ios_strings_vi.xtb index 740e521..f103486 100644 --- a/ios/chrome/app/strings/resources/ios_strings_vi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_vi.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">Đánh dấu là đã đọc</translation> <translation id="4908869848243824489">Tính năng Khám phá của Google</translation> <translation id="4913626501929406101">Bạn có thể chia sẻ bản sao mật khẩu của mình một cách an toàn với thành viên trong nhóm gia đình. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Ống kính</translation> <translation id="4918086044614829423">Chấp nhận</translation> <translation id="4922154083994158612">Bạn muốn tăng cường bảo mật?</translation> <translation id="4930714375720679147">Bật</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb b/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb index ce9fed8..8262908 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb
@@ -739,7 +739,6 @@ <translation id="4904877109095351937">标记为已读</translation> <translation id="4908869848243824489">Google 探索</translation> <translation id="4913626501929406101">您可以安全地与家人群组成员分享您的密码副本。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">镜头</translation> <translation id="4918086044614829423">接受</translation> <translation id="4922154083994158612">想提升安全性?</translation> <translation id="4930714375720679147">开启</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_zh-HK.xtb b/ios/chrome/app/strings/resources/ios_strings_zh-HK.xtb index bb7f50c..c06789e 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zh-HK.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zh-HK.xtb
@@ -741,7 +741,6 @@ <translation id="4904877109095351937">標示為已閱讀</translation> <translation id="4908869848243824489">Google 探索</translation> <translation id="4913626501929406101">你可安全地與家庭群組的成員分享密碼副本。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">透鏡</translation> <translation id="4918086044614829423">接受</translation> <translation id="4922154083994158612">想增強安全性嗎?</translation> <translation id="4930714375720679147">開啟</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb b/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb index e8f46232..36e21fd 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb
@@ -739,7 +739,6 @@ <translation id="4904877109095351937">標示為已讀取</translation> <translation id="4908869848243824489">Google 探索</translation> <translation id="4913626501929406101">你可以安全地分享密碼副本給家庭群組的成員。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">透鏡</translation> <translation id="4918086044614829423">接受</translation> <translation id="4922154083994158612">想要讓安全性更上一層樓嗎?</translation> <translation id="4930714375720679147">開啟</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_zu.xtb b/ios/chrome/app/strings/resources/ios_strings_zu.xtb index 0b1ce0a..32a0c17 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zu.xtb
@@ -740,7 +740,6 @@ <translation id="4904877109095351937">Maka njengokufundiwe</translation> <translation id="4908869848243824489">I-Discover nge-Google</translation> <translation id="4913626501929406101">Ungakwazi ukwabelana ngokuphephile nekhophi yephasiwedi yakho nomuntu othile eqenjini lomndeni wakho. <ph name="BEGIN_LINK" />Funda kabanzi<ph name="END_LINK" /></translation> -<translation id="4916679969857390442">Ilensi</translation> <translation id="4918086044614829423">Yamukela</translation> <translation id="4922154083994158612">Ukuvikeleka okwengeziwe?</translation> <translation id="4930714375720679147">Vula</translation>
diff --git a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h index 463e8522..21f0d49a 100644 --- a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h +++ b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h
@@ -12,6 +12,7 @@ #include "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/web_state_observer.h" #import "ios/web/public/web_state_user_data.h" +#import "url/origin.h" namespace autofill { class AutofillBottomSheetObserver; @@ -26,6 +27,15 @@ @class CommandDispatcher; @protocol PasswordsAccountStorageNoticeHandler; +// This class manages state and events relating to the showing of various bottom +// sheets for Autofill/Password Manager. +// +// Some bottom sheets show in response to browser-layer interactions. These can +// be instantiated directly using public Show... methods. +// +// Others show in response to JS-layer interactions. In these cases, this class +// attaches/detaches listeners in the document, and shows the appropriate bottom +// sheet when these listeners are triggered. class AutofillBottomSheetTabHelper : public web::WebFramesManager::Observer, public web::WebStateObserver, @@ -46,6 +56,13 @@ void AddObserver(autofill::AutofillBottomSheetObserver* observer); void RemoveObserver(autofill::AutofillBottomSheetObserver* observer); + // Shows the plus address bottom sheet, taken in response to choosing a + // `kCreateNewPlusAddress` autofill suggestion. Also stores `callback` for + // if/when the UI completes successfully. + void ShowPlusAddressesBottomSheet( + const url::Origin& main_frame_origin, + plus_addresses::PlusAddressCallback callback); + // Handler for JavaScript messages. Dispatch to more specific handler. void OnFormMessageReceived(const web::ScriptMessage& message); @@ -89,6 +106,9 @@ autofill::FormGlobalId form_id, FieldTypeSource source) override; + // Used to get the callback to be run on completion of the plus_address UI. + plus_addresses::PlusAddressCallback GetPendingPlusAddressFillCallback(); + private: friend class web::WebStateUserData<AutofillBottomSheetTabHelper>; @@ -155,6 +175,10 @@ base::ObserverList<autofill::AutofillBottomSheetObserver>::Unchecked observers_; + // A callback to be run on completion of the plus address bottom sheet UI + // flow. + plus_addresses::PlusAddressCallback pending_plus_address_callback_; + WEB_STATE_USER_DATA_KEY_DECL(); };
diff --git a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm index d437784..b3e655e 100644 --- a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm +++ b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm
@@ -65,6 +65,13 @@ // Public methods +void AutofillBottomSheetTabHelper::ShowPlusAddressesBottomSheet( + const url::Origin& main_frame_origin, + plus_addresses::PlusAddressCallback callback) { + pending_plus_address_callback_ = std::move(callback); + [commands_handler_ showPlusAddressesBottomSheet]; +} + void AutofillBottomSheetTabHelper::SetAutofillBottomSheetHandler( id<AutofillBottomSheetCommands> commands_handler) { commands_handler_ = commands_handler; @@ -337,6 +344,11 @@ /*must_be_empty=*/true); } +plus_addresses::PlusAddressCallback +AutofillBottomSheetTabHelper::GetPendingPlusAddressFillCallback() { + return std::move(pending_plus_address_callback_); +} + // Private methods bool AutofillBottomSheetTabHelper::HasReachedDismissLimit() {
diff --git a/ios/chrome/browser/enterprise/model/idle/BUILD.gn b/ios/chrome/browser/enterprise/model/idle/BUILD.gn index 4f94a68..f14ac327 100644 --- a/ios/chrome/browser/enterprise/model/idle/BUILD.gn +++ b/ios/chrome/browser/enterprise/model/idle/BUILD.gn
@@ -11,6 +11,8 @@ "idle_service.mm", "idle_service_factory.h", "idle_service_factory.mm", + "idle_service_observer_bridge.h", + "idle_service_observer_bridge.mm", ] deps = [ "//base",
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service.h b/ios/chrome/browser/enterprise/model/idle/idle_service.h index c9f49bf6..4829823 100644 --- a/ios/chrome/browser/enterprise/model/idle/idle_service.h +++ b/ios/chrome/browser/enterprise/model/idle/idle_service.h
@@ -23,12 +23,24 @@ public: enum class LastState { kIdleOnBackground, kIdleOnForeground }; + // Observer handling the browsing timing out without being active. + class Observer : public base::CheckedObserver { + public: + virtual void OnIdleTimeoutInForeground() = 0; + virtual void OnClearDataOnStartup() = 0; + virtual void OnIdleTimeoutActionsCompleted() = 0; + }; + explicit IdleService(ChromeBrowserState* browser_state); IdleService(const IdleService&) = delete; IdleService& operator=(const IdleService&) = delete; ~IdleService() override; + // Adds and removes observers. Called when the scene agent implementing the + // observer is created or destroyed. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); // TODO(b/301676922): Move calls to `OnApplicationWillEnterForeground` // and `OnApplicationWillEnterBackground` to an AppStateObserver. // Called when the application is foregrounded, which can be after one of @@ -57,10 +69,11 @@ // Checks whether the idle state has been reached. If idle state is reached, // it calls `RunActionsForState` to run actions. Otherwise, it posts a task to // check again when the browser might possibly become idle. - void MaybeRunActions(); + void CheckIfIdle(); // Runs the actions based on `IdleTimeoutActions` and update the UI based on // the last state the browser was idle in. void RunActionsForState(LastState last_state); + void RunActions(); // Calculates the time to when the browser might become idle. base::TimeDelta GetPossibleTimeToIdle(); @@ -71,6 +84,7 @@ std::unique_ptr<ActionRunner> action_runner_; PrefChangeRegistrar pref_change_registrar_; base::CancelableOnceCallback<void()> cancelable_actions_callback_; + base::ObserverList<Observer, true> observer_list_; base::WeakPtrFactory<IdleService> weak_factory_{this}; };
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service.mm b/ios/chrome/browser/enterprise/model/idle/idle_service.mm index ab45e5b..aae18f0 100644 --- a/ios/chrome/browser/enterprise/model/idle/idle_service.mm +++ b/ios/chrome/browser/enterprise/model/idle/idle_service.mm
@@ -35,6 +35,14 @@ action_runner_.reset(); } +void IdleService::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void IdleService::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + base::TimeDelta IdleService::GetTimeout() const { return browser_state_->GetPrefs()->GetTimeDelta( enterprise_idle::prefs::kIdleTimeout); @@ -91,7 +99,7 @@ void IdleService::OnIdleTimeoutPrefChanged() { if (GetTimeout().is_positive()) { - MaybeRunActions(); + CheckIfIdle(); } else { // Cancel any outstanding callback if idle timeout is no longer valid. cancelable_actions_callback_.Cancel(); @@ -103,14 +111,14 @@ } void IdleService::PostCheckIdleTask(base::TimeDelta time_from_now) { - cancelable_actions_callback_.Reset(base::BindOnce( - &IdleService::MaybeRunActions, weak_factory_.GetWeakPtr())); + cancelable_actions_callback_.Reset( + base::BindOnce(&IdleService::CheckIfIdle, weak_factory_.GetWeakPtr())); // Post task to check idle state when it can potentially happen. base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, cancelable_actions_callback_.callback(), time_from_now); } -void IdleService::MaybeRunActions() { +void IdleService::CheckIfIdle() { DCHECK(base::FeatureList::IsEnabled(kIdleTimeout)); base::TimeDelta idle_threshold = GetTimeout(); base::Time last_active_time = GetLastActiveTime(); @@ -125,15 +133,32 @@ void IdleService::RunActionsForState(LastState last_state) { DCHECK(base::FeatureList::IsEnabled(kIdleTimeout)); + if (last_state == LastState::kIdleOnBackground) { + // TODO: check if data will be cleared. + for (auto& observer : observer_list_) { + // Show loading UI on re-foreground right away if data will be clared. + observer.OnClearDataOnStartup(); + } + RunActions(); + } else if (observer_list_.empty()) { + RunActions(); + } else { + for (auto& observer : observer_list_) { + // Confirm that the user is not active by showing dialog before running + // actions. + observer.OnIdleTimeoutInForeground(); + } + } + browser_state_->GetPrefs()->SetTime( enterprise_idle::prefs::kLastIdleTimestamp, base::Time::Now()); - // TODO: Implement the IdleTimeoutActions and UI changes. Show UI if - // action runner will clear data and last state is background. - action_runner_->Run(); - PostCheckIdleTask(GetTimeout()); } +void IdleService::RunActions() { + action_runner_->Run(); +} + void IdleService::SetLastActiveTime() { GetApplicationContext()->GetLocalState()->SetTime( enterprise_idle::prefs::kLastActiveTimestamp, base::Time::Now());
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.h b/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.h new file mode 100644 index 0000000..0eff1337 --- /dev/null +++ b/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.h
@@ -0,0 +1,41 @@ +// 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 IOS_CHROME_BROWSER_ENTERPRISE_MODEL_IDLE_IDLE_SERVICE_OBSERVER_BRIDGE_H_ +#define IOS_CHROME_BROWSER_ENTERPRISE_MODEL_IDLE_IDLE_SERVICE_OBSERVER_BRIDGE_H_ + +#import <Foundation/Foundation.h> + +#import "base/scoped_observation.h" +#import "ios/chrome/browser/enterprise/model/idle/idle_service.h" + +// Objective-C protocol mirroring IdleService::Observer. +@protocol IdleServiceObserving <NSObject> +@optional +- (void)onIdleTimeoutInForeground; +- (void)onClearDataOnStartup; +- (void)onIdleTimeoutActionsCompleted; +@end + +// Simple observer bridge that forwards all events to its delegate observer. +class IdleServiceObserverBridge + : public enterprise_idle::IdleService::Observer { + public: + IdleServiceObserverBridge(enterprise_idle::IdleService* service, + id<IdleServiceObserving> observer); + ~IdleServiceObserverBridge() override; + + // IdleService::Observer implementation. + void OnIdleTimeoutInForeground() override; + void OnClearDataOnStartup() override; + void OnIdleTimeoutActionsCompleted() override; + + private: + __weak id<IdleServiceObserving> observer_ = nil; + base::ScopedObservation<enterprise_idle::IdleService, + enterprise_idle::IdleService::Observer> + scoped_observation_{this}; +}; + +#endif // IOS_CHROME_BROWSER_ENTERPRISE_MODEL_IDLE_IDLE_SERVICE_OBSERVER_BRIDGE_H_
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.mm b/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.mm new file mode 100644 index 0000000..78b2f08 --- /dev/null +++ b/ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.mm
@@ -0,0 +1,33 @@ +// 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. + +#import "ios/chrome/browser/enterprise/model/idle/idle_service_observer_bridge.h" + +IdleServiceObserverBridge::IdleServiceObserverBridge( + enterprise_idle::IdleService* service, + id<IdleServiceObserving> observer) + : observer_(observer) { + DCHECK(observer_); + scoped_observation_.Observe(service); +} + +IdleServiceObserverBridge::~IdleServiceObserverBridge() = default; + +void IdleServiceObserverBridge::OnIdleTimeoutInForeground() { + if ([observer_ respondsToSelector:@selector(onIdleTimeoutInForeground)]) { + [observer_ onIdleTimeoutInForeground]; + } +} + +void IdleServiceObserverBridge::OnClearDataOnStartup() { + if ([observer_ respondsToSelector:@selector(onClearDataOnStartup)]) { + [observer_ onClearDataOnStartup]; + } +} + +void IdleServiceObserverBridge::OnIdleTimeoutActionsCompleted() { + if ([observer_ respondsToSelector:@selector(onIdleTimeoutActionsCompleted)]) { + [observer_ onIdleTimeoutActionsCompleted]; + } +}
diff --git a/ios/chrome/browser/enterprise/model/idle/idle_service_unittest.mm b/ios/chrome/browser/enterprise/model/idle/idle_service_unittest.mm index 3d3b59d..e8b0495 100644 --- a/ios/chrome/browser/enterprise/model/idle/idle_service_unittest.mm +++ b/ios/chrome/browser/enterprise/model/idle/idle_service_unittest.mm
@@ -3,6 +3,7 @@ // found in the LICENSE file. #import "ios/chrome/browser/enterprise/model/idle/idle_service.h" +#import "base/test/gmock_callback_support.h" #import "base/test/scoped_feature_list.h" #import "base/time/time.h" #import "components/enterprise/idle/idle_features.h" @@ -37,6 +38,15 @@ }; public: + class MockObserver : public IdleService::Observer { + public: + MockObserver() {} + ~MockObserver() override {} + MOCK_METHOD(void, OnIdleTimeoutInForeground, (), (override)); + MOCK_METHOD(void, OnClearDataOnStartup, (), (override)); + MOCK_METHOD(void, OnIdleTimeoutActionsCompleted, (), (override)); + }; + IdleTimeoutServiceTest() = default; void SetIdleTimeoutPolicy(base::TimeDelta timeout) { @@ -88,6 +98,10 @@ IOSChromeScopedTestingLocalState local_state_; }; +ACTION(RunActionsForNoUserAction) { + std::move(const_cast<base::OnceCallback<void()>>(arg0)).Run(); +} + // When policy timeout is set after being unset. TEST_F(IdleTimeoutServiceTest, IdleTimeoutPrefsSet_OnPolicySet) { InitIdleService(); @@ -231,6 +245,8 @@ EXPECT_EQ(GetLastIdleTime(), base::Time::Now()); } +// Foreground case: idle check should be scheduled for the right time when it +// might become idle. TEST_F(IdleTimeoutServiceTest, ActionsRunAtCorrectTimesWhileForegrounded) { SetIdleTimeoutPolicy(base::Minutes(3)); InitIdleService(); @@ -250,4 +266,34 @@ EXPECT_EQ(GetLastIdleTime(), base::Time::Now()); } +// If there are observers for the service, the service should call +// `OnIdleTimeoutInForeground` without running the actions right away. The +// observer will decide if actions should run or not. +TEST_F(IdleTimeoutServiceTest, + ActionsDoNotRunWhenObserverDoesNotInvokeCallback) { + SetIdleTimeoutPolicy(base::Minutes(3)); + InitIdleService(); + MockObserver mock_observer; + idle_service_->AddObserver(&mock_observer); + idle_service_->OnApplicationWillEnterForeground(); + task_environment_.FastForwardBy(base::Seconds(40)); + // Simulate user activity at t=40s. + SetLastActiveTime(base::Time::Now()); + + // At t=3, actions will not run because idle time has not reached 3. + // Should check again and run at t=3:40. + EXPECT_CALL(*action_runner_, Run()).Times(0); + task_environment_.FastForwardBy(base::Minutes(3) - base::Seconds(40)); + + // Not running the callback passed to `OnIdleTimeoutInForeground` means no + // actions should run. + testing::InSequence in_sequence; + EXPECT_CALL(mock_observer, OnIdleTimeoutInForeground()); + EXPECT_CALL(*action_runner_, Run()).Times(0); + task_environment_.FastForwardBy(base::Seconds(40)); + EXPECT_EQ(GetLastIdleTime(), base::Time::Now()); + // Remove observer before it is destroyed. + idle_service_->RemoveObserver(&mock_observer); +} + } // namespace enterprise_idle
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index f9518ed..54d68f4c 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -284,6 +284,17 @@ {"Compact Vertical", kDiscoverFeedTopSyncPromoCompactVertical, std::size(kDiscoverFeedTopSyncPromoCompactVertical), nullptr}}; +const FeatureEntry::FeatureParam kContentPushNotificationsEnabledPromo[] = { + {kContentPushNotificationsExperimentType, "1"}}; +const FeatureEntry::FeatureParam kContentPushNotificationsEnabledSetupLists[] = + {{kContentPushNotificationsExperimentType, "2"}}; + +const FeatureEntry::FeatureVariation kContentPushNotificationsVariations[] = { + {"Promo", kContentPushNotificationsEnabledPromo, + std::size(kContentPushNotificationsEnabledPromo), nullptr}, + {"Set up list", kContentPushNotificationsEnabledSetupLists, + std::size(kContentPushNotificationsEnabledSetupLists), nullptr}}; + const FeatureEntry::FeatureParam kFeedHeaderSettingDisabledStickyHeader[] = { {kDisableStickyHeaderForFollowingFeed, "true"}}; const FeatureEntry::FeatureParam kFeedHeaderSettingReducedHeight[] = { @@ -612,6 +623,13 @@ std::size(kBottomOmniboxDefaultSettingSafariSwitcher), nullptr}, }; +const FeatureEntry::FeatureParam kBottomOmniboxPromoForced[] = { + {kBottomOmniboxPromoParam, kBottomOmniboxPromoParamForced}}; +const FeatureEntry::FeatureVariation kBottomOmniboxPromoVariations[] = { + {"Forced", kBottomOmniboxPromoForced, std::size(kBottomOmniboxPromoForced), + nullptr}, +}; + const FeatureEntry::Choice kReplaceSyncPromosWithSignInPromosChoices[] = { {"Default", "", ""}, {"Disabled", "disable-features", @@ -916,7 +934,9 @@ {"content-push-notifications", flag_descriptions::kContentPushNotificationsName, flag_descriptions::kContentPushNotificationsDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kContentPushNotifications)}, + FEATURE_WITH_PARAMS_VALUE_TYPE(kContentPushNotifications, + kContentPushNotificationsVariations, + "ContentPushNotifications")}, {"overflow-menu-customization", flag_descriptions::kOverflowMenuCustomizationName, flag_descriptions::kOverflowMenuCustomizationDescription, flags_ui::kOsIos, @@ -1632,6 +1652,22 @@ flag_descriptions::kShowUserPolicyNotificationAtStartupIfNeededDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(policy::kShowUserPolicyNotificationAtStartupIfNeeded)}, + {"tab-grid-compositional-layout", + flag_descriptions::kTabGridCompositionalLayoutName, + flag_descriptions::kTabGridCompositionalLayoutDescription, + flags_ui::kOsIos, FEATURE_VALUE_TYPE(kTabGridCompositionalLayout)}, + {"bottom-omnibox-promo-fre", flag_descriptions::kBottomOmniboxPromoFREName, + flag_descriptions::kBottomOmniboxPromoFREDescription, flags_ui::kOsIos, + FEATURE_WITH_PARAMS_VALUE_TYPE(kBottomOmniboxPromoFRE, + kBottomOmniboxPromoVariations, + "BottomOmniboxPromoFRE")}, + {"bottom-omnibox-promo-app-launch", + flag_descriptions::kBottomOmniboxPromoAppLaunchName, + flag_descriptions::kBottomOmniboxPromoAppLaunchDescription, + flags_ui::kOsIos, + FEATURE_WITH_PARAMS_VALUE_TYPE(kBottomOmniboxPromoAppLaunch, + kBottomOmniboxPromoVariations, + "BottomOmniboxPromoAppLaunch")}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index eeb4cb0..4fb862c2 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -166,6 +166,15 @@ "Enabled by default. Retrieve device switcher results for the default " "omnibox position."; +const char kBottomOmniboxPromoAppLaunchName[] = + "Bottom omnibox promo app-launch"; +const char kBottomOmniboxPromoAppLaunchDescription[] = + "Enables the app-launch promo for the bottom omnibox."; + +const char kBottomOmniboxPromoFREName[] = "Bottom omnibox promo FRE"; +const char kBottomOmniboxPromoFREDescription[] = + "Enables the FRE promo for the bottom omnibox."; + const char kBottomOmniboxSteadyStateName[] = "Bottom Omnibox (Steady)"; const char kBottomOmniboxSteadyStateDescription[] = "Move the omnibox to the bottom in steady state"; @@ -1018,10 +1027,16 @@ "and the ability to load only the minimum amount of data when restoring " "the session from disk."; +const char kTabGridCompositionalLayoutName[] = + "Enable tab grid with the new compositional layout"; +const char kTabGridCompositionalLayoutDescription[] = + "When enabled, the Tab Grid uses the new compositional layout. Items sizes " + "are different and more dynamic than before."; + const char kTabGridRefactoringName[] = "Enable tab grid refactoring"; const char kTabGridRefactoringDescription[] = - "When enabled, the Tab Grid use the refactored version, it should not have " - "any visual difference nor different feature with the legacy one."; + "When enabled, the Tab Grid uses the refactored version, it should not " + "have any visual difference nor different feature with the legacy one."; const char kTabGridNewTransitionsName[] = "Enable new TabGrid transitions"; const char kTabGridNewTransitionsDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 11c72a9d..1c603c9 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -143,6 +143,16 @@ extern const char kBottomOmniboxDeviceSwitcherResultsName[]; extern const char kBottomOmniboxDeviceSwitcherResultsDescription[]; +// Title and description for the flag that enables the app-launch promo of +// bottom omnibox. +extern const char kBottomOmniboxPromoAppLaunchName[]; +extern const char kBottomOmniboxPromoAppLaunchDescription[]; + +// Title and description for the flag that enables the FRE promo of bottom +// omnibox. +extern const char kBottomOmniboxPromoFREName[]; +extern const char kBottomOmniboxPromoFREDescription[]; + // Title and description for the flag that moves the omnibox to the bottom in // the steady state. extern const char kBottomOmniboxSteadyStateName[]; @@ -895,6 +905,10 @@ extern const char kEnableSessionSerializationOptimizationsName[]; extern const char kEnableSessionSerializationOptimizationsDescription[]; +// Title and description for the tab grid new compositional layout. +extern const char kTabGridCompositionalLayoutName[]; +extern const char kTabGridCompositionalLayoutDescription[]; + // Title and description for the tab grid refactoring flag. extern const char kTabGridRefactoringName[]; extern const char kTabGridRefactoringDescription[];
diff --git a/ios/chrome/browser/lens/BUILD.gn b/ios/chrome/browser/lens/model/BUILD.gn similarity index 96% rename from ios/chrome/browser/lens/BUILD.gn rename to ios/chrome/browser/lens/model/BUILD.gn index c604484..af5688fc 100644 --- a/ios/chrome/browser/lens/BUILD.gn +++ b/ios/chrome/browser/lens/model/BUILD.gn
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("lens") { +source_set("model") { sources = [ "lens_browser_agent.h", "lens_browser_agent.mm", @@ -28,7 +28,7 @@ testonly = true sources = [ "lens_tab_helper_unittest.mm" ] deps = [ - ":lens", + ":model", "//base/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", "//ios/chrome/browser/shared/public/commands",
diff --git a/ios/chrome/browser/lens/DEPS b/ios/chrome/browser/lens/model/DEPS similarity index 100% rename from ios/chrome/browser/lens/DEPS rename to ios/chrome/browser/lens/model/DEPS
diff --git a/ios/chrome/browser/lens/lens_browser_agent.h b/ios/chrome/browser/lens/model/lens_browser_agent.h similarity index 100% rename from ios/chrome/browser/lens/lens_browser_agent.h rename to ios/chrome/browser/lens/model/lens_browser_agent.h
diff --git a/ios/chrome/browser/lens/lens_browser_agent.mm b/ios/chrome/browser/lens/model/lens_browser_agent.mm similarity index 98% rename from ios/chrome/browser/lens/lens_browser_agent.mm rename to ios/chrome/browser/lens/model/lens_browser_agent.mm index 00311b5..c3b3bea 100644 --- a/ios/chrome/browser/lens/lens_browser_agent.mm +++ b/ios/chrome/browser/lens/model/lens_browser_agent.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "components/search_engines/template_url.h" #import "components/search_engines/template_url_service.h"
diff --git a/ios/chrome/browser/lens/lens_tab_helper.h b/ios/chrome/browser/lens/model/lens_tab_helper.h similarity index 100% rename from ios/chrome/browser/lens/lens_tab_helper.h rename to ios/chrome/browser/lens/model/lens_tab_helper.h
diff --git a/ios/chrome/browser/lens/lens_tab_helper.mm b/ios/chrome/browser/lens/model/lens_tab_helper.mm similarity index 97% rename from ios/chrome/browser/lens/lens_tab_helper.mm rename to ios/chrome/browser/lens/model/lens_tab_helper.mm index 47fcdd4..858fd5b 100644 --- a/ios/chrome/browser/lens/lens_tab_helper.mm +++ b/ios/chrome/browser/lens/model/lens_tab_helper.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/lens/lens_tab_helper.h" +#import "ios/chrome/browser/lens/model/lens_tab_helper.h" #import "ios/chrome/browser/shared/public/commands/lens_commands.h" #import "ios/chrome/browser/shared/public/commands/open_lens_input_selection_command.h" #import "ios/chrome/browser/ui/lens/lens_entrypoint.h"
diff --git a/ios/chrome/browser/lens/lens_tab_helper_unittest.mm b/ios/chrome/browser/lens/model/lens_tab_helper_unittest.mm similarity index 98% rename from ios/chrome/browser/lens/lens_tab_helper_unittest.mm rename to ios/chrome/browser/lens/model/lens_tab_helper_unittest.mm index ff83d033..7a4daa5 100644 --- a/ios/chrome/browser/lens/lens_tab_helper_unittest.mm +++ b/ios/chrome/browser/lens/model/lens_tab_helper_unittest.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/lens/lens_tab_helper.h" +#import "ios/chrome/browser/lens/model/lens_tab_helper.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
diff --git a/ios/chrome/browser/main/BUILD.gn b/ios/chrome/browser/main/BUILD.gn index 497c3fc..558d8f27 100644 --- a/ios/chrome/browser/main/BUILD.gn +++ b/ios/chrome/browser/main/BUILD.gn
@@ -25,7 +25,7 @@ "//ios/chrome/browser/favicon", "//ios/chrome/browser/follow:browser_agent", "//ios/chrome/browser/infobars/overlays/browser_agent:browser_agent_util", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/metrics:metrics_browser_agent", "//ios/chrome/browser/metrics/model", "//ios/chrome/browser/policy",
diff --git a/ios/chrome/browser/main/DEPS b/ios/chrome/browser/main/DEPS index ca4a1856..dd2edf8 100644 --- a/ios/chrome/browser/main/DEPS +++ b/ios/chrome/browser/main/DEPS
@@ -14,7 +14,7 @@ "+ios/chrome/browser/device_sharing/model/device_sharing_browser_agent.h", "+ios/chrome/browser/follow/follow_browser_agent.h", "+ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.h", - "+ios/chrome/browser/lens/lens_browser_agent.h", + "+ios/chrome/browser/lens/model/lens_browser_agent.h", "+ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h", "+ios/chrome/browser/policy/policy_watcher_browser_agent.h", "+ios/chrome/browser/reading_list/model/reading_list_browser_agent.h", @@ -48,4 +48,3 @@ "+ios/chrome/browser/ui/commands/command_dispatcher.h", ] } -
diff --git a/ios/chrome/browser/main/browser_agent_util.mm b/ios/chrome/browser/main/browser_agent_util.mm index 45b03d94..c817529 100644 --- a/ios/chrome/browser/main/browser_agent_util.mm +++ b/ios/chrome/browser/main/browser_agent_util.mm
@@ -12,7 +12,7 @@ #import "ios/chrome/browser/favicon/favicon_browser_agent.h" #import "ios/chrome/browser/follow/follow_browser_agent.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/metrics/model/web_state_list_metrics_browser_agent.h" #import "ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h" #import "ios/chrome/browser/policy/policy_watcher_browser_agent.h"
diff --git a/ios/chrome/browser/plus_addresses/coordinator/BUILD.gn b/ios/chrome/browser/plus_addresses/coordinator/BUILD.gn new file mode 100644 index 0000000..eebfeb3 --- /dev/null +++ b/ios/chrome/browser/plus_addresses/coordinator/BUILD.gn
@@ -0,0 +1,23 @@ +# 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. + +source_set("coordinator") { + sources = [ + "plus_address_bottom_sheet_coordinator.h", + "plus_address_bottom_sheet_coordinator.mm", + ] + deps = [ + "//base", + "//components/plus_addresses", + "//ios/chrome/browser/autofill/bottom_sheet:bottom_sheet", + "//ios/chrome/browser/plus_addresses/model", + "//ios/chrome/browser/plus_addresses/ui", + "//ios/chrome/browser/shared/coordinator/chrome_coordinator", + "//ios/chrome/browser/shared/model/browser", + "//ios/chrome/browser/shared/model/browser_state", + "//ios/chrome/browser/shared/model/web_state_list", + "//ios/chrome/browser/shared/public/commands", + "//ios/chrome/common/ui/confirmation_alert", + ] +}
diff --git a/ios/chrome/browser/plus_addresses/coordinator/DEPS b/ios/chrome/browser/plus_addresses/coordinator/DEPS new file mode 100644 index 0000000..41b2b0d8 --- /dev/null +++ b/ios/chrome/browser/plus_addresses/coordinator/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+ios/chrome/browser/shared/coordinator/chrome_coordinator", + "+ios/chrome/browser/autofill/bottom_sheet", +] \ No newline at end of file
diff --git a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h new file mode 100644 index 0000000..abcdd2a --- /dev/null +++ b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h
@@ -0,0 +1,30 @@ +// 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 IOS_CHROME_BROWSER_PLUS_ADDRESSES_COORDINATOR_PLUS_ADDRESS_BOTTOM_SHEET_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_PLUS_ADDRESSES_COORDINATOR_PLUS_ADDRESS_BOTTOM_SHEET_COORDINATOR_H_ + +#import "components/plus_addresses/plus_address_types.h" +#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "url/origin.h" + +@protocol BrowserCoordinatorCommands; +@protocol PlusAddressBottomSheetCoordinatorDelegate; + +// The coordinator responsible for creating the bottom sheet's view controller, +// and eventually a mediator. +@interface PlusAddressBottomSheetCoordinator : ChromeCoordinator + +// `viewController` is the VC used to present the bottom sheet. +// TODO(b/311204704): create a mediator that will orchestrate the data +// operations via the `PlusAddressService`. This will entail reserving a +// plus_address, showing a preview of it, confirming via service call when the +// primary button is clicked, and then running a callback to fill the field from +// which the bottom sheet was triggered. +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser; + +@end + +#endif // IOS_CHROME_BROWSER_PLUS_ADDRESSES_COORDINATOR_PLUS_ADDRESS_BOTTOM_SHEET_COORDINATOR_H_
diff --git a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.mm b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.mm new file mode 100644 index 0000000..bd68ead --- /dev/null +++ b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.mm
@@ -0,0 +1,111 @@ +// 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. + +#import "ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h" + +#import "components/plus_addresses/plus_address_service.h" +#import "components/plus_addresses/plus_address_types.h" +#import "ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h" +#import "ios/chrome/browser/plus_addresses/model/plus_address_service_factory.h" +#import "ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" +#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" +#import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" +#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h" + +namespace { +constexpr CGFloat kHalfSheetCornerRadius = 20; +} // namespace + +@interface PlusAddressBottomSheetCoordinator () <ConfirmationAlertActionHandler> + +@end + +@implementation PlusAddressBottomSheetCoordinator { + plus_addresses::PlusAddressCallback _callback; + url::Origin _mainFrameOrigin; + PlusAddressBottomSheetViewController* _viewController; + plus_addresses::PlusAddressService* _plusAddressService; + id<BrowserCoordinatorCommands> _browserCoordinatorHandler; +} + +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser { + self = [super initWithBaseViewController:viewController browser:browser]; + if (self) { + ChromeBrowserState* browserState = + browser->GetBrowserState()->GetOriginalChromeBrowserState(); + _plusAddressService = PlusAddressServiceFactory::GetForBrowserState( + browserState->GetOriginalChromeBrowserState()); + _browserCoordinatorHandler = HandlerForProtocol( + browser->GetCommandDispatcher(), BrowserCoordinatorCommands); + + web::WebState* activeWebState = + browser->GetWebStateList()->GetActiveWebState(); + AutofillBottomSheetTabHelper* bottomSheetTabHelper = + AutofillBottomSheetTabHelper::FromWebState(activeWebState); + _mainFrameOrigin = + url::Origin::Create(activeWebState->GetLastCommittedURL()); + _callback = bottomSheetTabHelper->GetPendingPlusAddressFillCallback(); + } + return self; +} + +#pragma mark - ChromeCoordinator + +- (void)start { + _viewController = [[PlusAddressBottomSheetViewController alloc] init]; + + // Indicate a preference for half sheet detents, and other styling concerns. + _viewController.modalPresentationStyle = UIModalPresentationPageSheet; + _viewController.actionHandler = self; + UISheetPresentationController* presentationController = + _viewController.sheetPresentationController; + presentationController.prefersEdgeAttachedInCompactHeight = YES; + presentationController.detents = @[ + UISheetPresentationControllerDetent.mediumDetent, + UISheetPresentationControllerDetent.largeDetent + ]; + presentationController.preferredCornerRadius = kHalfSheetCornerRadius; + + [self.baseViewController presentViewController:_viewController + animated:YES + completion:nil]; +} + +- (void)stop { + [super stop]; + [_viewController.presentingViewController dismissViewControllerAnimated:NO + completion:nil]; + _viewController = nil; +} + +#pragma mark - ConfirmationAlertActionHandler + +- (void)confirmationAlertPrimaryAction { + __weak __typeof(self) weakSelf = self; + [_viewController.presentingViewController + dismissViewControllerAnimated:NO + completion:^{ + [weakSelf didConfirm]; + }]; +} + +- (void)confirmationAlertSecondaryAction { + // The cancel button was tapped, which dismisses the bottom sheet. + // Call out to the command handler to hide the view and stop the coordinator. + [_browserCoordinatorHandler dismissPlusAddressBottomSheet]; +} + +#pragma mark - Private + +- (void)didConfirm { + _plusAddressService->OfferPlusAddressCreation(_mainFrameOrigin, + std::move(_callback)); + [_browserCoordinatorHandler dismissPlusAddressBottomSheet]; +} + +@end
diff --git a/ios/chrome/browser/plus_addresses/ui/BUILD.gn b/ios/chrome/browser/plus_addresses/ui/BUILD.gn new file mode 100644 index 0000000..2474cce --- /dev/null +++ b/ios/chrome/browser/plus_addresses/ui/BUILD.gn
@@ -0,0 +1,35 @@ +# 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. + +source_set("ui") { + sources = [ + "plus_address_bottom_sheet_view_controller.h", + "plus_address_bottom_sheet_view_controller.mm", + ] + deps = [ + "//components/strings", + "//ios/chrome/common/ui/confirmation_alert", + "//ui/base", + ] +} + +source_set("eg2_tests") { + configs += [ "//build/config/ios:xctest_config" ] + testonly = true + sources = [ "plus_addresses_egtest.mm" ] + deps = [ + "//components/plus_addresses", + "//components/strings:components_strings_grit", + "//ios/chrome/browser/shared/public/features", + "//ios/chrome/browser/signin/model:fake_system_identity", + "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", + "//ios/chrome/test:eg_test_support+eg2", + "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/testing/earl_grey:eg_test_support+eg2", + "//net", + "//net:test_support", + "//ui/base", + ] + frameworks = [ "UIKit.framework" ] +}
diff --git a/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.h b/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.h new file mode 100644 index 0000000..57ac935 --- /dev/null +++ b/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.h
@@ -0,0 +1,21 @@ +// 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 IOS_CHROME_BROWSER_PLUS_ADDRESSES_UI_PLUS_ADDRESS_BOTTOM_SHEET_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_PLUS_ADDRESSES_UI_PLUS_ADDRESS_BOTTOM_SHEET_VIEW_CONTROLLER_H_ + +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h" + +@protocol PlusAddressBottomSheetHandler; + +// Plus Address Bottom Sheet UI, which will eventually include a description of +// the feature, a preview of the plus address that can be filled, a button to +// use the plus address and a button to cancel the process and dismiss the UI. +// For now, however, it is a skeleton implementation. +@interface PlusAddressBottomSheetViewController + : ConfirmationAlertViewController + +@end + +#endif // IOS_CHROME_BROWSER_PLUS_ADDRESSES_UI_PLUS_ADDRESS_BOTTOM_SHEET_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.mm b/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.mm new file mode 100644 index 0000000..edb6634 --- /dev/null +++ b/ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.mm
@@ -0,0 +1,25 @@ +// 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. + +#import "ios/chrome/browser/plus_addresses/ui/plus_address_bottom_sheet_view_controller.h" + +#import "components/strings/grit/components_strings.h" +#import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h" +#import "ui/base/l10n/l10n_util_mac.h" + +@implementation PlusAddressBottomSheetViewController + +#pragma mark - UIViewController + +- (void)viewDidLoad { + // Set the properties read by the super when constructing the + // views in `-[ConfirmationAlertViewController viewDidLoad]`. + self.primaryActionString = + l10n_util::GetNSString(IDS_PLUS_ADDRESS_MODAL_OK_TEXT); + self.secondaryActionString = + l10n_util::GetNSString(IDS_PLUS_ADDRESS_MODAL_CANCEL_TEXT); + [super viewDidLoad]; +} + +@end
diff --git a/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm b/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm new file mode 100644 index 0000000..1bef4f85 --- /dev/null +++ b/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm
@@ -0,0 +1,92 @@ +// 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. + +#import "base/strings/stringprintf.h" +#import "base/strings/sys_string_conversions.h" +#import "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/signin/model/fake_system_identity.h" +#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" +#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" +#import "ios/chrome/test/earl_grey/chrome_actions.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#import "ios/testing/earl_grey/matchers.h" +#import "net/test/embedded_test_server/default_handlers.h" + +namespace { +const char kEmailFormUrl[] = "/email_signup_form.html"; +const char kEmailFieldId[] = "email"; +const char kFakeSuggestionLabel[] = "plus?"; +} // namespace + +// Test suite that tests plus addresses functionality. +@interface PlusAddressesTestCase : WebHttpServerChromeTestCase +@end + +@implementation PlusAddressesTestCase + +- (void)setUp { + [super setUp]; + net::test_server::RegisterDefaultHandlers(self.testServer); + GREYAssertTrue(self.testServer->Start(), @"Server did not start."); + // Ensure a fake identity is available, as this is required by the + // plus_addresses feature. + [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]]; +} + +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + // Ensure the feature is enabled, including a required param. + // TODO(crbug.com/1467623): Set up an app interface or a demo feature param + // instead of supplying a fake, un-called server URL. + config.additional_args.push_back( + base::StringPrintf("--enable-features=PlusAddressesEnabled:suggestion-" + "label/%s/server-url/fake.example", + kFakeSuggestionLabel)); + return config; +} + +#pragma mark - Helper methods + +// Loads simple page on localhost, ensuring that it is eligible for the +// plus_addresses feature. +- (void)loadPlusAddressEligiblePage { + [ChromeEarlGrey loadURL:self.testServer->GetURL(kEmailFormUrl)]; + [ChromeEarlGrey waitForWebStateContainingText:"Signup form"]; +} + +#pragma mark - Tests + +// A basic test that simply opens and dismisses the bottom sheet. +- (void)testShowPlusAddressBottomSheet { + [self loadPlusAddressEligiblePage]; + // Tap an element that is eligible for plus_address autofilling. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElementWithId(kEmailFieldId)]; + id<GREYMatcher> user_chip = + grey_text(base::SysUTF8ToNSString(kFakeSuggestionLabel)); + + // Ensure the plus_address suggestion appears. + [ChromeEarlGrey waitForUIElementToAppearWithMatcher:user_chip]; + + // Tapping it will trigger the UI. + // TODO(crbug.com/1467623): Flesh this out as more functionality is + // implemented. An app interface or demo feature param will be necessary here, + // too, such that actions that normally trigger server calls can be mocked + // out. + [[EarlGrey selectElementWithMatcher:user_chip] performAction:grey_tap()]; + + // Ensure the cancel button is shown. + id<GREYMatcher> cancelButton = + chrome_test_util::ButtonWithAccessibilityLabelId( + IDS_PLUS_ADDRESS_MODAL_CANCEL_TEXT); + + // Click the cancel button, dismissing the bottom sheet. + [[EarlGrey selectElementWithMatcher:cancelButton] performAction:grey_tap()]; +} + +@end
diff --git a/ios/chrome/browser/prerender/model/BUILD.gn b/ios/chrome/browser/prerender/model/BUILD.gn index 2178fb6..c4efe27 100644 --- a/ios/chrome/browser/prerender/model/BUILD.gn +++ b/ios/chrome/browser/prerender/model/BUILD.gn
@@ -31,6 +31,7 @@ "//components/prefs/ios", "//components/signin/ios/browser", "//components/supervised_user/core/browser", + "//components/supervised_user/core/browser:supervised_user_preferences", "//components/supervised_user/core/common", "//ios/chrome/browser/app_launcher/model:model", "//ios/chrome/browser/crash_report/model:model_internal",
diff --git a/ios/chrome/browser/prerender/model/preload_controller.mm b/ios/chrome/browser/prerender/model/preload_controller.mm index 2183dbb..4f7bf4fd 100644 --- a/ios/chrome/browser/prerender/model/preload_controller.mm +++ b/ios/chrome/browser/prerender/model/preload_controller.mm
@@ -15,7 +15,7 @@ #import "components/prefs/ios/pref_observer_bridge.h" #import "components/prefs/pref_service.h" #import "components/signin/ios/browser/account_consistency_service.h" -#import "components/supervised_user/core/browser/supervised_user_service.h" +#import "components/supervised_user/core/browser/supervised_user_preferences.h" #import "components/supervised_user/core/common/supervised_user_utils.h" #import "ios/chrome/browser/app_launcher/model/app_launcher_tab_helper.h" #import "ios/chrome/browser/crash_report/model/crash_report_helper.h" @@ -27,7 +27,6 @@ #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/prefs/pref_names.h" #import "ios/chrome/browser/signin/model/account_consistency_service_factory.h" -#import "ios/chrome/browser/supervised_user/model/supervised_user_service_factory.h" #import "ios/chrome/browser/tabs/model/tab_helper_util.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" @@ -91,10 +90,8 @@ // Returns true if the primary account is subject to parental controls and the // URL filtering control has been enabled. bool IsSubjectToParentalControls(ChromeBrowserState* browserState) { - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForBrowserState(browserState); - return supervised_user_service && - supervised_user_service->IsURLFilteringEnabled(); + return browserState && + supervised_user:: IsUrlFilteringEnabled(*browserState->GetPrefs()); } // Returns whether `url` can be prerendered.
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm index ad013a3..4b780af 100644 --- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm +++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -3471,6 +3471,12 @@ self.passwordCheckupCoordinator = nil; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [self closeSettingsUI]; +} + #pragma mark - Helpers for web state list events // Called when the last incognito tab was closed.
diff --git a/ios/chrome/browser/shared/public/commands/BUILD.gn b/ios/chrome/browser/shared/public/commands/BUILD.gn index 913cc00..27cd18e 100644 --- a/ios/chrome/browser/shared/public/commands/BUILD.gn +++ b/ios/chrome/browser/shared/public/commands/BUILD.gn
@@ -80,6 +80,7 @@ "//base", "//components/browsing_data/core", "//components/password_manager/core/browser", + "//components/plus_addresses", "//ios/chrome/browser/browsing_data/model:model_remove_mask", "//ios/chrome/browser/discover_feed:constants", "//ios/chrome/browser/promos_manager:constants",
diff --git a/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h b/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h index 11294ae..115dfa8 100644 --- a/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h +++ b/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_ #define IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_ +#import "components/plus_addresses/plus_address_types.h" + namespace autofill { struct FormActivityParams; } // namespace autofill @@ -18,6 +20,9 @@ // Shows the payments suggestion view controller. - (void)showPaymentsBottomSheet:(const autofill::FormActivityParams&)params; +// Shows the plus address bottom sheet view controller. +- (void)showPlusAddressesBottomSheet; + @end #endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h index 37cbf0c..a2a757a5 100644 --- a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h +++ b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h
@@ -107,6 +107,9 @@ // Dismiss the payments suggestions. - (void)dismissPaymentSuggestions; +// Dismiss the plus address bottom sheet. +- (void)dismissPlusAddressBottomSheet; + @end #endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_BROWSER_COORDINATOR_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/features/BUILD.gn b/ios/chrome/browser/shared/public/features/BUILD.gn index f5d8fa1..666e76c 100644 --- a/ios/chrome/browser/shared/public/features/BUILD.gn +++ b/ios/chrome/browser/shared/public/features/BUILD.gn
@@ -11,6 +11,7 @@ "//components/country_codes", "//components/version_info:channel", "//ios/chrome/app:background_mode_buildflags", + "//ios/chrome/browser/ui/ntp/feed_top_section:constants", "//ios/chrome/common", "//ui/base", ]
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h index 7c54fa78..51f0c141 100644 --- a/ios/chrome/browser/shared/public/features/features.h +++ b/ios/chrome/browser/shared/public/features/features.h
@@ -10,6 +10,7 @@ #include "Availability.h" #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#import "ios/chrome/browser/ui/ntp/feed_top_section/notifications_promo_view_constants.h" namespace base { class TimeDelta; @@ -209,6 +210,30 @@ // enabled. bool IsBottomOmniboxDeviceSwitcherResultsEnabled(); +// Feature flag to enable the bottom omnibox FRE promo. +BASE_DECLARE_FEATURE(kBottomOmniboxPromoFRE); + +// Feature flag to enable the bottom omnibox app-launch promo. +BASE_DECLARE_FEATURE(kBottomOmniboxPromoAppLaunch); + +// Feature param under kBottomOmniboxPromoFRE or kBottomOmniboxPromoAppLaunch to +// skip the promo conditions for testing. +extern const char kBottomOmniboxPromoParam[]; +extern const char kBottomOmniboxPromoParamForced[]; + +// Type of bottom omnibox promo. +enum class BottomOmniboxPromoType { + // kBottomOmniboxPromoFRE. + kFRE, + // kBottomOmniboxPromoAppLaunch. + kAppLaunch, + // Any promo type. + kAny, +}; + +// Whether the bottom omnibox promo of `type` is enabled. +bool IsBottomOmniboxPromoFlagEnabled(BottomOmniboxPromoType type); + // Feature flag to put all clipboard access onto a background thread. Any // synchronous clipboard access will always return nil/false. BASE_DECLARE_FEATURE(kOnlyAccessClipboardAsync); @@ -239,6 +264,9 @@ // Feature flag enabling tab grid refactoring. BASE_DECLARE_FEATURE(kTabGridRefactoring); +// Feature flag enabling the tab grid new compositional layout. +BASE_DECLARE_FEATURE(kTabGridCompositionalLayout); + // Whether the Safety Check module should be shown in the Magic Stack. bool IsSafetyCheckMagicStackEnabled(); @@ -307,6 +335,9 @@ // Feature flag to enable the live sport card in the Discover feed. BASE_DECLARE_FEATURE(kDiscoverFeedSportCard); +// Content Push Notifications Variations. +extern const char kContentPushNotificationsExperimentType[]; + // Feature flag to enable the content notifications. BASE_DECLARE_FEATURE(kContentPushNotifications); @@ -511,9 +542,18 @@ // YES when Follow UI Update is enabled. bool IsFollowUIUpdateEnabled(); -// YES when the Content Push Notifications are enabled. +// YES when any of the content push notification variations are enabled. bool IsContentPushNotificationsEnabled(); +// Returns the Experiment type from the content push notifications flag. +NotificationsExperimentType ContentNotificationsExperimentTypeEnabled(); + +// YES when the Content Push Notifications Promo is enabled. +bool IsContentPushNotificationsPromoEnabled(); + +// YES when the Content Push Notifications Setup List is enabled. +bool IsContentPushNotificationsSetUpListEnabled(); + // Returns true when the IOSLargeFakebox feature is enabled. bool IsIOSLargeFakeboxEnabled();
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm index da9394c..8d3bd472 100644 --- a/ios/chrome/browser/shared/public/features/features.mm +++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -266,6 +266,34 @@ base::FeatureList::IsEnabled(kBottomOmniboxDeviceSwitcherResults); } +BASE_FEATURE(kBottomOmniboxPromoFRE, + "BottomOmniboxPromoFRE", + base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kBottomOmniboxPromoAppLaunch, + "BottomOmniboxPromoAppLaunch", + base::FEATURE_DISABLED_BY_DEFAULT); + +const char kBottomOmniboxPromoParam[] = "BottomOmniboxPromoParam"; +const char kBottomOmniboxPromoParamForced[] = "Forced"; + +bool IsBottomOmniboxPromoFlagEnabled(BottomOmniboxPromoType type) { + if (!IsBottomOmniboxSteadyStateEnabled()) { + return false; + } + if ((type == BottomOmniboxPromoType::kFRE || + type == BottomOmniboxPromoType::kAny) && + base::FeatureList::IsEnabled(kBottomOmniboxPromoFRE)) { + return true; + } + if ((type == BottomOmniboxPromoType::kAppLaunch || + type == BottomOmniboxPromoType::kAny) && + base::FeatureList::IsEnabled(kBottomOmniboxPromoAppLaunch)) { + return true; + } + return false; +} + BASE_FEATURE(kOnlyAccessClipboardAsync, "OnlyAccessClipboardAsync", base::FEATURE_DISABLED_BY_DEFAULT); @@ -290,6 +318,10 @@ "DynamicBackgroundColor", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kTabGridCompositionalLayout, + "TabGridCompositionalLayout", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kTabGridRefactoring, "TabGridRefactoring", base::FEATURE_DISABLED_BY_DEFAULT); @@ -358,6 +390,9 @@ "DiscoverFeedSportCard", base::FEATURE_DISABLED_BY_DEFAULT); +const char kContentPushNotificationsExperimentType[] = + "ContentPushNotificationsExperimentType"; + BASE_FEATURE(kContentPushNotifications, "ContentPushNotifications", base::FEATURE_DISABLED_BY_DEFAULT); @@ -657,6 +692,26 @@ return base::FeatureList::IsEnabled(kContentPushNotifications); } +NotificationsExperimentType ContentNotificationsExperimentTypeEnabled() { + // This translates to the `NotificationsExperimentType` enum. + // Value 0 corresponds to `Enabled` on the feature flag. Only activates the + // Settings tab for content notifications. + return static_cast<NotificationsExperimentType>( + base::GetFieldTrialParamByFeatureAsInt( + kContentPushNotifications, kContentPushNotificationsExperimentType, + 0)); +} + +bool IsContentPushNotificationsPromoEnabled() { + return (ContentNotificationsExperimentTypeEnabled() == + NotificationsExperimentTypePromoEnabled); +} + +bool IsContentPushNotificationsSetUpListEnabled() { + return (ContentNotificationsExperimentTypeEnabled() == + NotificationsExperimentTypeSetUpListsEnabled); +} + bool IsIOSLargeFakeboxEnabled() { return base::FeatureList::IsEnabled(kIOSLargeFakebox); }
diff --git a/ios/chrome/browser/signin/model/BUILD.gn b/ios/chrome/browser/signin/model/BUILD.gn index f824b3e7..f419fe9 100644 --- a/ios/chrome/browser/signin/model/BUILD.gn +++ b/ios/chrome/browser/signin/model/BUILD.gn
@@ -366,7 +366,7 @@ "//components/sync_preferences:test_support", "//google_apis", "//ios/chrome/browser/content_settings/model", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/policy:policy_util", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser/test:test_support",
diff --git a/ios/chrome/browser/signin/model/account_consistency_browser_agent_unittest.mm b/ios/chrome/browser/signin/model/account_consistency_browser_agent_unittest.mm index 6f32fda..3d1931ac 100644 --- a/ios/chrome/browser/signin/model/account_consistency_browser_agent_unittest.mm +++ b/ios/chrome/browser/signin/model/account_consistency_browser_agent_unittest.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/browser/signin/model/account_consistency_browser_agent.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/shared/model/browser/test/test_browser.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
diff --git a/ios/chrome/browser/snapshots/model/snapshot_generator.h b/ios/chrome/browser/snapshots/model/snapshot_generator.h index 8daef0b..737a00a 100644 --- a/ios/chrome/browser/snapshots/model/snapshot_generator.h +++ b/ios/chrome/browser/snapshots/model/snapshot_generator.h
@@ -16,13 +16,19 @@ } // A class that takes care of creating, storing and returning snapshots of a -// tab's web page. +// tab's web page. This lives on the UI thread. @interface SnapshotGenerator : NSObject // Weak reference to the snapshot storage which is used to store and retrieve // snapshots for the WebState associated with this SnapshotGenerator. @property(nonatomic, weak) SnapshotStorage* snapshotStorage; +// The SnapshotGenerator delegate. +@property(nonatomic, weak) id<SnapshotGeneratorDelegate> delegate; + +// The snapshot ID. +@property(nonatomic, readonly) SnapshotID snapshotID; + // Designated initializer. - (instancetype)initWithWebState:(web::WebState*)webState snapshotID:(SnapshotID)snapshotID @@ -38,21 +44,19 @@ // `callback` will be called with nil. - (void)retrieveGreySnapshot:(void (^)(UIImage*))callback; -// Generates a new snapshot, updates the snapshot storage, and returns the new -// snapshot image. -- (UIImage*)updateSnapshot; +// Asynchronously generates a new snapshot with WebKit-based snapshot API, +// updates the snapshot storage, and runs `callback` with the new snapshot +// image. It is an error to call this method if the web state is showing +// anything other (e.g., native content) than a web view. +- (void)updateWKWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion; -// Asynchronously generates a new snapshot, updates the snapshot storage, and -// runs `callback` with the new snapshot image. It is an error to call this -// method if the web state is showing anything other (e.g., native content) than -// a web view. -- (void)updateWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion; +// Generates a new snapshot with UIKit-based snapshot API, updates the snapshot +// storage, and runs `callback` with the new snapshot image. +- (void)updateUIViewSnapshotWithCompletion:(void (^)(UIImage*))completion; -// Generates a new snapshot and returns the new snapshot image. This does not -// update the snapshot storage. If `shouldAddOverlay` is YES, overlays (e.g., -// infobars, the download manager, and sad tab view) are also captured in the -// snapshot image. -- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay; +// Generates and returns a new snapshot image with UIKit-based snapshot API. +// This does not update the snapshot storage. +- (UIImage*)generateUIViewSnapshot; // Hints that the snapshot will likely be saved to disk when the application is // backgrounded. The snapshot is then saved in memory, so it does not need to @@ -66,12 +70,6 @@ // Requests deletion of the current page snapshot from disk and memory. - (void)removeSnapshot; -// The SnapshotGenerator delegate. -@property(nonatomic, weak) id<SnapshotGeneratorDelegate> delegate; - -// The snapshot ID. -@property(nonatomic, readonly) SnapshotID snapshotID; - @end #endif // IOS_CHROME_BROWSER_SNAPSHOTS_MODEL_SNAPSHOT_GENERATOR_H_
diff --git a/ios/chrome/browser/snapshots/model/snapshot_generator.mm b/ios/chrome/browser/snapshots/model/snapshot_generator.mm index b62b7af..eab27b8 100644 --- a/ios/chrome/browser/snapshots/model/snapshot_generator.mm +++ b/ios/chrome/browser/snapshots/model/snapshot_generator.mm
@@ -18,7 +18,6 @@ #import "ios/chrome/browser/snapshots/model/snapshot_generator_delegate.h" #import "ios/chrome/browser/snapshots/model/snapshot_id.h" #import "ios/chrome/browser/snapshots/model/snapshot_storage.h" -#import "ios/web/public/thread/web_task_traits.h" #import "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_client.h" #import "ios/web/public/web_state.h" @@ -33,7 +32,6 @@ UIView* baseView; CGRect snapshotFrameInBaseView; CGRect snapshotFrameInWindow; - NSArray<UIView*>* overlays; }; // Returns YES if `view` or any view it contains is a WKWebView. @@ -109,7 +107,8 @@ __weak SnapshotGenerator* weakSelf = self; void (^wrappedCallback)(UIImage*) = ^(UIImage* image) { if (!image) { - image = [weakSelf updateSnapshot]; + image = [weakSelf generateUIViewSnapshotWithOverlays]; + [weakSelf updateSnapshotStorageWithImage:image]; if (image) { image = GreyImage(image); } @@ -117,48 +116,41 @@ callback(image); }; - SnapshotStorage* snapshotStorage = _snapshotStorage; - if (snapshotStorage) { - [snapshotStorage retrieveGreyImageForSnapshotID:_snapshotID - callback:wrappedCallback]; + if (_snapshotStorage) { + [_snapshotStorage retrieveGreyImageForSnapshotID:_snapshotID + callback:wrappedCallback]; } else { wrappedCallback(nil); } } -- (UIImage*)updateSnapshot { - UIImage* snapshot = [self generateSnapshotWithOverlays:YES]; - [self updateSnapshotStorageWithImage:snapshot]; - return snapshot; -} - -- (void)updateWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion { +- (void)updateWKWebViewSnapshotWithCompletion:(void (^)(UIImage*))completion { DCHECK( !web::GetWebClient()->IsAppSpecificURL(_webState->GetLastCommittedURL())); if (![self canTakeSnapshot]) { if (completion) { - web::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(^{ - completion(nil); - })); + // Post a task to the current thread (UI thread). + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, base::BindOnce(completion, nil)); } return; } + [_delegate snapshotGenerator:self willUpdateSnapshotForWebState:_webState]; + SnapshotInfo snapshotInfo = [self snapshotInfo]; CGRect snapshotFrameInWebView = [_webState->GetView() convertRect:snapshotInfo.snapshotFrameInBaseView fromView:snapshotInfo.baseView]; - [_delegate snapshotGenerator:self willUpdateSnapshotForWebState:_webState]; __weak SnapshotGenerator* weakSelf = self; _webState->TakeSnapshot( gfx::RectF(snapshotFrameInWebView), base::BindRepeating(^(const gfx::Image& image) { UIImage* snapshot = nil; if (!image.IsEmpty()) { - snapshot = [weakSelf - snapshotWithOverlays:snapshotInfo.overlays - baseImage:image.ToUIImage() - frameInWindow:snapshotInfo.snapshotFrameInWindow]; + snapshot = [weakSelf addOverlays:[weakSelf overlays] + baseImage:image.ToUIImage() + frameInWindow:snapshotInfo.snapshotFrameInWindow]; } [weakSelf updateSnapshotStorageWithImage:snapshot]; if (completion) { @@ -167,19 +159,31 @@ })); } -- (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay { +- (void)updateUIViewSnapshotWithCompletion:(void (^)(UIImage*))completion { + UIImage* snapshot = [self generateUIViewSnapshotWithOverlays]; + [self updateSnapshotStorageWithImage:snapshot]; + // Post a task to the current thread (UI thread). + if (completion) { + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, base::BindOnce(completion, snapshot)); + } +} + +- (UIImage*)generateUIViewSnapshot { if (![self canTakeSnapshot]) { return nil; } - SnapshotInfo snapshotInfo = [self snapshotInfo]; [_delegate snapshotGenerator:self willUpdateSnapshotForWebState:_webState]; - UIImage* baseImage = - [self snapshotBaseView:snapshotInfo.baseView - frameInBaseView:snapshotInfo.snapshotFrameInBaseView]; - return [self - snapshotWithOverlays:(shouldAddOverlay ? snapshotInfo.overlays : nil) - baseImage:baseImage - frameInWindow:snapshotInfo.snapshotFrameInWindow]; + + SnapshotInfo snapshotInfo = [self snapshotInfo]; + // Ideally, generate an UIImage by one step with `UIGraphicsImageRenderer`, + // however, it generates a black image when the size of `baseView` is larger + // than `frameInBaseView`. So this is a workaround to generate an UIImage by + // dividing the step into 2 steps; 1) convert an UIView to an UIImage 2) crop + // an UIImage with `frameInBaseView`. + UIImage* baseImage = [self convertFromBaseView:snapshotInfo.baseView]; + return [self cropImage:baseImage + frameInBaseView:snapshotInfo.snapshotFrameInBaseView]; } - (void)willBeSavedGreyWhenBackgrounding { @@ -213,18 +217,27 @@ canTakeSnapshotForWebState:_webState]; } -// Returns a snapshot of `baseView` with `frameInBaseView`. -- (UIImage*)snapshotBaseView:(UIView*)baseView - frameInBaseView:(CGRect)frameInBaseView { - DCHECK(baseView); - DCHECK(!CGRectIsEmpty(frameInBaseView)); - // Ideally, generate an UIImage by one step with `UIGraphicsImageRenderer`, - // however, it generates a black image when the size of `baseView` is larger - // than `frameInBaseView`. So this is a workaround to generate an UIImage by - // dividing the step into 2 steps; 1) convert an UIView to an UIImage 2) crop - // an UIImage with `frameInBaseView`. - UIImage* baseImage = [self convertFromBaseView:baseView]; - return [self cropImage:baseImage frameInBaseView:frameInBaseView]; +// Updates the snapshot storage with `snapshot`. +- (void)updateSnapshotStorageWithImage:(UIImage*)snapshot { + if (snapshot) { + [_snapshotStorage setImage:snapshot withSnapshotID:_snapshotID]; + } else { + // Remove any stale snapshot since the snapshot failed. + [_snapshotStorage removeImageWithSnapshotID:_snapshotID]; + } +} + +// Generates and returns a new snapshot image with UIKit-based snapshot API. The +// generated image includes overlays (e.g., infobars, the download manager, and +// sad tab view). This does not update the snapshot storage. +- (UIImage*)generateUIViewSnapshotWithOverlays { + if (![self canTakeSnapshot]) { + return nil; + } + SnapshotInfo snapshotInfo = [self snapshotInfo]; + return [self addOverlays:[self overlays] + baseImage:[self generateUIViewSnapshot] + frameInWindow:snapshotInfo.snapshotFrameInWindow]; } // Converts an UIView to an UIImage. The size of generated UIImage is the same @@ -326,9 +339,9 @@ // Returns an image of the `baseImage` overlaid with `overlays` with the given // `frameInWindow`. -- (UIImage*)snapshotWithOverlays:(NSArray<UIView*>*)overlays - baseImage:(UIImage*)baseImage - frameInWindow:(CGRect)frameInWindow { +- (UIImage*)addOverlays:(NSArray<UIView*>*)overlays + baseImage:(UIImage*)baseImage + frameInWindow:(CGRect)frameInWindow { DCHECK(!CGRectIsEmpty(frameInWindow)); if (!baseImage) { return nil; @@ -370,16 +383,6 @@ }]; } -// Updates the snapshot storage with `snapshot`. -- (void)updateSnapshotStorageWithImage:(UIImage*)snapshot { - if (snapshot) { - [_snapshotStorage setImage:snapshot withSnapshotID:_snapshotID]; - } else { - // Remove any stale snapshot since the snapshot failed. - [_snapshotStorage removeImageWithSnapshotID:_snapshotID]; - } -} - // Draws `overlays` onto `context` at offsets relative to the window. - (void)drawOverlays:(NSArray<UIView*>*)overlays context:(CGContext*)context { for (UIView* overlay in overlays) { @@ -394,23 +397,29 @@ } } +// Retrieves the overlays laid down on the WebState. +- (NSArray<UIView*>*)overlays { + return [_delegate snapshotGenerator:self + snapshotOverlaysForWebState:_webState]; +} + // Retrieves information needed for snapshotting. - (SnapshotInfo)snapshotInfo { SnapshotInfo snapshotInfo; snapshotInfo.baseView = [_delegate snapshotGenerator:self baseViewForWebState:_webState]; DCHECK(snapshotInfo.baseView); + UIEdgeInsets baseViewInsets = [_delegate snapshotGenerator:self snapshotEdgeInsetsForWebState:_webState]; snapshotInfo.snapshotFrameInBaseView = UIEdgeInsetsInsetRect(snapshotInfo.baseView.bounds, baseViewInsets); DCHECK(!CGRectIsEmpty(snapshotInfo.snapshotFrameInBaseView)); + snapshotInfo.snapshotFrameInWindow = [snapshotInfo.baseView convertRect:snapshotInfo.snapshotFrameInBaseView toView:nil]; DCHECK(!CGRectIsEmpty(snapshotInfo.snapshotFrameInWindow)); - snapshotInfo.overlays = [_delegate snapshotGenerator:self - snapshotOverlaysForWebState:_webState]; return snapshotInfo; }
diff --git a/ios/chrome/browser/snapshots/model/snapshot_tab_helper.mm b/ios/chrome/browser/snapshots/model/snapshot_tab_helper.mm index 244fcec..81659a6 100644 --- a/ios/chrome/browser/snapshots/model/snapshot_tab_helper.mm +++ b/ios/chrome/browser/snapshots/model/snapshot_tab_helper.mm
@@ -10,7 +10,6 @@ #import "base/task/sequenced_task_runner.h" #import "ios/chrome/browser/snapshots/model/snapshot_generator.h" #import "ios/chrome/browser/snapshots/model/snapshot_storage.h" -#import "ios/web/public/thread/web_task_traits.h" #import "ios/web/public/web_client.h" #import "ios/web/public/web_state.h" @@ -70,21 +69,16 @@ if (!showing_native_content && web_state_->CanTakeSnapshot()) { // Take the snapshot using the optimized WKWebView snapshotting API for // pages loaded in the web view when the WebState snapshot API is available. - [snapshot_generator_ updateWebViewSnapshotWithCompletion:callback]; + [snapshot_generator_ updateWKWebViewSnapshotWithCompletion:callback]; return; } // Use the UIKit-based snapshot API as a fallback when the WKWebView API is // unavailable. - UIImage* image = [snapshot_generator_ updateSnapshot]; - dispatch_async(dispatch_get_main_queue(), ^{ - if (callback) { - callback(image); - } - }); + [snapshot_generator_ updateUIViewSnapshotWithCompletion:callback]; } UIImage* SnapshotTabHelper::GenerateSnapshotWithoutOverlays() { - return [snapshot_generator_ generateSnapshotWithOverlays:NO]; + return [snapshot_generator_ generateUIViewSnapshot]; } void SnapshotTabHelper::RemoveSnapshot() {
diff --git a/ios/chrome/browser/supervised_user/model/BUILD.gn b/ios/chrome/browser/supervised_user/model/BUILD.gn index e66bc7f..1c809ea 100644 --- a/ios/chrome/browser/supervised_user/model/BUILD.gn +++ b/ios/chrome/browser/supervised_user/model/BUILD.gn
@@ -34,6 +34,7 @@ "//components/security_interstitials/core", "//components/supervised_user/core/browser", "//components/supervised_user/core/browser:list_family_members_service", + "//components/supervised_user/core/browser:supervised_user_preferences", "//components/supervised_user/core/common", "//components/variations/service", "//ios/chrome/browser/first_run/model",
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper.mm b/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper.mm index f0f2ba9..bc28387e 100644 --- a/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper.mm +++ b/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper.mm
@@ -10,6 +10,7 @@ #import "components/prefs/pref_service.h" #import "components/supervised_user/core/browser/kids_chrome_management_client.h" #import "components/supervised_user/core/browser/supervised_user_interstitial.h" +#import "components/supervised_user/core/browser/supervised_user_preferences.h" #import "components/supervised_user/core/browser/supervised_user_service.h" #import "components/supervised_user/core/browser/supervised_user_url_filter.h" #import "components/supervised_user/core/common/features.h" @@ -84,14 +85,15 @@ return; } - supervised_user::SupervisedUserService* supervised_user_service = - SupervisedUserServiceFactory::GetForBrowserState(chrome_browser_state); - - if (!supervised_user_service->IsURLFilteringEnabled()) { + if (!supervised_user::IsUrlFilteringEnabled( + *chrome_browser_state->GetPrefs())) { std::move(callback).Run(PolicyDecision::Allow()); return; } + supervised_user::SupervisedUserService* supervised_user_service = + SupervisedUserServiceFactory::GetForBrowserState(chrome_browser_state); + // Set up the callback taking filtering results, and perform URL filtering. GURL request_url = net::GURLWithNSURL(request.URL); supervised_user::SupervisedUserURLFilter::FilteringBehaviorCallback
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn index 0554670..1e241ae 100644 --- a/ios/chrome/browser/tabs/model/BUILD.gn +++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -78,7 +78,7 @@ "//ios/chrome/browser/infobars/overlays", "//ios/chrome/browser/itunes_urls/model", "//ios/chrome/browser/language/model", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/link_to_text/model", "//ios/chrome/browser/main", "//ios/chrome/browser/metrics",
diff --git a/ios/chrome/browser/tabs/model/tab_helper_util.mm b/ios/chrome/browser/tabs/model/tab_helper_util.mm index 72835eb3..eebb844 100644 --- a/ios/chrome/browser/tabs/model/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/model/tab_helper_util.mm
@@ -54,7 +54,7 @@ #import "ios/chrome/browser/infobars/overlays/infobar_overlay_tab_helper.h" #import "ios/chrome/browser/infobars/overlays/translate_overlay_tab_helper.h" #import "ios/chrome/browser/itunes_urls/model/itunes_urls_handler_tab_helper.h" -#import "ios/chrome/browser/lens/lens_tab_helper.h" +#import "ios/chrome/browser/lens/model/lens_tab_helper.h" #import "ios/chrome/browser/link_to_text/model/link_to_text_tab_helper.h" #import "ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index b3fc6ac..aee164b 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -455,14 +455,10 @@ void ChromeAutofillClientIOS::OfferPlusAddressCreation( const url::Origin& main_frame_origin, plus_addresses::PlusAddressCallback callback) { - plus_addresses::PlusAddressService* service = GetPlusAddressService(); - // This code path should have set up the service. If not, something is badly - // wrong, so bail out. - CHECK(service); - // TODO(crbug.com/1467623): Run UI orchestration here rather than filling - // directly in response to the eventual service call. This will eventually - // trigger a bottom sheet. - service->OfferPlusAddressCreation(main_frame_origin, std::move(callback)); + AutofillBottomSheetTabHelper* bottomSheetTabHelper = + AutofillBottomSheetTabHelper::FromWebState(web_state_); + bottomSheetTabHelper->ShowPlusAddressesBottomSheet(main_frame_origin, + std::move(callback)); } void ChromeAutofillClientIOS::UpdateAutofillPopupDataListValues(
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn index 9053712..9c78642 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -247,7 +247,9 @@ "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", "//ios/chrome/browser/ui/autofill:eg_test_support+eg2", "//ios/chrome/browser/ui/settings/google_services:constants", + "//ios/chrome/browser/ui/settings/password:eg_test_support", "//ios/chrome/browser/ui/settings/password:eg_test_support+eg2", + "//ios/chrome/browser/ui/settings/password:features", "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/test:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_all_password_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_all_password_coordinator.mm index d5c794f1..88e6821 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_all_password_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_all_password_coordinator.mm
@@ -158,6 +158,13 @@ // No-op. } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + [self.manualFillAllPasswordCoordinatorDelegate + manualFillAllPasswordCoordinatorWantsToBeDismissed:self]; +} + - (void)willPushReauthenticationViewController { // No-op. }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm index 6f3a7f03..8b2c3250b 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -15,6 +15,8 @@ #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" #import "ios/chrome/browser/ui/autofill/autofill_app_interface.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h" +#import "ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h" +#import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h" #import "ios/chrome/browser/ui/settings/password/password_settings_app_interface.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" #import "ios/chrome/grit/ios_strings.h" @@ -89,6 +91,43 @@ grey_interactable(), nullptr); } +// Validates that the Password Manager UI opened from the manual fallback UI is +// dismissed when local authentication fails. +// - manual_fallback_action_matcher: Matcher for the action button opening the +// Password Manager UI (e.g. "Manage Passwords..." button). +void CheckPasswordManagerUIDismissesAfterFailedAuthentication( + id<GREYMatcher> manual_fallback_action_matcher) { + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:TapWebElementWithId(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + performAction:grey_tap()]; + + // // Simulate failed authentication. + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kFailure]; + [PasswordSettingsAppInterface + mockReauthenticationModuleShouldReturnSynchronously:NO]; + + // Tap the action in the manual fallback UI. + [[EarlGrey selectElementWithMatcher:manual_fallback_action_matcher] + performAction:grey_tap()]; + + // Validate reauth UI is visible until auth result is delivered. + [[EarlGrey selectElementWithMatcher:password_manager_test_utils:: + ReauthenticationController()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Deliver authentication result should dismiss the UI. + [PasswordSettingsAppInterface mockReauthenticationModuleReturnMockedResult]; + + // Verify that the whole navigation stack is gone. + [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsNavigationBar()] + assertWithMatcher:grey_nil()]; +} + } // namespace // Integration Tests for Mannual Fallback Passwords View Controller. @@ -140,6 +179,9 @@ syncer::kReplaceSyncPromosWithSignInPromos); } + config.features_enabled.push_back( + password_manager::features::kIOSPasswordAuthOnEntryV2); + return config; } @@ -184,7 +226,7 @@ } // Tests that the "Manage Passwords..." action works. -- (void)testManagePasswordsActionOpensPasswordSettings { +- (void)testManagePasswordsActionOpensPasswordManager { // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:TapWebElementWithId(kFormElementUsername)]; @@ -205,6 +247,13 @@ assertWithMatcher:grey_minimumVisiblePercent(0.7)]; } +// Tests that the Password Manager is dismissed when local authentication fails +// after tapping "Manage Passwords...". +- (void)testManagePasswordsActionWithFailedAuthDismissesPasswordManager { + CheckPasswordManagerUIDismissesAfterFailedAuthentication( + ManualFallbackManagePasswordsMatcher()); +} + // Tests that the "Manage Settings..." action works. - (void)testManageSettingsActionOpensPasswordSettings { // Bring up the keyboard. @@ -226,6 +275,13 @@ assertWithMatcher:grey_minimumVisiblePercent(0.7)]; } +// Tests that Password Settings is dismissed when local authentication fails +// after tapping "Manage Passwords...". +- (void)testManageSettingsActionWithFailedAuthDismissesPasswordSettings { + CheckPasswordManagerUIDismissesAfterFailedAuthentication( + ManualFallbackManageSettingsMatcher()); +} + // Tests that the "Manage Passwords..." action works in incognito mode. - (void)testManagePasswordsActionOpensPasswordSettingsInIncognito { // Open a tab in incognito. @@ -378,6 +434,61 @@ assertWithMatcher:grey_nil()]; } +// Tests that the "Use Other Password..." UI is dismissed after failed local +// authentication. +- (void)testUseOtherPasswordUIDismissedAfterFailedAuth { + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:TapWebElementWithId(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:ManualFallbackPasswordIconMatcher()] + performAction:grey_tap()]; + + // Tap the "Manage Passwords..." action. + [[EarlGrey selectElementWithMatcher:ManualFallbackOtherPasswordsMatcher()] + performAction:grey_tap()]; + + std::u16string origin = base::ASCIIToUTF16( + password_manager::GetShownOrigin(url::Origin::Create(self.URL))); + + NSString* message = l10n_util::GetNSStringF( + IDS_IOS_MANUAL_FALLBACK_SELECT_PASSWORD_DIALOG_MESSAGE, origin); + + [[EarlGrey selectElementWithMatcher:grey_text(message)] + assertWithMatcher:grey_notNil()]; + + // Setup failed authentication. + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kFailure]; + [PasswordSettingsAppInterface + mockReauthenticationModuleShouldReturnSynchronously:NO]; + + // Acknowledge concerns using other passwords on a website. + [[EarlGrey selectElementWithMatcher:ConfirmUsingOtherPasswordButton()] + performAction:grey_tap()]; + + // Validate reauth UI is visible until auth result is delivered. + [[EarlGrey selectElementWithMatcher:password_manager_test_utils:: + ReauthenticationController()] + assertWithMatcher:grey_sufficientlyVisible()]; + // Passwords UI shouldn't be visible. + [[EarlGrey + selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] + assertWithMatcher:grey_notVisible()]; + + // Deliver authentication result should dismiss the UI. + [PasswordSettingsAppInterface mockReauthenticationModuleReturnMockedResult]; + + // Verify that the whole navigation stack is gone. + [[EarlGrey selectElementWithMatcher:password_manager_test_utils:: + ReauthenticationController()] + assertWithMatcher:grey_nil()]; + [[EarlGrey + selectElementWithMatcher:ManualFallbackOtherPasswordsDismissMatcher()] + assertWithMatcher:grey_nil()]; +} + // Tests that returning from "Use Other Password..." leaves the view and icons // in the right state. - (void)testPasswordsStateAfterPresentingUseOtherPassword {
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index 3d40645..3b564dc 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -72,7 +72,7 @@ "//ios/chrome/browser/intents:intents_donation_helper", "//ios/chrome/browser/itunes_urls/model", "//ios/chrome/browser/language/model", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/link_to_text/model", "//ios/chrome/browser/main", "//ios/chrome/browser/metrics:metrics_browser_agent", @@ -89,6 +89,8 @@ "//ios/chrome/browser/parcel_tracking:tracking_source", "//ios/chrome/browser/parcel_tracking:util", "//ios/chrome/browser/passwords/model", + "//ios/chrome/browser/plus_addresses/coordinator", + "//ios/chrome/browser/plus_addresses/ui", "//ios/chrome/browser/policy:policy_util", "//ios/chrome/browser/prefs/model", "//ios/chrome/browser/prerender/model", @@ -299,7 +301,7 @@ "//ios/chrome/browser/find_in_page/model", "//ios/chrome/browser/find_in_page/model:util", "//ios/chrome/browser/history", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/metrics:metrics_browser_agent", "//ios/chrome/browser/ntp", "//ios/chrome/browser/policy:policy_util",
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index 8b3905d..e04a153 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -54,6 +54,7 @@ #import "ios/chrome/browser/parcel_tracking/parcel_tracking_util.h" #import "ios/chrome/browser/parcel_tracking/tracking_source.h" #import "ios/chrome/browser/passwords/model/password_controller_delegate.h" +#import "ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h" #import "ios/chrome/browser/prerender/model/preload_controller_delegate.h" #import "ios/chrome/browser/prerender/model/prerender_service.h" #import "ios/chrome/browser/prerender/model/prerender_service_factory.h" @@ -341,6 +342,9 @@ @property(nonatomic, strong) PaymentsSuggestionBottomSheetCoordinator* paymentsSuggestionBottomSheetCoordinator; +@property(nonatomic, strong) + PlusAddressBottomSheetCoordinator* plusAddressBottomSheetCoordinator; + // Coordinator for the choice screen. @property(nonatomic, strong) ChromeCoordinator* choiceCoordinator; @@ -670,6 +674,9 @@ [self.paymentsSuggestionBottomSheetCoordinator stop]; self.paymentsSuggestionBottomSheetCoordinator = nil; + [self.plusAddressBottomSheetCoordinator stop]; + self.plusAddressBottomSheetCoordinator = nil; + [_sendTabToSelfCoordinator stop]; _sendTabToSelfCoordinator = nil; @@ -732,6 +739,13 @@ self.storeKitCoordinator = nil; } +// Stops the coordinator for password manager settings. +- (void)stopPasswordSettingsCoordinator { + [self.passwordSettingsCoordinator stop]; + self.passwordSettingsCoordinator.delegate = nil; + self.passwordSettingsCoordinator = nil; +} + - (void)setWebUsageEnabled:(BOOL)webUsageEnabled { if (!self.browser->GetBrowserState() || !self.started) { return; @@ -1294,6 +1308,9 @@ [self.paymentsSuggestionBottomSheetCoordinator stop]; self.paymentsSuggestionBottomSheetCoordinator = nil; + [self.plusAddressBottomSheetCoordinator stop]; + self.plusAddressBottomSheetCoordinator = nil; + [self.printCoordinator stop]; self.printCoordinator = nil; @@ -1539,6 +1556,14 @@ [self.passwordSuggestionBottomSheetCoordinator start]; } +- (void)showPlusAddressesBottomSheet { + self.plusAddressBottomSheetCoordinator = + [[PlusAddressBottomSheetCoordinator alloc] + initWithBaseViewController:self.viewController + browser:self.browser]; + [self.plusAddressBottomSheetCoordinator start]; +} + - (void)showPaymentsBottomSheet:(const autofill::FormActivityParams&)params { if (self.paymentsSuggestionBottomSheetCoordinator) { return; @@ -1775,6 +1800,11 @@ self.paymentsSuggestionBottomSheetCoordinator = nil; } +- (void)dismissPlusAddressBottomSheet { + [self.plusAddressBottomSheetCoordinator stop]; + self.plusAddressBottomSheetCoordinator = nil; +} + - (void)showChoice { if (!ios::provider::IsChoiceEnabled()) { return; @@ -2944,9 +2974,14 @@ - (void)passwordSettingsCoordinatorDidRemove: (PasswordSettingsCoordinator*)coordinator { DCHECK_EQ(self.passwordSettingsCoordinator, coordinator); - [self.passwordSettingsCoordinator stop]; - self.passwordSettingsCoordinator.delegate = nil; - self.passwordSettingsCoordinator = nil; + + [self stopPasswordSettingsCoordinator]; +} + +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [self stopPasswordSettingsCoordinator]; } #pragma mark - ReadingListCoordinatorDelegate
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm index b4fa21c..f6d1909a 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
@@ -13,7 +13,7 @@ #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h" #import "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/history/history_service_factory.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/prerender/model/prerender_service_factory.h" #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm index 5a01d76..939b587 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -23,7 +23,7 @@ #import "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h" #import "ios/chrome/browser/history/history_service_factory.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm b/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm index 5374015..debeebf 100644 --- a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
@@ -16,7 +16,7 @@ #import "ios/chrome/browser/find_in_page/model/find_tab_helper.h" #import "ios/chrome/browser/find_in_page/model/java_script_find_tab_helper.h" #import "ios/chrome/browser/find_in_page/model/util.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h" #import "ios/chrome/browser/policy/policy_util.h"
diff --git a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm b/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm index 8468609..788a26c 100644 --- a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm +++ b/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm
@@ -14,7 +14,7 @@ #import "ios/chrome/browser/follow/follow_iph_presenter.h" #import "ios/chrome/browser/follow/follow_tab_helper.h" #import "ios/chrome/browser/itunes_urls/model/itunes_urls_handler_tab_helper.h" -#import "ios/chrome/browser/lens/lens_tab_helper.h" +#import "ios/chrome/browser/lens/model/lens_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/overscroll_actions/model/overscroll_actions_tab_helper.h" #import "ios/chrome/browser/parcel_tracking/parcel_tracking_prefs.h"
diff --git a/ios/chrome/browser/ui/bubble/side_swipe_bubble/side_swipe_bubble_view.mm b/ios/chrome/browser/ui/bubble/side_swipe_bubble/side_swipe_bubble_view.mm index d81e73bc..6da43f2 100644 --- a/ios/chrome/browser/ui/bubble/side_swipe_bubble/side_swipe_bubble_view.mm +++ b/ios/chrome/browser/ui/bubble/side_swipe_bubble/side_swipe_bubble_view.mm
@@ -33,9 +33,13 @@ const CGFloat kFadingGestureIndicatorRadius = 46.0f; // Initial distance between the bubble and the center of the gesture indicator // ellipsis. -const CGFloat kInitialGestureIndicatorToBubbleSpacing = 62.0f; +const CGFloat kInitialGestureIndicatorToBubbleSpacingDefault = 62.0f; +const CGFloat + kInitialGestureIndicatorToBubbleSpacingVerticalSwipeInCompactHeight = 52.0f; // The distance that the gesture indicator should move during the animation. -const CGFloat kGestureIndicatorDistanceAnimated = 140.0f; +const CGFloat kGestureIndicatorDistanceAnimatedDefault = 140.0f; +const CGFloat kGestureIndicatorDistanceAnimatedVerticalSwipeInCompactHeight = + 80.0f; // The distance between the dismiss button and the bottom edge (or the top edge, // when the bubble points down.) @@ -63,7 +67,7 @@ // indicator should offset on iPhone portrait mode and iPad split screen. In // both cases, the horizontal size class is compact while the vertical size // class is regular. -BOOL GestureIndicatorShouldOffsetFromCenter( +BOOL ShouldGestureIndicatorOffsetFromCenter( UITraitCollection* trait_collection) { return trait_collection.horizontalSizeClass == UIUserInterfaceSizeClassCompact && @@ -250,10 +254,46 @@ return self; } +- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize { + // Computes the smallest possible size that would fit all the UI elements in + // all their animated positions. + CGFloat min_width = _bubbleView.frame.size.width; + CGFloat min_height = _bubbleView.frame.size.height + + [_dismissButton intrinsicContentSize].height + + kDismissButtonMargin; + if (UIAccessibilityIsReduceMotionEnabled()) { + return CGSizeMake(min_width, min_height); + } + switch (_bubbleView.direction) { + case BubbleArrowDirectionUp: + case BubbleArrowDirectionDown: + min_height += kInitialBubbleDistanceToEdgeSpacingVertical + + [self initialGestureIndicatorToBubbleSpacing] + + [self gestureIndicatorAnimatedDistance] + + kFadingGestureIndicatorRadius; + min_width = MAX(min_width, kFadingGestureIndicatorRadius * 2); + break; + case BubbleArrowDirectionLeading: + case BubbleArrowDirectionTrailing: + if (ShouldGestureIndicatorOffsetFromCenter(self.traitCollection)) { + min_width /= 2; + } else { + min_width += [self initialGestureIndicatorToBubbleSpacing]; + } + min_width += [self gestureIndicatorAnimatedDistance] + + kFadingGestureIndicatorRadius; + min_height = MAX(min_height, kFadingGestureIndicatorRadius * 2); + break; + } + // This view can expand as large as needed. + return CGSizeMake(MAX(min_width, targetSize.width), + MAX(min_height, targetSize.height)); +} + - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { [super traitCollectionDidChange:previousTraitCollection]; - if (GestureIndicatorShouldOffsetFromCenter(previousTraitCollection) != - GestureIndicatorShouldOffsetFromCenter(self.traitCollection)) { + if (ShouldGestureIndicatorOffsetFromCenter(previousTraitCollection) != + ShouldGestureIndicatorOffsetFromCenter(self.traitCollection)) { [_animator pauseAnimation]; _needsRepositionBubbleAndGestureIndicator = YES; } @@ -277,6 +317,7 @@ } - (void)startAnimationAfterDelay:(base::TimeDelta)delay { + CHECK(self.superview); __weak SideSwipeBubbleView* weakSelf = self; if (UIAccessibilityIsReduceMotionEnabled()) { @@ -326,6 +367,8 @@ options:UIViewKeyframeAnimationOptionLayoutSubviews animations:keyframes completion:^(BOOL completed) { + // This block gets invoked earlier than the + // completion block of `_animator`. if (completed) { [weakSelf onAnimationCycleComplete]; } @@ -367,8 +410,34 @@ #pragma mark - Initial positioning helpers +// Initial distance between the bubble and the center of the gesture indicator +// ellipsis. +- (CGFloat)initialGestureIndicatorToBubbleSpacing { + BOOL verticalSwipeInCompactHeight = + self.traitCollection.verticalSizeClass == + UIUserInterfaceSizeClassCompact && + (_bubbleView.direction == BubbleArrowDirectionUp || + _bubbleView.direction == BubbleArrowDirectionDown); + return verticalSwipeInCompactHeight + ? kInitialGestureIndicatorToBubbleSpacingVerticalSwipeInCompactHeight + : kInitialGestureIndicatorToBubbleSpacingDefault; +} + +// Animated distance of the gesture indicator. +- (CGFloat)gestureIndicatorAnimatedDistance { + BOOL verticalSwipeInCompactHeight = + self.traitCollection.verticalSizeClass == + UIUserInterfaceSizeClassCompact && + (_bubbleView.direction == BubbleArrowDirectionUp || + _bubbleView.direction == BubbleArrowDirectionDown); + return verticalSwipeInCompactHeight + ? kGestureIndicatorDistanceAnimatedVerticalSwipeInCompactHeight + : kGestureIndicatorDistanceAnimatedDefault; +} + // Puts the gesture indicator at its initial position. - (void)repositionGestureIndicator { + CHECK(self.superview); if (_gestureIndicatorMarginConstraint.active && _gestureIndicatorCenterConstraint.active) { [NSLayoutConstraint deactivateConstraints:@[ @@ -384,7 +453,7 @@ _gestureIndicatorMarginConstraint, _gestureIndicatorCenterConstraint, ]]; - [self layoutIfNeeded]; + [self.superview layoutIfNeeded]; } // Returns the desired value of `_gestureIndicatorMarginConstraint`. @@ -395,13 +464,14 @@ // animation would NOT be influenced by the bubble's movement. - (NSLayoutConstraint*)initialGestureIndicatorMarginConstraint { CGSize bubbleSize = _bubbleView.frame.size; + CGFloat gestureIndicatorToBubbleSpacing = + [self initialGestureIndicatorToBubbleSpacing]; switch (_bubbleView.direction) { case BubbleArrowDirectionUp: { // Gesture indicator should be `kInitialGestureIndicatorToBubbleSpacing` // away from the bubble's bottom edge. CGFloat margin = kInitialBubbleDistanceToEdgeSpacingVertical + - bubbleSize.height + - kInitialGestureIndicatorToBubbleSpacing; + bubbleSize.height + gestureIndicatorToBubbleSpacing; return [_gestureIndicator.centerYAnchor constraintEqualToAnchor:self.topAnchor constant:margin]; @@ -410,21 +480,20 @@ // Gesture indicator should be `kInitialGestureIndicatorToBubbleSpacing` // away from the bubble's top edge. CGFloat margin = kInitialBubbleDistanceToEdgeSpacingVertical + - bubbleSize.height + - kInitialGestureIndicatorToBubbleSpacing; + bubbleSize.height + gestureIndicatorToBubbleSpacing; return [_gestureIndicator.centerYAnchor constraintEqualToAnchor:self.bottomAnchor constant:-margin]; } case BubbleArrowDirectionLeading: { CGFloat margin; - if (GestureIndicatorShouldOffsetFromCenter(self.traitCollection)) { + if (ShouldGestureIndicatorOffsetFromCenter(self.traitCollection)) { // Gesture indicator should be center-aligned with the bubble. margin = bubbleSize.width / 2; } else { // Gesture indicator should be `kInitialGestureIndicatorToBubbleSpacing` // away from the bubble's trailing edge. - margin = bubbleSize.width + kInitialGestureIndicatorToBubbleSpacing; + margin = bubbleSize.width + gestureIndicatorToBubbleSpacing; } return [_gestureIndicator.centerXAnchor constraintEqualToAnchor:self.leadingAnchor @@ -432,13 +501,13 @@ } case BubbleArrowDirectionTrailing: { CGFloat margin; - if (GestureIndicatorShouldOffsetFromCenter(self.traitCollection)) { + if (ShouldGestureIndicatorOffsetFromCenter(self.traitCollection)) { // Gesture indicator should be center-aligned with the bubble. margin = bubbleSize.width / 2; } else { - // Gesture indicator should be `kInitialGestureIndicatorToBubbleSpacing` + // Gesture indicator should be `gestureIndicatorToBubbleSpacing` // away from the bubble's leading edge. - margin = bubbleSize.width + kInitialGestureIndicatorToBubbleSpacing; + margin = bubbleSize.width + gestureIndicatorToBubbleSpacing; } return [_gestureIndicator.centerXAnchor constraintEqualToAnchor:self.trailingAnchor @@ -458,11 +527,11 @@ break; case BubbleArrowDirectionLeading: case BubbleArrowDirectionTrailing: - CGFloat offset = kInitialGestureIndicatorToBubbleSpacing + + CGFloat offset = [self initialGestureIndicatorToBubbleSpacing] + _bubbleView.frame.size.height / 2; gestureIndicatorCenterConstraint = [_gestureIndicator.centerYAnchor constraintEqualToAnchor:self.centerYAnchor - constant:GestureIndicatorShouldOffsetFromCenter( + constant:ShouldGestureIndicatorOffsetFromCenter( self.traitCollection) ? offset : 0]; @@ -524,10 +593,12 @@ _bubbleView.frame = newFrame; [_bubbleView setArrowHidden:NO animated:YES]; + CGFloat gestureIndicatorAnimatedDistance = + [self gestureIndicatorAnimatedDistance]; CGFloat animateDistance = (direction == BubbleArrowDirectionUp || direction == BubbleArrowDirectionLeading) - ? kGestureIndicatorDistanceAnimated - : -kGestureIndicatorDistanceAnimated; + ? gestureIndicatorAnimatedDistance + : -gestureIndicatorAnimatedDistance; _gestureIndicatorMarginConstraint.constant += animateDistance; [self layoutIfNeeded]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/parcel_tracking_view.mm b/ios/chrome/browser/ui/content_suggestions/cells/parcel_tracking_view.mm index 8d8bf76..163a9d1 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/parcel_tracking_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/parcel_tracking_view.mm
@@ -28,13 +28,14 @@ // Icon container size. const CGFloat kIconContainerWidth = 72.0f; -// Margin between icon and its container. -const CGFloat kIconContainerMargin = 8.0f; +// Margin between icon and its container when using the default image. +const CGFloat kIconContainerMargin = 18.0f; -#if !BUILDFLAG(IOS_USE_BRANDED_SYMBOLS) +// Margin between icon and its container when using the carrier's logo. +const CGFloat kIconContainerMarginForCarrierLogo = 8.0f; + // Size of the icon. const CGFloat kIconSize = 53.0f; -#endif // Spacing between text StackView subviews. const CGFloat kTextStackViewSpacing = 5.0f; @@ -103,6 +104,7 @@ UILabel* _titleLabel; UILabel* _subtitleLabel; UITapGestureRecognizer* _tapGestureRecognizer; + BOOL _useCarrierLogo; } - (instancetype)initWithFrame:(CGRect)frame { @@ -152,6 +154,7 @@ self.traitCollection.userInterfaceStyle) { _imageContainer.layer.borderColor = [UIColor colorNamed:kGrey200Color].CGColor; + _imageContainer.layer.borderWidth = [self iconBorderWidth]; } if (previousTraitCollection.preferredContentSizeCategory != self.traitCollection.preferredContentSizeCategory) { @@ -214,14 +217,16 @@ _imageContainer = [[UIView alloc] init]; _imageContainer.layer.cornerRadius = kIconContainerCornerRadius; _imageContainer.layer.masksToBounds = YES; - _imageContainer.layer.borderWidth = 1; + _imageContainer.layer.borderWidth = [self iconBorderWidth]; _imageContainer.layer.borderColor = [UIColor colorNamed:kGrey200Color].CGColor; [_imageContainer addSubview:_iconImageView]; + CGFloat containerMargin = _useCarrierLogo ? kIconContainerMarginForCarrierLogo + : kIconContainerMargin; AddSameConstraintsWithInsets( _iconImageView, _imageContainer, - NSDirectionalEdgeInsetsMake(kIconContainerMargin, kIconContainerMargin, - kIconContainerMargin, kIconContainerMargin)); + NSDirectionalEdgeInsetsMake(containerMargin, containerMargin, + containerMargin, containerMargin)); UIStackView* horizontalStackView = [[UIStackView alloc] initWithArrangedSubviews:@[ _imageContainer, rightVerticalStackView ]]; @@ -259,6 +264,7 @@ // Returns the appropriate icon image for a `parcelType`. - (UIImage*)iconImageForParcelType:(ParcelType)parcelType { #if !BUILDFLAG(IOS_USE_BRANDED_SYMBOLS) + _useCarrierLogo = NO; if (@available(iOS 16.0, *)) { return DefaultSymbolWithPointSize(kBoxTruckFillSymbol, kIconSize); } else { @@ -266,14 +272,19 @@ } #else switch (parcelType) { - case ParcelType::kUSPS: - return [UIImage imageNamed:kUSPSCarrierImage]; case ParcelType::kUPS: + _useCarrierLogo = YES; return [UIImage imageNamed:kUPSCarrierImage]; case ParcelType::kFedex: + _useCarrierLogo = YES; return [UIImage imageNamed:kFedexCarrierImage]; default: - return nil; + _useCarrierLogo = NO; + if (@available(iOS 16.0, *)) { + return DefaultSymbolWithPointSize(kBoxTruckFillSymbol, kIconSize); + } else { + return DefaultSymbolWithPointSize(kShippingBoxFillSymbol, kIconSize); + } } #endif } @@ -285,6 +296,8 @@ NSString* dateString = base::SysUTF16ToNSString(base::LocalizedTimeFormatWithPattern( estimatedDeliveryTime, "EEEE MMMM d")); + NSString* imageColorName; + NSString* imageContainerColorName; // Configure the status bars (and title text color if needed) depending on // status. @@ -295,6 +308,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:YES]; [_thirdStatusBar configureAsError:NO lighterTone:YES]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; case ParcelState::kLabelCreated: _titleLabel.text = l10n_util::GetNSString( @@ -302,6 +317,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:YES]; [_thirdStatusBar configureAsError:NO lighterTone:YES]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; case ParcelState::kFinished: { // Use Today date descriptor if the delivery day matches the current day @@ -319,6 +336,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:NO]; [_thirdStatusBar configureAsError:NO lighterTone:NO]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; } case ParcelState::kAtPickupLocation: @@ -327,6 +346,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:NO]; [_thirdStatusBar configureAsError:NO lighterTone:NO]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; case ParcelState::kPickedUp: case ParcelState::kHandedOff: @@ -337,6 +358,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:NO]; [_thirdStatusBar configureAsError:NO lighterTone:YES]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; case ParcelState::kOutForDelivery: _titleLabel.text = l10n_util::GetNSStringF( @@ -346,6 +369,8 @@ [_firstStatusBar configureAsError:NO lighterTone:NO]; [_secondStatusBar configureAsError:NO lighterTone:NO]; [_thirdStatusBar configureAsError:NO lighterTone:YES]; + imageColorName = kGreen300Color; + imageContainerColorName = kGreen50Color; break; case ParcelState::kDeliveryFailed: _titleLabel.text = l10n_util::GetNSString( @@ -354,6 +379,8 @@ [_firstStatusBar configureAsError:YES lighterTone:NO]; [_secondStatusBar configureAsError:YES lighterTone:NO]; [_thirdStatusBar configureAsError:YES lighterTone:YES]; + imageColorName = kRed300Color; + imageContainerColorName = kRed50Color; break; case ParcelState::kError: _titleLabel.text = l10n_util::GetNSString( @@ -362,6 +389,8 @@ [_firstStatusBar configureAsError:YES lighterTone:NO]; [_secondStatusBar configureAsError:YES lighterTone:NO]; [_thirdStatusBar configureAsError:YES lighterTone:YES]; + imageColorName = kRed300Color; + imageContainerColorName = kRed50Color; break; case ParcelState::kCancelled: _titleLabel.text = l10n_util::GetNSString( @@ -371,6 +400,8 @@ [_firstStatusBar removeFromSuperview]; [_secondStatusBar removeFromSuperview]; [_thirdStatusBar removeFromSuperview]; + imageColorName = kGrey400Color; + imageContainerColorName = kGrey100Color; break; case ParcelState::kUndeliverable: _titleLabel.text = l10n_util::GetNSString( @@ -380,6 +411,8 @@ [_firstStatusBar removeFromSuperview]; [_secondStatusBar removeFromSuperview]; [_thirdStatusBar removeFromSuperview]; + imageColorName = kGrey400Color; + imageContainerColorName = kGrey100Color; break; case ParcelState::kReturnToSender: case ParcelState::kReturnCompleted: @@ -390,10 +423,18 @@ [_firstStatusBar removeFromSuperview]; [_secondStatusBar removeFromSuperview]; [_thirdStatusBar removeFromSuperview]; + imageColorName = kGrey400Color; + imageContainerColorName = kGrey100Color; break; default: break; } + + if (!_useCarrierLogo) { + _imageContainer.backgroundColor = + [UIColor colorNamed:imageContainerColorName]; + _iconImageView.tintColor = [UIColor colorNamed:imageColorName]; + } } - (void)handleTap:(UITapGestureRecognizer*)sender { @@ -402,4 +443,13 @@ } } +// Returns the icon container's border width. +- (CGFloat)iconBorderWidth { + if (!_useCarrierLogo && + self.traitCollection.userInterfaceStyle != UIUserInterfaceStyleDark) { + return 0; + } + return 1; +} + @end
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/safety_check/BUILD.gn index c9e7839..e4a0b712 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/BUILD.gn
@@ -85,6 +85,7 @@ "//ios/chrome/browser/ui/content_suggestions:constants", "//ios/chrome/browser/ui/settings/password:eg_test_support", "//ios/chrome/browser/ui/settings/password:eg_test_support+eg2", + "//ios/chrome/browser/ui/settings/password:features", "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm index 7fbb4c3..2590ed6 100644 --- a/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_view_egtest.mm
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_prefs.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_constants.h" #import "ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h" +#import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h" #import "ios/chrome/browser/ui/settings/password/password_settings_app_interface.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" @@ -54,30 +55,35 @@ @implementation SafetyCheckViewCase -- (AppLaunchConfiguration)appConfigurationForTestCase { - AppLaunchConfiguration config; - - config.additional_args.push_back( - "--enable-features=" + std::string(kMagicStack.name) + "," + - std::string(kSafetyCheckMagicStack.name)); - - return config; -} - - (void)setUp { [super setUp]; + // Mock local authentication for opening Password Checkup. + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kSuccess]; [ChromeEarlGrey resetDataForLocalStatePref: safety_check_prefs::kSafetyCheckInMagicStackDisabledPref]; } - (void)tearDown { + [PasswordSettingsAppInterface removeMockReauthenticationModule]; [ChromeEarlGrey resetDataForLocalStatePref: safety_check_prefs::kSafetyCheckInMagicStackDisabledPref]; - [super tearDown]; } +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + + config.features_enabled.push_back(kMagicStack); + config.features_enabled.push_back(kSafetyCheckMagicStack); + config.features_enabled.push_back( + password_manager::features::kIOSPasswordAuthOnEntryV2); + + return config; +} + // Tests that long pressing the Safety Check view displays a context menu; tests // the Safety Check view is properly hidden via the context menu. - (void)testLongPressAndHide { @@ -152,4 +158,67 @@ assertWithMatcher:grey_nil()]; } +// Tests that the Password Checkup view is dismissed when the user doesn't pass +// Local Authentication. +- (void)testPasswordCheckupDismissedAfterFailedAuthentication { + password_manager_test_utils::SavePasswordForm(); + + [[[EarlGrey + selectElementWithMatcher:grey_allOf(grey_accessibilityID( + safety_check::kSafetyCheckViewID), + grey_sufficientlyVisible(), nil)] + usingSearchAction:grey_scrollInDirection(kGREYDirectionRight, 350) + onElementWithMatcher:grey_accessibilityID( + kMagicStackScrollViewAccessibilityIdentifier)] + performAction:grey_tap()]; + + ConditionBlock condition = ^{ + NSError* error = nil; + [[EarlGrey + selectElementWithMatcher:grey_text(l10n_util::GetNSString( + IDS_IOS_CHECK_PASSWORDS_NOW_BUTTON))] + assertWithMatcher:grey_sufficientlyVisible() + error:&error]; + return error == nil; + }; + + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(base::Seconds(10), + condition), + @"Timeout waiting for the Safety Check to complete its run."); + + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kFailure]; + // Delay the auth result to be able to validate that the passwords are not + // visible until the result is emitted. + [PasswordSettingsAppInterface + mockReauthenticationModuleShouldReturnSynchronously:NO]; + + [[EarlGrey selectElementWithMatcher: + grey_text(l10n_util::GetNSString( + IDS_IOS_SETTINGS_SAFETY_CHECK_PASSWORDS_TITLE))] + performAction:grey_tap()]; + + // Verify that the Password Checkup Homepage is not displayed. + [[EarlGrey + selectElementWithMatcher: + grey_accessibilityID(password_manager::kPasswordCheckupTableViewId)] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey selectElementWithMatcher:password_manager_test_utils:: + ReauthenticationController()] + assertWithMatcher:grey_sufficientlyVisible()]; + + [PasswordSettingsAppInterface mockReauthenticationModuleReturnMockedResult]; + + // Password Checkup and reauthentication UI should be gone, leaving Safety + // Check visible. + [[EarlGrey + selectElementWithMatcher: + grey_accessibilityID(password_manager::kPasswordCheckupTableViewId)] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey + selectElementWithMatcher:chrome_test_util::SafetyCheckTableViewMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + ; +} + @end
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/notifications_promo_view_constants.h b/ios/chrome/browser/ui/ntp/feed_top_section/notifications_promo_view_constants.h index 71461dc..a66a9077 100644 --- a/ios/chrome/browser/ui/ntp/feed_top_section/notifications_promo_view_constants.h +++ b/ios/chrome/browser/ui/ntp/feed_top_section/notifications_promo_view_constants.h
@@ -7,6 +7,12 @@ #import <Foundation/Foundation.h> +typedef NS_ENUM(NSInteger, NotificationsExperimentType) { + NotificationsExperimentTypeEnabled = 0, + NotificationsExperimentTypePromoEnabled = 1, + NotificationsExperimentTypeSetUpListsEnabled = 2, +}; + extern NSString* const kNotificationsPromoCloseButtonId; #endif // IOS_CHROME_BROWSER_UI_NTP_FEED_TOP_SECTION_NOTIFICATIONS_PROMO_VIEW_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/debugger/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/debugger/BUILD.gn index 36d2465..24b176f 100644 --- a/ios/chrome/browser/ui/omnibox/popup/debugger/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/debugger/BUILD.gn
@@ -13,6 +13,10 @@ "omnibox_autocomplete_event_view_controller.h", "omnibox_autocomplete_event_view_controller.mm", "omnibox_event.h", + "omnibox_remote_suggestion_event.h", + "omnibox_remote_suggestion_event.mm", + "omnibox_remote_suggestion_event_view_controller.h", + "omnibox_remote_suggestion_event_view_controller.mm", ] deps = [ "//base",
diff --git a/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.h b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.h new file mode 100644 index 0000000..5136df72 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.h
@@ -0,0 +1,25 @@ +// 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 IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_H_ +#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_H_ + +#import "base/unguessable_token.h" +#import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_event.h" + +// A class that captures the state of a RemoteSuggestionsService event +@interface OmniboxRemoteSuggestionEvent : NSObject <OmniboxEvent> + +@property(nonatomic, strong) NSString* requestBody; +@property(nonatomic, strong) NSString* responseBody; +@property(nonatomic, assign) NSInteger responseCode; + +- (instancetype)initWithUniqueIdentifier: + (const base::UnguessableToken&)requestIdentifier; + +- (const base::UnguessableToken&)uniqueIdentifier; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.mm b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.mm new file mode 100644 index 0000000..55d0ab2 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.mm
@@ -0,0 +1,5 @@ +// 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. + +#import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.h b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.h new file mode 100644 index 0000000..06ce60b --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.h
@@ -0,0 +1,8 @@ +// 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 IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_VIEW_CONTROLLER_H_ + +#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_DEBUGGER_OMNIBOX_REMOTE_SUGGESTION_EVENT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.mm new file mode 100644 index 0000000..4254ed94 --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.mm
@@ -0,0 +1,5 @@ +// 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. + +#import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event_view_controller.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm index b595284b..3e169af 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm
@@ -198,7 +198,7 @@ if (self.remoteSuggestionsService) { _remoteSuggestionsServiceObserverBridge = std::make_unique<RemoteSuggestionsServiceObserverBridge>( - debugInfoConsumer); + debugInfoConsumer, self.remoteSuggestionsService); self.remoteSuggestionsService->AddObserver( _remoteSuggestionsServiceObserverBridge.get()); }
diff --git a/ios/chrome/browser/ui/omnibox/popup/popup_debug_info_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/popup_debug_info_view_controller.mm index 79ec2e54..c91a5dad 100644 --- a/ios/chrome/browser/ui/omnibox/popup/popup_debug_info_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/popup_debug_info_view_controller.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_autocomplete_event.h" #import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_autocomplete_event_view_controller.h" #import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_event.h" +#import "ios/chrome/browser/ui/omnibox/popup/debugger/omnibox_remote_suggestion_event.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" namespace { @@ -268,15 +269,23 @@ #pragma mark - RemoteSuggestionsServiceObserver - (void)remoteSuggestionsService:(RemoteSuggestionsService*)service - startingRequest:(const network::ResourceRequest*)request - uniqueIdentifier: - (const base::UnguessableToken&)requestIdentifier { + createdRequestWithIdentifier: + (const base::UnguessableToken&)requestIdentifier + request:(const network::ResourceRequest*)request { +} + +- (void)remoteSuggestionsService:(RemoteSuggestionsService*)service + startedRequestWithIdentifier: + (const base::UnguessableToken&)requestIdentifier + requestBody:(NSString*)requestBody + URLLoader:(network::SimpleURLLoader*)URLLoader { } - (void)remoteSuggestionsService:(RemoteSuggestionsService*)service completedRequestWithIdentifier: (const base::UnguessableToken&)requestIdentifier - receivedResponse:(NSString*)response { + responseCode:(NSInteger)code + responseBody:(NSString*)responseBody { } #pragma mark - UITableViewDataSource
diff --git a/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.h b/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.h index a10782a..6f6b104a 100644 --- a/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.h +++ b/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.h
@@ -5,28 +5,37 @@ #ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_REMOTE_SUGGESTIONS_SERVICE_OBSERVER_BRIDGE_H_ #define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_REMOTE_SUGGESTIONS_SERVICE_OBSERVER_BRIDGE_H_ -#include "components/omnibox/browser/remote_suggestions_service.h" +#import "components/omnibox/browser/remote_suggestions_service.h" +#import "base/memory/raw_ptr.h" #import "base/strings/sys_string_conversions.h" #import "base/strings/utf_string_conversions.h" @protocol RemoteSuggestionsServiceObserver - (void)remoteSuggestionsService:(RemoteSuggestionsService*)service - startingRequest:(const network::ResourceRequest*)request - uniqueIdentifier: - (const base::UnguessableToken&)requestIdentifier; + createdRequestWithIdentifier: + (const base::UnguessableToken&)requestIdentifier + request:(const network::ResourceRequest*)request; + +- (void)remoteSuggestionsService:(RemoteSuggestionsService*)service + startedRequestWithIdentifier: + (const base::UnguessableToken&)requestIdentifier + requestBody:(NSString*)requestBody + URLLoader:(network::SimpleURLLoader*)URLLoader; - (void)remoteSuggestionsService:(RemoteSuggestionsService*)service completedRequestWithIdentifier: (const base::UnguessableToken&)requestIdentifier - receivedResponse:(NSString*)response; + responseCode:(NSInteger)code + responseBody:(NSString*)responseBody; @end class RemoteSuggestionsServiceObserverBridge : public RemoteSuggestionsService::Observer { public: RemoteSuggestionsServiceObserverBridge( - id<RemoteSuggestionsServiceObserver> observer); + id<RemoteSuggestionsServiceObserver> observer, + RemoteSuggestionsService* remote_suggestions_service); RemoteSuggestionsServiceObserverBridge( const RemoteSuggestionsServiceObserverBridge&) = delete; @@ -48,6 +57,7 @@ private: __weak id<RemoteSuggestionsServiceObserver> observer_; + raw_ptr<RemoteSuggestionsService> remote_suggestions_service_; }; #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_REMOTE_SUGGESTIONS_SERVICE_OBSERVER_BRIDGE_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.mm b/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.mm index 58b78eaf..46bccb395 100644 --- a/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.mm +++ b/ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.mm
@@ -5,37 +5,40 @@ #import "ios/chrome/browser/ui/omnibox/popup/remote_suggestions_service_observer_bridge.h" RemoteSuggestionsServiceObserverBridge::RemoteSuggestionsServiceObserverBridge( - id<RemoteSuggestionsServiceObserver> observer) - : observer_(observer) {} + id<RemoteSuggestionsServiceObserver> observer, + RemoteSuggestionsService* remote_suggestions_service) + : observer_(observer), + remote_suggestions_service_(remote_suggestions_service) {} void RemoteSuggestionsServiceObserverBridge::OnSuggestRequestCreated( const base::UnguessableToken& request_id, const network::ResourceRequest* request) { - // TODO: add remote suggestion service arg - [observer_ remoteSuggestionsService:nil - startingRequest:request - uniqueIdentifier:request_id]; + [observer_ remoteSuggestionsService:remote_suggestions_service_ + createdRequestWithIdentifier:request_id + request:request]; } void RemoteSuggestionsServiceObserverBridge::OnSuggestRequestStarted( const base::UnguessableToken& request_id, network::SimpleURLLoader* loader, const std::string& request_body) { - // TODO: notify the observer. For the existing applications on iOS this is - // called immediately after `OnSuggestRequestCreated`. But it is possible for - // this to be called asynchronously in the future. + NSString* requestBody = base::SysUTF8ToNSString(request_body); + [observer_ remoteSuggestionsService:remote_suggestions_service_ + startedRequestWithIdentifier:request_id + requestBody:requestBody + URLLoader:loader]; } void RemoteSuggestionsServiceObserverBridge::OnSuggestRequestCompleted( const base::UnguessableToken& request_id, const int response_code, const std::unique_ptr<std::string>& response_body) { - NSString* response_string = nil; + NSString* responseBody = nil; if (response_code == 200 && response_body) { - response_string = base::SysUTF8ToNSString(*response_body.get()); + responseBody = base::SysUTF8ToNSString(*response_body.get()); } - // TODO: add remote suggestion service arg - [observer_ remoteSuggestionsService:nil + [observer_ remoteSuggestionsService:remote_suggestions_service_ completedRequestWithIdentifier:request_id - receivedResponse:response_string]; + responseCode:response_code + responseBody:responseBody]; }
diff --git a/ios/chrome/browser/ui/passwords/account_storage_notice/passwords_account_storage_notice_coordinator.mm b/ios/chrome/browser/ui/passwords/account_storage_notice/passwords_account_storage_notice_coordinator.mm index a016114..0c10d6f44 100644 --- a/ios/chrome/browser/ui/passwords/account_storage_notice/passwords_account_storage_notice_coordinator.mm +++ b/ios/chrome/browser/ui/passwords/account_storage_notice/passwords_account_storage_notice_coordinator.mm
@@ -191,4 +191,10 @@ // `self` is deleted. } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [self passwordSettingsCoordinatorDidRemove:self.passwordSettingsCoordinator]; +} + @end
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn index 3c68e21..8a9d66e 100644 --- a/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn +++ b/ios/chrome/browser/ui/passwords/bottom_sheet/BUILD.gn
@@ -103,6 +103,7 @@ "//ios/chrome/browser/ui/settings/password:eg_test_support+eg2", "//ios/chrome/browser/ui/settings/password:features", "//ios/chrome/browser/ui/settings/password:password_constants", + "//ios/chrome/browser/ui/settings/password/password_details:password_details_table_view_constants", "//ios/chrome/common/ui/confirmation_alert:constants", "//ios/chrome/test:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm index a6bbd27..258294ea 100644 --- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm +++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_egtest.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/signin/model/fake_system_identity.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" #import "ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_app_interface.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h" #import "ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h" #import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h" #import "ios/chrome/browser/ui/settings/password/password_settings_app_interface.h" @@ -122,6 +123,7 @@ - (void)tearDown { [PasswordManagerAppInterface clearCredentials]; + [PasswordSettingsAppInterface removeMockReauthenticationModule]; [PasswordSuggestionBottomSheetAppInterface removeMockReauthenticationModule]; [MetricsAppInterface stopOverridingMetricsAndCrashReportingForTesting]; @@ -137,7 +139,11 @@ password_manager::features::kIOSPasswordBottomSheet); if ([self isRunningTest:@selector - (testOpenPasswordBottomSheetOpenPasswordDetails)]) { + (testOpenPasswordBottomSheetOpenPasswordDetails)] || + [self + isRunningTest:@selector + (testOpenPasswordBottomSheetOpenPasswordDetailsWithFailedAuthentication + )]) { config.features_enabled.push_back( password_manager::features::kIOSPasswordAuthOnEntryV2); } @@ -436,6 +442,82 @@ CheckPasswordDetailsVisitMetricCount(1); } +// Verifies that Password Details is not revealed when local authentication +// fails. +- (void)testOpenPasswordBottomSheetOpenPasswordDetailsWithFailedAuthentication { + [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1] + enableSync:NO]; + NSURL* URL = + net::NSURLWithGURL(self.testServer->GetURL("/simple_login_form.html")); + + [PasswordManagerAppInterface storeCredentialWithUsername:@"user" + password:@"password" + URL:URL]; + [PasswordManagerAppInterface storeCredentialWithUsername:@"user2" + password:@"password2" + URL:URL]; + int credentialsCount = [PasswordManagerAppInterface storedCredentialsCount]; + GREYAssertEqual(2, credentialsCount, @"."); + + [self loadLoginPage]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElementWithId(kFormPassword)]; + + [ChromeEarlGrey + waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user")]; + + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user")] + performAction:grey_tap()]; + + [ChromeEarlGrey + waitForUIElementToAppearWithMatcher:grey_accessibilityID(@"user2")]; + + [ChromeEarlGreyUI waitForAppToIdle]; + + // Delay the auth result to be able to validate that password details is + // not visible until the result is emitted. + [PasswordSettingsAppInterface setUpMockReauthenticationModule]; + [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult: + ReauthenticationResult::kFailure]; + [PasswordSettingsAppInterface + mockReauthenticationModuleShouldReturnSynchronously:NO]; + + // Long press to open context menu. + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"user2")] + performAction:grey_longPress()]; + + [[EarlGrey + selectElementWithMatcher: + grey_allOf(chrome_test_util::ContextMenuItemWithAccessibilityLabelId( + IDS_IOS_PASSWORD_BOTTOM_SHEET_SHOW_DETAILS), + grey_interactable(), nullptr)] performAction:grey_tap()]; + + [ChromeEarlGreyUI waitForAppToIdle]; + + // Password details shouldn't be visible until auth is passed. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TextFieldForCellWithLabelId( + IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME)] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsNavigationBar()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Verify visit metric was not recorded yet. + CheckPasswordDetailsVisitMetricCount(0); + + // Emit auth result so password details surface is dismissed due to failed + // auth. + [PasswordSettingsAppInterface mockReauthenticationModuleReturnMockedResult]; + + // Validate the whole settings UI is gone. + [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsNavigationBar()] + assertWithMatcher:grey_nil()]; + + // Verify visit metric was not recorded. + CheckPasswordDetailsVisitMetricCount(0); +} + - (void)testOpenPasswordBottomSheetOpenPasswordDetailsWithoutAuthentication { [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1] enableSync:NO];
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm index 780971be..0529b42 100644 --- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm +++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm
@@ -102,9 +102,6 @@ self.titleString = _title; self.titleTextStyle = UIFontTextStyleTitle2; - // Check that the primary string was set before loading the view. - CHECK(self.primaryActionString && self.primaryActionString.length > 0); - self.secondaryActionString = l10n_util::GetNSString(IDS_IOS_PASSWORD_BOTTOM_SHEET_USE_KEYBOARD); self.secondaryActionImage =
diff --git a/ios/chrome/browser/ui/sad_tab/BUILD.gn b/ios/chrome/browser/ui/sad_tab/BUILD.gn index afdde18..6a1a5760 100644 --- a/ios/chrome/browser/ui/sad_tab/BUILD.gn +++ b/ios/chrome/browser/ui/sad_tab/BUILD.gn
@@ -62,7 +62,7 @@ ] deps = [ "//components/strings", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", "//ios/chrome/browser/shared/public/commands",
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator_unittest.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator_unittest.mm index 0651ca6..7b849a6 100644 --- a/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/sad_tab/sad_tab_coordinator_unittest.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/shared/model/browser/test/test_browser.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h"
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index c776e5c..3829a1c 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -42,6 +42,14 @@ deps = [ "//base" ] } +source_set("settings_navigation_controller_constants") { + sources = [ + "settings_navigation_controller_constants.h", + "settings_navigation_controller_constants.mm", + ] + frameworks = [ "Foundation.framework" ] +} + source_set("settings_root_categories") { sources = [ "settings_root_table_view_controller+toolbar_add.h", @@ -78,6 +86,7 @@ ] deps = [ ":constants", + ":settings_navigation_controller_constants", ":settings_root", "resources:enterprise_icon", "resources:family_link_icon",
diff --git a/ios/chrome/browser/ui/settings/password/BUILD.gn b/ios/chrome/browser/ui/settings/password/BUILD.gn index eea70c2a..a3b249b 100644 --- a/ios/chrome/browser/ui/settings/password/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/BUILD.gn
@@ -41,6 +41,7 @@ "//ios/chrome/browser/ui/settings/password/password_issues", "//ios/chrome/browser/ui/settings/password/password_settings", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/password/widget_promo_instructions", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/common:string_util", @@ -249,6 +250,7 @@ "//ios/chrome/browser/ui/settings/password:eg_test_support+eg2", "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_constants", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", "//ui/base",
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn index bb2dea6..0926a59 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_checkup/BUILD.gn
@@ -28,6 +28,7 @@ "//ios/chrome/browser/ui/settings/password:features", "//ios/chrome/browser/ui/settings/password/password_issues", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/password/widget_promo_instructions", "//ios/chrome/common:string_util", "//ios/chrome/common/ui/reauthentication",
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h index b3674383..1255ecd 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.h
@@ -7,6 +7,7 @@ #import "components/password_manager/core/browser/ui/password_check_referrer.h" #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" @protocol ApplicationCommands; @class PasswordCheckupCoordinator; @@ -16,7 +17,8 @@ @protocol ReauthenticationProtocol; // Delegate for PasswordCheckupCoordinator. -@protocol PasswordCheckupCoordinatorDelegate +@protocol + PasswordCheckupCoordinatorDelegate <PasswordManagerReauthenticationDelegate> // Called when the view controller is removed from navigation controller. - (void)passwordCheckupCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm index ebc15c96..fc7b0d2 100644 --- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm
@@ -194,6 +194,12 @@ [self restartReauthCoordinator]; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + #pragma mark - ReauthenticationCoordinatorDelegate - (void)successfulReauthenticationWithCoordinator: @@ -201,6 +207,13 @@ [_visitsRecorder maybeRecordVisitMetric]; } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { // No-op. }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn index a1ded47..5c51dd57 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
@@ -50,6 +50,7 @@ "//ios/chrome/browser/ui/settings/password/password_sharing", "//ios/chrome/browser/ui/settings/password/password_sharing:password_sharing_metrics", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/reauthentication", @@ -152,6 +153,7 @@ "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", "//ios/chrome/browser/shared/public/commands", + "//ios/chrome/browser/shared/public/features", "//ios/chrome/browser/shared/ui/table_view:test_support", "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/sync/model",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm index 4ce9a91..52bf806 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator.mm
@@ -196,6 +196,12 @@ // No-op. } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { [self dismissAlertCoordinator]; }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator_delegate.h index 868144e4..da5615a 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator_delegate.h +++ b/ios/chrome/browser/ui/settings/password/password_details/add_password_coordinator_delegate.h
@@ -5,12 +5,15 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_COORDINATOR_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_COORDINATOR_DELEGATE_H_ +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" + namespace password_manager { struct CredentialUIEntry; } // namespace password_manager // Delegate for AddPasswordCoordinator. -@protocol AddPasswordCoordinatorDelegate +@protocol + AddPasswordCoordinatorDelegate <PasswordManagerReauthenticationDelegate> // Called when the add view controller is to removed. - (void)passwordDetailsTableViewControllerDidFinish:
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm index b00ddd0..72f26b1 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -448,6 +448,13 @@ [_visitsRecorder maybeRecordVisitMetric]; } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { // Dismiss modal ui before reauth view controller is pushed in front of // password details.
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h index 3f2ae9818..2a81b48 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h
@@ -5,10 +5,13 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_DELEGATE_H_ +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" + @class PasswordDetailsCoordinator; // Delegate for PasswordIssuesCoordinator. -@protocol PasswordDetailsCoordinatorDelegate +@protocol + PasswordDetailsCoordinatorDelegate <PasswordManagerReauthenticationDelegate> // Called when the view controller was removed from navigation controller. - (void)passwordDetailsCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller+private.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller+private.h index 547a124..09bbad4 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller+private.h +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller+private.h
@@ -8,7 +8,11 @@ // Class extension exposing private methods of // PasswordDetailsTableViewController for testing. @interface PasswordDetailsTableViewController () +#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0 - (void)copyPasswordDetails:(id)sender; +#endif + +- (void)copyPasswordDetailsHelper:(NSInteger)itemType; @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_PRIVATE_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm index 52903355..b718b508 100644 --- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller_unittest.mm
@@ -19,6 +19,7 @@ #import "ios/chrome/browser/shared/public/commands/application_commands.h" #import "ios/chrome/browser/shared/public/commands/open_new_tab_command.h" #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h" +#import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_line_text_edit_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller_test.h" @@ -205,7 +206,8 @@ PasswordDetailsTableViewControllerTest() { feature_list_.InitWithFeatures( /*enabled_features=*/{password_manager::features:: - kIOSPasswordAuthOnEntryV2}, + kIOSPasswordAuthOnEntryV2, + kEnableUIEditMenuInteraction}, /*disabled_features=*/{}); handler_ = [[FakePasswordDetailsHandler alloc] init]; delegate_ = [[FakePasswordDetailsDelegate alloc] init]; @@ -370,9 +372,18 @@ [password_details tableView:password_details.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; - UIMenuController* menu = [UIMenuController sharedMenuController]; - EXPECT_EQ(1u, menu.menuItems.count); - [password_details copyPasswordDetails:menu]; + + if (@available(iOS 16, *)) { + [password_details + copyPasswordDetailsHelper:PasswordDetailsItemTypeWebsite]; + } +#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0 + else { + UIMenuController* menu = [UIMenuController sharedMenuController]; + EXPECT_EQ(1u, menu.menuItems.count); + [password_details copyPasswordDetails:menu]; + } +#endif UIPasteboard* general_pasteboard = [UIPasteboard generalPasteboard]; EXPECT_NSEQ(expected_pasteboard, general_pasteboard.string); @@ -803,11 +814,17 @@ [password_details tableView:password_details.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]]; - - UIMenuController* menu = [UIMenuController sharedMenuController]; - EXPECT_EQ(1u, menu.menuItems.count); - [password_details copyPasswordDetails:menu]; - + if (@available(iOS 16, *)) { + [password_details + copyPasswordDetailsHelper:PasswordDetailsItemTypeUsername]; + } +#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0 + else { + UIMenuController* menu = [UIMenuController sharedMenuController]; + EXPECT_EQ(1u, menu.menuItems.count); + [password_details copyPasswordDetails:menu]; + } +#endif UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard]; EXPECT_NSEQ(@"test@egmail.com", generalPasteboard.string); EXPECT_NSEQ( @@ -828,10 +845,17 @@ [password_details tableView:password_details.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]]; - - UIMenuController* menu = [UIMenuController sharedMenuController]; - EXPECT_EQ(1u, menu.menuItems.count); - [password_details copyPasswordDetails:menu]; + if (@available(iOS 16, *)) { + [password_details + copyPasswordDetailsHelper:PasswordDetailsItemTypePassword]; + } +#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0 + else { + UIMenuController* menu = [UIMenuController sharedMenuController]; + EXPECT_EQ(1u, menu.menuItems.count); + [password_details copyPasswordDetails:menu]; + } +#endif EXPECT_TRUE(handler().passwordCopiedByUserCalled); @@ -849,10 +873,16 @@ PasswordDetailsTableViewController* password_details = base::apple::ObjCCastStrict<PasswordDetailsTableViewController>( controller()); - - // When no menu controller is passed, there's no way of knowing which field - // should be copied to the pasteboard and thus copying should fail. - [password_details copyPasswordDetails:nil]; + if (@available(iOS 16, *)) { + [password_details copyPasswordDetailsHelper:NSIntegerMax]; + } +#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0 + else { + // When no menu controller is passed, there's no way of knowing which field + // should be copied to the pasteboard and thus copying should fail. + [password_details copyPasswordDetails:nil]; + } +#endif EXPECT_FALSE(handler().passwordCopiedByUserCalled); }
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn index 88e86d32..b8dd78c 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
@@ -33,6 +33,7 @@ "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants", "//ios/chrome/browser/ui/settings/password/password_details", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/common/ui/favicon:favicon_constants", "//ios/chrome/common/ui/reauthentication",
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h index dbab80a..a898318 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h
@@ -6,6 +6,7 @@ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_ISSUES_PASSWORD_ISSUES_COORDINATOR_H_ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" @protocol ApplicationCommands; class Browser; @@ -17,7 +18,8 @@ } // Delegate for PasswordIssuesCoordinator. -@protocol PasswordIssuesCoordinatorDelegate +@protocol + PasswordIssuesCoordinatorDelegate <PasswordManagerReauthenticationDelegate> // Called when the view controller is removed from navigation controller. - (void)passwordIssuesCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm index 982ba5595..f9e5a86 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm
@@ -257,6 +257,12 @@ [self onChildCoordinatorDidRemove]; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + #pragma mark - ReauthenticationCoordinatorDelegate - (void)successfulReauthenticationWithCoordinator: @@ -264,6 +270,13 @@ [_visitsRecorder maybeRecordVisitMetric]; } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { // No-op. }
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm index bea44d492..140aff9c 100644 --- a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
@@ -3391,9 +3391,11 @@ [[EarlGrey selectElementWithMatcher:PasswordsTableViewMatcher()] assertWithMatcher:grey_notVisible()]; - // Failed auth should dismiss the Password Manager, leaving the NTP visible. + // Failed auth should dismiss the Password Manager, the Settings menu is + // displayed. [PasswordSettingsAppInterface mockReauthenticationModuleReturnMockedResult]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPCollectionView()] + [[EarlGrey + selectElementWithMatcher:chrome_test_util::SettingsCollectionView()] assertWithMatcher:grey_sufficientlyVisible()]; // Check password manager visit metric. @@ -3419,8 +3421,9 @@ // Dismiss the passcode alert, this should dismiss the Password Manager. DismissSetPasscodeDialog(); - // Check for the NTP after Password Manager is gone. - [[EarlGrey selectElementWithMatcher:chrome_test_util::NTPCollectionView()] + // Check for the Settings page after Password Manager is gone. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::SettingsCollectionView()] assertWithMatcher:grey_sufficientlyVisible()]; // Check Reauthentication UI metrics.
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h index 5d90b3c..965b3fbf 100644 --- a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h +++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.h
@@ -71,6 +71,10 @@ id<GREYMatcher> DeleteButtonForUsernameAndSites(NSString* username, NSString* sites); +// Matcher for the Reauthentication Controller used for covered the UI until +// Local Authentication is passed. +id<GREYMatcher> ReauthenticationController(); + // GREYElementInteraction* for the item on the password issues list // with the given `matcher`. It scrolls in `direction` if necessary to ensure // that the matched item is interactable.
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm index 94c3711e..7fc4cf5 100644 --- a/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm +++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest_utils.mm
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_constants.h" #import "ios/chrome/browser/ui/settings/password/password_settings_app_interface.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" +#import "ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.h" #import "ios/chrome/browser/ui/settings/settings_root_table_constants.h" #import "ios/chrome/grit/ios_branded_strings.h" #import "ios/chrome/grit/ios_strings.h" @@ -143,6 +144,11 @@ grey_interactable(), nullptr); } +id<GREYMatcher> ReauthenticationController() { + return grey_accessibilityID( + password_manager::kReauthenticationViewControllerAccessibilityIdentifier); +} + GREYElementInteraction* GetInteractionForIssuesListItem( id<GREYMatcher> matcher, GREYDirection direction) {
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_settings/BUILD.gn index c2378d5..aaf6c62 100644 --- a/ios/chrome/browser/ui/settings/password/password_settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_settings/BUILD.gn
@@ -44,6 +44,7 @@ "//ios/chrome/browser/ui/settings/password:password_ui", "//ios/chrome/browser/ui/settings/password/passwords_in_other_apps", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/common/ui/reauthentication", "//ui/base",
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator.mm index 2c6174d1..dcdc5a9 100644 --- a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator.mm
@@ -536,6 +536,12 @@ [self restartReauthCoordinator]; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + #pragma mark - SettingsNavigationControllerDelegate - (void)closeSettings { @@ -558,6 +564,12 @@ [_visitsRecorder maybeRecordVisitMetric]; } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { // Cancel password export flow before authentication UI is presented. if (_preparingPasswordsAlert.beingPresented) {
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator_delegate.h b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator_delegate.h index 38a8722..234d4de 100644 --- a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator_delegate.h +++ b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_coordinator_delegate.h
@@ -5,10 +5,13 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_SETTINGS_PASSWORD_SETTINGS_COORDINATOR_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_SETTINGS_PASSWORD_SETTINGS_COORDINATOR_DELEGATE_H_ +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" + @class PasswordSettingsCoordinator; // Delegate for PasswordSettingsCoordinator. -@protocol PasswordSettingsCoordinatorDelegate +@protocol PasswordSettingsCoordinatorDelegate < + PasswordManagerReauthenticationDelegate> // Called when the view controller was removed from navigation controller. - (void)passwordSettingsCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.h b/ios/chrome/browser/ui/settings/password/passwords_coordinator.h index f38391d..551d751 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.h
@@ -6,12 +6,13 @@ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORDS_COORDINATOR_H_ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" class Browser; @class PasswordsCoordinator; // Delegate for PasswordsCoordinator. -@protocol PasswordsCoordinatorDelegate +@protocol PasswordsCoordinatorDelegate <PasswordManagerReauthenticationDelegate> // Called when the view controller is removed from navigation controller. - (void)passwordsCoordinatorDidRemove:(PasswordsCoordinator*)coordinator;
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm index 2d6751c..5d8c514 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
@@ -424,6 +424,12 @@ [self restartReauthCoordinator]; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + #pragma mark PasswordDetailsCoordinatorDelegate - (void)passwordDetailsCoordinatorDidRemove: @@ -494,6 +500,13 @@ } } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { [self dismissAlertCoordinator]; [self dismissActionSheetCoordinator];
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/BUILD.gn b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/BUILD.gn index 01dede6..f976448 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/BUILD.gn
@@ -15,6 +15,7 @@ "//ios/chrome/browser/shared/coordinator/chrome_coordinator", "//ios/chrome/browser/ui/settings/password:features", "//ios/chrome/browser/ui/settings/password/reauthentication", + "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_delegate", "//ios/chrome/browser/ui/settings/utils", "//ios/public/provider/chrome/browser/password_auto_fill:password_auto_fill_api", ]
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.h b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.h index e7890d36..65afefea 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.h
@@ -7,12 +7,14 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" #import "ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.h" +#import "ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h" class Browser; @class PasswordsInOtherAppsCoordinator; // Delegate for PasswordsInOtherAppsCoordinator. -@protocol PasswordsInOtherAppsCoordinatorDelegate +@protocol PasswordsInOtherAppsCoordinatorDelegate < + PasswordManagerReauthenticationDelegate> // Called when the view controller is removed from navigation controller. - (void)passwordsInOtherAppsCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.mm index 9b600e9..dacfcf1d 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_coordinator.h" #import "base/check.h" +#import "base/check_op.h" #import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h" #import "ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_mediator.h" #import "ios/chrome/browser/ui/settings/password/passwords_in_other_apps/passwords_in_other_apps_view_controller.h" @@ -83,6 +84,12 @@ // No-op. } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + CHECK_EQ(_reauthCoordinator, coordinator); + [_delegate dismissPasswordManagerAfterFailedReauthentication]; +} + - (void)willPushReauthenticationViewController { // No-op. }
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/BUILD.gn b/ios/chrome/browser/ui/settings/password/reauthentication/BUILD.gn index a5e6897..e7be5ee24 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/reauthentication/BUILD.gn
@@ -12,6 +12,7 @@ ":reauthentication_ui", "//base", "//components/strings", + "//ios/chrome/app/application_delegate:app_state_header", "//ios/chrome/app/strings", "//ios/chrome/browser/shared/coordinator/alert", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", @@ -51,6 +52,13 @@ "reauthentication_constants.h", "reauthentication_constants.mm", ] + frameworks = [ "Foundation.framework" ] +} + +source_set("reauthentication_delegate") { + sources = [ "password_manager_reauthentication_delegate.h" ] + + frameworks = [ "Foundation.framework" ] } source_set("unit_tests") {
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h b/ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h new file mode 100644 index 0000000..ae386c5d --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/reauthentication/password_manager_reauthentication_delegate.h
@@ -0,0 +1,17 @@ +// 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 IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PASSWORD_MANAGER_REAUTHENTICATION_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PASSWORD_MANAGER_REAUTHENTICATION_DELEGATE_H_ + +// Delegate handling local authentication events for Password Manager surfaces. +@protocol PasswordManagerReauthenticationDelegate <NSObject> + +// Dismisses the Password Manager and any presented UI after the user failed to +// pass local authentication while in any of the Password Manager surfaces. +- (void)dismissPasswordManagerAfterFailedReauthentication; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_PASSWORD_MANAGER_REAUTHENTICATION_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.h b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.h index 05ccad2..26e06600 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.h +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.h
@@ -5,11 +5,16 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_REAUTHENTICATION_CONSTANTS_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_REAUTHENTICATION_CONSTANTS_H_ +#import <Foundation/Foundation.h> + namespace password_manager { // Name of histogram tracking events in the password manager reauthentication // UI. extern const char kReauthenticationUIEventHistogram[]; +// Accessibility for ReauthenticationViewController. +extern NSString* const kReauthenticationViewControllerAccessibilityIdentifier; + } // namespace password_manager #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_REAUTHENTICATION_REAUTHENTICATION_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.mm b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.mm index 0ce66d4..c5786e0 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.mm +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_constants.mm
@@ -7,4 +7,7 @@ namespace password_manager { const char kReauthenticationUIEventHistogram[] = "PasswordManager.iOS.ReauthenticationUI.Event"; + +NSString* const kReauthenticationViewControllerAccessibilityIdentifier = + @"ReauthenticationViewController"; }
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.h b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.h index 0686a43..536b20af 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.h +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.h
@@ -19,6 +19,14 @@ - (void)successfulReauthenticationWithCoordinator: (ReauthenticationCoordinator*)coordinator; +// Dismisses the UI protected by Local Authentication. When there are several +// levels of UI protected by LA , this function results in the dismissal of all +// LA-protected UI levels. For example if the user opens Settings > Password +// Manager > Password Details and LA is canceled, then Password Details and +// Password Manager are dismissed, leaving the user on the Settings page. +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator; + // Invoked when the coordinator is about to push its view controller. // Parent coordinators can prepare for reauthentication here, by stopping any // presented alerts or unregistering observers not needed while reauth is
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.mm b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.mm index 95eddc7..b4431e419 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.mm
@@ -124,23 +124,20 @@ __weak __typeof(self) weakSelf = self; - // Action OK -> Close settings. + // Action OK -> Close UI. [_passcodeRequestAlertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_OK) action:^{ - [weakSelf.dispatcher closeSettingsUI]; + [weakSelf closeUI]; } style:UIAlertActionStyleCancel]; // Action Learn How -> Close settings and open passcode help page. - OpenNewTabCommand* command = - [OpenNewTabCommand commandWithURLFromChrome:GURL(kPasscodeArticleURL)]; - [_passcodeRequestAlertCoordinator addItemWithTitle:l10n_util::GetNSString( IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_LEARN_HOW) action:^{ - [weakSelf.dispatcher closeSettingsUIAndOpenURL:command]; + [weakSelf openPasscodeHelpPage]; } style:UIAlertActionStyleDefault]; @@ -154,7 +151,7 @@ [_delegate successfulReauthenticationWithCoordinator:self]; } else { - [_dispatcher closeSettingsUI]; + [self closeUI]; } } @@ -264,4 +261,17 @@ _reauthViewController = nil; } +// Dismisses the UI protected with Local Authentication. +- (void)closeUI { + [_delegate dismissUIAfterFailedReauthenticationWithCoordinator:self]; +} + +// Closes the UI and open the support page on setting up a passcode. +- (void)openPasscodeHelpPage { + // TODO(crbug.com/1462419): Move to ReauthenticationCoordinatorDelegate. + OpenNewTabCommand* command = + [OpenNewTabCommand commandWithURLFromChrome:GURL(kPasscodeArticleURL)]; + [_dispatcher closeSettingsUIAndOpenURL:command]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator_unittest.mm b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator_unittest.mm index 95fa9dc..6616d678 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator_unittest.mm
@@ -32,6 +32,9 @@ // Set when `willPushReauthenticationViewController` is called. @property(nonatomic) BOOL willPushReauthVCCalled; +// Set when `dismissUIAfterFailedReauthenticationWithCoordinator` is called. +@property(nonatomic) BOOL dismissUICalled; + @end @implementation FakeReauthenticationCoordinatorDelegate @@ -45,6 +48,11 @@ self.willPushReauthVCCalled = YES; } +- (void)dismissUIAfterFailedReauthenticationWithCoordinator: + (ReauthenticationCoordinator*)coordinator { + _dismissUICalled = YES; +} + @end // Test fixture for ReauthenticationCoordinator. @@ -242,9 +250,7 @@ // Reauth vc should still be there. CheckReauthenticationViewControllerIsPresented(); ASSERT_FALSE(delegate_.successfulReauth); - - // Cancelling reauth should close settings. - OCMExpect([mocked_application_commands_handler_ closeSettingsUI]); + ASSERT_FALSE(delegate_.dismissUICalled); // Mock reauth result when app is in the foreground and active again. mock_reauth_module_.expectedResult = ReauthenticationResult::kFailure; @@ -255,6 +261,6 @@ ASSERT_FALSE(delegate_.successfulReauth); - // Verify command was dispatched. - EXPECT_OCMOCK_VERIFY(mocked_application_commands_handler_); + // Cancelling reauth should close settings. + ASSERT_TRUE(delegate_.dismissUICalled); }
diff --git a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_view_controller.mm b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_view_controller.mm index c78a4c1..cc80fde1 100644 --- a/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_view_controller.mm
@@ -43,6 +43,9 @@ - (void)viewDidLoad { [super viewDidLoad]; + self.view.accessibilityIdentifier = + password_manager::kReauthenticationViewControllerAccessibilityIdentifier; + // Set background color matching the one used in the settings UI. self.view.backgroundColor = [UIColor colorNamed:kGroupedPrimaryBackgroundColor];
diff --git a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn index beafc86..b699d1d5 100644 --- a/ios/chrome/browser/ui/settings/safety_check/BUILD.gn +++ b/ios/chrome/browser/ui/settings/safety_check/BUILD.gn
@@ -83,7 +83,6 @@ "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/settings/elements:enterprise_info_popover_view_controller", - "//ios/chrome/browser/ui/settings/password", "//ios/chrome/browser/ui/settings/password/password_checkup", "//ios/chrome/browser/ui/settings/password/password_issues", "//ios/chrome/browser/ui/settings/privacy:privacy_ui",
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm index 77bf110..19a8c9b 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
@@ -261,6 +261,26 @@ self.passwordCheckupCoordinator = nil; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + // Pop everything up to the Safety Check page. + // When there is content presented, don't animate the dismissal of the view + // controllers in the navigation controller to prevent revealing passwords + // when the presented content is the one covered by the reauthentication UI. + UINavigationController* navigationController = self.baseNavigationController; + UIViewController* topViewController = navigationController.topViewController; + UIViewController* presentedViewController = + topViewController.presentedViewController; + + [navigationController popToViewController:_viewController + animated:presentedViewController == nil]; + + [presentedViewController.presentingViewController + dismissViewControllerAnimated:YES + completion:nil]; +} + #pragma mark - PrivacySafeBrowsingCoordinatorDelegate - (void)privacySafeBrowsingCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm index 9746d80..0d2acdd 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -55,6 +55,7 @@ #import "ios/chrome/browser/ui/settings/privacy/privacy_safe_browsing_coordinator.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h" #import "ios/chrome/browser/ui/settings/settings_root_view_controlling.h" #import "ios/chrome/browser/ui/settings/settings_table_view_controller.h" #import "ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.h" @@ -611,7 +612,8 @@ [UIColor colorNamed:kGroupedPrimaryBackgroundColor]; self.navigationBar.prefersLargeTitles = YES; - self.navigationBar.accessibilityIdentifier = @"SettingNavigationBar"; + self.navigationBar.accessibilityIdentifier = + password_manager::kSettingsNavigationBarAccessibilityID; // Set the NavigationController delegate. self.delegate = self; @@ -916,6 +918,15 @@ [self stopPasswordsCoordinator]; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + id<ApplicationCommands> applicationHandler = HandlerForProtocol( + self.browser->GetCommandDispatcher(), ApplicationCommands); + + [applicationHandler closeSettingsUI]; +} + #pragma mark PasswordDetailsCoordinatorDelegate - (void)passwordDetailsCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h b/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h new file mode 100644 index 0000000..07d90ee --- /dev/null +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.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 IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_NAVIGATION_CONTROLLER_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_NAVIGATION_CONTROLLER_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +namespace password_manager { + +// Accessibility identifier of the Navigation Bar embedded in the Settings +// Navigation Controller. +extern NSString* const kSettingsNavigationBarAccessibilityID; + +} // namespace password_manager + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_NAVIGATION_CONTROLLER_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.mm new file mode 100644 index 0000000..525e7b16 --- /dev/null +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller_constants.mm
@@ -0,0 +1,12 @@ +// 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. + +#import "ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h" + +namespace password_manager { + +NSString* const kSettingsNavigationBarAccessibilityID = + @"SettingsNavigationBar"; + +}
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm index db61ce3..3ab8177 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -2290,7 +2290,7 @@ _safetyCheckCoordinator = nil; } -#pragma mark - SafetyCheckCoordinatorDelegate +#pragma mark - PasswordsCoordinatorDelegate - (void)passwordsCoordinatorDidRemove:(PasswordsCoordinator*)coordinator { DCHECK_EQ(_passwordsCoordinator, coordinator); @@ -2299,6 +2299,27 @@ _passwordsCoordinator = nil; } +#pragma mark - PasswordManagerReauthenticationDelegate + +- (void)dismissPasswordManagerAfterFailedReauthentication { + // Pop everything up to the Settings page. + // When there is content presented, don't animate the dismissal of the view + // controllers in the navigation controller to prevent revealing passwords + // when the presented content is the one covered by the reauthentication UI. + + UINavigationController* navigationController = self.navigationController; + UIViewController* topViewController = navigationController.topViewController; + UIViewController* presentedViewController = + topViewController.presentedViewController; + + [navigationController popToViewController:self + animated:presentedViewController == nil]; + + [presentedViewController.presentingViewController + dismissViewControllerAnimated:YES + completion:nil]; +} + #pragma mark - NotificationsDelegate - (void)notificationsCoordinatorDidRemove:
diff --git a/ios/chrome/browser/ui/sharing/activity_services/activities/BUILD.gn b/ios/chrome/browser/ui/sharing/activity_services/activities/BUILD.gn index 13e4bec..21fd50b 100644 --- a/ios/chrome/browser/ui/sharing/activity_services/activities/BUILD.gn +++ b/ios/chrome/browser/ui/sharing/activity_services/activities/BUILD.gn
@@ -63,7 +63,7 @@ "//components/prefs:test_support", "//ios/chrome/app/strings", "//ios/chrome/browser/bookmarks/model:test_support", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support",
diff --git a/ios/chrome/browser/ui/sharing/activity_services/activities/request_desktop_or_mobile_site_activity_unittest.mm b/ios/chrome/browser/ui/sharing/activity_services/activities/request_desktop_or_mobile_site_activity_unittest.mm index 85b664b..87a1a4f5 100644 --- a/ios/chrome/browser/ui/sharing/activity_services/activities/request_desktop_or_mobile_site_activity_unittest.mm +++ b/ios/chrome/browser/ui/sharing/activity_services/activities/request_desktop_or_mobile_site_activity_unittest.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/browser/ui/sharing/activity_services/activities/request_desktop_or_mobile_site_activity.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/shared/model/browser/test/test_browser.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn index 4036a5df..f330c49b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -82,10 +82,10 @@ "grid_item_identifier.h", "grid_item_identifier.mm", "grid_item_provider.h", - "grid_layout.h", - "grid_layout.mm", "grid_shareable_items_provider.h", "grid_theme.h", + "legacy_grid_layout.h", + "legacy_grid_layout.mm", ] deps = [
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm index 7732582..132154c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
@@ -32,9 +32,9 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_empty_view.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_header.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_item_identifier.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_shareable_items_provider.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_mutator.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_delegate.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_grid_cell.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/suggested_actions/suggested_actions_view_controller.h" @@ -126,7 +126,7 @@ // Animator to show or hide the empty state. @property(nonatomic, strong) UIViewPropertyAnimator* emptyStateAnimator; // The layout for the tab grid. -@property(nonatomic, strong) GridLayout* gridLayout; +@property(nonatomic, strong) LegacyGridLayout* gridLayout; // The view controller that holds the view of the suggested search actions. @property(nonatomic, strong) SuggestedActionsViewController* suggestedActionsViewController; @@ -187,7 +187,7 @@ #pragma mark - UIViewController - (void)loadView { - self.gridLayout = [[GridLayout alloc] init]; + self.gridLayout = [[LegacyGridLayout alloc] init]; UICollectionView* collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero @@ -464,7 +464,7 @@ return nil; } - GridCell* cell = base::apple::ObjCCastStrict<GridCell>( + GridCell* cell = ObjCCastStrict<GridCell>( [self.collectionView cellForItemAtIndexPath:selectedItemIndexPath]); UICollectionViewLayoutAttributes* attributes = [self.collectionView
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h similarity index 65% rename from ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h rename to ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h index b83484b..6fed032 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_LAYOUT_H_ -#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_LAYOUT_H_ +#ifndef IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_LEGACY_GRID_LAYOUT_H_ +#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_LEGACY_GRID_LAYOUT_H_ #import <UIKit/UIKit.h> @@ -12,11 +12,11 @@ // - The number of columns adapts to the available width and whether an // Accessibility Dynamic Type is selected. // - Item insertions and deletions are animated by default. -@interface GridLayout : UICollectionViewFlowLayout +@interface LegacyGridLayout : UICollectionViewFlowLayout // Whether to animate item insertions and deletions. Defaults to YES. @property(nonatomic, assign) BOOL animatesItemUpdates; @end -#endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_LAYOUT_H_ +#endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_LEGACY_GRID_LAYOUT_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.mm similarity index 98% rename from ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm rename to ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.mm index 6742481..fc2e2c6 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.mm
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/legacy_grid_layout.h" #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" -@implementation GridLayout { +@implementation LegacyGridLayout { NSArray<NSIndexPath*>* _indexPathsOfDeletingItems; NSArray<NSIndexPath*>* _indexPathsOfInsertingItems; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_cell.mm index c70c5f1..cf459c4 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_cell.mm
@@ -252,9 +252,9 @@ - (void)setupSnapshotView { TopAlignedImageView* snapshotView = [[TopAlignedImageView alloc] init]; snapshotView.translatesAutoresizingMaskIntoConstraints = NO; - // Snapshot view is shown only during the animation transtion to the Tab - // view. The Tab view uses not static, but dynaic colors. Therefore, it is - // safe to apply dynaimc color here. + // Snapshot view is shown only during the animation transition to the Tab + // view. The Tab view uses not static, but dynamic colors. Therefore, it is + // safe to apply dynamic color here. snapshotView.backgroundColor = [UIColor colorNamed:kSecondaryBackgroundColor]; snapshotView.hidden = YES; _snapshotView = snapshotView;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm index af667b1..2a9ca60 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -793,7 +793,7 @@ arrayByAddingObjectsFromArray:secondaryInactiveItems]; } -// Sets the proper insets for the Remote Tabs ViewController to accomodate for +// Sets the proper insets for the Remote Tabs ViewController to accommodate for // the safe area, toolbar, and status bar. - (void)setInsetForRemoteTabs { // Sync the scroll view offset to the current page value if the scroll view @@ -827,7 +827,7 @@ } } -// Sets the proper insets for the Grid ViewControllers to accomodate for the +// Sets the proper insets for the Grid ViewControllers to accommodate for the // safe area and toolbars. - (void)setInsetForGridViews { // Sync the scroll view offset to the current page value if the scroll view @@ -1008,6 +1008,9 @@ scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + [self addChildViewController:self.incognitoGridContainerViewController]; + [self addChildViewController:self.regularGridContainerViewController]; + [self addChildViewController:self.remoteGridContainerViewController]; UIStackView* gridsStack = [[UIStackView alloc] initWithArrangedSubviews:@[ self.incognitoGridContainerViewController.view, self.regularGridContainerViewController.view, @@ -1018,6 +1021,10 @@ [scrollView addSubview:gridsStack]; [self.view addSubview:scrollView]; + [self.incognitoGridContainerViewController + didMoveToParentViewController:self]; + [self.regularGridContainerViewController didMoveToParentViewController:self]; + [self.remoteGridContainerViewController didMoveToParentViewController:self]; self.scrollView = scrollView; self.scrollView.scrollEnabled = YES; @@ -1634,7 +1641,7 @@ } } -// Returns YES if a new tab action that tagets the `destinationPage` can be +// Returns YES if a new tab action that targets the `destinationPage` can be // performed. The _currentPage can be the same page as the `destinationPage`. - (BOOL)canPerformOpenNewTabActionForDestinationPage: (TabGridPage)destinationPage { @@ -1746,7 +1753,7 @@ } // Calculates the proper insets for the Incognito Grid ViewController to -// accomodate for the safe area and toolbar. +// accommodate for the safe area and toolbar. - (UIEdgeInsets)calculateInsetForIncognitoGridView { // The content inset of the tab grids must be modified so that the toolbars // do not obscure the tabs. This may change depending on orientation. @@ -1765,7 +1772,7 @@ } // Calculates the proper insets for the Regular Grid ViewController to -// accomodate for the safe area and toolbars. +// accommodate for the safe area and toolbars. - (UIEdgeInsets)calculateInsetForRegularGridView { UIEdgeInsets inset = [self calculateInsetForIncognitoGridView]; @@ -1790,7 +1797,7 @@ - (void)fetchSearchHistoryResultsCountForText:(NSString*)searchText completion:(void (^)(size_t))completion { if (self.currentPage == TabGridPageIncognitoTabs) { - // History retrival shouldn't be done from incognito tabs page. + // History retrieval shouldn't be done from incognito tabs page. completion(0); return; }
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index e158f09c..8457d5d 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -49,7 +49,7 @@ "//ios/chrome/browser/feature_engagement/model", "//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars:public", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/ntp", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser", @@ -175,7 +175,7 @@ "//components/sync_preferences:test_support", "//ios/chrome/app:app_internal", "//ios/chrome/app/application_delegate:application_delegate_internal", - "//ios/chrome/browser/lens", + "//ios/chrome/browser/lens/model", "//ios/chrome/browser/main", "//ios/chrome/browser/ntp", "//ios/chrome/browser/overlays/model",
diff --git a/ios/chrome/browser/web/DEPS b/ios/chrome/browser/web/DEPS index f36612c..b65c1f6 100644 --- a/ios/chrome/browser/web/DEPS +++ b/ios/chrome/browser/web/DEPS
@@ -12,7 +12,7 @@ "+ios/chrome/browser/follow", "+ios/chrome/browser/https_upgrades/model", "+ios/chrome/browser/infobars", - "+ios/chrome/browser/lens/lens_browser_agent.h", + "+ios/chrome/browser/lens/model/lens_browser_agent.h", "+ios/chrome/browser/link_to_text/model", "+ios/chrome/browser/mailto_handler/model", "+ios/chrome/browser/metrics",
diff --git a/ios/chrome/browser/web/web_navigation_browser_agent.mm b/ios/chrome/browser/web/web_navigation_browser_agent.mm index cd2199f..c3394b5 100644 --- a/ios/chrome/browser/web/web_navigation_browser_agent.mm +++ b/ios/chrome/browser/web/web_navigation_browser_agent.mm
@@ -7,7 +7,7 @@ #import "components/feature_engagement/public/event_constants.h" #import "components/feature_engagement/public/tracker.h" #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/shared/model/browser/browser.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
diff --git a/ios/chrome/browser/web/web_navigation_browser_agent_unittest.mm b/ios/chrome/browser/web/web_navigation_browser_agent_unittest.mm index 0755b41..2b7f825 100644 --- a/ios/chrome/browser/web/web_navigation_browser_agent_unittest.mm +++ b/ios/chrome/browser/web/web_navigation_browser_agent_unittest.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/browser/web/web_navigation_browser_agent.h" -#import "ios/chrome/browser/lens/lens_browser_agent.h" +#import "ios/chrome/browser/lens/model/lens_browser_agent.h" #import "ios/chrome/browser/shared/model/browser/browser.h" #import "ios/chrome/browser/shared/model/browser/test/test_browser.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
diff --git a/ios/chrome/common/ui/colors/resources/BUILD.gn b/ios/chrome/common/ui/colors/resources/BUILD.gn index 3731e3d..b4bcfede 100644 --- a/ios/chrome/common/ui/colors/resources/BUILD.gn +++ b/ios/chrome/common/ui/colors/resources/BUILD.gn
@@ -19,6 +19,7 @@ ":disabled_tint_color", ":favicon_background_color", ":green_100_color", + ":green_300_color", ":green_400_color", ":green_500_color", ":green_50_color", @@ -50,8 +51,10 @@ ":purple_500_color", ":purple_600_color", ":red_100_color", + ":red_300_color", ":red_400_color", ":red_500_color", + ":red_50_color", ":red_600_color", ":scrim_background_color", ":secondary_background_color", @@ -138,6 +141,10 @@ sources = [ "green_100_color.colorset/Contents.json" ] } +colorset("green_300_color") { + sources = [ "green_300_color.colorset/Contents.json" ] +} + colorset("green_400_color") { sources = [ "green_400_color.colorset/Contents.json" ] } @@ -202,10 +209,18 @@ sources = [ "static_grey_300_color.colorset/Contents.json" ] } +colorset("red_50_color") { + sources = [ "red_50_color.colorset/Contents.json" ] +} + colorset("red_100_color") { sources = [ "red_100_color.colorset/Contents.json" ] } +colorset("red_300_color") { + sources = [ "red_300_color.colorset/Contents.json" ] +} + colorset("red_400_color") { sources = [ "red_400_color.colorset/Contents.json" ] }
diff --git a/ios/chrome/common/ui/colors/resources/green_300_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/green_300_color.colorset/Contents.json new file mode 100644 index 0000000..afb0c60 --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/green_300_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "alpha": "1.000", + "red": "0x81", + "green": "0xC9", + "blue": "0x95" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "red" : "0x1E", + "green" : "0x8E", + "blue" : "0x3E" + } + } + } + ] +}
diff --git a/ios/chrome/common/ui/colors/resources/red_300_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/red_300_color.colorset/Contents.json new file mode 100644 index 0000000..20071bb --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/red_300_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "alpha": "1.000", + "red": "0xF2", + "green": "0x8B", + "blue": "0x82" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "red" : "0xD9", + "green" : "0x30", + "blue" : "0x25" + } + } + } + ] +}
diff --git a/ios/chrome/common/ui/colors/resources/red_50_color.colorset/Contents.json b/ios/chrome/common/ui/colors/resources/red_50_color.colorset/Contents.json new file mode 100644 index 0000000..65e4b79 --- /dev/null +++ b/ios/chrome/common/ui/colors/resources/red_50_color.colorset/Contents.json
@@ -0,0 +1,38 @@ +{ + "info": { + "version": 1, + "author": "xcode" + }, + "colors": [ + { + "idiom": "universal", + "color": { + "color-space": "display-p3", + "components": { + "alpha": "1.000", + "red": "0xFC", + "green": "0xE8", + "blue": "0xE6" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "red" : "0xA5", + "green" : "0x0E", + "blue" : "0x0E" + } + } + } + ] +}
diff --git a/ios/chrome/common/ui/colors/semantic_color_names.h b/ios/chrome/common/ui/colors/semantic_color_names.h index 5f3d690a..ee9d01ee 100644 --- a/ios/chrome/common/ui/colors/semantic_color_names.h +++ b/ios/chrome/common/ui/colors/semantic_color_names.h
@@ -84,6 +84,7 @@ // Green palette. extern NSString* const kGreen50Color; extern NSString* const kGreen100Color; +extern NSString* const kGreen300Color; extern NSString* const kGreen400Color; extern NSString* const kGreen500Color; extern NSString* const kGreen600Color; @@ -95,7 +96,9 @@ extern NSString* const kRedColor; // Red palette +extern NSString* const kRed50Color; extern NSString* const kRed100Color; +extern NSString* const kRed300Color; extern NSString* const kRed400Color; extern NSString* const kRed500Color; extern NSString* const kRed600Color;
diff --git a/ios/chrome/common/ui/colors/semantic_color_names.mm b/ios/chrome/common/ui/colors/semantic_color_names.mm index e6ee1342..ba65264 100644 --- a/ios/chrome/common/ui/colors/semantic_color_names.mm +++ b/ios/chrome/common/ui/colors/semantic_color_names.mm
@@ -55,13 +55,16 @@ NSString* const kGreenColor = @"green_color"; NSString* const kGreen50Color = @"green_50_color"; NSString* const kGreen100Color = @"green_100_color"; +NSString* const kGreen300Color = @"green_300_color"; NSString* const kGreen400Color = @"green_400_color"; NSString* const kGreen500Color = @"green_500_color"; NSString* const kGreen600Color = @"green_600_color"; NSString* const kGreen700Color = @"green_700_color"; NSString* const kGreen800Color = @"green_800_color"; +NSString* const kRed50Color = @"red_50_color"; NSString* const kRed100Color = @"red_100_color"; +NSString* const kRed300Color = @"red_300_color"; NSString* const kRed400Color = @"red_400_color"; NSString* const kRed500Color = @"red_500_color"; NSString* const kRed600Color = @"red_600_color";
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 79dc31c..26d24acd 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -231,7 +231,7 @@ "//ios/chrome/browser/itunes_urls/model:unit_tests", "//ios/chrome/browser/json_parser:unit_tests", "//ios/chrome/browser/language/model:unit_tests", - "//ios/chrome/browser/lens:unit_tests", + "//ios/chrome/browser/lens/model:unit_tests", "//ios/chrome/browser/link_to_text/model:unit_tests", "//ios/chrome/browser/main:unit_tests", "//ios/chrome/browser/metrics:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 7d4d1ac..83b396f 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -159,6 +159,7 @@ "//ios/chrome/browser/ui/settings:constants", "//ios/chrome/browser/ui/settings:eg_app_support+eg2", "//ios/chrome/browser/ui/settings:settings", + "//ios/chrome/browser/ui/settings:settings_navigation_controller_constants", "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings:settings_root_constants", "//ios/chrome/browser/ui/settings/autofill",
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index 4d7dd43..c604114 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -343,6 +343,10 @@ // Returns a matcher for the Google Services Settings view. id<GREYMatcher> GoogleServicesSettingsView(); +// Returns matcher for the Navigation Bar embedded in the Settings Navigation +// Controller. +id<GREYMatcher> SettingsNavigationBar(); + // Returns a matcher for the back button on a settings menu. id<GREYMatcher> SettingsMenuBackButton();
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index 2e5556b..d986d99 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -425,6 +425,10 @@ return [ChromeMatchersAppInterface googleServicesSettingsView]; } +id<GREYMatcher> SettingsNavigationBar() { + return [ChromeMatchersAppInterface settingsNavigationBar]; +} + id<GREYMatcher> SettingsMenuBackButton() { return [ChromeMatchersAppInterface settingsMenuBackButton]; }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index 7c9c745..e99b331c 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -331,6 +331,10 @@ // Returns matcher for the Google Services Settings view. + (id<GREYMatcher>)googleServicesSettingsView; +// Returns matcher for the Navigation Bar embedded in the Settings Navigation +// Controller. ++ (id<GREYMatcher>)settingsNavigationBar; + // Returns matcher for the back button on a settings menu. + (id<GREYMatcher>)settingsMenuBackButton;
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index 4234696..27f224e 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -57,6 +57,7 @@ #import "ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.h" #import "ios/chrome/browser/ui/settings/safety_check/safety_check_ui_swift.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" +#import "ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h" #import "ios/chrome/browser/ui/settings/settings_root_table_constants.h" #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h" #import "ios/chrome/browser/ui/settings/tabs/tabs_settings_constants.h" @@ -715,6 +716,14 @@ return grey_accessibilityID(kGoogleServicesSettingsViewIdentifier); } ++ (id<GREYMatcher>)settingsNavigationBar { + return grey_allOf( + grey_kindOfClass([UINavigationBar class]), + grey_accessibilityID( + password_manager::kSettingsNavigationBarAccessibilityID), + nil); +} + + (id<GREYMatcher>)settingsMenuBackButton:(NSString*)buttonTitle { return grey_allOf( grey_anyOf(grey_accessibilityLabel(buttonTitle), @@ -726,8 +735,9 @@ + (id<GREYMatcher>)settingsMenuBackButton { UINavigationBar* navBar = base::apple::ObjCCastStrict<UINavigationBar>( - SubviewWithAccessibilityIdentifier(@"SettingNavigationBar", - GetAnyKeyWindow())); + SubviewWithAccessibilityIdentifier( + password_manager::kSettingsNavigationBarAccessibilityID, + GetAnyKeyWindow())); return [ChromeMatchersAppInterface settingsMenuBackButton:navBar.backItem.title]; } @@ -735,8 +745,9 @@ + (id<GREYMatcher>)settingsMenuBackButtonInWindowWithNumber:(int)windowNumber { UINavigationBar* navBar = base::apple::ObjCCastStrict<UINavigationBar>( SubviewWithAccessibilityIdentifier( - @"SettingNavigationBar", WindowWithAccessibilityIdentifier([NSString - stringWithFormat:@"%d", windowNumber]))); + password_manager::kSettingsNavigationBarAccessibilityID, + WindowWithAccessibilityIdentifier( + [NSString stringWithFormat:@"%d", windowNumber]))); return [ChromeMatchersAppInterface settingsMenuBackButton:navBar.backItem.title]; }
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn index ff6e7df4..1d3ac06c 100644 --- a/ios/chrome/test/earl_grey2/BUILD.gn +++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -177,6 +177,7 @@ xcode_test_application_name = "ios_chrome_eg2tests" deps = [ + "//ios/chrome/browser/plus_addresses/ui:eg2_tests", "//ios/chrome/browser/settings/model/sync/utils:eg2_tests", "//ios/chrome/browser/ui/autofill/bottom_sheet:eg2_tests", "//ios/chrome/browser/ui/autofill/form_input_accessory:eg2_tests",
diff --git a/ios/showcase/bubble/sc_side_swipe_bubble_view_controller.mm b/ios/showcase/bubble/sc_side_swipe_bubble_view_controller.mm index e1f81b79..9efcb55 100644 --- a/ios/showcase/bubble/sc_side_swipe_bubble_view_controller.mm +++ b/ios/showcase/bubble/sc_side_swipe_bubble_view_controller.mm
@@ -14,7 +14,13 @@ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - UILayoutGuide* guide = self.view.safeAreaLayoutGuide; + UILayoutGuide* guide = [[UILayoutGuide alloc] init]; + [self.view addLayoutGuide:guide]; + AddSameConstraintsToSides(guide, self.view.safeAreaLayoutGuide, + LayoutSides::kTop); + AddSameConstraintsToSides( + guide, self.view, + LayoutSides::kLeading | LayoutSides::kTrailing | LayoutSides::kBottom); SideSwipeBubbleView* sideSwipeBubbleView = [[SideSwipeBubbleView alloc] initWithText:@"Lorem ipsum dolor" bubbleBoundingSize:guide.layoutFrame.size
diff --git a/ios/testing/data/http_server_files/email_signup_form.html b/ios/testing/data/http_server_files/email_signup_form.html new file mode 100644 index 0000000..61270f8f --- /dev/null +++ b/ios/testing/data/http_server_files/email_signup_form.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> + +<html><body> +Signup form, where the username is an email field. This mimics common two-step registration forms. +<form name='signup_form' id='signup_form' action='https://google.com/'> + <input type='email' autocomplete="email" name='email' id='email'><br/> + <button id='submit_button' value='Submit'>Submit</button> +</form> +</body></html>
diff --git a/ios/testing/http_server_bundle_data.filelist b/ios/testing/http_server_bundle_data.filelist index 44f0c51d..78f718ab 100644 --- a/ios/testing/http_server_bundle_data.filelist +++ b/ios/testing/http_server_bundle_data.filelist
@@ -34,6 +34,7 @@ data/http_server_files/permissions/camera_and_microphone.html data/http_server_files/permissions/camera_only.html data/http_server_files/permissions/microphone_only.html +data/http_server_files/email_signup_form.html data/http_server_files/pony.html data/http_server_files/profile_form.html data/http_server_files/readonly_form.html
diff --git a/ios_internal b/ios_internal index 12205ca..5949510 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 12205cac93d6adfbfad832d5c9401fbd1c19fa35 +Subproject commit 59495100bd8b3729c012f890af55c96c9abb3e27
diff --git a/media/base/media_serializers.h b/media/base/media_serializers.h index 7a398e2..d0168d8 100644 --- a/media/base/media_serializers.h +++ b/media/base/media_serializers.h
@@ -281,21 +281,19 @@ template <> struct MediaSerializer<gfx::HDRMetadata> { static base::Value Serialize(const gfx::HDRMetadata& value) { - // TODO(tmathmeyer) serialize more fields here potentially. - gfx::HdrMetadataSmpteSt2086 smpte_st_2086 = - value.smpte_st_2086.value_or(gfx::HdrMetadataSmpteSt2086()); base::Value::Dict result; - FIELD_SERIALIZE( - "luminance range", - base::StringPrintf("%.2f => %.2f", smpte_st_2086.luminance_min, - smpte_st_2086.luminance_max)); - const auto& primaries = smpte_st_2086.primaries; - FIELD_SERIALIZE( - "primaries", - base::StringPrintf( - "[r:%.4f,%.4f, g:%.4f,%.4f, b:%.4f,%.4f, wp:%.4f,%.4f]", - primaries.fRX, primaries.fRY, primaries.fGX, primaries.fGY, - primaries.fBX, primaries.fBY, primaries.fWX, primaries.fWY)); + if (value.smpte_st_2086.has_value()) { + FIELD_SERIALIZE("smpte_st_2086", value.smpte_st_2086->ToString()); + } + if (value.cta_861_3.has_value()) { + FIELD_SERIALIZE("cta_861_3", value.cta_861_3->ToString()); + } + if (value.ndwl.has_value()) { + FIELD_SERIALIZE("ndwl", value.ndwl->ToString()); + } + if (value.extended_range.has_value()) { + FIELD_SERIALIZE("extended_range", value.extended_range->ToString()); + } return base::Value(std::move(result)); } };
diff --git a/media/ffmpeg/ffmpeg_common.cc b/media/ffmpeg/ffmpeg_common.cc index ca4ad005..d98b9b6 100644 --- a/media/ffmpeg/ffmpeg_common.cc +++ b/media/ffmpeg/ffmpeg_common.cc
@@ -726,33 +726,44 @@ if (stream->nb_side_data) { for (int i = 0; i < stream->nb_side_data; ++i) { AVPacketSideData side_data = stream->side_data[i]; - if (side_data.type != AV_PKT_DATA_MASTERING_DISPLAY_METADATA) - continue; + switch (side_data.type) { + case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: { + AVMasteringDisplayMetadata* mdcv = + reinterpret_cast<AVMasteringDisplayMetadata*>(side_data.data); + gfx::HdrMetadataSmpteSt2086 smpte_st_2086; + if (mdcv->has_primaries) { + smpte_st_2086.primaries = { + static_cast<float>(av_q2d(mdcv->display_primaries[0][0])), + static_cast<float>(av_q2d(mdcv->display_primaries[0][1])), + static_cast<float>(av_q2d(mdcv->display_primaries[1][0])), + static_cast<float>(av_q2d(mdcv->display_primaries[1][1])), + static_cast<float>(av_q2d(mdcv->display_primaries[2][0])), + static_cast<float>(av_q2d(mdcv->display_primaries[2][1])), + static_cast<float>(av_q2d(mdcv->white_point[0])), + static_cast<float>(av_q2d(mdcv->white_point[1])), + }; + } + if (mdcv->has_luminance) { + smpte_st_2086.luminance_max = av_q2d(mdcv->max_luminance); + smpte_st_2086.luminance_min = av_q2d(mdcv->min_luminance); + } - AVMasteringDisplayMetadata* metadata = - reinterpret_cast<AVMasteringDisplayMetadata*>(side_data.data); - gfx::HdrMetadataSmpteSt2086 smpte_st_2086; - if (metadata->has_primaries) { - smpte_st_2086.primaries = { - static_cast<float>(av_q2d(metadata->display_primaries[0][0])), - static_cast<float>(av_q2d(metadata->display_primaries[0][1])), - static_cast<float>(av_q2d(metadata->display_primaries[1][0])), - static_cast<float>(av_q2d(metadata->display_primaries[1][1])), - static_cast<float>(av_q2d(metadata->display_primaries[2][0])), - static_cast<float>(av_q2d(metadata->display_primaries[2][1])), - static_cast<float>(av_q2d(metadata->white_point[0])), - static_cast<float>(av_q2d(metadata->white_point[1])), - }; - } - if (metadata->has_luminance) { - smpte_st_2086.luminance_max = av_q2d(metadata->max_luminance); - smpte_st_2086.luminance_min = av_q2d(metadata->min_luminance); - } - - // TODO(https://crbug.com/1446302): Consider rejecting metadata that does - // not specify all values. - if (metadata->has_primaries || metadata->has_luminance) { - hdr_metadata.smpte_st_2086 = smpte_st_2086; + // TODO(https://crbug.com/1446302): Consider rejecting metadata that + // does not specify all values. + if (mdcv->has_primaries || mdcv->has_luminance) { + hdr_metadata.smpte_st_2086 = smpte_st_2086; + } + break; + } + case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: { + AVContentLightMetadata* clli = + reinterpret_cast<AVContentLightMetadata*>(side_data.data); + hdr_metadata.cta_861_3 = + gfx::HdrMetadataCta861_3(clli->MaxCLL, clli->MaxFALL); + break; + } + default: + break; } } }
diff --git a/media/ffmpeg/ffmpeg_common_unittest.cc b/media/ffmpeg/ffmpeg_common_unittest.cc index f86cb59..69b5309 100644 --- a/media/ffmpeg/ffmpeg_common_unittest.cc +++ b/media/ffmpeg/ffmpeg_common_unittest.cc
@@ -372,6 +372,9 @@ EXPECT_EQ(0.2f, smpte_st_2086.primaries.fBY); EXPECT_EQ(0.1f, smpte_st_2086.primaries.fWX); EXPECT_EQ(0.2f, smpte_st_2086.primaries.fWY); + const auto& cta_861_3 = video_config.hdr_metadata()->cta_861_3.value(); + EXPECT_EQ(11.0f, cta_861_3.max_content_light_level); + EXPECT_EQ(12.0f, cta_861_3.max_frame_average_light_level); EXPECT_EQ(VideoColorSpace(VideoColorSpace::PrimaryID::SMPTEST428_1, VideoColorSpace::TransferID::LOG, VideoColorSpace::MatrixID::RGB,
diff --git a/media/mojo/mojom/audio_stream_factory.mojom b/media/mojo/mojom/audio_stream_factory.mojom index 981a511..59cca42 100644 --- a/media/mojo/mojom/audio_stream_factory.mojom +++ b/media/mojo/mojom/audio_stream_factory.mojom
@@ -12,6 +12,7 @@ import "media/mojo/mojom/audio_processing.mojom"; import "mojo/public/mojom/base/shared_memory.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; +import "sandbox/policy/mojom/context.mojom"; // Mutes a group of AudioOutputStreams while at least one binding to an instance // exists. Once the last binding is dropped, all streams in the group are @@ -25,6 +26,9 @@ // // The client must keep the connection to the factory while streams are // running. +// Note: requires kPrivilegedUtility (rather than kBrowser) as the speech +// recognition service & libassistant call these directly. +[RequireContext=sandbox.mojom.Context.kPrivilegedUtility] interface AudioStreamFactory { // Creates an AudioInputStream and returns the AudioDataPipe it writes data to // and a bool indicating whether the stream is initially muted. |data_pipe| is
diff --git a/media/mojo/mojom/speech_recognition_service.mojom b/media/mojo/mojom/speech_recognition_service.mojom index bce5a83..e5dc2f4 100644 --- a/media/mojo/mojom/speech_recognition_service.mojom +++ b/media/mojo/mojom/speech_recognition_service.mojom
@@ -10,6 +10,7 @@ import "media/mojo/mojom/media_types.mojom"; import "media/mojo/mojom/speech_recognition.mojom"; import "mojo/public/mojom/base/file_path.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; // Like a SpeechRecognitionContext, except it binds AudioSourceFetcher speech @@ -17,10 +18,12 @@ // Chrome OS features like Dictation and Projector, every // OnDeviceSpeechRecognizer can own a // Remote<AudioSourceSpeechRecognitionContext>. +[RequireContext=sandbox.mojom.Context.kBrowser] interface AudioSourceSpeechRecognitionContext { // Prepares microphone audio to be captured from within the // SpeechRecognitionService process, with results passed back to the // SpeechRecognitionRecognizerClient. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindAudioSourceFetcher( pending_receiver<AudioSourceFetcher> fetcher_receiver, pending_remote<SpeechRecognitionRecognizerClient> client, @@ -31,7 +34,8 @@ // The main interface to a speech secognition service process. // Used by the browser to issue top-level control requests to the service, // acquired during process launch. -[ServiceSandbox=sandbox.mojom.Sandbox.kSpeechRecognition] +[ServiceSandbox=sandbox.mojom.Sandbox.kSpeechRecognition, + RequireContext=sandbox.mojom.Context.kBrowser] interface SpeechRecognitionService { // Binds a new SpeechRecognitionContext hosted in the service process. BindSpeechRecognitionContext( @@ -39,6 +43,7 @@ // Binds a new AudioSourceSpeechRecognitionContext hosted in the service // process. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindAudioSourceSpeechRecognitionContext( pending_receiver<AudioSourceSpeechRecognitionContext> context); @@ -57,11 +62,14 @@ }; // The interface used to start and stop fetching audio from the microphone -// for speech recognition. +// for speech recognition. Provided by the browser to the speech recognition +// service. +[RequireContext=sandbox.mojom.Context.kPrivilegedUtility] interface AudioSourceFetcher { // Begin fetching audio. Results will be returned using the // Remote<SpeechRecognitionRecognizerClient> which was passed in // BindAudioSourceFetcher. + [AllowedContext=sandbox.mojom.Context.kPrivilegedUtility] Start(pending_remote<AudioStreamFactory> factory, string device_id, media.mojom.AudioParameters audio_parameters);
diff --git a/media/renderers/win/media_foundation_video_stream.cc b/media/renderers/win/media_foundation_video_stream.cc index a6e2685..767dc89 100644 --- a/media/renderers/win/media_foundation_video_stream.cc +++ b/media/renderers/win/media_foundation_video_stream.cc
@@ -272,6 +272,19 @@ RETURN_IF_FAILED(media_type->SetBlob(MF_MT_CUSTOM_VIDEO_PRIMARIES, reinterpret_cast<UINT8*>(&primaries), sizeof(MT_CUSTOM_VIDEO_PRIMARIES))); + + if (hdr_metadata.cta_861_3.has_value()) { + UINT32 max_luminance_level = + hdr_metadata.cta_861_3->max_content_light_level; + RETURN_IF_FAILED(media_type->SetUINT32(MF_MT_MAX_LUMINANCE_LEVEL, + max_luminance_level)); + + UINT32 max_frame_average_luminance_level = + hdr_metadata.cta_861_3->max_frame_average_light_level; + RETURN_IF_FAILED( + media_type->SetUINT32(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL, + max_frame_average_luminance_level)); + } } base::UmaHistogramEnumeration( "Media.MediaFoundation.VideoColorSpace.TransferID",
diff --git a/net/cert/ct_serialization.cc b/net/cert/ct_serialization.cc index 8cf2d4d5..56fe9a9 100644 --- a/net/cert/ct_serialization.cc +++ b/net/cert/ct_serialization.cc
@@ -376,22 +376,33 @@ return true; } -bool EncodeSCTListForTesting(base::StringPiece sct, std::string* output) { - bssl::ScopedCBB encoded_sct, output_cbb; - CBB encoded_sct_child, output_child; - if (!CBB_init(encoded_sct.get(), 64) || !CBB_init(output_cbb.get(), 64) || - !CBB_add_u16_length_prefixed(encoded_sct.get(), &encoded_sct_child) || - !CBB_add_bytes(&encoded_sct_child, - reinterpret_cast<const uint8_t*>(sct.data()), - sct.size()) || - !CBB_flush(encoded_sct.get()) || - !CBB_add_u16_length_prefixed(output_cbb.get(), &output_child) || - !CBB_add_bytes(&output_child, CBB_data(encoded_sct.get()), - CBB_len(encoded_sct.get())) || - !CBB_flush(output_cbb.get())) { +bool EncodeSCTListForTesting(const std::vector<std::string>& scts, + std::string* output) { + bssl::ScopedCBB output_cbb; + CBB output_child; + if (!CBB_init(output_cbb.get(), 64) || + !CBB_add_u16_length_prefixed(output_cbb.get(), &output_child)) { return false; } + for (const std::string& sct : scts) { + bssl::ScopedCBB encoded_sct; + CBB encoded_sct_child; + if (!CBB_init(encoded_sct.get(), 64) || + !CBB_add_u16_length_prefixed(encoded_sct.get(), &encoded_sct_child) || + !CBB_add_bytes(&encoded_sct_child, + reinterpret_cast<const uint8_t*>(sct.data()), + sct.size()) || + !CBB_flush(encoded_sct.get()) || + !CBB_add_bytes(&output_child, CBB_data(encoded_sct.get()), + CBB_len(encoded_sct.get()))) { + return false; + } + } + + if (!CBB_flush(output_cbb.get())) { + return false; + } output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())), CBB_len(output_cbb.get())); return true;
diff --git a/net/cert/ct_serialization.h b/net/cert/ct_serialization.h index 589b9f3..edfc8ef 100644 --- a/net/cert/ct_serialization.h +++ b/net/cert/ct_serialization.h
@@ -92,9 +92,10 @@ const scoped_refptr<ct::SignedCertificateTimestamp>& input, std::string* output); -// Writes an SCTList into |output|, containing a single |sct|. -NET_EXPORT_PRIVATE bool EncodeSCTListForTesting(base::StringPiece sct, - std::string* output); +// Writes an SCTList into |output|, containing |scts|. +NET_EXPORT_PRIVATE bool EncodeSCTListForTesting( + const std::vector<std::string>& scts, + std::string* output); } // namespace net::ct #endif // NET_CERT_CT_SERIALIZATION_H_
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 5023298..12434e81 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -1207,7 +1207,6 @@ CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE); } - // Only apply SameSite-related warnings if SameParty is not in effect. ApplySameSiteCookieWarningToStatus(SameSite(), effective_same_site, IsSecure(), options.same_site_cookie_context(), @@ -1381,7 +1380,6 @@ break; } - // Only apply SameSite-related warnings if SameParty is not in effect. ApplySameSiteCookieWarningToStatus( SameSite(), access_result.effective_same_site, IsSecure(), options.same_site_cookie_context(), &access_result.status,
diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h index 8d07fde..20ae24b 100644 --- a/net/cookies/canonical_cookie.h +++ b/net/cookies/canonical_cookie.h
@@ -232,7 +232,6 @@ bool IsHttpOnly() const { return httponly_; } CookieSameSite SameSite() const { return same_site_; } CookiePriority Priority() const { return priority_; } - bool IsSameParty() const { return false; } bool IsPartitioned() const { return partition_key_.has_value(); } const absl::optional<CookiePartitionKey>& PartitionKey() const { return partition_key_;
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc index 6fc4599..18f97e0 100644 --- a/net/cookies/canonical_cookie_unittest.cc +++ b/net/cookies/canonical_cookie_unittest.cc
@@ -67,7 +67,6 @@ EXPECT_FALSE(cookie1->IsHttpOnly()); EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1->SameSite()); EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1->Priority()); - EXPECT_FALSE(cookie1->IsSameParty()); EXPECT_FALSE(cookie1->IsPartitioned()); EXPECT_EQ(cookie1->SourceScheme(), CookieSourceScheme::kSecure); EXPECT_EQ(cookie1->SourcePort(), 443); @@ -86,7 +85,6 @@ EXPECT_FALSE(cookie2->IsHttpOnly()); EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite()); EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2->Priority()); - EXPECT_FALSE(cookie2->IsSameParty()); EXPECT_TRUE(cookie2->IsPartitioned()); EXPECT_EQ(cookie2->SourceScheme(), CookieSourceScheme::kNonSecure); // Because the port can be set explicitly in the constructor its value can be @@ -114,7 +112,6 @@ EXPECT_FALSE(cookie4->IsSecure()); EXPECT_FALSE(cookie4->IsHttpOnly()); EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4->SameSite()); - EXPECT_FALSE(cookie4->IsSameParty()); EXPECT_FALSE(cookie4->IsPartitioned()); EXPECT_EQ(cookie4->SourceScheme(), CookieSourceScheme::kUnset); EXPECT_EQ(cookie4->SourcePort(), url::PORT_UNSPECIFIED); @@ -651,58 +648,6 @@ } } -TEST(CanonicalCookieTest, CreateSameParty) { - GURL url("http://www.example.com/test/foo.html"); - GURL https_url("https://www.example.com/test/foo.html"); - base::Time creation_time = base::Time::Now(); - absl::optional<base::Time> server_time = absl::nullopt; - - CookieInclusionStatus status; - std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create( - url, "A=2; SameParty; Secure", creation_time, server_time, - /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true, - &status); - ASSERT_TRUE(cookie.get()); - EXPECT_TRUE(status.IsInclude()); - EXPECT_TRUE(cookie->IsSecure()); - EXPECT_FALSE(cookie->IsSameParty()); - EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite()); - - cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=None; Secure", - creation_time, server_time, - /*cookie_partition_key=*/absl::nullopt, - /*block_truncated=*/true, &status); - ASSERT_TRUE(cookie.get()); - EXPECT_TRUE(status.IsInclude()); - EXPECT_TRUE(cookie->IsSecure()); - EXPECT_FALSE(cookie->IsSameParty()); - EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite()); - - cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=Lax; Secure", - creation_time, server_time, - /*cookie_partition_key=*/absl::nullopt, - /*block_truncated=*/true, &status); - ASSERT_TRUE(cookie.get()); - EXPECT_TRUE(status.IsInclude()); - EXPECT_TRUE(cookie->IsSecure()); - EXPECT_FALSE(cookie->IsSameParty()); - EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite()); - - // SameParty cookie with SameSite=Strict is valid, since SameParty is ignored. - cookie = CanonicalCookie::Create( - url, "A=2; SameParty; SameSite=Strict; Secure", creation_time, - server_time, /*cookie_partition_key=*/absl::nullopt, - /*block_truncated=*/true, &status); - EXPECT_TRUE(cookie.get()); - - // SameParty cookie without Secure is valid, since SameParty is ignored. - cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=Lax", - creation_time, server_time, - /*cookie_partition_key=*/absl::nullopt, - /*block_truncated=*/true, &status); - EXPECT_TRUE(cookie.get()); -} - TEST(CanonicalCookieTest, CreateWithPartitioned) { GURL url("https://www.example.com/test/foo.html"); base::Time creation_time = base::Time::Now(); @@ -2102,50 +2047,6 @@ {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE})); } -TEST(CanonicalCookieTest, IncludeForRequestURLSameParty) { - GURL url("https://www.example.com"); - base::Time creation_time = base::Time::Now(); - absl::optional<base::Time> server_time = absl::nullopt; - CookieOptions options; - - // SameSite is not specified. - std::unique_ptr<CanonicalCookie> cookie_samesite_unspecified = - CanonicalCookie::Create(url, "A=2; SameParty; Secure", creation_time, - server_time, - absl::nullopt /* cookie_partition_key */); - ASSERT_TRUE(cookie_samesite_unspecified.get()); - EXPECT_TRUE(cookie_samesite_unspecified->IsSecure()); - EXPECT_EQ(CookieSameSite::UNSPECIFIED, - cookie_samesite_unspecified->SameSite()); - EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, - cookie_samesite_unspecified->GetEffectiveSameSiteForTesting()); - EXPECT_FALSE(cookie_samesite_unspecified->IsSameParty()); - - // SameSite=None. - std::unique_ptr<CanonicalCookie> cookie_samesite_none = - CanonicalCookie::Create(url, "A=2; SameSite=None; SameParty; Secure", - creation_time, server_time, - absl::nullopt /* cookie_partition_key */); - ASSERT_TRUE(cookie_samesite_none.get()); - EXPECT_TRUE(cookie_samesite_none->IsSecure()); - EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie_samesite_none->SameSite()); - EXPECT_EQ(CookieEffectiveSameSite::NO_RESTRICTION, - cookie_samesite_none->GetEffectiveSameSiteForTesting()); - EXPECT_FALSE(cookie_samesite_none->IsSameParty()); - - // SameSite=Lax. - std::unique_ptr<CanonicalCookie> cookie_samesite_lax = - CanonicalCookie::Create(url, "A=2; SameSite=Lax; SameParty; Secure", - creation_time, server_time, - absl::nullopt /* cookie_partition_key */); - ASSERT_TRUE(cookie_samesite_lax.get()); - EXPECT_TRUE(cookie_samesite_lax->IsSecure()); - EXPECT_EQ(CookieSameSite::LAX_MODE, cookie_samesite_lax->SameSite()); - EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE, - cookie_samesite_lax->GetEffectiveSameSiteForTesting()); - EXPECT_FALSE(cookie_samesite_lax->IsSameParty()); -} - TEST(CanonicalCookieTest, IncludeForRequestURL_SameSiteNone_Metrics) { constexpr bool delegate_treats_url_as_trustworthy = false; const base::Time now = base::Time::Now(); @@ -3655,7 +3556,6 @@ EXPECT_FALSE(cc->IsHttpOnly()); EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite()); EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority()); - EXPECT_FALSE(cc->IsSameParty()); EXPECT_FALSE(cc->IsPartitioned()); EXPECT_FALSE(cc->IsDomainCookie()); EXPECT_TRUE(status.IsInclude()); @@ -4206,7 +4106,7 @@ absl::nullopt /*partition_key*/, &status)); EXPECT_TRUE(status.IsInclude()); - // Partitioned attribute requires __Host- and forbids SameParty. + // Partitioned attribute requires __Host-. status = CookieInclusionStatus(); EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie( GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/", @@ -5552,32 +5452,6 @@ MatchesCookieAccessResult(net::IsInclude(), _, _, true)); } -TEST(CanonicalCookieTest, IsSetPermitted_SameParty) { - GURL url("https://www.example.com/test"); - base::Time current_time = base::Time::Now(); - CookieOptions options; - options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext( - CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE)); - - { - bool delegate_treats_url_as_trustworthy = false; - auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting( - "A", "2", "www.example.com", "/test", current_time, base::Time(), - base::Time(), base::Time(), true /* secure */, false /*httponly*/, - CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT); - - EXPECT_THAT(cookie->IsSetPermittedInContext( - url, options, - CookieAccessParams(CookieAccessSemantics::LEGACY, - delegate_treats_url_as_trustworthy), - kCookieableSchemes), - MatchesCookieAccessResult( - CookieInclusionStatus::MakeFromReasonsForTesting( - {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}), - _, _, true)); - } -} - // Test that the CookieInclusionStatus warning for inclusion changed by // cross-site redirect context downgrade is applied correctly. TEST(CanonicalCookieTest, IsSetPermittedInContext_RedirectDowngradeWarning) {
diff --git a/net/cookies/cookie_inclusion_status.h b/net/cookies/cookie_inclusion_status.h index 1eefc3d..fa6562e 100644 --- a/net/cookies/cookie_inclusion_status.h +++ b/net/cookies/cookie_inclusion_status.h
@@ -78,8 +78,7 @@ // Cookie was set with an invalid __Host- or __Secure- prefix. EXCLUDE_INVALID_PREFIX = 15, /// Cookie was set with an invalid Partitioned attribute, which is only - // valid if the cookie has a __Host- prefix and does not have the SameParty - // attribute. + // valid if the cookie has a __Host- prefix. EXCLUDE_INVALID_PARTITIONED = 16, // Cookie exceeded the name/value pair size limit. EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE = 17, @@ -379,9 +378,7 @@ // Returns true if the cookie was excluded because of user preferences. // HasOnlyExclusionReason(EXCLUDE_USER_PREFERENCES) will not return true for - // third-party cookies blocked in sites in the same First-Party Set (note: - // this is not the same as the cookie being blocked in a same-party context, - // which takes the entire ancestor chain into account). See + // third-party cookies blocked in sites in the same First-Party Set. See // https://crbug.com/1366868. bool ExcludedByUserPreferences() const;
diff --git a/net/cookies/cookie_monster_netlog_params.cc b/net/cookies/cookie_monster_netlog_params.cc index 7f7660606..6679203 100644 --- a/net/cookies/cookie_monster_netlog_params.cc +++ b/net/cookies/cookie_monster_netlog_params.cc
@@ -33,7 +33,6 @@ dict.Set("same_site", CookieSameSiteToString(cookie->SameSite())); dict.Set("is_persistent", cookie->IsPersistent()); dict.Set("sync_requested", sync_requested); - dict.Set("same_party", cookie->IsSameParty()); return dict; }
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 005bbb87..d6afec6 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -269,7 +269,6 @@ // * Three levels of host cookie (w.b.a, w.c.b.a, w.d.c.b.a) // * http_only cookie (w.c.b.a) // * same_site cookie (w.c.b.a) - // * same_party cookie (w.c.b.a) // * Two secure cookies (.c.b.a, w.c.b.a) // * Two domain path cookies (.c.b.a/dir1, .c.b.a/dir1/dir2) // * Two host path cookies (w.c.b.a/dir1, w.c.b.a/dir1/dir2) @@ -317,12 +316,6 @@ base::Time(), base::Time(), base::Time(), false, false, CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT)); - // same-party cookie - cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting( - "same_party_check", "A", url_top_level_domain_plus_2, "/", now, - base::Time(), base::Time(), base::Time(), true /* secure */, false, - CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT)); - // Secure cookies cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting( "sec_dom", "A", ".math.harvard.edu", "/", now, base::Time(), @@ -1915,7 +1908,7 @@ EXPECT_TRUE(CreateAndSetCookie( cm.get(), https_www_foo_.url(), - https_www_foo_.Format("I=J; domain=.%D; secure; sameparty"), options)); + https_www_foo_.Format("I=J; domain=.%D; secure"), options)); // Create partitioned cookies for the same site with some partition key. auto cookie_partition_key1 = @@ -2646,7 +2639,7 @@ CookieDeletionInfo delete_info(base::Time(), now); delete_info.value_for_testing = "A"; - EXPECT_EQ(9u, DeleteAllMatchingInfo(cm.get(), std::move(delete_info))); + EXPECT_EQ(8u, DeleteAllMatchingInfo(cm.get(), std::move(delete_info))); EXPECT_EQ("dom_2=B; dom_3=C; host_3=C", GetCookies(cm.get(), GURL(kTopLevelDomainPlus3))); @@ -4693,50 +4686,6 @@ NetLogEventPhase::NONE); } -TEST_F(CookieMonsterTest, SetSamePartyCookies) { - CookieMonster cm(nullptr, net::NetLog::Get()); - GURL http_url("http://www.foo.com"); - GURL http_superdomain_url("http://foo.com"); - GURL https_url("https://www.foo.com"); - GURL https_foo_url("https://www.foo.com/foo"); - GURL http_foo_url("http://www.foo.com/foo"); - - // A non-SameParty cookie can be created from either a URL with a secure or - // insecure scheme. - EXPECT_TRUE( - CreateAndSetCookieReturnStatus(&cm, http_url, "A=C;").IsInclude()); - EXPECT_TRUE( - CreateAndSetCookieReturnStatus(&cm, https_url, "A=B;").IsInclude()); - - // A SameParty cookie can be set without the Secure attribute. - EXPECT_TRUE(CreateAndSetCookieReturnStatus(&cm, https_url, "A=B; SameParty") - .IsInclude()); - - // A SameParty cookie can be set from a URL with a secure scheme. - EXPECT_TRUE( - CreateAndSetCookieReturnStatus(&cm, https_url, "A=B; Secure; SameParty") - .IsInclude()); - - // If a non-SameParty cookie is created from a URL with an secure scheme, and - // a SameParty cookie with the same name already exists, update the cookie. - EXPECT_TRUE( - CreateAndSetCookieReturnStatus(&cm, https_url, "A=B; Secure; SameParty") - .IsInclude()); - EXPECT_TRUE(CreateAndSetCookieReturnStatus(&cm, https_url, "A=C; Secure;") - .IsInclude()); - - DeleteAll(&cm); - - // If a SameParty cookie is set on top of an existing non-SameParty cookie but - // with a different path, both are retained. - EXPECT_TRUE( - CreateAndSetCookieReturnStatus(&cm, https_url, "A=B; path=/foo; Secure") - .IsInclude()); - EXPECT_TRUE(CreateAndSetCookieReturnStatus(&cm, https_url, - "A=C; Secure; path=/; SameParty") - .IsInclude()); -} - // Tests the behavior of "Leave Secure Cookies Alone" in // MaybeDeleteEquivalentCookieAndUpdateStatus(). // Check domain-match criterion: If either cookie domain matches the other,
diff --git a/net/cookies/cookie_options.h b/net/cookies/cookie_options.h index 183c1f6..b240265 100644 --- a/net/cookies/cookie_options.h +++ b/net/cookies/cookie_options.h
@@ -228,14 +228,12 @@ // * Excludes SameSite cookies // * Updates last-accessed time. // * Does not report excluded cookies in APIs that can do so. - // * Excludes SameParty cookies. // // These settings can be altered by calling: // // * |set_{include,exclude}_httponly()| // * |set_same_site_cookie_context()| // * |set_do_not_update_access_time()| - // * |set_same_party_cookie_context_type()| CookieOptions(); CookieOptions(const CookieOptions& other); CookieOptions(CookieOptions&& other);
diff --git a/net/cookies/parsed_cookie_unittest.cc b/net/cookies/parsed_cookie_unittest.cc index 5300035f..dca2c1b 100644 --- a/net/cookies/parsed_cookie_unittest.cc +++ b/net/cookies/parsed_cookie_unittest.cc
@@ -29,7 +29,7 @@ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, pc1.Priority()); ParsedCookie pc2( - "c=d; secure; httponly; sameparty; path=/foo; domain=bar.test; " + "c=d; secure; httponly; path=/foo; domain=bar.test; " "max-age=60; samesite=lax; priority=high; partitioned;"); EXPECT_TRUE(pc2.IsValid()); EXPECT_TRUE(pc2.IsSecure()); @@ -212,7 +212,7 @@ TEST(ParsedCookieTest, TestAttributeCase) { ParsedCookie pc( - "BLAH; Path=/; sECuRe; httpONLY; sAmESitE=LaX; pRIoRitY=hIgH; samePaRtY; " + "BLAH; Path=/; sECuRe; httpONLY; sAmESitE=LaX; pRIoRitY=hIgH; " "pARTitIoNeD;"); EXPECT_TRUE(pc.IsValid()); EXPECT_TRUE(pc.IsSecure()); @@ -224,7 +224,7 @@ EXPECT_EQ("", pc.Name()); EXPECT_EQ("BLAH", pc.Value()); EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority()); - EXPECT_EQ(7U, pc.NumberOfAttributes()); + EXPECT_EQ(6U, pc.NumberOfAttributes()); } TEST(ParsedCookieTest, TestDoubleQuotedNameless) { @@ -981,7 +981,7 @@ } TEST(ParsedCookieTest, ToCookieLineSpecialTokens) { - // Special tokens "secure", "httponly", and "sameparty" should be treated as + // Special tokens "secure", "httponly" should be treated as // any other name when they are in the first position. { ParsedCookie pc(""); @@ -1005,10 +1005,6 @@ EXPECT_EQ(pc.ToCookieLine(), "httponly=foo"); } { - ParsedCookie pc("sameparty=foo"); - EXPECT_EQ(pc.ToCookieLine(), "sameparty=foo"); - } - { ParsedCookie pc("foo"); pc.SetName("secure"); EXPECT_EQ(pc.ToCookieLine(), "secure=foo"); @@ -1048,13 +1044,6 @@ EXPECT_FALSE(pc.IsHttpOnly()); } { - ParsedCookie pc("sameparty; sameparty; secure; httponly; httponly; secure"); - EXPECT_EQ("", pc.Name()); - EXPECT_EQ("sameparty", pc.Value()); - EXPECT_TRUE(pc.IsSecure()); - EXPECT_TRUE(pc.IsHttpOnly()); - } - { ParsedCookie pc("partitioned=foo"); EXPECT_EQ("partitioned", pc.Name()); EXPECT_EQ("foo", pc.Value());
diff --git a/net/data/ssl/chrome_root_store/root_store.md b/net/data/ssl/chrome_root_store/root_store.md index 5909f78..495f50c 100644 --- a/net/data/ssl/chrome_root_store/root_store.md +++ b/net/data/ssl/chrome_root_store/root_store.md
@@ -1,6 +1,6 @@ <!-- mdformat off(generated) --> <!-- mdlint off(generated) --> -Version: 12 +Version: 13 SHA 256 Hash | Subject | NotBefore | NotAfter ---|---|---|---
diff --git a/net/data/ssl/chrome_root_store/root_store.textproto b/net/data/ssl/chrome_root_store/root_store.textproto index 1e5a2ba3..3a7c2f6f 100644 --- a/net/data/ssl/chrome_root_store/root_store.textproto +++ b/net/data/ssl/chrome_root_store/root_store.textproto
@@ -8,7 +8,7 @@ # Version # should always be incremented up whenever this (or any pem file that # it references) is changed. -version_major: 12 +version_major: 13 # CN=Actalis Authentication Root CA, O=Actalis S.p.A./03358520967, L=Milan, C=IT # https://ssltest-a.actalis.it:8443 @@ -126,6 +126,8 @@ # https://certdemo-ev-valid.ssl.d-trust.net/ trust_anchors { sha256_hex: "eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881" + # TODO(cclements,hchao): remove non-CABF OID once it is not used anymore. + ev_policy_oids: "1.3.6.1.4.1.4788.2.202.1" ev_policy_oids: "2.23.140.1.1" } @@ -521,6 +523,8 @@ # https://www.secomtrust.net/contact/form.html trust_anchors { sha256_hex: "513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6" + # TODO(cclements,hchao): remove non-CABF OID once it is not used anymore. + ev_policy_oids: "1.2.392.200091.100.721.1" ev_policy_oids: "2.23.140.1.1" }
diff --git a/net/disk_cache/blockfile/storage_block-inl.h b/net/disk_cache/blockfile/storage_block-inl.h index 8114c21..cbb810cd 100644 --- a/net/disk_cache/blockfile/storage_block-inl.h +++ b/net/disk_cache/blockfile/storage_block-inl.h
@@ -36,10 +36,10 @@ DCHECK(!modified_); DCHECK(!other->modified_); Discard(); - *Data() = *other->Data(); - file_ = other->file_; address_ = other->address_; extended_ = other->extended_; + file_ = other->file_; + *Data() = *other->Data(); } template<typename T> void* StorageBlock<T>::buffer() const {
diff --git a/net/disk_cache/blockfile/storage_block_unittest.cc b/net/disk_cache/blockfile/storage_block_unittest.cc index e816826..b5deced 100644 --- a/net/disk_cache/blockfile/storage_block_unittest.cc +++ b/net/disk_cache/blockfile/storage_block_unittest.cc
@@ -70,3 +70,22 @@ EXPECT_TRUE(entry2.Load()); EXPECT_TRUE(0x45687912 == entry2.Data()->hash); } + +TEST_F(DiskCacheTest, StorageBlock_DifferentNumBuffers) { + base::FilePath filename = cache_path_.AppendASCII("a_test"); + auto file = base::MakeRefCounted<disk_cache::MappedFile>(); + ASSERT_TRUE(CreateCacheTestFile(filename)); + ASSERT_TRUE(file->Init(filename, 8192)); + + // 2 buffers at index 1. + CacheEntryBlock entry1(file.get(), disk_cache::Addr(0xa1010001)); + EXPECT_TRUE(entry1.Load()); + + // 1 buffer at index 3. + CacheEntryBlock entry2(file.get(), disk_cache::Addr(0xa0010003)); + EXPECT_TRUE(entry2.Load()); + + // Now specify 2 buffers at index 1. + entry2.CopyFrom(&entry1); + EXPECT_TRUE(entry2.Load()); +}
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 4ab1b02..6435fc4 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -1369,7 +1369,7 @@ 14, CookieSameSiteToDBCookieSameSite(po->cc().SameSite())); add_statement.BindInt(15, static_cast<int>(po->cc().SourceScheme())); add_statement.BindInt(16, po->cc().SourcePort()); - add_statement.BindBool(17, po->cc().IsSameParty()); + add_statement.BindBool(17, false /* is_same_party */); add_statement.BindTime(18, po->cc().LastUpdateDate()); if (!add_statement.Run()) { DLOG(WARNING) << "Could not add a cookie to the DB.";
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc index fdaf8d8..1ac522f 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -989,53 +989,6 @@ EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookies[0]->SameSite()); } -TEST_F(SQLitePersistentCookieStoreTest, SamePartyIsPersistent) { - const char kDomain[] = "sessioncookie.com"; - const char kNonSamePartyCookieName[] = "no_party"; - const char kSamePartyCookieName[] = "party"; - const char kCookieValue[] = "value"; - const char kCookiePath[] = "/"; - - InitializeStore(false, true); - - // Add a non-SameParty persistent cookie. - store_->AddCookie(*CanonicalCookie::CreateUnsafeCookieForTesting( - kNonSamePartyCookieName, kCookieValue, kDomain, kCookiePath, - base::Time::Now() - base::Minutes(1), base::Time::Now() + base::Days(1), - base::Time(), base::Time(), - /*secure=*/true, false, CookieSameSite::LAX_MODE, - COOKIE_PRIORITY_DEFAULT)); - - // Add a SameParty persistent cookie. - store_->AddCookie(*CanonicalCookie::CreateUnsafeCookieForTesting( - kSamePartyCookieName, kCookieValue, kDomain, kCookiePath, - base::Time::Now() - base::Minutes(1), base::Time::Now() + base::Days(1), - base::Time(), base::Time(), - /*secure=*/true, false, CookieSameSite::LAX_MODE, - COOKIE_PRIORITY_DEFAULT)); - - // Force the store to write its data to the disk. - DestroyStore(); - - // Create a store that loads session cookie and test that the SameParty - // attribute values are restored. - CanonicalCookieVector cookies; - CreateAndLoad(false, true, &cookies); - ASSERT_EQ(2U, cookies.size()); - - // Put the cookies into a map, by name, for comparison below. - std::map<std::string, CanonicalCookie*> cookie_map; - for (const auto& cookie : cookies) - cookie_map[cookie->Name()] = cookie.get(); - - // Validate that each cookie has the correct SameParty. - ASSERT_EQ(1u, cookie_map.count(kNonSamePartyCookieName)); - EXPECT_FALSE(cookie_map[kNonSamePartyCookieName]->IsSameParty()); - - ASSERT_EQ(1u, cookie_map.count(kSamePartyCookieName)); - EXPECT_FALSE(cookie_map[kSamePartyCookieName]->IsSameParty()); -} - TEST_F(SQLitePersistentCookieStoreTest, SourcePortIsPersistent) { const char kDomain[] = "sessioncookie.com"; const char kCookieValue[] = "value"; @@ -1720,8 +1673,6 @@ // Note: These are all constructed with the default value of // is_source_scheme_secure, which is false, but that doesn't matter because // v11 doesn't store that info. - // Some of these are constructed with SameParty set to true, to test that in - // the DB migration, the is_same_party values are all defaulted to false. cookies.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting( "A", "B", "example.com", "/", now, now, now, now, true /* secure */, false /* httponly */, CookieSameSite::UNSPECIFIED, @@ -1790,7 +1741,7 @@ statement.BindInt(14, static_cast<int>(cookie.Priority())); statement.BindInt(15, static_cast<int>(cookie.SourceScheme())); statement.BindInt(16, cookie.SourcePort()); - statement.BindInt(17, cookie.IsSameParty()); + statement.BindInt(17, false /* is_same_party */); if (!statement.Run()) return false; } @@ -1853,7 +1804,7 @@ statement.BindInt(14, static_cast<int>(cookie.Priority())); statement.BindInt(15, static_cast<int>(cookie.SourceScheme())); statement.BindInt(16, cookie.SourcePort()); - statement.BindInt(17, cookie.IsSameParty()); + statement.BindInt(17, false /* is_same_party */); statement.BindTime(18, cookie.LastUpdateDate()); if (!statement.Run()) { return false; @@ -1878,7 +1829,6 @@ EXPECT_EQ("/", read_in_cookies[i]->Path()); EXPECT_TRUE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time()); @@ -1892,7 +1842,6 @@ EXPECT_EQ("/path", read_in_cookies[i]->Path()); EXPECT_FALSE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time()); @@ -1906,7 +1855,6 @@ EXPECT_EQ("/", read_in_cookies[i]->Path()); EXPECT_TRUE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time()); @@ -1920,7 +1868,6 @@ EXPECT_EQ("/", read_in_cookies[i]->Path()); EXPECT_TRUE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time()); @@ -1934,7 +1881,6 @@ EXPECT_EQ("/path", read_in_cookies[i]->Path()); EXPECT_FALSE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time()); @@ -1951,7 +1897,6 @@ EXPECT_EQ("/", read_in_cookies[i]->Path()); EXPECT_FALSE(read_in_cookies[i]->IsSecure()); EXPECT_EQ(CookieSourceScheme::kUnset, read_in_cookies[i]->SourceScheme()); - EXPECT_FALSE(read_in_cookies[i]->IsSameParty()); EXPECT_EQ(read_in_cookies[i]->LastUpdateDate(), expect_last_update_date ? read_in_cookies[i]->CreationDate() : base::Time());
diff --git a/net/http/structured_headers.h b/net/http/structured_headers.h index f20b64c8..77c7a24c 100644 --- a/net/http/structured_headers.h +++ b/net/http/structured_headers.h
@@ -60,6 +60,11 @@ return quiche::structured_headers::SerializeDictionary(value); } +inline absl::string_view ItemTypeToString( + net::structured_headers::Item::ItemType type) { + return quiche::structured_headers::ItemTypeToString(type); +} + } // namespace net::structured_headers #endif // NET_HTTP_STRUCTURED_HEADERS_H_
diff --git a/net/proxy_resolution/proxy_info.cc b/net/proxy_resolution/proxy_info.cc index 70c5912..d4525456 100644 --- a/net/proxy_resolution/proxy_info.cc +++ b/net/proxy_resolution/proxy_info.cc
@@ -38,11 +38,6 @@ proxy_list_.Set(proxy_uri_list); } -void ProxyInfo::UseProxyServer(const ProxyServer& proxy_server) { - Reset(); - proxy_list_.SetSingleProxyServer(proxy_server); -} - void ProxyInfo::UseProxyChain(const ProxyChain& proxy_chain) { Reset(); proxy_list_.SetSingleProxyChain(proxy_chain);
diff --git a/net/proxy_resolution/proxy_info.h b/net/proxy_resolution/proxy_info.h index e218170..cc64d3a 100644 --- a/net/proxy_resolution/proxy_info.h +++ b/net/proxy_resolution/proxy_info.h
@@ -45,10 +45,6 @@ // It is OK to have LWS between entries. void UseNamedProxy(const std::string& proxy_uri_list); - // Sets the proxy list to a single entry, |proxy_server|. - // TODO(crbug.com/1491092): Remove this method, as it is only used in a test. - void UseProxyServer(const ProxyServer& proxy_server); - // Sets the proxy list to a single entry, |proxy_chain|. void UseProxyChain(const ProxyChain& proxy_chain);
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc index 46052be1..899f1b2f 100644 --- a/net/test/cert_builder.cc +++ b/net/test/cert_builder.cc
@@ -4,8 +4,15 @@ #include "net/test/cert_builder.h" +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + #include "base/files/file_path.h" #include "base/memory/ptr_util.h" +#include "base/memory/scoped_refptr.h" #include "base/notreached.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" @@ -14,7 +21,11 @@ #include "crypto/ec_private_key.h" #include "crypto/openssl_util.h" #include "crypto/rsa_private_key.h" +#include "crypto/sha2.h" #include "net/cert/asn1_util.h" +#include "net/cert/ct_objects_extractor.h" +#include "net/cert/ct_serialization.h" +#include "net/cert/signed_certificate_timestamp.h" #include "net/cert/time_conversions.h" #include "net/cert/x509_util.h" #include "net/test/cert_test_util.h" @@ -111,6 +122,29 @@ } // namespace +CertBuilder::SctConfig::SctConfig() = default; +CertBuilder::SctConfig::SctConfig(std::string log_id, + bssl::UniquePtr<EVP_PKEY> log_key, + base::Time timestamp) + : log_id(std::move(log_id)), + log_key(std::move(log_key)), + timestamp(timestamp) {} +CertBuilder::SctConfig::SctConfig(const SctConfig& other) + : SctConfig(other.log_id, + bssl::UpRef(other.log_key.get()), + other.timestamp) {} +CertBuilder::SctConfig::SctConfig(SctConfig&&) = default; +CertBuilder::SctConfig::~SctConfig() = default; +CertBuilder::SctConfig& CertBuilder::SctConfig::operator=( + const SctConfig& other) { + log_id = other.log_id; + log_key = bssl::UpRef(other.log_key.get()); + timestamp = other.timestamp; + return *this; +} +CertBuilder::SctConfig& CertBuilder::SctConfig::operator=(SctConfig&&) = + default; + CertBuilder::CertBuilder(CRYPTO_BUFFER* orig_cert, CertBuilder* issuer) : CertBuilder(orig_cert, issuer, /*unique_subject_key_identifier=*/true) {} @@ -914,6 +948,12 @@ Invalidate(); } +void CertBuilder::SetSctConfig( + std::vector<CertBuilder::SctConfig> sct_configs) { + sct_configs_ = std::move(sct_configs); + Invalidate(); +} + CRYPTO_BUFFER* CertBuilder::GetCertBuffer() { if (!cert_) GenerateCertificate(); @@ -1266,6 +1306,61 @@ *out = FinishCBB(cbb.get()); } +void CertBuilder::BuildSctListExtension(const std::string& pre_tbs_certificate, + std::string* out) { + std::vector<std::string> encoded_scts; + for (const SctConfig& sct_config : sct_configs_) { + ct::SignedEntryData entry; + entry.type = ct::SignedEntryData::LOG_ENTRY_TYPE_PRECERT; + bssl::ScopedCBB issuer_spki_cbb; + ASSERT_TRUE(CBB_init(issuer_spki_cbb.get(), 32)); + ASSERT_TRUE( + EVP_marshal_public_key(issuer_spki_cbb.get(), issuer_->GetKey())); + crypto::SHA256HashString(FinishCBB(issuer_spki_cbb.get()), + entry.issuer_key_hash.data, + sizeof(entry.issuer_key_hash.data)); + entry.tbs_certificate = pre_tbs_certificate; + + std::string serialized_log_entry; + std::string serialized_data; + ASSERT_TRUE(ct::EncodeSignedEntry(entry, &serialized_log_entry)); + ASSERT_TRUE(ct::EncodeV1SCTSignedData(sct_config.timestamp, + serialized_log_entry, + /*extensions=*/"", &serialized_data)); + + scoped_refptr<ct::SignedCertificateTimestamp> sct = + base::MakeRefCounted<ct::SignedCertificateTimestamp>(); + sct->log_id = sct_config.log_id; + sct->timestamp = sct_config.timestamp; + sct->signature.hash_algorithm = ct::DigitallySigned::HASH_ALGO_SHA256; + sct->signature.signature_algorithm = ct::DigitallySigned::SIG_ALGO_ECDSA; + + bssl::ScopedCBB sct_signature_cbb; + ASSERT_TRUE(CBB_init(sct_signature_cbb.get(), 0)); + ASSERT_TRUE(SignData(bssl::SignatureAlgorithm::kEcdsaSha256, + serialized_data, sct_config.log_key.get(), + sct_signature_cbb.get())); + sct->signature.signature_data = FinishCBB(sct_signature_cbb.get()); + + sct->origin = ct::SignedCertificateTimestamp::SCT_EMBEDDED; + + std::string encoded_sct; + ASSERT_TRUE(ct::EncodeSignedCertificateTimestamp(sct, &encoded_sct)); + encoded_scts.push_back(std::move(encoded_sct)); + } + std::string encoded_sct_list; + ASSERT_TRUE(ct::EncodeSCTListForTesting(encoded_scts, &encoded_sct_list)); + + bssl::ScopedCBB sct_extension_cbb; + ASSERT_TRUE(CBB_init(sct_extension_cbb.get(), 32)); + ASSERT_TRUE(CBB_add_asn1_octet_string( + sct_extension_cbb.get(), + reinterpret_cast<const uint8_t*>(encoded_sct_list.data()), + encoded_sct_list.size())); + + *out = FinishCBB(sct_extension_cbb.get()); +} + void CertBuilder::GenerateCertificate() { ASSERT_FALSE(cert_); @@ -1287,6 +1382,16 @@ : SignatureAlgorithmToDer(*signature_algorithm); ASSERT_FALSE(tbs_signature_algorithm_tlv.empty()); + if (!sct_configs_.empty()) { + EraseExtension(bssl::der::Input(ct::kEmbeddedSCTOid)); + std::string pre_tbs_certificate; + BuildTBSCertificate(tbs_signature_algorithm_tlv, &pre_tbs_certificate); + std::string sct_extension; + BuildSctListExtension(pre_tbs_certificate, &sct_extension); + SetExtension(bssl::der::Input(ct::kEmbeddedSCTOid), sct_extension, + /*critical=*/false); + } + std::string tbs_cert; BuildTBSCertificate(tbs_signature_algorithm_tlv, &tbs_cert);
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h index 6bb4927..e9ce9f9 100644 --- a/net/test/cert_builder.h +++ b/net/test/cert_builder.h
@@ -6,7 +6,9 @@ #define NET_TEST_CERT_BUILDER_H_ #include <map> +#include <memory> #include <string> +#include <vector> #include "base/memory/raw_ptr.h" #include "base/rand_util.h" @@ -43,6 +45,24 @@ // dependent on ordering. class CertBuilder { public: + // Parameters for creating an embedded SignedCertificateTimestamp. + struct SctConfig { + SctConfig(); + SctConfig(std::string log_id, + bssl::UniquePtr<EVP_PKEY> log_key, + base::Time timestamp); + SctConfig(const SctConfig&); + SctConfig(SctConfig&&); + ~SctConfig(); + SctConfig& operator=(const SctConfig&); + SctConfig& operator=(SctConfig&&); + + std::string log_id; + // Only EC keys are supported currently. + bssl::UniquePtr<EVP_PKEY> log_key; + base::Time timestamp; + }; + // Initializes the CertBuilder, if |orig_cert| is non-null it will be used as // a template. If |issuer| is null then the generated certificate will be // self-signed. Otherwise, it will be signed using |issuer|. @@ -265,6 +285,10 @@ void SetSerialNumber(uint64_t serial_number); void SetRandomSerialNumber(); + // Sets the configuration that will be used to generate a + // SignedCertificateTimestampList extension in the certificate. + void SetSctConfig(std::vector<CertBuilder::SctConfig> sct_configs); + // Sets the private key for the generated certificate to an EC key. If a key // was already set, it will be replaced. void GenerateECKey(); @@ -380,6 +404,9 @@ void BuildTBSCertificate(base::StringPiece signature_algorithm_tlv, std::string* out); + void BuildSctListExtension(const std::string& pre_tbs_certificate, + std::string* out); + void GenerateCertificate(); struct ExtensionValue { @@ -397,6 +424,8 @@ uint64_t serial_number_ = 0; int default_pkey_id_ = EVP_PKEY_EC; + std::vector<SctConfig> sct_configs_; + std::map<std::string, ExtensionValue> extensions_; bssl::UniquePtr<CRYPTO_BUFFER> cert_;
diff --git a/net/test/ct_test_util.cc b/net/test/ct_test_util.cc index 67573570..f335d9a 100644 --- a/net/test/ct_test_util.cc +++ b/net/test/ct_test_util.cc
@@ -374,7 +374,7 @@ std::string GetSCTListForTesting() { const std::string sct = ct::GetTestSignedCertificateTimestamp(); std::string sct_list; - ct::EncodeSCTListForTesting(sct, &sct_list); + ct::EncodeSCTListForTesting({sct}, &sct_list); return sct_list; } @@ -386,7 +386,7 @@ sct[15] = 't'; std::string sct_list; - ct::EncodeSCTListForTesting(sct, &sct_list); + ct::EncodeSCTListForTesting({sct}, &sct_list); return sct_list; }
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 80cbd97..357b3621 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -454,6 +454,10 @@ leaf->SetKeyUsages(cert_config_.key_usages); } + if (!cert_config_.embedded_scts.empty()) { + leaf->SetSctConfig(cert_config_.embedded_scts); + } + const std::string leaf_serial_text = base::NumberToString(leaf->GetSerialNumber()); const std::string intermediate_serial_text =
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h index 8d97ff7..95a1fd1 100644 --- a/net/test/embedded_test_server/embedded_test_server.h +++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -29,6 +29,7 @@ #include "net/socket/stream_socket.h" #include "net/socket/tcp_server_socket.h" #include "net/ssl/ssl_server_config.h" +#include "net/test/cert_builder.h" #include "net/test/embedded_test_server/http_connection.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/boringssl/src/pki/ocsp_revocation_status.h" @@ -312,6 +313,9 @@ // A list of key usages to include in the leaf keyUsage extension. std::vector<bssl::KeyUsageBit> key_usages; + + // Generate embedded SCTList in the certificate for the specified logs. + std::vector<CertBuilder::SctConfig> embedded_scts; }; typedef base::RepeatingCallback<std::unique_ptr<HttpResponse>(
diff --git a/net/third_party/quiche/src b/net/third_party/quiche/src index e894f32..45374cb 160000 --- a/net/third_party/quiche/src +++ b/net/third_party/quiche/src
@@ -1 +1 @@ -Subproject commit e894f322dcd82ef0642834ea2e5ab432d22ec43b +Subproject commit 45374cbe5557a6d3da7aa1a43c969314f7b1894e
diff --git a/printing/buildflags/buildflags.gni b/printing/buildflags/buildflags.gni index b3ba66120d..9382e3e 100644 --- a/printing/buildflags/buildflags.gni +++ b/printing/buildflags/buildflags.gni
@@ -41,11 +41,10 @@ !is_fuchsia } - # Enables out-of-process printing. While this definition matches - # `enable_print_preview`, do not base this definition upon that. This - # feature could still be appropriate for some build configurations which - # explicitly disable print preview. - enable_oop_printing = enable_printing && !is_android + # Enables out-of-process printing. Do not have this definition just be + # based on `enable_print_preview`; this feature could still be appropriate + # for some build configurations which explicitly disable print preview. + enable_oop_printing = enable_printing && !is_android && !is_fuchsia # Enable snapshotting a page when printing for its content to be analyzed for # sensitive content by enterprise users.
diff --git a/printing/printing_features.cc b/printing/printing_features.cc index 0ed4f7e..1ad4bfb7c 100644 --- a/printing/printing_features.cc +++ b/printing/printing_features.cc
@@ -95,12 +95,6 @@ const base::FeatureParam<bool> kEnableOopPrintDriversSingleProcess{ &kEnableOopPrintDrivers, "SingleProcess", true}; #endif - -bool ShouldPrintJobOop() { - return base::FeatureList::IsEnabled(features::kEnableOopPrintDrivers) && - kEnableOopPrintDriversJobPrint.Get(); -} - #endif // BUILDFLAG(ENABLE_OOP_PRINTING) #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
diff --git a/printing/printing_features.h b/printing/printing_features.h index c79c7a3..e2b1a0f 100644 --- a/printing/printing_features.h +++ b/printing/printing_features.h
@@ -55,10 +55,6 @@ COMPONENT_EXPORT(PRINTING_BASE) extern const base::FeatureParam<bool> kEnableOopPrintDriversSingleProcess; #endif - -// Helper function to determine if a printing of a document should be made OOP -// using a Print Backend service. -COMPONENT_EXPORT(PRINTING_BASE) bool ShouldPrintJobOop(); #endif // BUILDFLAG(ENABLE_OOP_PRINTING) #if BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
diff --git a/remoting/host/desktop_display_info_loader_x11.cc b/remoting/host/desktop_display_info_loader_x11.cc index c6d78d26..f1ec40b 100644 --- a/remoting/host/desktop_display_info_loader_x11.cc +++ b/remoting/host/desktop_display_info_loader_x11.cc
@@ -24,7 +24,7 @@ namespace { // Monitors were added in XRANDR 1.5. -constexpr int kMinRandrVersion = 105; +constexpr std::pair<uint32_t, uint32_t> kMinRandrVersion{1, 5}; } // namespace @@ -45,9 +45,10 @@ return; } - xrandr_version_ = ui::GetXrandrVersion(); - if (xrandr_version_ < kMinRandrVersion) { - HOST_LOG << "XRANDR version (" << xrandr_version_ << ") is too old."; + auto randr_version = connection_->randr_version(); + if (randr_version < kMinRandrVersion) { + HOST_LOG << "XRANDR version (" << randr_version.first << ", " + << randr_version.second << ") is too old."; return; } @@ -107,7 +108,7 @@ } void DesktopDisplayInfoLoaderX11::LoadMonitors() { - if (xrandr_version_ < kMinRandrVersion) { + if (connection_->randr_version() < kMinRandrVersion) { return; }
diff --git a/remoting/host/desktop_display_info_loader_x11.h b/remoting/host/desktop_display_info_loader_x11.h index fe8bc7d..41dd90e 100644 --- a/remoting/host/desktop_display_info_loader_x11.h +++ b/remoting/host/desktop_display_info_loader_x11.h
@@ -30,9 +30,6 @@ // Queries the X server and updates |monitors_|. void LoadMonitors(); - // XRANDR version as MAJOR * 100 + MINOR, or 0 if XRANDR is not present. - int xrandr_version_ = 0; - raw_ptr<x11::Connection> connection_ = nullptr; raw_ptr<x11::RandR> randr_ = nullptr;
diff --git a/remoting/host/desktop_resizer_x11.cc b/remoting/host/desktop_resizer_x11.cc index cc6d5019..3370d516 100644 --- a/remoting/host/desktop_resizer_x11.cc +++ b/remoting/host/desktop_resizer_x11.cc
@@ -179,10 +179,6 @@ if (!has_randr_) { return; } - // Let the server know the client version so it sends us data consistent with - // xcbproto's definitions. We don't care about the returned server version, - // so no need to sync. - randr_->QueryVersion({x11::RandR::major_version, x11::RandR::minor_version}); randr_->SelectInput({root_, x11::RandR::NotifyMask::ScreenChange}); }
diff --git a/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc b/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc index 078fb7c1..12a3a39 100644 --- a/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc +++ b/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc
@@ -73,10 +73,6 @@ return; } - // Let the server know the client XInput version. - connection_->xinput().XIQueryVersion( - {x11::Input::major_version, x11::Input::minor_version}); - auto mask = CommonXIEventMaskForRootWindow(); connection_->xinput().XISelectEvents( {connection_->default_root(),
diff --git a/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc b/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc index 129a2b4..21cb651 100644 --- a/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc +++ b/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc
@@ -80,9 +80,6 @@ LOG(ERROR) << "X Input extension not available."; return; } - // Let the server know the client XInput version. - connection_->xinput().XIQueryVersion( - {x11::Input::major_version, x11::Input::minor_version}); auto mask = CommonXIEventMaskForRootWindow(); connection_->xinput().XISelectEvents(
diff --git a/remoting/host/keyboard_layout_monitor_linux.cc b/remoting/host/keyboard_layout_monitor_linux.cc index f9f7d51..5285098 100644 --- a/remoting/host/keyboard_layout_monitor_linux.cc +++ b/remoting/host/keyboard_layout_monitor_linux.cc
@@ -145,8 +145,7 @@ // which is a pain. connection_ = x11::Connection::Get(); auto& xkb = connection_->xkb(); - if (xkb.UseExtension({x11::Xkb::major_version, x11::Xkb::minor_version}) - .Sync()) { + if (xkb.present()) { constexpr auto kXkbAllStateComponentsMask = static_cast<x11::Xkb::StatePart>(0x3fff); xkb.SelectEvents({
diff --git a/remoting/host/linux/active_display_monitor_x11.cc b/remoting/host/linux/active_display_monitor_x11.cc index b4aea06..0dfa635 100644 --- a/remoting/host/linux/active_display_monitor_x11.cc +++ b/remoting/host/linux/active_display_monitor_x11.cc
@@ -26,7 +26,7 @@ // For X11, webrtc::ScreenId is implemented as a RANDR Monitor ID, which // requires XRANDR 1.5. -constexpr int kMinRandrVersion = 105; +constexpr std::pair<uint32_t, uint32_t> kMinRandrVersion{1, 5}; } // namespace @@ -94,9 +94,10 @@ void ActiveDisplayMonitorX11::Core::Init() { connection_ = x11::Connection::Get(); - int xrandr_version = ui::GetXrandrVersion(); + auto xrandr_version = connection_->randr_version(); if (xrandr_version < kMinRandrVersion) { - LOG(ERROR) << "XRANDR version (" << xrandr_version << ") is unsupported."; + LOG(ERROR) << "XRANDR version (" << xrandr_version.first << ", " + << xrandr_version.second << ") is unsupported."; return; }
diff --git a/remoting/host/linux/x11_util.cc b/remoting/host/linux/x11_util.cc index e29083f..c1b6921 100644 --- a/remoting/host/linux/x11_util.cc +++ b/remoting/host/linux/x11_util.cc
@@ -27,9 +27,7 @@ } bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore) { - if (!connection->xtest() - .GetVersion({x11::Test::major_version, x11::Test::minor_version}) - .Sync()) { + if (!connection->xtest().present()) { return false; }
diff --git a/remoting/host/linux/x_server_clipboard.cc b/remoting/host/linux/x_server_clipboard.cc index fff7ea0..0092f7f7 100644 --- a/remoting/host/linux/x_server_clipboard.cc +++ b/remoting/host/linux/x_server_clipboard.cc
@@ -34,10 +34,6 @@ return; } - // Let the server know the client version. - connection_->xfixes().QueryVersion( - {x11::XFixes::major_version, x11::XFixes::minor_version}); - clipboard_window_ = connection_->GenerateId<x11::Window>(); connection_->CreateWindow({ .wid = clipboard_window_,
diff --git a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc index 1548fdc..64b149d 100644 --- a/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc +++ b/sandbox/policy/fuchsia/sandbox_policy_fuchsia.cc
@@ -165,7 +165,7 @@ case sandbox::mojom::Sandbox::kAudio: case sandbox::mojom::Sandbox::kCdm: case sandbox::mojom::Sandbox::kOnDeviceModelExecution: -#if BUILDFLAG(ENABLE_PRINTING) +#if BUILDFLAG(ENABLE_OOP_PRINTING) case sandbox::mojom::Sandbox::kPrintBackend: #endif case sandbox::mojom::Sandbox::kPrintCompositor:
diff --git a/services/audio/public/mojom/audio_service.mojom b/services/audio/public/mojom/audio_service.mojom index 0b04f37..dd10d9e1 100644 --- a/services/audio/public/mojom/audio_service.mojom +++ b/services/audio/public/mojom/audio_service.mojom
@@ -5,6 +5,7 @@ module audio.mojom; import "media/mojo/mojom/audio_stream_factory.mojom"; +import "sandbox/policy/mojom/context.mojom"; import "sandbox/policy/mojom/sandbox.mojom"; import "services/audio/public/mojom/debug_recording.mojom"; import "services/audio/public/mojom/device_notifications.mojom"; @@ -15,21 +16,26 @@ // The main interface to the Audio service. This is a privileged interface and // must only be bound by trusted processes, e.g. a browser process. Note that // the sandbox can be disabled (to kNoSandbox) by policy. -[ServiceSandbox=sandbox.mojom.Sandbox.kAudio] +[ServiceSandbox=sandbox.mojom.Sandbox.kAudio, + RequireContext=sandbox.mojom.Context.kBrowswer] interface AudioService { // Binds a SystemInfo interface receiver. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindSystemInfo(pending_receiver<SystemInfo> receiver); // Binds a DebugRecording interface receiver. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindDebugRecording(pending_receiver<DebugRecording> receiver); // Binds a StreamFactory interface receiver. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindStreamFactory(pending_receiver<media.mojom.AudioStreamFactory> receiver); // Binds a DeviceNotifier interface receiver. BindDeviceNotifier(pending_receiver<DeviceNotifier> receiver); // Binds a LogFactoryManager interface receiver. + [AllowedContext=sandbox.mojom.Context.kBrowser] BindLogFactoryManager(pending_receiver<LogFactoryManager> receiver); // Binds a TestingApi interface receiver. Only callable in some test
diff --git a/services/audio/public/mojom/debug_recording.mojom b/services/audio/public/mojom/debug_recording.mojom index 50b2f3a..995a9b2 100644 --- a/services/audio/public/mojom/debug_recording.mojom +++ b/services/audio/public/mojom/debug_recording.mojom
@@ -5,6 +5,7 @@ module audio.mojom; import "mojo/public/mojom/base/file.mojom"; +import "sandbox/policy/mojom/context.mojom"; enum DebugRecordingStreamType { kInput = 0, @@ -15,6 +16,7 @@ // behalf of the sandboxed audio service's DebugRecording interface. The created // files are scoped inside a directory controlled by the browser process, and // only the file handle is returned to the audio service. +[RequireContext=sandbox.mojom.Context.kPrivilegedUtility] interface DebugRecordingFileProvider { // Creates a file at the base file path, with appended extensions ".output" or @@ -38,6 +40,8 @@ // browser process. To enable, bind interface and call Enable with a bound // DebugRecordingFileProvider interface pointer. To disable, close debug // recording message pipe or bind a new DebugRecording to the audio service. +[RequireContext=sandbox.mojom.Context.kBrowser] interface DebugRecording { + [AllowedContext=sandbox.mojom.Context.kBrowser] Enable(pending_remote<DebugRecordingFileProvider> file_provider); };
diff --git a/services/audio/public/mojom/log_factory_manager.mojom b/services/audio/public/mojom/log_factory_manager.mojom index 1837e6f0..a6913745 100644 --- a/services/audio/public/mojom/log_factory_manager.mojom +++ b/services/audio/public/mojom/log_factory_manager.mojom
@@ -5,9 +5,11 @@ module audio.mojom; import "media/mojo/mojom/audio_logging.mojom"; +import "sandbox/policy/mojom/context.mojom"; // This interface is exposed by the audio service to allow trusted clients // (like the browser process) to set a factory for creating audio logs. +[RequireContext=sandbox.mojom.Context.kBrowser] interface LogFactoryManager { // Sets the factory for creating audio logs. If a previous factory exists,
diff --git a/services/audio/public/mojom/system_info.mojom b/services/audio/public/mojom/system_info.mojom index 6dc37f9..16e1afc 100644 --- a/services/audio/public/mojom/system_info.mojom +++ b/services/audio/public/mojom/system_info.mojom
@@ -6,8 +6,10 @@ import "media/mojo/mojom/audio_parameters.mojom"; import "services/audio/public/mojom/audio_device_description.mojom"; +import "sandbox/policy/mojom/context.mojom"; // Provides information about audio system. +[RequireContext=sandbox.mojom.Context.kPrivilegedUtility] interface SystemInfo { // Replies with parameters for a specified input device (empty parameters if // the device is not found).
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 11f6186d5..cad806c 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -444,7 +444,6 @@ EXPECT_FALSE(cookies[0].IsHttpOnly()); EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[0].SameSite()); EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[0].Priority()); - EXPECT_FALSE(cookies[0].IsSameParty()); EXPECT_EQ("C", cookies[1].Name()); EXPECT_EQ("D", cookies[1].Value()); @@ -459,7 +458,6 @@ EXPECT_FALSE(cookies[1].IsHttpOnly()); EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[1].SameSite()); EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[1].Priority()); - EXPECT_FALSE(cookies[1].IsSameParty()); EXPECT_EQ("HttpOnly", cookies[2].Name()); EXPECT_EQ("F", cookies[2].Value()); @@ -474,7 +472,6 @@ EXPECT_TRUE(cookies[2].IsHttpOnly()); EXPECT_EQ(net::CookieSameSite::LAX_MODE, cookies[2].SameSite()); EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[2].Priority()); - EXPECT_FALSE(cookies[2].IsSameParty()); EXPECT_EQ("Secure", cookies[3].Name()); EXPECT_EQ("E", cookies[3].Value()); @@ -489,7 +486,6 @@ EXPECT_FALSE(cookies[3].IsHttpOnly()); EXPECT_EQ(net::CookieSameSite::NO_RESTRICTION, cookies[3].SameSite()); EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[3].Priority()); - EXPECT_FALSE(cookies[3].IsSameParty()); } TEST_F(CookieManagerTest, GetAllCookiesWithAccessSemantics) {
diff --git a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc index 055a2a9..51812756 100644 --- a/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc +++ b/services/network/public/cpp/cookie_manager_mojom_traits_unittest.cc
@@ -44,7 +44,6 @@ EXPECT_EQ(original->IsHttpOnly(), copied.IsHttpOnly()); EXPECT_EQ(original->SameSite(), copied.SameSite()); EXPECT_EQ(original->Priority(), copied.Priority()); - EXPECT_EQ(original->IsSameParty(), copied.IsSameParty()); EXPECT_EQ(absl::nullopt, copied.PartitionKey()); EXPECT_EQ(original->SourceScheme(), copied.SourceScheme()); EXPECT_EQ(original->SourcePort(), copied.SourcePort()); @@ -142,7 +141,6 @@ EXPECT_EQ(original.cookie.IsHttpOnly(), copied.cookie.IsHttpOnly()); EXPECT_EQ(original.cookie.SameSite(), copied.cookie.SameSite()); EXPECT_EQ(original.cookie.Priority(), copied.cookie.Priority()); - EXPECT_EQ(original.cookie.IsSameParty(), copied.cookie.IsSameParty()); EXPECT_EQ(original.access_result.effective_same_site, copied.access_result.effective_same_site); EXPECT_EQ(original.access_result.status, copied.access_result.status);
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index 65a75413..e326d7f 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -374,6 +374,9 @@ "PrefetchNoVarySearch", base::FEATURE_ENABLED_BY_DEFAULT); +const base::FeatureParam<bool> kPrefetchNoVarySearchShippedByDefault{ + &kPrefetchNoVarySearch, "shipped_by_default", true}; + // Enables the backend of the compression dictionary transport feature. // When this feature is enabled, the following will happen: // * The network service loads the metadata database.
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h index cbbc6c5..5d24341 100644 --- a/services/network/public/cpp/features.h +++ b/services/network/public/cpp/features.h
@@ -134,6 +134,12 @@ COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kPrefetchNoVarySearch); +// If this feature param is true, No-Vary-Search will not only be parsed but +// also respected by default, without needing to be turned on for a document +// using an origin trial token. +COMPONENT_EXPORT(NETWORK_CPP) +extern const base::FeatureParam<bool> kPrefetchNoVarySearchShippedByDefault; + // Enables UMA to track received GetCookiesString IPCs. This feature is enabled // by default, it is just here to allow some tests to disable it. These tests // make use of TaskEnvironment::FastForward with very long delays (days) which
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 4060e51..93c7550 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -974,7 +974,7 @@ // document's frame)), or a request origin when |role| is // RestrictedCookieManagerRole::NETWORK (a network request). // - // |isolation_info| contains info for SameSite and SameParty cookie queries. + // |isolation_info| contains info for SameSite cookie queries. // Must be fully populated. // // If |role| == SCRIPT, this interface can be safely handed out to a process
diff --git a/services/proxy_resolver/public/cpp/proxy_resolver_mojom_traits_unittests.cc b/services/proxy_resolver/public/cpp/proxy_resolver_mojom_traits_unittests.cc index f7783c8..80e0152 100644 --- a/services/proxy_resolver/public/cpp/proxy_resolver_mojom_traits_unittests.cc +++ b/services/proxy_resolver/public/cpp/proxy_resolver_mojom_traits_unittests.cc
@@ -22,11 +22,6 @@ direct.UseDirect(); infos.push_back(std::move(direct)); - net::ProxyInfo single_proxy_server; - single_proxy_server.UseProxyServer(net::ProxyServer::FromSchemeHostAndPort( - net::ProxyServer::SCHEME_HTTPS, "foo1", 443)); - infos.push_back(std::move(single_proxy_server)); - net::ProxyInfo single_proxy_chain; single_proxy_chain.UseProxyChain(net::ProxyChain::FromSchemeHostAndPort( net::ProxyServer::SCHEME_HTTPS, "foo1", 443));
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 5bac14a2..6248ecdd 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -783,7 +783,8 @@ if (!is_win) { cflags = [ "-w", - "-march=haswell", + "-mavx2", + "-mf16c", "-std=c11", ] } else { @@ -796,7 +797,11 @@ if (!is_win) { cflags = [ "-w", - "-march=skylake-avx512", + "-mavx512f", + "-mavx512dq", + "-mavx512cd", + "-mavx512bw", + "-mavx512vl", "-std=c11", ] } else {
diff --git a/skia/ext/image_operations.cc b/skia/ext/image_operations.cc index 594f404..c39d3be 100644 --- a/skia/ext/image_operations.cc +++ b/skia/ext/image_operations.cc
@@ -344,9 +344,6 @@ ((RESIZE_FIRST_ALGORITHM_METHOD <= method) && (method <= RESIZE_LAST_ALGORITHM_METHOD))); - // Time how long this takes to see if it's a problem for users. - base::TimeTicks resize_start = base::TimeTicks::Now(); - // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just // return empty. if (source.width() < 1 || source.height() < 1 || @@ -387,9 +384,6 @@ static_cast<unsigned char*>(result.getPixels()), true); - base::TimeDelta delta = base::TimeTicks::Now() - resize_start; - UMA_HISTOGRAM_TIMES("Image.ResampleMS", delta); - return result; }
diff --git a/skia/features.gni b/skia/features.gni index 0b11db93..7eee129 100644 --- a/skia/features.gni +++ b/skia/features.gni
@@ -6,16 +6,16 @@ import("//printing/buildflags/buildflags.gni") declare_args() { - # Enable experimental Skia Graphite Dawn backend. Currently enabled for Apple - # and Windows only. - skia_use_dawn = is_apple || is_win + # Enable experimental Skia Graphite Dawn backend. Current enabled on Windows, + # macOS and iOS when Blink is used. + skia_use_dawn = is_mac || is_win || (is_ios && use_blink) # Enable experimental Skia Graphite Metal backend. Intended only for debugging # on non-official developer builds. - skia_use_metal = is_apple && !is_official_build + skia_use_metal = (is_mac || (is_ios && use_blink)) && !is_official_build # Enable gtests using SkiaRenderer on Skia Graphite. - enable_skia_graphite_gtests = is_apple + enable_skia_graphite_gtests = is_mac || (is_ios && use_blink) } # Skia only needs to support GPU rasterization if we use the full Chromium
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index bda6dd4..cef385e8 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -61,15 +61,8 @@ // Definitions for database schema. const char kBucketTable[] = "buckets"; -// Deprecated flag that ensured that the buckets table was bootstrapped -// with existing storage key data for eviction logic. -// TODO(crbug.com/1254535): Remove once enough time has passed to ensure that -// this flag is no longer stored and supported in the QuotaDatabase. -const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped"; -// Deprecated bootstrap flag, invalidated in 03/2022 as part of crbug/1306279. -const char kDeprecatedBucketsTableBootstrapped[] = "IsBucketsTableBootstrapped"; // Flag to ensure that all existing data for storage keys have been -// registered into the buckets table. +// registered into the buckets table. Introduced 2022-05 (crrev.com/c/3594211). const char kBucketsTableBootstrapped[] = "IsBucketsBootstrapped"; const int kCommitIntervalMs = 30000; @@ -806,12 +799,6 @@ return open_error; } - // Delete deprecated bootstrap flag if it still exists. - // TODO(crbug.com/1254535): Remove once enough time has passed to ensure that - // this flag is no longer stored and supported in the QuotaDatabase. - meta_table_->DeleteKey(kIsOriginTableBootstrapped); - meta_table_->DeleteKey(kDeprecatedBucketsTableBootstrapped); - return meta_table_->SetValue(kBucketsTableBootstrapped, bootstrap_flag) ? QuotaError::kNone : QuotaError::kDatabaseError;
diff --git a/testing/buildbot/autoshard_exceptions.json b/testing/buildbot/autoshard_exceptions.json index 32e6768..772e02a 100644 --- a/testing/buildbot/autoshard_exceptions.json +++ b/testing/buildbot/autoshard_exceptions.json
@@ -128,17 +128,18 @@ }, "browser_tests": { "debug": { - "avg_num_builds_per_peak_hour": "79.0", - "estimated_bot_hour_delta": "16.9", - "prev_avg_pending_time_sec": "191.7", - "prev_p50_pending_time_sec": "61.0", - "prev_p90_pending_time_sec": "711.0", - "prev_percentile_duration_minutes": "16.04", - "prev_shard_count": "83", - "simulated_max_shard_duration": "14.79", + "avg_num_builds_per_peak_hour": 102, + "estimated_bot_hour_delta": 23.21, + "prev_avg_pending_time_sec": 63.7, + "prev_p50_pending_time_sec": 4.0, + "prev_p90_pending_time_sec": 205.0, + "prev_percentile_duration_minutes": 16.0, + "prev_shard_count": 90, + "simulated_max_shard_duration": 14.85, + "test_overhead_min": 1.95, "try_builder": "linux-chromeos-rel" }, - "shards": "90" + "shards": 97 }, "browser_tests_require_lacros": { "debug": { @@ -467,17 +468,18 @@ }, "interactive_ui_tests": { "debug": { - "avg_num_builds_per_peak_hour": "82.0", - "estimated_bot_hour_delta": "3.34", - "prev_avg_pending_time_sec": "302.1", - "prev_p50_pending_time_sec": "67.0", - "prev_p90_pending_time_sec": "1041.0", - "prev_percentile_duration_minutes": "15.1", - "prev_shard_count": "20", - "simulated_max_shard_duration": "14.38", + "avg_num_builds_per_peak_hour": 107, + "estimated_bot_hour_delta": 4.1, + "prev_avg_pending_time_sec": 60.2, + "prev_p50_pending_time_sec": 2.0, + "prev_p90_pending_time_sec": 194.0, + "prev_percentile_duration_minutes": 16.13, + "prev_shard_count": 21, + "simulated_max_shard_duration": 14.73, + "test_overhead_min": 1.15, "try_builder": "linux_chromium_asan_rel_ng" }, - "shards": "21" + "shards": 23 }, "sync_integration_tests": { "debug": {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index b8fe59a0..c5215a5a 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -4216,7 +4216,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 90 + "shards": 97 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -6093,9 +6093,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_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6105,8 +6105,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -6243,9 +6243,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6255,8 +6255,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 57e689b..1a7830a 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -20442,9 +20442,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_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20454,8 +20454,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -20592,9 +20592,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -20604,8 +20604,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index a001920..d4b2ff4a 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -5339,6 +5339,56 @@ { "args": [ "--test-launcher-bot-mode", + "--test-launcher-filter-file=testing/buildbot/filters/ios.compositor_unittests.filter", + "--platform", + "iPhone 14", + "--version", + "17.0", + "--out-dir", + "${ISOLATED_OUTDIR}", + "--xcode-build-version", + "15c5042i", + "--xctest" + ], + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "compositor_unittests iPhone 14 17.0", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "cipd_packages": [ + { + "cipd_package": "infra/tools/mac_toolchain/${platform}", + "location": ".", + "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce" + } + ], + "dimensions": { + "cpu": "arm64", + "os": "Mac-13" + }, + "named_caches": [ + { + "name": "xcode_ios_15c5042i", + "path": "Xcode.app" + }, + { + "name": "runtime_ios_17_0", + "path": "Runtime-ios-17.0" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "compositor_unittests", + "test_id_prefix": "ninja://ui/compositor:compositor_unittests/", + "variant_id": "iPhone 14 17.0" + }, + { + "args": [ + "--test-launcher-bot-mode", "--test-launcher-filter-file=testing/buildbot/filters/ios.content_browsertests.filter", "--platform", "iPhone 14", @@ -43585,9 +43635,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_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43596,8 +43646,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -43735,9 +43785,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43746,8 +43796,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -45044,9 +45094,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_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45055,8 +45105,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -45194,9 +45244,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45205,8 +45255,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -45889,9 +45939,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_v121.0.6137.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45900,8 +45950,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index c574efeb..866f7f5 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -779,7 +779,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 21 + "shards": 23 }, "test": "interactive_ui_tests", "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/" @@ -16151,12 +16151,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_v121.0.6137.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16166,8 +16166,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": { @@ -16321,12 +16321,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 121.0.6137.0", + "description": "Run with ash-chrome version 121.0.6138.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -16336,8 +16336,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v121.0.6137.0", - "revision": "version:121.0.6137.0" + "location": "lacros_version_skew_tests_v121.0.6138.0", + "revision": "version:121.0.6138.0" } ], "dimensions": {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 81a42ab..659d807 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3890,6 +3890,13 @@ }, 'components_browsertests': {}, 'components_unittests': {}, + 'compositor_unittests': { + 'test': 'compositor_unittests', + 'args': [ + '--test-launcher-bot-mode', + '--test-launcher-filter-file=testing/buildbot/filters/ios.compositor_unittests.filter', + ], + }, 'content_browsertests': { 'args': [ '--test-launcher-bot-mode',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index ea191b9..75e4cfc 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 121.0.6137.0', + 'description': 'Run with ash-chrome version 121.0.6138.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6137.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6138.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v121.0.6137.0', - 'revision': 'version:121.0.6137.0', + 'location': 'lacros_version_skew_tests_v121.0.6138.0', + 'revision': 'version:121.0.6138.0', }, ], },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 868bf34..85dd2c0 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -13156,27 +13156,6 @@ ] } ], - "PrefetchNewLimits": [ - { - "platforms": [ - "android", - "android_webview", - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "PrefetchNewLimits" - ] - } - ] - } - ], "PreinstalledWebAppWindowExperiment": [ { "platforms": [
diff --git a/third_party/angle b/third_party/angle index c8a544d..cb28076 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit c8a544dddbae3d1f495e05a36d5c2f4427b4994b +Subproject commit cb28076f897ba219a3db42e1755b44076dfebc37
diff --git a/third_party/blink/manual_tests/system-accent-color-disabled-in-images-1.html b/third_party/blink/manual_tests/system-accent-color-disabled-in-images-1.html new file mode 100644 index 0000000..e7af24bf --- /dev/null +++ b/third_party/blink/manual_tests/system-accent-color-disabled-in-images-1.html
@@ -0,0 +1,22 @@ +<!doctype html> +System accent color should not be applied in image contexts, as that can allow +sites to fingerprint by reading the system accent color via canvas.<br><br> + +Change the system accent color to a non-default value. Only the first checkbox +should change:<br> +<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'> + <foreignObject width='100px' height='100px'> + <body xmlns='http://www.w3.org/1999/xhtml'> + <input type='checkbox' checked='checked'/> + </body> + </foreignObject> +</svg> +<br> +<img src="data:image/svg+xml;utf8, +<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'> + <foreignObject width='100px' height='100px'> + <body xmlns='http://www.w3.org/1999/xhtml'> + <input type='checkbox' checked='checked'/> + </body> + </foreignObject> +</svg>">
diff --git a/third_party/blink/manual_tests/system-accent-color-disabled-in-images-2.html b/third_party/blink/manual_tests/system-accent-color-disabled-in-images-2.html new file mode 100644 index 0000000..71024b6 --- /dev/null +++ b/third_party/blink/manual_tests/system-accent-color-disabled-in-images-2.html
@@ -0,0 +1,22 @@ +<!doctype html> +System accent color should not be applied in image contexts, as that can allow +sites to fingerprint by reading the system accent color via canvas.<br><br> + +Change the system accent color to a non-default value. Only the first box +should change:<br> +<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'> + <foreignObject width='100px' height='100px'> + <body xmlns='http://www.w3.org/1999/xhtml'> + <div style='width: 100px; height: 100px; background: AccentColor'></div> + </body> + </foreignObject> +</svg> +<br> +<img src="data:image/svg+xml;utf8, +<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'> + <foreignObject width='100px' height='100px'> + <body xmlns='http://www.w3.org/1999/xhtml'> + <div style='width: 100px; height: 100px; background: AccentColor'></div> + </body> + </foreignObject> +</svg>">
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 82d01439..3b5ae0bd 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -5827,7 +5827,7 @@ # Cookie Priority experimental CookiePriority priority # True if cookie is SameParty. - experimental boolean sameParty + experimental deprecated boolean sameParty # Cookie source scheme type. experimental CookieSourceScheme sourceScheme # Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom index 3652bed..bc6358a 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -834,6 +834,7 @@ kMaskComposite = 778, kMaskPosition = 779, kMaskMode = 780, + kInsetArea = 781, // 1. Add new features above this line (don't change the assigned numbers of // the existing items).
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index 6a82bcd5..ec14391 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -4076,6 +4076,7 @@ kThirdPartyCookieDeprecation_AllowByTopLevelStorageAccess = 4737, kIframeAdAuctionHeadersAttribute = 4738, kAutoSpeculationRulesOptedOut = 4739, + kOverrideFlashEmbedwithHTML = 4740, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/strings/translations/blink_strings_pa.xtb b/third_party/blink/public/strings/translations/blink_strings_pa.xtb index 1216633..7488cf2 100644 --- a/third_party/blink/public/strings/translations/blink_strings_pa.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_pa.xtb
@@ -70,7 +70,7 @@ <translation id="4664250907885839816">'<ph name="ATSIGN" />' ਤੋਂ ਬਾਅਦ ਇੱਕ ਭਾਗ ਵਿੱਚ ਚਿੰਨ੍ਹ '<ph name="INVALIDCHARACTER" />' ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ।</translation> <translation id="4718048029184481307">ਤਸਵੀਰ-ਵਿੱਚ-ਤਸਵੀਰ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ</translation> <translation id="4748357248530471599">ਡਿਸਪਲੇ ਕੱਟਆਊਟ ਪੂਰੀ ਸਕ੍ਰੀਨ 'ਤੇ ਟੌਗਲ ਕਰੋ</translation> -<translation id="4763480195061959176">ਵੀਡਿਓ</translation> +<translation id="4763480195061959176">ਵੀਡੀਓ</translation> <translation id="4792862212177489858">ਟਿਕਾਣਾ ਸਾਂਝਾ ਕਰੋ</translation> <translation id="4812940957355064477">ਕਿਰਪਾ ਕਰਕੇ ਇੱਕ ਨੰਬਰ ਦਰਜ ਕਰੋ।</translation> <translation id="4912200001568447310">ਮੌਜੂਦਾ ਆਈਟਮ</translation>
diff --git a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py index 053b5f02..32375ba 100755 --- a/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py +++ b/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py
@@ -93,6 +93,7 @@ 'size_t', 'wtf_size_t', 'int', + 'InsetArea', # Aligns like short 'unsigned short', 'short',
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h index a6aa3b8..42092a3 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -129,7 +129,6 @@ // Called to process queued subtree removals when flat tree traversal is safe. virtual void ProcessSubtreeRemovals() = 0; - // Returns true if the AXObjectCache cares about this attribute virtual void HandleAttributeChanged(const QualifiedName& attr_name, Element*) = 0; virtual void HandleFocusedUIElementChanged(Element* old_focused_node,
diff --git a/third_party/blink/renderer/core/aom/accessible_node.cc b/third_party/blink/renderer/core/aom/accessible_node.cc index b518e65..8aeca26 100644 --- a/third_party/blink/renderer/core/aom/accessible_node.cc +++ b/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -1214,8 +1214,6 @@ return; } - // By definition, any attribute on an AccessibleNode is interesting to - // AXObjectCache, so no need to check return value. cache->HandleAttributeChanged(attribute, element_); }
diff --git a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h index 19b473f..5f91226 100644 --- a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h +++ b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
@@ -43,6 +43,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" +#include "third_party/blink/renderer/core/style/inset_area.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" #include "third_party/blink/renderer/platform/fonts/font_smoothing_mode.h" #include "third_party/blink/renderer/platform/fonts/text_rendering_mode.h" @@ -2121,6 +2122,117 @@ }; } +template <> +inline CSSIdentifierValue::CSSIdentifierValue(InsetAreaRegion region) + : CSSValue(kIdentifierClass) { + switch (region) { + case InsetAreaRegion::kNone: + value_id_ = CSSValueID::kNone; + break; + case InsetAreaRegion::kAll: + value_id_ = CSSValueID::kAll; + break; + case InsetAreaRegion::kCenter: + value_id_ = CSSValueID::kCenter; + break; + case InsetAreaRegion::kStart: + value_id_ = CSSValueID::kStart; + break; + case InsetAreaRegion::kEnd: + value_id_ = CSSValueID::kEnd; + break; + case InsetAreaRegion::kSelfStart: + value_id_ = CSSValueID::kSelfStart; + break; + case InsetAreaRegion::kSelfEnd: + value_id_ = CSSValueID::kSelfEnd; + break; + case InsetAreaRegion::kTop: + value_id_ = CSSValueID::kTop; + break; + case InsetAreaRegion::kBottom: + value_id_ = CSSValueID::kBottom; + break; + case InsetAreaRegion::kLeft: + value_id_ = CSSValueID::kLeft; + break; + case InsetAreaRegion::kRight: + value_id_ = CSSValueID::kRight; + break; + case InsetAreaRegion::kXStart: + value_id_ = CSSValueID::kXStart; + break; + case InsetAreaRegion::kXEnd: + value_id_ = CSSValueID::kXEnd; + break; + case InsetAreaRegion::kYStart: + value_id_ = CSSValueID::kYStart; + break; + case InsetAreaRegion::kYEnd: + value_id_ = CSSValueID::kYEnd; + break; + case InsetAreaRegion::kXSelfStart: + value_id_ = CSSValueID::kXSelfStart; + break; + case InsetAreaRegion::kXSelfEnd: + value_id_ = CSSValueID::kXSelfEnd; + break; + case InsetAreaRegion::kYSelfStart: + value_id_ = CSSValueID::kYSelfStart; + break; + case InsetAreaRegion::kYSelfEnd: + value_id_ = CSSValueID::kYSelfEnd; + break; + } +} + +template <> +inline InsetAreaRegion CSSIdentifierValue::ConvertTo() const { + switch (GetValueID()) { + case CSSValueID::kNone: + return InsetAreaRegion::kNone; + case CSSValueID::kAll: + return InsetAreaRegion::kAll; + case CSSValueID::kCenter: + return InsetAreaRegion::kCenter; + case CSSValueID::kStart: + return InsetAreaRegion::kStart; + case CSSValueID::kEnd: + return InsetAreaRegion::kEnd; + case CSSValueID::kSelfStart: + return InsetAreaRegion::kSelfStart; + case CSSValueID::kSelfEnd: + return InsetAreaRegion::kSelfEnd; + case CSSValueID::kTop: + return InsetAreaRegion::kTop; + case CSSValueID::kBottom: + return InsetAreaRegion::kBottom; + case CSSValueID::kLeft: + return InsetAreaRegion::kLeft; + case CSSValueID::kRight: + return InsetAreaRegion::kRight; + case CSSValueID::kXStart: + return InsetAreaRegion::kXStart; + case CSSValueID::kXEnd: + return InsetAreaRegion::kXEnd; + case CSSValueID::kYStart: + return InsetAreaRegion::kYStart; + case CSSValueID::kYEnd: + return InsetAreaRegion::kYEnd; + case CSSValueID::kXSelfStart: + return InsetAreaRegion::kXSelfStart; + case CSSValueID::kXSelfEnd: + return InsetAreaRegion::kXSelfEnd; + case CSSValueID::kYSelfStart: + return InsetAreaRegion::kYSelfStart; + case CSSValueID::kYSelfEnd: + return InsetAreaRegion::kYSelfEnd; + default: + NOTREACHED(); + return InsetAreaRegion::kNone; + }; +} + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PRIMITIVE_VALUE_MAPPINGS_H_
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 0168c5c..572aba5 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -6923,6 +6923,22 @@ is_property: false, runtime_flag: "ViewTransitionOnNavigation", }, + { + name: "inset-area", + property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"], + field_group: "*", + field_template: "external", + include_paths: ["third_party/blink/renderer/core/style/inset_area.h"], + converter: "ConvertInsetArea", + default_value: "InsetArea()", + type_name: "InsetArea", + keywords: [ + "none", "top", "bottom", "center", "left", "right", "x-start", "x-end", + "y-start", "y-end", "start", "end", "self-start", "self-end", "all" + ], + typedom_types: ["Keyword"], + runtime_flag: "CSSAnchorPositioning", + }, // Shorthands {
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc index b28b27a..bc5b073 100644 --- a/third_party/blink/renderer/core/css/css_property_equality.cc +++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -465,6 +465,8 @@ return a.ImageRendering() == b.ImageRendering(); case CSSPropertyID::kInitialLetter: return a.InitialLetter() == b.InitialLetter(); + case CSSPropertyID::kInsetArea: + return a.GetInsetArea() == b.GetInsetArea(); case CSSPropertyID::kIsolation: return a.Isolation() == b.Isolation(); case CSSPropertyID::kJustifyContent:
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5 index f382fc49..fcac4a2 100644 --- a/third_party/blink/renderer/core/css/css_value_keywords.json5 +++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1751,5 +1751,26 @@ "enabled", "initial-only", // none + + // inset-area + // none, + // all, + // center, + // start, + // end, + // self-start, + // self-end, + // top, + // bottom, + // left, + // right, + "x-start", + "x-end", + "y-start", + "y-end", + "x-self-start", + "x-self-end", + "y-self-start", + "y-self-end", ], }
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index 551d038..563b739 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -76,6 +76,8 @@ #include "third_party/blink/renderer/core/frame/deprecation/deprecation.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/style_property_shorthand.h" #include "third_party/blink/renderer/core/svg/svg_parsing_error.h" #include "third_party/blink/renderer/core/svg/svg_path_utilities.h" @@ -1931,6 +1933,26 @@ ResolveColor(colors_to_compare_against[highest_contrast_index])); } +namespace { + +bool SystemAccentColorAllowed(const CSSParserContext& context) { + if (!RuntimeEnabledFeatures::CSSSystemAccentColorEnabled()) { + return false; + } + + if (RuntimeEnabledFeatures::PreventReadingSystemAccentColorEnabled()) { + if (const auto* document = context.GetDocument()) { + if (document->GetPage()->GetChromeClient().IsSVGImageChromeClient()) { + return false; + } + } + } + + return true; +} + +} // namespace + CSSValue* ConsumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool accept_quirky_colors, @@ -1947,7 +1969,7 @@ CSSValueID id = range.Peek().Id(); if ((id == CSSValueID::kAccentcolor || id == CSSValueID::kAccentcolortext) && - !RuntimeEnabledFeatures::CSSSystemAccentColorEnabled()) { + !SystemAccentColorAllowed(context)) { return nullptr; } if (StyleColor::IsColorKeyword(id)) {
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 6651bb9..1476c47 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -4254,6 +4254,205 @@ return layout_object && (layout_object->IsBox() || layout_object->IsSVG()); } +namespace { + +inline bool IsInsetAreaStartRegion(CSSValueID region) { + switch (region) { + case CSSValueID::kStart: + case CSSValueID::kSelfStart: + case CSSValueID::kTop: + case CSSValueID::kLeft: + case CSSValueID::kXStart: + case CSSValueID::kYStart: + case CSSValueID::kXSelfStart: + case CSSValueID::kYSelfStart: + return true; + default: + return false; + } +} + +CSSValueList* ConsumeInsetAreaSpan(CSSParserTokenRange& range) { + CSSValueList* area = CSSValueList::CreateSpaceSeparated(); + if (range.Peek().Id() == CSSValueID::kAll) { + area->Append(*css_parsing_utils::ConsumeIdent(range)); + return area; + } + + bool allow_center = true; + CSSValueID allow_region = CSSValueID::kAll; + auto consume_inset_area_region = + [&allow_center, + &allow_region](CSSParserTokenRange& range) -> CSSIdentifierValue* { + if (range.Peek().Id() == CSSValueID::kCenter) { + // 'center' is allowed in all spans unless we have seen it before. + if (!allow_center) { + return nullptr; + } + allow_center = false; + } else if (allow_region == CSSValueID::kAll) { + // This is the first non-'center' region. Allow any keyword, but set + // allow_region to only allow the opposite non-'center' region. + switch (range.Peek().Id()) { + case CSSValueID::kStart: + allow_region = CSSValueID::kEnd; + break; + case CSSValueID::kEnd: + allow_region = CSSValueID::kStart; + break; + case CSSValueID::kSelfStart: + allow_region = CSSValueID::kSelfEnd; + break; + case CSSValueID::kSelfEnd: + allow_region = CSSValueID::kSelfStart; + break; + case CSSValueID::kTop: + allow_region = CSSValueID::kBottom; + break; + case CSSValueID::kBottom: + allow_region = CSSValueID::kTop; + break; + case CSSValueID::kLeft: + allow_region = CSSValueID::kRight; + break; + case CSSValueID::kRight: + allow_region = CSSValueID::kLeft; + break; + case CSSValueID::kXStart: + allow_region = CSSValueID::kXEnd; + break; + case CSSValueID::kXEnd: + allow_region = CSSValueID::kXStart; + break; + case CSSValueID::kYStart: + allow_region = CSSValueID::kYEnd; + break; + case CSSValueID::kYEnd: + allow_region = CSSValueID::kYStart; + break; + case CSSValueID::kXSelfStart: + allow_region = CSSValueID::kXSelfEnd; + break; + case CSSValueID::kXSelfEnd: + allow_region = CSSValueID::kXSelfStart; + break; + case CSSValueID::kYSelfStart: + allow_region = CSSValueID::kYSelfEnd; + break; + case CSSValueID::kYSelfEnd: + allow_region = CSSValueID::kYSelfStart; + break; + default: + return nullptr; + } + } else { + if (allow_region == CSSValueID::kInvalid || + allow_region != range.Peek().Id()) { + // Either, both non-'center' regions have been consumed, or there was a + // mismatch with the previously consumed non-'center' region. + return nullptr; + } + allow_region = CSSValueID::kInvalid; + } + return css_parsing_utils::ConsumeIdent(range); + }; + + CSSIdentifierValue* start = nullptr; + CSSIdentifierValue* end = nullptr; + + while (CSSIdentifierValue* region = consume_inset_area_region(range)) { + if (region->GetValueID() == CSSValueID::kCenter) { + if (!start) { + start = region; + } + if (!end) { + end = region; + } + } else if (IsInsetAreaStartRegion(region->GetValueID())) { + start = region; + } else { + end = region; + } + } + if (!start && !end) { + return nullptr; + } + if (start && start->GetValueID() == CSSValueID::kStart && end && + end->GetValueID() == CSSValueID::kEnd) { + area->Append(*CSSIdentifierValue::Create(CSSValueID::kAll)); + } else { + if (start) { + area->Append(*start); + } + if (end) { + area->Append(*end); + } + } + return area; +} + +} // namespace + +const CSSValue* InsetArea::ParseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext&) const { + if (range.Peek().Id() == CSSValueID::kNone) { + return css_parsing_utils::ConsumeIdent(range); + } + CSSValueList* area = CSSValueList::CreateSlashSeparated(); + if (CSSValueList* span = ConsumeInsetAreaSpan(range)) { + area->Append(*span); + } else { + return nullptr; + } + if (css_parsing_utils::ConsumeSlashIncludingWhitespace(range)) { + if (CSSValueList* span = ConsumeInsetAreaSpan(range)) { + if (To<CSSIdentifierValue>(span->First()).GetValueID() != + CSSValueID::kAll) { + area->Append(*span); + } + } else { + return nullptr; + } + } + return area; +} + +const CSSValue* InsetArea::CSSValueFromComputedStyleInternal( + const ComputedStyle& style, + const LayoutObject*, + bool allow_visited_style) const { + blink::InsetArea area = style.GetInsetArea(); + if (area.FirstStart() == InsetAreaRegion::kNone) { + return CSSIdentifierValue::Create(CSSValueID::kNone); + } + CSSValueList* area_value = CSSValueList::CreateSlashSeparated(); + CSSValueList* span_value = CSSValueList::CreateSpaceSeparated(); + + InsetAreaRegion start = area.FirstStart(); + InsetAreaRegion end = area.FirstEnd(); + + span_value->Append(*CSSIdentifierValue::Create(start)); + if (start != end) { + span_value->Append(*CSSIdentifierValue::Create(end)); + } + area_value->Append(*span_value); + + start = area.SecondStart(); + end = area.SecondEnd(); + + if (start != InsetAreaRegion::kAll) { + span_value = CSSValueList::CreateSpaceSeparated(); + span_value->Append(*CSSIdentifierValue::Create(start)); + if (start != end) { + span_value->Append(*CSSIdentifierValue::Create(end)); + } + area_value->Append(*span_value); + } + return area_value; +} + const CSSValue* InsetBlockEnd::ParseSingleValue( CSSParserTokenRange& range, const CSSParserContext& context,
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 99cd130..a6275ab 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -3113,4 +3113,42 @@ return MakeGarbageCollected<ScopedCSSNameList>(std::move(names)); } +InsetArea StyleBuilderConverter::ConvertInsetArea(StyleResolverState& state, + const CSSValue& value) { + if (value.IsIdentifierValue()) { + DCHECK_EQ(CSSValueID::kNone, To<CSSIdentifierValue>(value).GetValueID()); + return InsetArea(); + } + + auto extract_inset_area_span = + [](const CSSValue& span) -> std::pair<InsetAreaRegion, InsetAreaRegion> { + InsetAreaRegion start = InsetAreaRegion::kNone; + InsetAreaRegion end = InsetAreaRegion::kNone; + if (const auto* all = DynamicTo<CSSIdentifierValue>(span)) { + DCHECK(all->GetValueID() == CSSValueID::kAll); + start = InsetAreaRegion::kAll; + end = InsetAreaRegion::kAll; + } else { + const auto& span_list = To<CSSValueList>(span); + CHECK_GT(span_list.length(), 0u); + start = To<CSSIdentifierValue>(span_list.First()) + .ConvertTo<InsetAreaRegion>(); + end = + To<CSSIdentifierValue>(span_list.Last()).ConvertTo<InsetAreaRegion>(); + } + return std::make_pair(start, end); + }; + const CSSValueList& span_list = To<CSSValueList>(value); + InsetAreaRegion start1 = InsetAreaRegion::kAll; + InsetAreaRegion end1 = InsetAreaRegion::kAll; + InsetAreaRegion start2 = InsetAreaRegion::kAll; + InsetAreaRegion end2 = InsetAreaRegion::kAll; + CHECK_GT(span_list.length(), 0u); + std::tie(start1, end1) = extract_inset_area_span(span_list.Item(0)); + if (span_list.length() == 2) { + std::tie(start2, end2) = extract_inset_area_span(span_list.Item(1)); + } + return InsetArea(start1, end1, start2, end2); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h index 083dff8..3cec2b0 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -375,6 +375,8 @@ const CSSValue&); static ScopedCSSNameList* ConvertTimelineScope(StyleResolverState&, const CSSValue&); + + static InsetArea ConvertInsetArea(StyleResolverState&, const CSSValue&); }; template <typename T>
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 071fdf8..b22d1fa 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5799,6 +5799,15 @@ scripted_animation_controller_->EnqueuePerFrameEvent(snapchanged_event); } +void Document::EnqueueSnapChangingEvent( + Node* target, + HeapVector<Member<Node>>& snap_targets) { + Event* snapchanging_event = + SnapEvent::Create(event_type_names::kSnapchanging, snap_targets); + snapchanging_event->SetTarget(target); + scripted_animation_controller_->EnqueuePerFrameEvent(snapchanging_event); +} + void Document::EnqueueResizeEvent() { Event* event = Event::Create(event_type_names::kResize); event->SetTarget(domWindow()); @@ -9276,10 +9285,7 @@ CHECK(RuntimeEnabledFeatures::PageRevealEventEnabled()); CHECK(dom_window_); - DOMViewTransition* dom_view_transition = - ViewTransitionUtils::GetTransitionScriptDelegate(*this); - auto* page_reveal_event = - MakeGarbageCollected<PageRevealEvent>(dom_view_transition); + auto* page_reveal_event = MakeGarbageCollected<PageRevealEvent>(); page_reveal_event->SetTarget(dom_window_); page_reveal_event->SetCurrentTarget(dom_window_); EnqueueAnimationFrameEvent(page_reveal_event);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 4cb5a1b..1a539d8 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1462,6 +1462,8 @@ void EnqueueVisualViewportScrollEvent(); void EnqueueVisualViewportResizeEvent(); void EnqueueSnapChangedEvent(Node* target, HeapVector<Member<Node>>& targets); + void EnqueueSnapChangingEvent(Node* target, + HeapVector<Member<Node>>& targets); void DispatchEventsForPrinting();
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 35b3a02..b62eb29 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -6127,11 +6127,11 @@ if (!Element::IsFocusable(update_behavior)) { return false; } - // Note that IsKeyboardFocusableScroller() will get - // called twice, once in IsFocusable (via SupportsFocus) and the other - // here. Note that IsKeyboardFocusableScroller is slow. - return GetIntegralAttribute(html_names::kTabindexAttr, 0) >= 0 || - IsKeyboardFocusableScroller(update_behavior); + if (!HasElementFlag(ElementFlags::kTabIndexWasSetExplicitly) && + CanBeKeyboardFocusableScroller(update_behavior)) { + return IsKeyboardFocusableScroller(update_behavior); + } + return GetIntegralAttribute(html_names::kTabindexAttr, 0) >= 0; } bool Element::IsFocusable(UpdateBehavior update_behavior) const { @@ -6149,7 +6149,7 @@ return HasElementFlag(ElementFlags::kTabIndexWasSetExplicitly) || IsRootEditableElementWithCounting(*this) || - IsKeyboardFocusableScroller(update_behavior) || + CanBeKeyboardFocusableScroller(update_behavior) || SupportsSpatialNavigationFocus(); }
diff --git a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc index d8144c1b..db96f117 100644 --- a/third_party/blink/renderer/core/dom/scripted_animation_controller.cc +++ b/third_party/blink/renderer/core/dom/scripted_animation_controller.cc
@@ -37,6 +37,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page_animator.h" #include "third_party/blink/renderer/core/probe/core_probes.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { @@ -83,10 +84,10 @@ } void ScriptedAnimationController::DispatchEventsAndCallbacksForPrinting() { - DispatchEvents([](const Event* event) { + DispatchEvents(WTF::BindRepeating([](Event* event) { return event->InterfaceName() == event_interface_names::kMediaQueryListEvent; - }); + })); CallMediaQueryListListeners(); } @@ -119,15 +120,15 @@ std::move(task).Run(); } -void ScriptedAnimationController::DispatchEvents(const DispatchFilter& filter) { +bool ScriptedAnimationController::DispatchEvents(DispatchFilter filter) { HeapVector<Member<Event>> events; - if (!filter.has_value()) { + if (filter.is_null()) { events.swap(event_queue_); per_frame_events_.clear(); } else { HeapVector<Member<Event>> remaining; for (auto& event : event_queue_) { - if (event && filter.value()(event)) { + if (event && filter.Run(event)) { EraseFromPerFrameEventsMap(event.Get()); events.push_back(event.Release()); } else { @@ -137,7 +138,10 @@ remaining.swap(event_queue_); } + bool did_dispatch = false; + for (const auto& event : events) { + did_dispatch = true; EventTarget* event_target = event->target(); // FIXME: we should figure out how to make dispatchEvent properly virtual to // avoid special casting window. @@ -150,6 +154,8 @@ else event_target->DispatchEvent(*event); } + + return did_dispatch; } void ScriptedAnimationController::ExecuteVideoFrameCallbacks() {
diff --git a/third_party/blink/renderer/core/dom/scripted_animation_controller.h b/third_party/blink/renderer/core/dom/scripted_animation_controller.h index 51a4ab8..a246d7457 100644 --- a/third_party/blink/renderer/core/dom/scripted_animation_controller.h +++ b/third_party/blink/renderer/core/dom/scripted_animation_controller.h
@@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_ANIMATION_CONTROLLER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SCRIPTED_ANIMATION_CONTROLLER_H_ +#include "base/functional/callback.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h" @@ -98,9 +99,8 @@ void ScheduleAnimationIfNeeded(); void RunTasks(); - typedef absl::optional<bool (*)(const Event*)> DispatchFilter; - void DispatchEvents( - const DispatchFilter& filter = DispatchFilter(absl::nullopt)); + using DispatchFilter = base::RepeatingCallback<bool(Event*)>; + bool DispatchEvents(DispatchFilter filter = DispatchFilter{}); void ExecuteFrameCallbacks(); void ExecuteVideoFrameCallbacks(); void CallMediaQueryListListeners();
diff --git a/third_party/blink/renderer/core/dom/subscriber.cc b/third_party/blink/renderer/core/dom/subscriber.cc index 4cbb227..7e316a72 100644 --- a/third_party/blink/renderer/core/dom/subscriber.cc +++ b/third_party/blink/renderer/core/dom/subscriber.cc
@@ -9,27 +9,82 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_observer_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_observer_complete_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" +#include "third_party/blink/renderer/core/dom/abort_controller.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { +class Subscriber::CloseSubscriptionAlgorithm final + : public AbortSignal::Algorithm { + public: + explicit CloseSubscriptionAlgorithm(Subscriber* subscriber) + : subscriber_(subscriber) {} + ~CloseSubscriptionAlgorithm() override = default; + + void Run() override { subscriber_->CloseSubscription(); } + + void Trace(Visitor* visitor) const override { + visitor->Trace(subscriber_); + Algorithm::Trace(visitor); + } + + private: + Member<Subscriber> subscriber_; +}; + Subscriber::Subscriber(base::PassKey<Observable>, ScriptState* script_state, Observer* observer) : ExecutionContextClient(ExecutionContext::From(script_state)), next_(observer->hasNext() ? observer->next() : nullptr), complete_(observer->hasComplete() ? observer->complete() : nullptr), - error_(observer->hasError() ? observer->error() : nullptr) { - // Initialize `signal_` as a dependent signal on the input Observer's `signal` - // member, if it exists. See - // https://dom.spec.whatwg.org/#abortsignal-dependent-signals. + error_(observer->hasError() ? observer->error() : nullptr), + complete_or_error_controller_(AbortController::Create(script_state)) { + // Initialize `signal_` as a dependent signal on based on two input signals: + // 1. [Possibly null]: The input `Observer#signal` member, if it exists. + // When this input signal is aborted we: + // a. Call `CloseSubscription()`, which sets `active_` to false and + // ensures that no `Observer` callback methods can be called. + // b. Runs all of the teardowns. TODO(domfarolino): Implement this in + // https://crrev.com/c/5018147. + // 2. [Never null]: The signal associated with + // `complete_or_error_controller_`. This signal is aborted when the + // `complete()` or `error()` method is called. Specifically, in this + // case, the order of operations is: + // a. `Subscriber#{complete(), error()}` gets called + // b. We mark the subscription as closed, so that all `Observer` + // callbacks can never be invoked again. This sets `active_` to false. + // c. Invoke the appropriate `Observer` callback, if it exists. This + // callback can observe that `active_` is false. + // d. Abort `complete_or_error_controller_`, which is only used to abort + // `signal_`. + // e. In response to `signal_`'s abortion, run all of the teardowns. + // TODO(domfarolino): Implement this in https://crrev.com/c/5018147. + // f. Finally return from the `Subscriber#{complete(), error()}` method. + // + // See https://dom.spec.whatwg.org/#abortsignal-dependent-signals for more + // info on the dependent signal infrastructure. HeapVector<Member<AbortSignal>> signals; + signals.push_back(complete_or_error_controller_->signal()); if (observer->hasSignal()) { signals.push_back(observer->signal()); } signal_ = MakeGarbageCollected<AbortSignal>(script_state, signals); + + // When `signal_` is finally aborted, this should immediately close the + // subscription. Note that the subscription might *already* be closed, if + // `signal_` was aborted as a result of `complete()` or `error()` being + // called, which both have to manually close the subscription before invoking + // their respective `Observer` callbacks. Closing the subscription is + // idempotent though. + close_subscription_algorithm_handle_ = signal_->AddAlgorithm( + MakeGarbageCollected<CloseSubscriptionAlgorithm>(this)); + + if (signal_->aborted()) { + CloseSubscription(); + } } void Subscriber::next(ScriptValue value) { @@ -38,13 +93,21 @@ } } -void Subscriber::complete() { +void Subscriber::complete(ScriptState* script_state) { V8ObserverCompleteCallback* complete = complete_; CloseSubscription(); if (complete) { + // Once `signal_` is aborted, the first thing that runs is + // `CloseSubscription()`, which makes it impossible to invoke user-provided + // callbacks anymore. + CHECK(!signal_->aborted()); complete->InvokeAndReportException(nullptr); } + + // This will trigger the abort of `signal_`, which will run all of the + // registered teardown callbacks. + complete_or_error_controller_->abort(script_state); } void Subscriber::error(ScriptState* script_state, ScriptValue error_value) { @@ -52,6 +115,10 @@ CloseSubscription(); if (error) { + // Once `signal_` is aborted, the first thing that runs is + // `CloseSubscription()`, which makes it impossible to invoke user-provided + // callbacks anymore. + CHECK(!signal_->aborted()); error->InvokeAndReportException(nullptr, error_value); } else { // The given observer's `error()` handler can be null here for one of two @@ -75,9 +142,14 @@ V8ScriptRunner::ReportException(script_state->GetIsolate(), error_value.V8Value()); } + + // This will trigger the abort of `signal_`, which will run all of the + // registered teardown callbacks. + complete_or_error_controller_->abort(script_state); } void Subscriber::CloseSubscription() { + close_subscription_algorithm_handle_.Clear(); active_ = false; // Reset all handlers, making it impossible to signal any more values to the @@ -85,16 +157,15 @@ next_ = nullptr; complete_ = nullptr; error_ = nullptr; - signal_ = nullptr; - - // TODO(crbug.com/1485981): Implement tear-down semantics. } void Subscriber::Trace(Visitor* visitor) const { visitor->Trace(next_); visitor->Trace(complete_); visitor->Trace(error_); + visitor->Trace(complete_or_error_controller_); visitor->Trace(signal_); + visitor->Trace(close_subscription_algorithm_handle_); ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor);
diff --git a/third_party/blink/renderer/core/dom/subscriber.h b/third_party/blink/renderer/core/dom/subscriber.h index 4d204fb2..a4992f6 100644 --- a/third_party/blink/renderer/core/dom/subscriber.h +++ b/third_party/blink/renderer/core/dom/subscriber.h
@@ -8,6 +8,7 @@ #include "base/types/pass_key.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -15,7 +16,7 @@ namespace blink { -class AbortSignal; +class AbortController; class Observable; class Observer; class ScriptState; @@ -31,7 +32,7 @@ // API methods. void next(ScriptValue); - void complete(); + void complete(ScriptState*); void error(ScriptState*, ScriptValue); // API attributes. @@ -41,6 +42,10 @@ void Trace(Visitor*) const override; private: + class CloseSubscriptionAlgorithm; + + // This method may be called more than once. See the documentation in the + // constructor implementation. void CloseSubscription(); // Any of these may be null, since they are derived from non-required @@ -56,9 +61,21 @@ // `AbortSignal` that it passed into `Observable::subscribe()`. bool active_ = true; - // This is never null. It is exposed via the `signal` WebIDL attribute, and - // represents whether or not the current subscription has been aborted or not. + // `complete_or_error_controller_` is aborted in response to `complete()` or + // `error()` methods being called on `this`. Specifically, the signal is + // aborted *after* the associated `Observer` callback is invoked. This + // controller's signal is one of the parent signals for `signal_` below. + Member<AbortController> complete_or_error_controller_; + + // Never null. It is exposed via the `signal` WebIDL attribute, and represents + // whether or not the current subscription has been aborted or not. This + // signal is a dependent signal, constructed from two signals: + // - The input `Observer#signal`, if present + // - The signal associated with `complete_or_error_controller_` above Member<AbortSignal> signal_; + + // Non-null before `CloseSubscription()` is called. + Member<AbortSignal::AlgorithmHandle> close_subscription_algorithm_handle_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/subscriber.idl b/third_party/blink/renderer/core/dom/subscriber.idl index 580814c..ea83965 100644 --- a/third_party/blink/renderer/core/dom/subscriber.idl +++ b/third_party/blink/renderer/core/dom/subscriber.idl
@@ -7,7 +7,7 @@ [Exposed=(Window,Worker), RuntimeEnabled=ObservableAPI] interface Subscriber { void next(any result); - void complete(); + [CallWith=ScriptState] void complete(); [CallWith=ScriptState] void error(any error); readonly attribute boolean active;
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc index fc74e5d..197332b 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -746,4 +746,15 @@ LayoutViewport().UpdateSnappedTargetsAndEnqueueSnapChanged(); } +void RootFrameViewport::SetSnapChangingTargetData( + absl::optional<cc::SnappedTargetData> data) { + LayoutViewport().SetSnapChangingTargetData(data); +} + +void RootFrameViewport::UpdateSnapChangingTargetsAndEnqueueSnapChanging( + const gfx::PointF& scroll_offset) { + LayoutViewport().UpdateSnapChangingTargetsAndEnqueueSnapChanging( + scroll_offset); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h index 734cb655..f518045 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -133,6 +133,10 @@ absl::optional<gfx::PointF> GetSnapPositionAndSetTarget( const cc::SnapSelectionStrategy& strategy) override; void UpdateSnappedTargetsAndEnqueueSnapChanged() override; + void SetSnapChangingTargetData( + absl::optional<cc::SnappedTargetData>) override; + void UpdateSnapChangingTargetsAndEnqueueSnapChanging( + const gfx::PointF&) override; void SetPendingHistoryRestoreScrollOffset( const HistoryItem::ViewState& view_state,
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 77694b7..a8deb04a 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -4715,8 +4715,9 @@ // test finishes so ensure the transition moves out of rendering // blocked state. if (RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()) { - if (auto* transition = - ViewTransitionUtils::GetTransition(*document)) { + if (ViewTransition* transition = + ViewTransitionUtils::GetTransition(*document); + transition && transition->IsForNavigationOnNewDocument()) { transition->ActivateFromSnapshot(); } }
diff --git a/third_party/blink/renderer/core/html/html_embed_element.cc b/third_party/blink/renderer/core/html/html_embed_element.cc index fb8810b..bdb60aceb1 100644 --- a/third_party/blink/renderer/core/html/html_embed_element.cc +++ b/third_party/blink/renderer/core/html/html_embed_element.cc
@@ -166,6 +166,7 @@ GetDocument().GetFrame()->Client()->OverrideFlashEmbedWithHTML( GetDocument().CompleteURL(url_)); if (!overriden_url.IsEmpty()) { + UseCounter::Count(GetDocument(), WebFeature::kOverrideFlashEmbedwithHTML); url_ = overriden_url.GetString(); SetServiceType("text/html"); }
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc index 6a3f460..0b320833 100644 --- a/third_party/blink/renderer/core/html/html_object_element.cc +++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -221,6 +221,7 @@ GetDocument().GetFrame()->Client()->OverrideFlashEmbedWithHTML( GetDocument().CompleteURL(url_)); if (!overriden_url.IsEmpty()) { + UseCounter::Count(GetDocument(), WebFeature::kOverrideFlashEmbedwithHTML); url_ = overriden_url.GetString(); SetServiceType("text/html"); }
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index 683c7b4..eb11e06 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1648,23 +1648,10 @@ return gesture_manager_->HandleGestureEventInFrame(targeted_event); } -WebInputEventResult EventHandler::HandleGestureScrollEvent( - const WebGestureEvent& gesture_event) { - TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); - if (!frame_->GetPage()) - return WebInputEventResult::kNotHandled; - - return scroll_manager_->HandleGestureScrollEvent(gesture_event); -} - void EventHandler::SetMouseDownMayStartAutoscroll() { mouse_event_manager_->SetMouseDownMayStartAutoscroll(); } -bool EventHandler::IsScrollbarHandlingGestures() const { - return scroll_manager_->IsScrollbarHandlingGestures(); -} - bool EventHandler::ShouldApplyTouchAdjustment( const WebGestureEvent& event) const { if (event.primary_pointer_type == WebPointerProperties::PointerType::kPen)
diff --git a/third_party/blink/renderer/core/input/event_handler.h b/third_party/blink/renderer/core/input/event_handler.h index 12e388d..95dce22 100644 --- a/third_party/blink/renderer/core/input/event_handler.h +++ b/third_party/blink/renderer/core/input/event_handler.h
@@ -181,11 +181,6 @@ const WebGestureEvent&, HitTestRequest::HitTestRequestType); - // Handle the provided scroll gesture event, propagating down to child frames - // as necessary. - WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&); - bool IsScrollbarHandlingGestures() const; - bool BestNodeForHitTestResult(TouchAdjustmentCandidateType candidate_type, const HitTestLocation& location, const HitTestResult&,
diff --git a/third_party/blink/renderer/core/input/gesture_manager.cc b/third_party/blink/renderer/core/input/gesture_manager.cc index d6dd7e4..6583a7c6 100644 --- a/third_party/blink/renderer/core/input/gesture_manager.cc +++ b/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -117,15 +117,17 @@ WebInputEventResult GestureManager::HandleGestureEventInFrame( const GestureEventWithHitTestResults& targeted_event) { - DCHECK(!targeted_event.Event().IsScrollEvent()); - - Node* event_target = targeted_event.GetHitTestResult().InnerNode(); + const HitTestResult& hit_test_result = targeted_event.GetHitTestResult(); const WebGestureEvent& gesture_event = targeted_event.Event(); + DCHECK(!gesture_event.IsScrollEvent()); - if (scroll_manager_->CanHandleGestureEvent(targeted_event)) - return WebInputEventResult::kHandledSuppressed; + if (Scrollbar* scrollbar = hit_test_result.GetScrollbar()) { + if (scrollbar->HandleGestureTapOrPress(gesture_event)) { + return WebInputEventResult::kHandledSuppressed; + } + } - if (event_target) { + if (Node* event_target = hit_test_result.InnerNode()) { GestureEvent* gesture_dom_event = GestureEvent::Create( event_target->GetDocument().domWindow(), gesture_event); if (gesture_dom_event) {
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc index 46d7584..291b645 100644 --- a/third_party/blink/renderer/core/input/scroll_manager.cc +++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -6,36 +6,22 @@ #include <utility> -#include "cc/base/features.h" -#include "cc/input/main_thread_scrolling_reason.h" -#include "cc/input/snap_selection_strategy.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" -#include "third_party/blink/renderer/core/events/gesture_event.h" -#include "third_party/blink/renderer/core/frame/browser_controls.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/root_frame_viewport.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" #include "third_party/blink/renderer/core/input/event_handler.h" -#include "third_party/blink/renderer/core/input/event_handling_util.h" #include "third_party/blink/renderer/core/input/keyboard_event_manager.h" #include "third_party/blink/renderer/core/layout/layout_block.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/page/autoscroll_controller.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" -#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" -#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" -#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/widget/input/input_metrics.h" #include "ui/gfx/geometry/point_conversions.h" namespace blink { @@ -45,16 +31,12 @@ } void ScrollManager::Clear() { - scrollbar_handling_scroll_gesture_ = nullptr; resize_scrollable_area_ = nullptr; offset_from_resize_corner_ = {}; - scroll_gesture_handling_node_ = nullptr; } void ScrollManager::Trace(Visitor* visitor) const { visitor->Trace(frame_); - visitor->Trace(scroll_gesture_handling_node_); - visitor->Trace(scrollbar_handling_scroll_gesture_); visitor->Trace(resize_scrollable_area_); } @@ -345,195 +327,6 @@ return frame_->BubbleLogicalScrollInParentFrame(direction, granularity); } -ScrollOffset GetScrollDirection(ScrollOffset delta) { - delta.SetToMax(ScrollOffset(-1, -1)); - delta.SetToMin(ScrollOffset(1, 1)); - return delta; -} - -WebInputEventResult ScrollManager::HandleGestureScrollEvent( - const WebGestureEvent& gesture_event) { - // TODO(crbug.com/1369739): This method is probably dead code. - if (!frame_->View()) - return WebInputEventResult::kNotHandled; - - TRACE_EVENT0("input", "ScrollManager::handleGestureScrollEvent"); - - Node* event_target = nullptr; - Scrollbar* scrollbar = nullptr; - if (gesture_event.GetType() != WebInputEvent::Type::kGestureScrollBegin) { - scrollbar = scrollbar_handling_scroll_gesture_.Get(); - event_target = scroll_gesture_handling_node_.Get(); - } else if (gesture_event.GetType() == - WebInputEvent::Type::kGestureScrollBegin && - gesture_event.data.scroll_begin.scrollable_area_element_id) { - CompositorElementId element_id = CompositorElementId( - gesture_event.data.scroll_begin.scrollable_area_element_id); - event_target = NodeTargetForScrollableAreaElementId(element_id); - if (!event_target) { - // If we couldn't find a node associated with the targeted scrollable - // area, just drop the gesture. This may be due to the fact that the - // targeted has been removed from the tree between when the gesture - // was queued and when we handle it. - return WebInputEventResult::kNotHandled; - } - - scroll_gesture_handling_node_ = event_target; - } - - if (!event_target) { - Document* document = frame_->GetDocument(); - if (!document->GetLayoutView()) - return WebInputEventResult::kNotHandled; - - TRACE_EVENT_INSTANT0("input", "Retargeting Scroll", - TRACE_EVENT_SCOPE_THREAD); - - LocalFrameView* view = frame_->View(); - PhysicalOffset view_point(view->ConvertFromRootFrame( - gfx::ToFlooredPoint(gesture_event.PositionInRootFrame()))); - HitTestRequest request(HitTestRequest::kReadOnly); - HitTestLocation location(view_point); - HitTestResult result(request, location); - document->GetLayoutView()->HitTest(location, result); - - event_target = result.InnerNode(); - - scroll_gesture_handling_node_ = event_target; - - if (!scrollbar) - scrollbar = result.GetScrollbar(); - } - - // Gesture scroll events injected by scrollbars should not be routed back to - // the scrollbar itself as they are intended to perform the scroll action on - // the scrollable area. Scrollbar injected gestures don't clear - // scrollbar_handling_scroll_gesture_ because touch-based scroll gestures need - // to continue going to the scrollbar first so that the scroll direction - // can be made proportional to the scroll thumb/ScrollableArea size and - // inverted. - if (scrollbar && - gesture_event.SourceDevice() != WebGestureDevice::kScrollbar) { - bool should_update_capture = false; - if (scrollbar->GestureEvent(gesture_event, &should_update_capture)) { - if (should_update_capture) - scrollbar_handling_scroll_gesture_ = scrollbar; - return WebInputEventResult::kHandledSuppressed; - } - - scrollbar_handling_scroll_gesture_ = nullptr; - } - - if (event_target) { - if (HandleScrollGestureOnResizer(event_target, gesture_event)) - return WebInputEventResult::kHandledSuppressed; - } - return WebInputEventResult::kNotHandled; -} - -Node* ScrollManager::NodeTargetForScrollableAreaElementId( - CompositorElementId element_id) const { - Page* page = frame_->GetPage(); - DCHECK(page); - ScrollableArea* scrollable_area = nullptr; - if (page->GetVisualViewport().GetScrollElementId() == element_id) { - // If the element_id is the visual viewport, redirect to the - // root LocalFrameView's scrollable area (i.e. the RootFrameViewport). - scrollable_area = frame_->LocalFrameRoot().View()->GetScrollableArea(); - } else { - ScrollingCoordinator* scrolling_coordinator = - page->GetScrollingCoordinator(); - scrollable_area = - scrolling_coordinator->ScrollableAreaWithElementIdInAllLocalFrames( - element_id); - } - - // It is possible for an unrelated task to run between the time that - // the gesture targeting element_id is queued and when we're processing - // the gesture here, so we must validate the scrollable_area still - // exists along with it's layout information. If not, just drop this - // gesture since there is no relevant data on where to target the gesture. - LayoutBox* layout_box = - scrollable_area ? scrollable_area->GetLayoutBox() : nullptr; - if (!layout_box) { - return nullptr; - } - - Node* event_target = nullptr; - if (layout_box->GetDocument().GetFrame() == frame_) { - event_target = scrollable_area->EventTargetNode(); - } else { - // The targeted ScrollableArea may not belong to this frame. If that - // is the case, target its ancestor HTMLFrameOwnerElement that exists - // in this view, so that the gesture handling can be passed down to - // the appropriate event handler. - LocalFrame* current_frame = layout_box->GetDocument().GetFrame(); - while (current_frame) { - HTMLFrameOwnerElement* owner = current_frame->GetDocument()->LocalOwner(); - // If the hosting element has no layout box, don't return it for targeting - // since there's nothing to scroll. - if (!owner->GetLayoutBox()) - break; - - LocalFrame* owner_frame = - owner ? owner->GetDocument().GetFrame() : nullptr; - if (owner_frame == frame_) { - event_target = owner; - break; - } - current_frame = owner_frame; - } - } - - return event_target; -} - -bool ScrollManager::IsScrollbarHandlingGestures() const { - return scrollbar_handling_scroll_gesture_.Get(); -} - -bool ScrollManager::HandleScrollGestureOnResizer( - Node* event_target, - const WebGestureEvent& gesture_event) { - if (gesture_event.SourceDevice() != WebGestureDevice::kTouchscreen) - return false; - - if (gesture_event.GetType() == WebInputEvent::Type::kGestureScrollBegin) { - PaintLayer* layer = event_target->GetLayoutObject() - ? event_target->GetLayoutObject()->EnclosingLayer() - : nullptr; - gfx::Point p = frame_->View()->ConvertFromRootFrame( - gfx::ToFlooredPoint(gesture_event.PositionInRootFrame())); - if (layer && layer->GetScrollableArea() && - layer->GetScrollableArea()->IsAbsolutePointInResizeControl( - p, kResizerForTouch)) { - resize_scrollable_area_ = layer->GetScrollableArea(); - resize_scrollable_area_->SetInResizeMode(true); - offset_from_resize_corner_ = - resize_scrollable_area_->OffsetFromResizeCorner(p); - return true; - } - } else if (gesture_event.GetType() == - WebInputEvent::Type::kGestureScrollUpdate) { - if (resize_scrollable_area_ && resize_scrollable_area_->InResizeMode()) { - gfx::Point pos = gfx::ToRoundedPoint(gesture_event.PositionInRootFrame()); - pos.Offset(gesture_event.DeltaXInRootFrame(), - gesture_event.DeltaYInRootFrame()); - resize_scrollable_area_->Resize(pos, offset_from_resize_corner_); - return true; - } - } else if (gesture_event.GetType() == - WebInputEvent::Type::kGestureScrollEnd) { - if (resize_scrollable_area_ && resize_scrollable_area_->InResizeMode()) { - resize_scrollable_area_->SetInResizeMode(false); - resize_scrollable_area_ = nullptr; - return false; - } - } - - return false; -} - bool ScrollManager::InResizeMode() const { return resize_scrollable_area_ && resize_scrollable_area_->InResizeMode(); } @@ -564,20 +357,4 @@ resize_scrollable_area_->OffsetFromResizeCorner(p); } -bool ScrollManager::CanHandleGestureEvent( - const GestureEventWithHitTestResults& targeted_event) { - Scrollbar* scrollbar = targeted_event.GetHitTestResult().GetScrollbar(); - - if (scrollbar) { - bool should_update_capture = false; - if (scrollbar->GestureEvent(targeted_event.Event(), - &should_update_capture)) { - if (should_update_capture) - scrollbar_handling_scroll_gesture_ = scrollbar; - return true; - } - } - return false; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/input/scroll_manager.h b/third_party/blink/renderer/core/input/scroll_manager.h index b5417be..da7b7335 100644 --- a/third_party/blink/renderer/core/input/scroll_manager.h +++ b/third_party/blink/renderer/core/input/scroll_manager.h
@@ -5,16 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_ -#include "base/functional/callback_helpers.h" -#include "cc/input/snap_fling_controller.h" -#include "third_party/blink/public/platform/web_input_event_result.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" -#include "third_party/blink/renderer/core/scroll/scrollable_area.h" -#include "third_party/blink/renderer/platform/geometry/layout_size.h" -#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -27,20 +21,19 @@ class LocalFrame; class PaintLayer; class PaintLayerScrollableArea; -class Scrollbar; -class WebGestureEvent; // Scroll directions used to check whether propagation is possible in a given // direction. Used in CanPropagate. enum class ScrollPropagationDirection { kHorizontal, kVertical, kBoth, kNone }; -// This class assists certain main-thread scroll operations such as keyboard -// scrolls and middle-click autoscroll, as well as resizer-control interactions. -// User scrolls from pointer devices (wheel/touch) are handled on the compositor -// (cc::InputHandler). For Javascript scrolls, see ProgrammaticScrollAnimator -// and the ScrollableArea APIs. -// TODO(crbug.com/1369739): Now that scroll unification has launched, much of -// this class can be deleted. +// This class is deprecated as scrolling is now handled by cc::InputHandler. +// It is still involved with the following main-thread operations: +// - keyboard scrolls +// - middle-click autoscroll +// - resizer-control interactions +// For Javascript scrolls, see ProgrammaticScrollAnimator. +// Do not add new things to this class. +// TODO(crbug.com/1503711): Remove keyboard scrolling. class CORE_EXPORT ScrollManager : public GarbageCollected<ScrollManager> { public: explicit ScrollManager(LocalFrame&); @@ -80,18 +73,6 @@ Node* mouse_press_node, bool scrolling_via_key = false); - // TODO(crbug.com/616491): Consider moving all gesture related functions to - // another class. - - // Handle the provided scroll gesture event, propagating down to child frames - // as necessary. - WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&); - - bool IsScrollbarHandlingGestures() const; - - // Returns true if the gesture event should be handled in ScrollManager. - bool CanHandleGestureEvent(const GestureEventWithHitTestResults&); - // These functions are related to |m_resizeScrollableArea|. bool InResizeMode() const; void Resize(const WebMouseEvent&); @@ -106,25 +87,13 @@ ScrollPropagationDirection direction); private: - Node* NodeTargetForScrollableAreaElementId( - CompositorElementId scrollable_area_element_id) const; - - bool HandleScrollGestureOnResizer(Node*, const WebGestureEvent&); - void RecomputeScrollChain(const Node& start_node, Deque<DOMNodeId>& scroll_chain, bool is_autoscroll); bool CanScroll(const Node& current_node, bool for_autoscroll); - // NOTE: If adding a new field to this class please ensure that it is - // cleared in |ScrollManager::clear()|. - const Member<LocalFrame> frame_; - Member<Node> scroll_gesture_handling_node_; - - Member<Scrollbar> scrollbar_handling_scroll_gesture_; - Member<PaintLayerScrollableArea> resize_scrollable_area_; // In the coords of resize_scrollable_area_.
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index 8bde50e..f8f24af 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -634,46 +634,6 @@ ASSERT_FALSE(scrollable_area->HorizontalScrollbar()); } -TEST_P(ScrollbarsTest, scrollbarIsNotHandlingTouchpadScroll) { - WebView().MainFrameViewWidget()->Resize(gfx::Size(200, 200)); - SimRequest request("https://example.com/test.html", "text/html"); - LoadURL("https://example.com/test.html"); - request.Complete(R"HTML( - <!DOCTYPE html> - <style> - #scrollable { height: 100px; width: 100px; overflow: scroll; } - #content { height: 200px; width: 200px;} - </style> - <div id='scrollable'> - <div id='content'></div> - </div> - )HTML"); - Compositor().BeginFrame(); - - Document& document = GetDocument(); - Element* scrollable = document.getElementById(AtomicString("scrollable")); - - auto* scrollable_area = GetScrollableArea(*scrollable); - DCHECK(scrollable_area->VerticalScrollbar()); - WebGestureEvent scroll_begin( - WebInputEvent::Type::kGestureScrollBegin, WebInputEvent::kNoModifiers, - base::TimeTicks::Now(), WebGestureDevice::kTouchpad); - scroll_begin.SetPositionInWidget( - gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2, - scrollable->OffsetTop())); - scroll_begin.SetPositionInScreen( - gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2, - scrollable->OffsetTop())); - scroll_begin.data.scroll_begin.delta_x_hint = 0; - scroll_begin.data.scroll_begin.delta_y_hint = 10; - scroll_begin.SetFrameScale(1); - GetWebFrameWidget().DispatchThroughCcInputHandler(scroll_begin); - DCHECK(!GetEventHandler().IsScrollbarHandlingGestures()); - bool should_update_capture = false; - DCHECK(!scrollable_area->VerticalScrollbar()->GestureEvent( - scroll_begin, &should_update_capture)); -} - TEST_P(ScrollbarsTest, HidingScrollbarsOnScrollableAreaDisablesScrollbars) { // This test is specifically checking the behavior when overlay scrollbars // are enabled.
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index 6ac3b81b..eab67316 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -499,10 +499,21 @@ } inline bool IsNonKeyboardFocusableShadowHost(const Element& element) { - return IsShadowHostWithoutCustomFocusLogic(element) && - !(element.GetShadowRoot() - ? (element.IsFocusable() || element.DelegatesFocus()) - : element.IsKeyboardFocusable()); + if (!IsShadowHostWithoutCustomFocusLogic(element) || + element.DelegatesFocus()) { + return false; + } + if (!element.IsFocusable()) { + return true; + } + if (element.IsKeyboardFocusable()) { + return false; + } + // This host supports focus, but cannot be keyboard focused. For example: + // - Tabindex is negative + // - It is a scroller with focusable children + // When tabindex is negative, we should not visit the host. + return !(element.GetIntegralAttribute(html_names::kTabindexAttr, 0) < 0); } inline bool IsKeyboardFocusableShadowHost(const Element& element) {
diff --git a/third_party/blink/renderer/core/page/page_animator.cc b/third_party/blink/renderer/core/page/page_animator.cc index 3cdc807d..2219e73 100644 --- a/third_party/blink/renderer/core/page/page_animator.cc +++ b/third_party/blink/renderer/core/page/page_animator.cc
@@ -24,11 +24,14 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/svg/svg_document_extensions.h" #include "third_party/blink/renderer/core/timing/time_clamper.h" +#include "third_party/blink/renderer/core/view_transition/page_reveal_event.h" #include "third_party/blink/renderer/core/view_transition/view_transition.h" +#include "third_party/blink/renderer/core/view_transition/view_transition_supplement.h" #include "third_party/blink/renderer/core/view_transition/view_transition_utils.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -160,25 +163,54 @@ // https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model - // TODO(bokan): Requires an update to "update the rendering" steps in HTML. - run_for_all_active_controllers_with_timing([&](wtf_size_t i) { - if (RuntimeEnabledFeatures::PageRevealEventEnabled()) { - active_controllers[i]->DispatchEvents([](const Event* event) { - return event->type() == event_type_names::kPagereveal; - }); - } + // For each fully active Document doc in docs, run the reveal steps for doc. + // Not currently in spec but comes from monkeypatch in: + // https://drafts.csswg.org/css-view-transitions-2/#monkey-patch-to-html + if (RuntimeEnabledFeatures::PageRevealEventEnabled()) { + // The event will be dispatched if the filter returns true. The sequencing + // here is important: + // 1. Resolve the view transition based on @view-transition and set it to + // the event. This happens in the filter so before the event is fired. + // 2. Dispatch the pagereveal event + // 3. Activate the view transition + auto page_reveal_event_filter = + WTF::BindRepeating([](const LocalDOMWindow* window, Event* event) { + PageRevealEvent* page_reveal = DynamicTo<PageRevealEvent>(event); + if (!page_reveal) { + return false; + } - if (RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()) { - CHECK(RuntimeEnabledFeatures::PageRevealEventEnabled()); - if (const LocalDOMWindow* window = active_controllers[i]->GetWindow()) { - CHECK(window->document()); + // pagereveal is only fired on Documents. + CHECK(window); + CHECK(window->document()); + + if (RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()) { + if (auto* supplement = ViewTransitionSupplement::FromIfExists( + *window->document())) { + DOMViewTransition* view_transition = + supplement->ResolveCrossDocumentViewTransition(); + page_reveal->SetViewTransition(view_transition); + } + } + + return true; + }); + + run_for_all_active_controllers_with_timing([&](wtf_size_t i) { + const LocalDOMWindow* window = active_controllers[i]->GetWindow(); + bool pagereveal_dispatched = active_controllers[i]->DispatchEvents( + WTF::BindRepeating(page_reveal_event_filter, WrapPersistent(window))); + + if (RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled() && + pagereveal_dispatched) { if (ViewTransition* transition = - ViewTransitionUtils::GetTransition(*window->document())) { + ViewTransitionUtils::GetTransition(*window->document()); + transition && transition->IsForNavigationOnNewDocument()) { transition->ActivateFromSnapshot(); } } - } - }); + }); + } // 6. For each fully active Document in docs, flush autofocus // candidates for that Document if its browsing context is a top-level @@ -195,9 +227,9 @@ auto start_time = base::TimeTicks::Now(); for (wtf_size_t i = 0; i < controllers.size(); ++i) { auto& [controller, can_throttle] = controllers[i]; - controller->DispatchEvents([](const Event* event) { + controller->DispatchEvents(WTF::BindRepeating([](Event* event) { return event->type() == event_type_names::kResize; - }); + })); auto end_time = base::TimeTicks::Now(); if (active_controller_id < active_controllers_ids.size() && i == active_controllers_ids[active_controller_id]) { @@ -217,11 +249,12 @@ // 8. For each fully active Document in docs, run the scroll steps // for that Document, passing in now as the timestamp. run_for_all_active_controllers_with_timing([&](wtf_size_t i) { - active_controllers[i]->DispatchEvents([](const Event* event) { + active_controllers[i]->DispatchEvents(WTF::BindRepeating([](Event* event) { return event->type() == event_type_names::kScroll || event->type() == event_type_names::kSnapchanged || + event->type() == event_type_names::kSnapchanging || event->type() == event_type_names::kScrollend; - }); + })); }); // 9. For each fully active Document in docs, evaluate media
diff --git a/third_party/blink/renderer/core/page/page_test.cc b/third_party/blink/renderer/core/page/page_test.cc index c2721d5..42871ab 100644 --- a/third_party/blink/renderer/core/page/page_test.cc +++ b/third_party/blink/renderer/core/page/page_test.cc
@@ -11,13 +11,17 @@ #include "third_party/blink/public/common/page/browsing_context_group_info.h" #include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/page/scoped_browsing_context_group_pauser.h" -#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h" +#include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/main_thread_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" namespace blink { TEST(PageTest, CreateOrdinaryBrowsingContextGroup) { EmptyChromeClient client; - auto* scheduler = scheduler::CreateDummyAgentGroupScheduler(); + auto* scheduler = ThreadScheduler::Current() + ->ToMainThreadScheduler() + ->CreateAgentGroupScheduler(); auto bcg_info = BrowsingContextGroupInfo::CreateUnique(); Page* page = @@ -30,7 +34,9 @@ TEST(PageTest, CreateNonOrdinaryBrowsingContextGroup) { EmptyChromeClient client; - auto* scheduler = scheduler::CreateDummyAgentGroupScheduler(); + auto* scheduler = ThreadScheduler::Current() + ->ToMainThreadScheduler() + ->CreateAgentGroupScheduler(); Page* page = Page::CreateNonOrdinary(client, *scheduler); @@ -42,7 +48,9 @@ TEST(PageTest, BrowsingContextGroupUpdate) { EmptyChromeClient client; - auto* scheduler = scheduler::CreateDummyAgentGroupScheduler(); + auto* scheduler = ThreadScheduler::Current() + ->ToMainThreadScheduler() + ->CreateAgentGroupScheduler(); auto initial_bcg_info = BrowsingContextGroupInfo::CreateUnique(); Page* page = Page::CreateOrdinary(client, /*opener=*/nullptr, *scheduler, @@ -68,7 +76,9 @@ features::kPausePagesPerBrowsingContextGroup); EmptyChromeClient client; - auto* scheduler = scheduler::CreateDummyAgentGroupScheduler(); + auto* scheduler = ThreadScheduler::Current() + ->ToMainThreadScheduler() + ->CreateAgentGroupScheduler(); auto group_a = BrowsingContextGroupInfo::CreateUnique();
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc index 8adb8b7..3c56800 100644 --- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -72,9 +72,10 @@ // Clear the old data if needed. if (old_snap_container_data) { snap_container.SetNeedsPaintPropertyUpdate(); - scrollable_area->SetSnapContainerData(absl::nullopt); - scrollable_area->UpdateSnappedTargetsAndEnqueueSnapChanged(); + scrollable_area->SetSnapChangingTargetData(absl::nullopt); scrollable_area->SetSnappedTargetData(absl::nullopt); + scrollable_area->EnqueueSnapChangedEvent(); + scrollable_area->SetSnapContainerData(absl::nullopt); } return false; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 2340ed3..ea2e10c 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1891,6 +1891,13 @@ EnsureRareData().snapped_target_data_ = data; } +const cc::SnappedTargetData* +PaintLayerScrollableArea::GetSnapChangingTargetData() const { + return RareData() && RareData()->snapchanging_target_data_ + ? &RareData()->snapchanging_target_data_.value() + : nullptr; +} + absl::optional<gfx::PointF> PaintLayerScrollableArea::GetSnapPositionAndSetTarget( const cc::SnapSelectionStrategy& strategy) { @@ -3091,10 +3098,14 @@ if (!RuntimeEnabledFeatures::CSSSnapChangedEventEnabled()) { return; } + const cc::SnapContainerData* container_data = GetSnapContainerData(); + if (!container_data) { + return; + } const cc::SnappedTargetData* snapped_target_data = GetSnappedTargetData(); std::set<cc::ElementId> new_targets = - cc::SnapContainerData::FindSnappedTargetsAtScrollOffset( - GetSnapContainerData(), ScrollPosition()); + cc::SnapContainerData::FindSnappedTargetsAtScrollOffset(container_data, + ScrollPosition()); bool snapchanged = snapped_target_data ? snapped_target_data->GetSnappedTargetIds() != new_targets @@ -3110,4 +3121,38 @@ } } +void PaintLayerScrollableArea::SetSnapChangingTargetData( + absl::optional<cc::SnappedTargetData> data) { + EnsureRareData().snapchanging_target_data_ = data; +} + +void PaintLayerScrollableArea::UpdateSnapChangingTargetsAndEnqueueSnapChanging( + const gfx::PointF& scroll_offset) { + if (!RuntimeEnabledFeatures::CSSSnapChangingEventEnabled()) { + return; + } + const cc::SnapContainerData* container_data = GetSnapContainerData(); + if (!container_data) { + return; + } + const cc::SnappedTargetData* snapchanging_target_data = + GetSnapChangingTargetData(); + if (!snapchanging_target_data) { + return; + } + + const std::set<cc::ElementId> new_snapchanging_targets = + cc::SnapContainerData::FindSnappedTargetsAtScrollOffset(container_data, + scroll_offset); + if (snapchanging_target_data->GetSnappedTargetIds() != + new_snapchanging_targets) { + if (!EnsureRareData().snapchanging_target_data_) { + RareData()->snapchanging_target_data_ = cc::SnappedTargetData(); + } + RareData()->snapchanging_target_data_->SetSnappedTargetIds( + std::move(new_snapchanging_targets)); + EnqueueSnapChangingEvent(); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index eb17eca..ef882198 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -83,6 +83,7 @@ absl::optional<cc::SnapContainerData> snap_container_data_; absl::optional<cc::SnappedTargetData> snapped_target_data_; + absl::optional<cc::SnappedTargetData> snapchanging_target_data_; Vector<gfx::Rect> tickmarks_override_; }; @@ -545,6 +546,12 @@ const cc::SnappedTargetData* GetSnappedTargetData() const override; void UpdateSnappedTargetsAndEnqueueSnapChanged() override; + const cc::SnappedTargetData* GetSnapChangingTargetData() const override; + void SetSnapChangingTargetData( + absl::optional<cc::SnappedTargetData>) override; + void UpdateSnapChangingTargetsAndEnqueueSnapChanging( + const gfx::PointF&) override; + void DisposeImpl() override; void SetPendingHistoryRestoreScrollOffset(
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc index f0984fe..96cf80c 100644 --- a/third_party/blink/renderer/core/paint/theme_painter_default.cc +++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -36,6 +36,8 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_progress.h" #include "third_party/blink/renderer/core/layout/layout_theme_default.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/paint_auto_dark_mode.h" #include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/platform/graphics/color.h" @@ -174,15 +176,21 @@ return ToPixelSnappedRect(part_rect); } -absl::optional<SkColor> GetAccentColor(const ComputedStyle& style) { +absl::optional<SkColor> GetAccentColor(const ComputedStyle& style, + const Document& document) { absl::optional<Color> css_accent_color = style.AccentColorResolved(); if (css_accent_color) return css_accent_color->Rgb(); - mojom::blink::ColorScheme color_scheme = style.UsedColorScheme(); - LayoutTheme& layout_theme = LayoutTheme::GetTheme(); - if (layout_theme.IsAccentColorCustomized(color_scheme)) { - return layout_theme.GetSystemAccentColor(color_scheme).Rgb(); + bool in_image = + document.GetPage()->GetChromeClient().IsSVGImageChromeClient(); + if (!RuntimeEnabledFeatures::PreventReadingSystemAccentColorEnabled() || + !in_image) { + mojom::blink::ColorScheme color_scheme = style.UsedColorScheme(); + LayoutTheme& layout_theme = LayoutTheme::GetTheme(); + if (layout_theme.IsAccentColorCustomized(color_scheme)) { + return layout_theme.GetSystemAccentColor(color_scheme).Rgb(); + } } return absl::nullopt; @@ -194,7 +202,7 @@ : ThemePainter(), theme_(theme) {} bool ThemePainterDefault::PaintCheckbox(const Element& element, - const Document&, + const Document& document, const ComputedStyle& style, const PaintInfo& paint_info, const gfx::Rect& rect) { @@ -211,12 +219,12 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartCheckbox, GetWebThemeState(element), unzoomed_rect, &extra_params, - style.UsedColorScheme(), GetAccentColor(style)); + style.UsedColorScheme(), GetAccentColor(style, document)); return false; } bool ThemePainterDefault::PaintRadio(const Element& element, - const Document&, + const Document& document, const ComputedStyle& style, const PaintInfo& paint_info, const gfx::Rect& rect) { @@ -233,12 +241,12 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartRadio, GetWebThemeState(element), unzoomed_rect, &extra_params, - style.UsedColorScheme(), GetAccentColor(style)); + style.UsedColorScheme(), GetAccentColor(style, document)); return false; } bool ThemePainterDefault::PaintButton(const Element& element, - const Document&, + const Document& document, const ComputedStyle& style, const PaintInfo& paint_info, const gfx::Rect& rect) { @@ -250,7 +258,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartButton, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, document)); return false; } @@ -284,7 +292,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartTextField, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, element.GetDocument())); return false; } @@ -321,7 +329,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartMenuList, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, document)); return false; } @@ -341,7 +349,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartMenuList, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, document)); return false; } @@ -451,7 +459,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartSliderTrack, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, element.GetDocument())); return false; } @@ -477,7 +485,8 @@ DCHECK(slider_element); // PaintSliderThumb should always be passed a // SliderThumbElement absl::optional<SkColor> accent_color = - GetAccentColor(*slider_element->HostInput()->EnsureComputedStyle()); + GetAccentColor(*slider_element->HostInput()->EnsureComputedStyle(), + element.GetDocument()); WebThemeEngine::ExtraParams extra_params(slider); WebThemeEngineHelper::GetNativeThemeEngine()->Paint( @@ -515,7 +524,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartInnerSpinButton, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, element.GetDocument())); return false; } @@ -544,7 +553,7 @@ WebThemeEngineHelper::GetNativeThemeEngine()->Paint( paint_info.context.Canvas(), WebThemeEngine::kPartProgressBar, GetWebThemeState(element), rect, &extra_params, style.UsedColorScheme(), - GetAccentColor(style)); + GetAccentColor(style, element.GetDocument())); return false; }
diff --git a/third_party/blink/renderer/core/permissions_policy/document_policy_parser.cc b/third_party/blink/renderer/core/permissions_policy/document_policy_parser.cc index eb5706a..2c3a0fd 100644 --- a/third_party/blink/renderer/core/permissions_policy/document_policy_parser.cc +++ b/third_party/blink/renderer/core/permissions_policy/document_policy_parser.cc
@@ -13,35 +13,16 @@ constexpr const char* kReportTo = "report-to"; constexpr const char* kNone = "none"; -const char* ItemTypeToString(net::structured_headers::Item::ItemType type) { - switch (type) { - case net::structured_headers::Item::ItemType::kIntegerType: - return "Integer"; - case net::structured_headers::Item::ItemType::kDecimalType: - return "Decimal"; - case net::structured_headers::Item::ItemType::kBooleanType: - return "Boolean"; - case net::structured_headers::Item::ItemType::kByteSequenceType: - return "ByteSequence"; - case net::structured_headers::Item::ItemType::kNullType: - return "Null"; - case net::structured_headers::Item::ItemType::kStringType: - return "String"; - case net::structured_headers::Item::ItemType::kTokenType: - return "Token"; - } -} - const char* PolicyValueTypeToString(mojom::blink::PolicyValueType type) { switch (type) { case mojom::blink::PolicyValueType::kNull: - return "Null"; + return "null"; case mojom::blink::PolicyValueType::kBool: - return "Boolean"; + return "boolean"; case mojom::blink::PolicyValueType::kDecDouble: - return "Double"; + return "double"; case mojom::blink::PolicyValueType::kEnum: - return "Enum"; + return "enum"; } } @@ -121,7 +102,7 @@ logger.Warn(String::Format( "Parameter for feature %s should be %s, not %s.", feature_name.c_str(), PolicyValueTypeToString(expected_policy_value_type), - ItemTypeToString(item.Type()))); + net::structured_headers::ItemTypeToString(item.Type()).data())); return absl::nullopt; } parsed_feature.policy_value = *policy_value;
diff --git a/third_party/blink/renderer/core/permissions_policy/document_policy_parser_test.cc b/third_party/blink/renderer/core/permissions_policy/document_policy_parser_test.cc index 6d3813e..071f8a2d 100644 --- a/third_party/blink/renderer/core/permissions_policy/document_policy_parser_test.cc +++ b/third_party/blink/renderer/core/permissions_policy/document_policy_parser_test.cc
@@ -334,8 +334,8 @@ }, /* messages */ {{mojom::blink::ConsoleMessageLevel::kWarning, - "Parameter for feature f-double should be Double, not " - "Boolean."}}, + "Parameter for feature f-double should be double, not " + "boolean."}}, }, { "ParsePolicyWithWrongTypeOfParamExpectedBooleanTypeButGet" @@ -348,8 +348,8 @@ }, /* messages */ {{mojom::blink::ConsoleMessageLevel::kWarning, - "Parameter for feature f-bool should be Boolean, not " - "Decimal."}}, + "Parameter for feature f-bool should be boolean, not " + "decimal."}}, }, { "FeatureValueItemShouldNotBeEmpty",
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc index f1a3145..7e1849e 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.cc +++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -599,6 +599,10 @@ }, std::move(callback), WrapWeakPersistent(this))); + // Enqueue snapchanging if necessary. + UpdateSnapChangingTargetsAndEnqueueSnapChanging( + gfx::PointF(offset.x(), offset.y())); + if (should_use_animation) { GetProgrammaticScrollAnimator().AnimateToOffset(offset, is_sequenced_scroll, std::move(callback)); @@ -1295,6 +1299,16 @@ return false; } + // We should set the snapchanging targets of a snap container the first + // time it is laid out to avoid a spurious snapchanging event firing the first + // time the scroller is scrolled. + if (!GetSnapChangingTargetData()) { + std::set<cc::ElementId> snap_targets = + cc::SnapContainerData::FindSnappedTargetsAtScrollOffset( + GetSnapContainerData(), snap_point.value()); + SetSnapChangingTargetData(cc::SnappedTargetData(std::move(snap_targets))); + } + CancelScrollAnimation(); CancelProgrammaticScrollAnimation(); if (!SetScrollOffset(ScrollPositionToOffset(snap_point.value()), @@ -1378,28 +1392,46 @@ : offset); } -void ScrollableArea::EnqueueSnapChangedEvent() const { - DCHECK(RuntimeEnabledFeatures::CSSSnapChangedEventEnabled()); - if (Node* target_node = EventTargetNode()) { - HeapVector<Member<Node>> snap_targets; - if (const cc::SnappedTargetData* snapped_target_data = - GetSnappedTargetData()) { - for (const cc::ElementId& id : - snapped_target_data->GetSnappedTargetIds()) { - if (Node* node = - DOMNodeIds::NodeForId(DOMNodeIdFromCompositorElementId(id))) { - snap_targets.push_back(node); - } +HeapVector<Member<Node>> ScrollableArea::PrepareSnapEventTargets( + const cc::SnappedTargetData* target_data) const { + HeapVector<Member<Node>> target_nodes; + if (target_data) { + for (const cc::ElementId& id : target_data->GetSnappedTargetIds()) { + if (Node* node = + DOMNodeIds::NodeForId(DOMNodeIdFromCompositorElementId(id))) { + target_nodes.push_back(node); } } auto compare_targets = [](Node* node1, Node* node2) { return node1->compareDocumentPosition(node2) & Node::kDocumentPositionFollowing; }; - std::sort(snap_targets.begin(), snap_targets.end(), compare_targets); - target_node->GetDocument().EnqueueSnapChangedEvent(target_node, - snap_targets); + std::sort(target_nodes.begin(), target_nodes.end(), compare_targets); } + return target_nodes; +} + +void ScrollableArea::EnqueueSnapChangedEvent() const { + DCHECK(RuntimeEnabledFeatures::CSSSnapChangedEventEnabled()); + Node* target_node = EventTargetNode(); + if (!target_node) { + return; + } + HeapVector<Member<Node>> snap_targets = + PrepareSnapEventTargets(GetSnappedTargetData()); + target_node->GetDocument().EnqueueSnapChangedEvent(target_node, snap_targets); +} + +void ScrollableArea::EnqueueSnapChangingEvent() const { + DCHECK(RuntimeEnabledFeatures::CSSSnapChangingEventEnabled()); + Node* target_node = EventTargetNode(); + if (!target_node) { + return; + } + HeapVector<Member<Node>> snap_targets = + PrepareSnapEventTargets(GetSnapChangingTargetData()); + target_node->GetDocument().EnqueueSnapChangingEvent(target_node, + snap_targets); } } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h index 726c356..e07cf9d 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.h +++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -581,6 +581,15 @@ bool ScrollOffsetIsNoop(const ScrollOffset& offset) const; + void EnqueueSnapChangingEvent() const; + virtual const cc::SnappedTargetData* GetSnapChangingTargetData() const { + return nullptr; + } + virtual void SetSnapChangingTargetData( + absl::optional<cc::SnappedTargetData>) {} + virtual void UpdateSnapChangingTargetsAndEnqueueSnapChanging( + const gfx::PointF&) {} + protected: // Deduces the mojom::blink::ScrollBehavior based on the // element style and the parameter set by programmatic scroll into either @@ -670,6 +679,9 @@ void ScrollToScrollStartTarget(const LayoutBox*, cc::SnapAxis); void ScrollToScrollStartTargets(const ScrollStartTargetCandidates*); + HeapVector<Member<Node>> PrepareSnapEventTargets( + const cc::SnappedTargetData* target_data) const; + // This animator is used to handle painting animations for MacOS scrollbars // using AppKit-specific code (Cocoa APIs). It requires input from // ScrollableArea about changes on scrollbars. For other platforms, painting
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.cc b/third_party/blink/renderer/core/scroll/scrollbar.cc index fb6e0ac..69f3cf9b 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar.cc +++ b/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -394,9 +394,8 @@ } } -bool Scrollbar::GestureEvent(const WebGestureEvent& evt, - bool* should_update_capture) { - DCHECK(should_update_capture); +bool Scrollbar::HandleGestureTapOrPress(const WebGestureEvent& evt) { + DCHECK(!evt.IsScrollEvent()); switch (evt.GetType()) { case WebInputEvent::Type::kGestureTapDown: { gfx::Point position = gfx::ToFlooredPoint(evt.PositionInRootFrame()); @@ -405,7 +404,6 @@ pressed_pos_ = Orientation() == kHorizontalScrollbar ? ConvertFromRootFrame(position).x() : ConvertFromRootFrame(position).y(); - *should_update_capture = true; return true; } case WebInputEvent::Type::kGestureTapCancel: @@ -413,58 +411,8 @@ return false; scroll_pos_ = pressed_pos_; return true; - case WebInputEvent::Type::kGestureScrollBegin: - switch (evt.SourceDevice()) { - case WebGestureDevice::kSyntheticAutoscroll: - case WebGestureDevice::kTouchpad: - // Update the state on GSB for touchpad since GestureTapDown - // is not generated by that device. Touchscreen uses the tap down - // gesture since the scrollbar enters a visual active state. - SetPressedPart(kNoPart, evt.GetType()); - pressed_pos_ = 0; - return false; - case WebGestureDevice::kTouchscreen: - if (pressed_part_ != kThumbPart) - return false; - scroll_pos_ = pressed_pos_; - return true; - default: - NOTREACHED(); - return true; - } - case WebInputEvent::Type::kGestureScrollUpdate: - switch (evt.SourceDevice()) { - case WebGestureDevice::kSyntheticAutoscroll: - case WebGestureDevice::kTouchpad: - return false; - case WebGestureDevice::kTouchscreen: - if (pressed_part_ != kThumbPart) - return false; - - // Prevent scrollbar fling by filtering gesture scroll updates that - // have the momentum bit set - if (evt.InertialPhase() == - WebGestureEvent::InertialPhaseState::kMomentum) { - return true; - } - scroll_pos_ += Orientation() == kHorizontalScrollbar - ? evt.DeltaXInRootFrame() - : evt.DeltaYInRootFrame(); - MoveThumb(scroll_pos_, false); - return true; - default: - NOTREACHED(); - return true; - } - case WebInputEvent::Type::kGestureScrollEnd: - // If we see a GSE targeted at the scrollbar, clear the state that - // says we injected GestureScrollBegin, since we no longer need to inject - // a GSE ourselves. - injected_gesture_scroll_begin_ = false; - [[fallthrough]]; case WebInputEvent::Type::kGestureShortPress: case WebInputEvent::Type::kGestureLongPress: - case WebInputEvent::Type::kGestureFlingStart: scroll_pos_ = 0; pressed_pos_ = 0; SetPressedPart(kNoPart, evt.GetType());
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.h b/third_party/blink/renderer/core/scroll/scrollbar.h index 6d96474..dbcbdf5 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar.h +++ b/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -135,10 +135,8 @@ bool IsWindowActive() const; - // Return if the gesture event was handled. |shouldUpdateCapture| - // will be set to true if the handler should update the capture - // state for this scrollbar. - bool GestureEvent(const WebGestureEvent&, bool* should_update_capture); + // Return if the gesture event (tap/press) was handled. + bool HandleGestureTapOrPress(const WebGestureEvent&); bool HandlePointerEvent(const WebPointerEvent&);
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc index 498ebef..f19efa8a 100644 --- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc +++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set.cc
@@ -121,6 +121,21 @@ } } +// In order to ship No-Vary-Search hint and keep the Origin Trial and be +// able to remotely go back to Origin Trial in case we unship, we use +// the suggested approach at +// go/graduating-from-finch#optional-leave-a-finch-hook of using a separate +// base feature to control shipping - in our case we will use the +// new feature SpeculationRulesNoVarySearchHintControlShipping. +bool IsSpeculationRulesNoVarySearchHintEnabled(ExecutionContext* context) { + // SpeculationRulesNoVarySearchHint controls the Origin Trial. + // SpeculationRulesNoVarySearchHintControlShipping controls shipping to all. + return RuntimeEnabledFeatures::SpeculationRulesNoVarySearchHintEnabled( + context) || + RuntimeEnabledFeatures:: + SpeculationRulesNoVarySearchHintShippedByDefaultEnabled(context); +} + SpeculationRule* ParseSpeculationRule(JSONObject* input, const KURL& base_url, ExecutionContext* context, @@ -130,20 +145,17 @@ // https://wicg.github.io/nav-speculation/speculation-rules.html#parse-a-speculation-rule // If input has any key other than "source", "urls", "where", "requires", - // "target_hint", "referrer_policy", "relative_to", and "eagerness", then - // return null. - const char* const kKnownKeys[] = { - "source", "urls", "where", "requires", "target_hint", - "referrer_policy", "relative_to"}; + // "target_hint", "referrer_policy", "relative_to", "eagerness" and + // "expects_no_vary_search", then return null. + const char* const kKnownKeys[] = {"source", "urls", + "where", "requires", + "target_hint", "referrer_policy", + "relative_to", "expects_no_vary_search"}; const auto kConditionalKnownKeys = [context]() { Vector<const char*, 4> conditional_known_keys; if (speculation_rules::EagernessEnabled(context)) { conditional_known_keys.push_back("eagerness"); } - if (RuntimeEnabledFeatures::SpeculationRulesNoVarySearchHintEnabled( - context)) { - conditional_known_keys.push_back("expects_no_vary_search"); - } return conditional_known_keys; }(); @@ -384,9 +396,9 @@ } network::mojom::blink::NoVarySearchPtr no_vary_search = nullptr; - if (JSONValue* no_vary_search_value = input->Get("expects_no_vary_search")) { - CHECK(RuntimeEnabledFeatures::SpeculationRulesNoVarySearchHintEnabled( - context)); + if (JSONValue* no_vary_search_value = input->Get("expects_no_vary_search"); + no_vary_search_value && + IsSpeculationRulesNoVarySearchHintEnabled(context)) { String no_vary_search_str; if (!no_vary_search_value->AsString(&no_vary_search_str)) { SetParseErrorMessage(out_error,
diff --git a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc index df4537f..653b4d27 100644 --- a/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc +++ b/third_party/blink/renderer/core/speculation_rules/speculation_rule_set_test.cc
@@ -949,11 +949,11 @@ page_holder.GetDocument().IsUseCounted(WebFeature::kSpeculationRules)); } -// Tests that the presence of a speculationrules No-Vary-Search hint is -// recorded. -TEST_F(SpeculationRuleSetTest, NoVarySearchHintUseCounter) { - ScopedSpeculationRulesNoVarySearchHintForTest enable_no_vary_search_hint{ - true}; +// Test helper method that returns if the No-Vary-Search hint use counter is +// properly counted during shipping. +// The use counter also acts as a proxy to check if the No-Vary-Search hint +// feature is enabled. +bool NoVarySearchHintUseCounterTestHelper() { DummyPageHolder page_holder; StubSpeculationHost speculation_host; page_holder.GetFrame().GetSettings()->SetScriptEnabled(true); @@ -968,8 +968,61 @@ }]})nvs"; PropagateRulesToStubSpeculationHost(page_holder, speculation_host, speculation_script); - EXPECT_TRUE(page_holder.GetDocument().IsUseCounted( - WebFeature::kSpeculationRulesNoVarySearchHint)); + + return page_holder.GetDocument().IsUseCounted( + WebFeature::kSpeculationRulesNoVarySearchHint); +} + +// Tests that the presence of a speculationrules No-Vary-Search hint is +// recorded. +TEST_F(SpeculationRuleSetTest, NoVarySearchHintUseCounter) { + { + // By default No-Vary-Search hint functionality is enabled without + // Origin Trial token. + ScopedSpeculationRulesNoVarySearchHintForTest enable_no_vary_search_hint{ + false}; + ScopedSpeculationRulesNoVarySearchHintShippedByDefaultForTest + ship_no_vary_search_hint{true}; + EXPECT_TRUE(NoVarySearchHintUseCounterTestHelper()) + << "No-Vary-Search hint functionality is enabled " + "when shipped and without an Origin Trial token."; + } + { + // By default No-Vary-Search hint is enabled with Origin Trial token. + ScopedSpeculationRulesNoVarySearchHintForTest enable_no_vary_search_hint{ + true}; + ScopedSpeculationRulesNoVarySearchHintShippedByDefaultForTest + ship_no_vary_search_hint{true}; + EXPECT_TRUE(NoVarySearchHintUseCounterTestHelper()) + << "No-Vary-Search hint functionality is enabled " + "when shipped and with an Origin Trial token."; + } + { + // No-Vary-Search hint is disabled when + // SpeculationRulesNoVarySearchHintControlShipping is set to false and + // there is no Origin Trial token. + ScopedSpeculationRulesNoVarySearchHintForTest enable_no_vary_search_hint{ + false}; + ScopedSpeculationRulesNoVarySearchHintShippedByDefaultForTest + ship_no_vary_search_hint{false}; + EXPECT_FALSE(NoVarySearchHintUseCounterTestHelper()) + << "No-Vary-Search hint functionality is " + "disabled when unshipped and without " + "an Origin Trial token"; + } + { + // No-Vary-Search hint is enabled when + // SpeculationRulesNoVarySearchHintControlShipping is set to false and + // there is an Origin Trial token. + ScopedSpeculationRulesNoVarySearchHintShippedByDefaultForTest + ship_no_vary_search_hint{false}; + ScopedSpeculationRulesNoVarySearchHintForTest enable_no_vary_search_hint{ + true}; + EXPECT_TRUE(NoVarySearchHintUseCounterTestHelper()) + << "No-Vary-Search hint functionality is enabled when unshipped and " + "with " + "an Origin Trial token"; + } } // Tests that the document's URL is excluded from candidates.
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni index 4379c2d..a58e978f 100644 --- a/third_party/blink/renderer/core/style/build.gni +++ b/third_party/blink/renderer/core/style/build.gni
@@ -43,6 +43,7 @@ "grid_track_list.cc", "grid_track_list.h", "grid_track_size.h", + "inset_area.h", "list_style_type_data.cc", "list_style_type_data.h", "member_copy.h",
diff --git a/third_party/blink/renderer/core/style/inset_area.h b/third_party/blink/renderer/core/style/inset_area.h new file mode 100644 index 0000000..e44ceb8 --- /dev/null +++ b/third_party/blink/renderer/core/style/inset_area.h
@@ -0,0 +1,71 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_INSET_AREA_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_INSET_AREA_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +// Possibly end points for a computed <inset-area-span> +enum class InsetAreaRegion { + kNone, + kAll, + kCenter, + kStart, + kEnd, + kSelfStart, + kSelfEnd, + kTop, + kBottom, + kLeft, + kRight, + kXStart, + kXEnd, + kYStart, + kYEnd, + kXSelfStart, + kXSelfEnd, + kYSelfStart, + kYSelfEnd, +}; + +// Represents the computed value for the inset-area property +class InsetArea { + DISALLOW_NEW(); + + public: + InsetArea() = default; + InsetArea(InsetAreaRegion span1_start, + InsetAreaRegion span1_end, + InsetAreaRegion span2_start, + InsetAreaRegion span2_end) + : span1_start_(span1_start), + span1_end_(span1_end), + span2_start_(span2_start), + span2_end_(span2_end) {} + + InsetAreaRegion FirstStart() const { return span1_start_; } + InsetAreaRegion FirstEnd() const { return span1_end_; } + InsetAreaRegion SecondStart() const { return span2_start_; } + InsetAreaRegion SecondEnd() const { return span2_end_; } + + bool operator==(const InsetArea& other) const { + return span1_start_ == other.span1_start_ && + span1_end_ == other.span1_end_ && + span2_start_ == other.span2_start_ && span2_end_ == other.span2_end_; + } + bool operator!=(const InsetArea& other) const { return !(*this == other); } + + private: + InsetAreaRegion span1_start_ = InsetAreaRegion::kNone; + InsetAreaRegion span1_end_ = InsetAreaRegion::kNone; + InsetAreaRegion span2_start_ = InsetAreaRegion::kNone; + InsetAreaRegion span2_end_ = InsetAreaRegion::kNone; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_INSET_AREA_H_
diff --git a/third_party/blink/renderer/core/timing/build.gni b/third_party/blink/renderer/core/timing/build.gni index 6482a03..cc32795 100644 --- a/third_party/blink/renderer/core/timing/build.gni +++ b/third_party/blink/renderer/core/timing/build.gni
@@ -108,5 +108,6 @@ "profiler_group_test.cc", "time_clamper_test.cc", "window_performance_test.cc", + "soft_navigation_heuristics_test.cc", "worker_performance_test.cc", ]
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc index 61c42fdb..9b16b89b 100644 --- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc +++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/timing/soft_navigation_heuristics.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -44,9 +45,41 @@ GetFrameIdForTracing(frame), "url", url, "navigationId", window->GetNavigationId()); } - } // namespace +namespace internal { +void RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + base::TimeTicks user_interaction_ts, + base::TimeTicks reference_ts) { + if (user_interaction_ts.is_null()) { + if (reference_ts.is_null()) { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + SoftNavigationFromReferenceInvalidTimingReasons:: + kUserInteractionTsAndReferenceTsBothNull); + } else { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + SoftNavigationFromReferenceInvalidTimingReasons:: + kNullUserInteractionTsAndNotNullReferenceTs); + } + } else { + if (reference_ts.is_null()) { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + SoftNavigationFromReferenceInvalidTimingReasons:: + kNullReferenceTsAndNotNullUserInteractionTs); + + } else { + base::UmaHistogramEnumeration( + kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + SoftNavigationFromReferenceInvalidTimingReasons:: + kUserInteractionTsAndReferenceTsBothNotNull); + } + } +} +} // namespace internal + // static const char SoftNavigationHeuristics::kSupplementName[] = "SoftNavigationHeuristics"; @@ -333,6 +366,13 @@ loader->GetTiming().MonotonicTimeToPseudoWallTime( soft_navigation_interaction_data_.user_interaction_timestamp); + if (soft_navigation_start_time.is_zero()) { + internal:: + RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + soft_navigation_interaction_data_.user_interaction_timestamp, + loader->GetTiming().ReferenceMonotonicTime()); + } + LocalDOMWindow* window = frame->DomWindow(); CHECK(window);
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h index 67604eb..b8d84de 100644 --- a/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h +++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
@@ -7,6 +7,7 @@ #include "base/containers/enum_set.h" #include "third_party/blink/public/common/scheduler/task_attribution_id.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/scheduler/public/task_attribution_tracker.h" @@ -15,6 +16,32 @@ namespace blink { +namespace internal { + +const char kPageLoadInternalSoftNavigationFromReferenceInvalidTiming[] = + "PageLoad.Internal.SoftNavigationFromReferenceInvalidTiming"; + +// These values are recorded into a UMA histogram as scenarios where the start +// time of soft navigation ends up being 0. These entries +// should not be renumbered and the numeric values should not be reused. These +// entries should be kept in sync with the definition in +// tools/metrics/histograms/enums.xml +// TODO(crbug.com/1489583): Remove the code here and related code once the bug +// is resolved. +enum class SoftNavigationFromReferenceInvalidTimingReasons { + kNullUserInteractionTsAndNotNullReferenceTs = 0, + kUserInteractionTsAndReferenceTsBothNull = 1, + kNullReferenceTsAndNotNullUserInteractionTs = 2, + kUserInteractionTsAndReferenceTsBothNotNull = 3, + kMaxValue = kUserInteractionTsAndReferenceTsBothNotNull, +}; + +CORE_EXPORT void +RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + base::TimeTicks user_interaction_ts, + base::TimeTicks reference_ts); +} // namespace internal + // This class contains the logic for calculating Single-Page-App soft navigation // heuristics. See https://github.com/WICG/soft-navigations class SoftNavigationHeuristics
diff --git a/third_party/blink/renderer/core/timing/soft_navigation_heuristics_test.cc b/third_party/blink/renderer/core/timing/soft_navigation_heuristics_test.cc new file mode 100644 index 0000000..25c3b2a --- /dev/null +++ b/third_party/blink/renderer/core/timing/soft_navigation_heuristics_test.cc
@@ -0,0 +1,75 @@ +// 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 "third_party/blink/renderer/core/timing/soft_navigation_heuristics.h" + +#include "base/test/metrics/histogram_tester.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { +using SoftNavigationHeuristicsTest = testing::Test; + +TEST_F(SoftNavigationHeuristicsTest, UmaHistogramRecording) { + base::HistogramTester histogram_tester; + + // Test case where user interaction timestamp and reference monotonic + // timestamp are both null. + base::TimeTicks user_interaction_ts; + base::TimeTicks reference_ts; + internal:: + RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + user_interaction_ts, reference_ts); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + internal::SoftNavigationFromReferenceInvalidTimingReasons:: + kUserInteractionTsAndReferenceTsBothNull, + 1); + + // Test case where both user interaction timestamp is not null and reference + // monotonic timestamp is null. + user_interaction_ts = base::TimeTicks() + base::Milliseconds(1); + + internal:: + RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + user_interaction_ts, reference_ts); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + internal::SoftNavigationFromReferenceInvalidTimingReasons:: + kNullReferenceTsAndNotNullUserInteractionTs, + 1); + + // Test case where user interaction timestamp is null and reference + // monotonic timestamp is not null. + user_interaction_ts = base::TimeTicks(); + reference_ts = base::TimeTicks() + base::Milliseconds(1); + + internal:: + RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + user_interaction_ts, reference_ts); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + internal::SoftNavigationFromReferenceInvalidTimingReasons:: + kNullUserInteractionTsAndNotNullReferenceTs, + 1); + + // Test case where user interaction timestamp and reference monotonic + // timestamp are both not null. + user_interaction_ts = base::TimeTicks() + base::Milliseconds(1); + reference_ts = base::TimeTicks() + base::Milliseconds(2); + + internal:: + RecordUmaForPageLoadInternalSoftNavigationFromReferenceInvalidTiming( + user_interaction_ts, reference_ts); + + histogram_tester.ExpectBucketCount( + internal::kPageLoadInternalSoftNavigationFromReferenceInvalidTiming, + internal::SoftNavigationFromReferenceInvalidTimingReasons:: + kUserInteractionTsAndReferenceTsBothNotNull, + 1); +} +} // namespace blink
diff --git a/third_party/blink/renderer/core/view_transition/page_reveal_event.cc b/third_party/blink/renderer/core/view_transition/page_reveal_event.cc index 09f104e..1258dd5 100644 --- a/third_party/blink/renderer/core/view_transition/page_reveal_event.cc +++ b/third_party/blink/renderer/core/view_transition/page_reveal_event.cc
@@ -6,14 +6,15 @@ #include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/view_transition/dom_view_transition.h" +#include "third_party/blink/renderer/core/view_transition/view_transition_utils.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -PageRevealEvent::PageRevealEvent(DOMViewTransition* dom_view_transition) - : Event(event_type_names::kPagereveal, Bubbles::kNo, Cancelable::kNo), - dom_view_transition_(dom_view_transition) { +PageRevealEvent::PageRevealEvent() + : Event(event_type_names::kPagereveal, Bubbles::kNo, Cancelable::kNo) { CHECK(RuntimeEnabledFeatures::PageRevealEventEnabled()); } @@ -32,4 +33,9 @@ return dom_view_transition_.Get(); } +void PageRevealEvent::SetViewTransition( + DOMViewTransition* dom_view_transition) { + dom_view_transition_ = dom_view_transition; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/view_transition/page_reveal_event.h b/third_party/blink/renderer/core/view_transition/page_reveal_event.h index ea5743c..1a970de 100644 --- a/third_party/blink/renderer/core/view_transition/page_reveal_event.h +++ b/third_party/blink/renderer/core/view_transition/page_reveal_event.h
@@ -6,7 +6,9 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_REVEAL_EVENT_H_ #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -21,7 +23,7 @@ DEFINE_WRAPPERTYPEINFO(); public: - explicit PageRevealEvent(DOMViewTransition*); + explicit PageRevealEvent(); ~PageRevealEvent() override; const AtomicString& InterfaceName() const override; @@ -29,11 +31,19 @@ void Trace(Visitor*) const override; DOMViewTransition* viewTransition() const; + void SetViewTransition(DOMViewTransition*); private: Member<DOMViewTransition> dom_view_transition_; }; +template <> +struct DowncastTraits<PageRevealEvent> { + static bool AllowFrom(const Event& event) { + return event.type() == event_type_names::kPagereveal; + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_VIEW_TRANSITION_PAGE_REVEAL_EVENT_H_
diff --git a/third_party/blink/renderer/core/view_transition/view_transition.cc b/third_party/blink/renderer/core/view_transition/view_transition.cc index 79109c3..86254bb 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition.cc
@@ -892,11 +892,11 @@ } void ViewTransition::ActivateFromSnapshot() { + CHECK(IsForNavigationOnNewDocument()); + if (state_ != State::kWaitForRenderBlock) return; - CHECK(IsForNavigationOnNewDocument()); - // This function implies that rendering has started. If we were waiting // for render-blocking resources to be loaded, they must have been fetched (or // timed out) before rendering is started.
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc index f4b1d99..0f7cd303 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
@@ -191,14 +191,6 @@ ->GetLocalFrameHostRemote() .OnViewTransitionOptInChanged(cross_document_opt_in); } - - if (cross_document_opt_in_ == - mojom::blink::ViewTransitionSameOriginOptIn::kDisabled && - transition_ && !transition_->IsCreatedViaScriptAPI()) { - transition_->SkipTransition(); - DCHECK(!transition_) - << "SkipTransition() should finish existing |transition_|"; - } } // static @@ -332,19 +324,29 @@ // TODO(https://crbug.com/1463966): This is probably a bit of a heavy hammer. // In the long term, we probably don't want to make this decision at // WillInsertBody or, if we do, we could look specifically for - // @view-transition rather than all rules. + // @view-transition rather than all rules. Note: the opt-in is checked below + // from dispatching the pagereveal event during the first update-the-rendering + // steps. document->GetStyleEngine().UpdateActiveStyle(); +} - // If the opt-in is enabled, then there's nothing to do in this function. - if (cross_document_opt_in_ == - mojom::blink::ViewTransitionSameOriginOptIn::kEnabled) { - return; +DOMViewTransition* +ViewTransitionSupplement::ResolveCrossDocumentViewTransition() { + if (!transition_ || !transition_->IsForNavigationOnNewDocument()) { + return nullptr; } - // Since we don't have an opt-in, skip a navigation transition if it exists. - transition_->SkipTransition(); - DCHECK(!transition_) - << "SkipTransition() should finish existing |transition_|"; + if (cross_document_opt_in_ == + mojom::blink::ViewTransitionSameOriginOptIn::kDisabled) { + transition_->SkipTransition(); + CHECK(!ViewTransitionUtils::GetTransition(*GetSupplementable())); + return nullptr; + } + + // TODO(https://crbug.com/1502628): This is where types from the used + // @view-transition should be applied. + + return transition_->GetScriptDelegate(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h index 9180b45..5b79adb 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
@@ -88,6 +88,12 @@ // Document. void WillInsertBody(); + // In the new page of a cross-document transition, this resolves the + // @view-transition rule to use, sets types, and returns the ViewTransition. + // It is the 'resolve cross-document view-transition` steps in the spec: + // https://drafts.csswg.org/css-view-transitions-2/#document-resolve-cross-document-view-transition + DOMViewTransition* ResolveCrossDocumentViewTransition(); + private: static DOMViewTransition* StartViewTransitionInternal( ScriptState*,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 5f3d43d..12e0af7b 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -5779,13 +5779,17 @@ return true; } - // Destroy all nested pseudo-elements, because we are only able to re-attach - // them via top-down tree walk and not via RepairMissingParent. See - // GetParentNodeForComputeParent for more commentary. + // Destroy all pseudo-elements that can't compute their parents, because we + // are only able to re-attach them via top-down tree walk and not via + // RepairMissingParent. See GetParentNodeForComputeParent for more + // commentary. auto* layout_object = GetLayoutObject(); - if (layout_object && layout_object->Parent() && - layout_object->Parent()->IsPseudoElement()) { - return true; + if (layout_object) { + Node* closest_node = + AXObjectCacheImpl::GetClosestNodeForLayoutObject(layout_object); + if (closest_node && closest_node->IsPseudoElement()) { + return true; + } } // Inline textbox children are dependent on their parent's ignored state.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index fa392d92..2f88e29 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -152,14 +152,6 @@ return document.Url().IsAboutBlankURL(); } -// Return a node for the current layout object or ancestor layout object. -Node* GetClosestNodeForLayoutObject(const LayoutObject* layout_object) { - if (!layout_object) - return nullptr; - Node* node = layout_object->GetNode(); - return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent()); -} - // Return true if display locked or inside slot recalc, false otherwise. // Also returns false if not a safe time to perform the check. bool IsDisplayLocked(const Node* node, bool inclusive = false) { @@ -890,6 +882,7 @@ // Next flush all accessibility events and dirty objects, for both the main // and popup document, and update tree if needed. if (IsDirty() || HasDirtyObjects()) { + node_to_parse_before_more_tree_updates_ = nullptr; pause_tree_updates_until_more_loaded_content_ = false; ProcessDeferredAccessibilityEvents(GetDocument()); } @@ -2309,6 +2302,16 @@ DeferTreeUpdate(TreeUpdateReason::kTextChangedFromTextChangedNode, node); } +// Return a node for the current layout object or ancestor layout object. +Node* AXObjectCacheImpl::GetClosestNodeForLayoutObject( + const LayoutObject* layout_object) { + if (!layout_object) { + return nullptr; + } + Node* node = layout_object->GetNode(); + return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent()); +} + void AXObjectCacheImpl::TextChanged(const LayoutObject* layout_object) { if (!layout_object) return; @@ -2405,12 +2408,29 @@ void AXObjectCacheImpl::NodeIsConnected(Node* node) { if (IsParsingMainDocument()) { - // Whitespace at the end of the document is problematic during page loads, + // Pausing tree updates during page loads until ready to process more: + // 1. An unrendeered subtree, which will not receive NodeIsAttached() + // signals for incrementally loaded content, and therefore is unsafe to + // finish parsing until it has completely loaded. + // 2. Whitespace at the end of the document is a problem during page loads, // because there is not yet enough context around the whitespace to // determine whether it's relevant. This will pause processing of the // a11y tree until the document is either completely loaded or it does // not end in whitespace. - pause_tree_updates_until_more_loaded_content_ = false; + if (node_to_parse_before_more_tree_updates_) { + CHECK(pause_tree_updates_until_more_loaded_content_); + // For case #1, keep the pause if the expected node isn't fully parsed. + if (node_to_parse_before_more_tree_updates_ + ->IsFinishedParsingChildren()) { + node_to_parse_before_more_tree_updates_ = nullptr; + pause_tree_updates_until_more_loaded_content_ = false; + } + } else { + // For case #2, any new content means there's enough context around + // the whitespace to process updates. + pause_tree_updates_until_more_loaded_content_ = false; + } + // Start a new tree update pause if we are on a whitespace node. if (Text* text = DynamicTo<Text>(node)) { if (text->ContainsOnlyWhitespaceOrEmpty()) { pause_tree_updates_until_more_loaded_content_ = true; @@ -2448,6 +2468,15 @@ // using AXLayoutObjects. AXObject* obj = Get(node); if (!obj) { + if (!node->GetLayoutObject() && !node->IsFinishedParsingChildren() && + !node_to_parse_before_more_tree_updates_) { + // Unrendered subtrees that are not fully parsed are unsafe to + // process until they are complete, because there are no NodeIsAttached() + // signals for incrementally loaded content. + node_to_parse_before_more_tree_updates_ = node; + pause_tree_updates_until_more_loaded_content_ = true; + } + // No AX subtree to invalidate: just add an AXObject for this node. // It will automatically add its subtree. ChildrenChanged(LayoutTreeBuilderTraversal::Parent(*node)); @@ -2930,6 +2959,7 @@ return; } pause_tree_updates_until_more_loaded_content_ = false; + node_to_parse_before_more_tree_updates_ = nullptr; } if (GetPopupDocumentIfShowing()) { @@ -5282,6 +5312,8 @@ visitor->Trace(ax_tree_source_); visitor->Trace(dirty_objects_); visitor->Trace(aria_notifications_); + visitor->Trace(node_to_parse_before_more_tree_updates_); + AXObjectCache::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 97f2961..420a7f3 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -153,7 +153,6 @@ // document lifecycle check is necessary but this is short-lived code. if (!serialize_post_lifecycle_ && GetDocument().Lifecycle().GetState() < DocumentLifecycle::kPrePaintClean) { - pause_tree_updates_until_more_loaded_content_ = false; UpdateAXForAllDocuments(); } ax_tree_source_->Freeze(); @@ -491,6 +490,7 @@ static bool IsRelevantPseudoElementDescendant( const LayoutObject& layout_object); static bool IsRelevantSlotElement(const HTMLSlotElement& slot); + static Node* GetClosestNodeForLayoutObject(const LayoutObject* layout_object); // Retrieves a vector of all AXObjects whose bounding boxes may have changed // since the last query. Sends the resulting vector over mojo to the browser @@ -861,6 +861,9 @@ // ProcessDeferredAccessibilityEvents(). Will be set to false when more // content is loaded or the load is completed. bool pause_tree_updates_until_more_loaded_content_ = false; + // If null, then any new connected node will unpause tree updates. + // Otherwise, tree updates will unpause once the node is fully parsed. + WeakMember<Node> node_to_parse_before_more_tree_updates_; HeapVector<Member<AXEventParams>> notifications_to_post_main_; HeapVector<Member<AXEventParams>> notifications_to_post_popup_;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h index 03a79fdc..f522a5e0 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -695,7 +695,7 @@ return false; } - virtual void FlushCanvas(FlushReason) = 0; + virtual absl::optional<cc::PaintRecord> FlushCanvas(FlushReason) = 0; // Only call if identifiability_study_helper_.ShouldUpdateBuilder() returns // true.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc index 6dd57f0..e7605a4 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc
@@ -132,7 +132,9 @@ } } - void FlushCanvas(FlushReason) override {} + absl::optional<cc::PaintRecord> FlushCanvas(FlushReason) override { + return recorder_.finishRecordingAsPicture(); + } Member<ExecutionContext> execution_context_; MemoryManagedPaintRecorder recorder_;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 6b2faf6..de6f5e0 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -394,10 +394,12 @@ } } -void CanvasRenderingContext2D::FlushCanvas(FlushReason reason) { +absl::optional<cc::PaintRecord> CanvasRenderingContext2D::FlushCanvas( + FlushReason reason) { if (Host() && Host()->ResourceProvider()) { - Host()->ResourceProvider()->FlushCanvas(reason); + return Host()->ResourceProvider()->FlushCanvas(reason); } + return absl::nullopt; } bool CanvasRenderingContext2D::WillSetFont() const {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index 6a1f14e9..76cbd53 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -181,7 +181,7 @@ void WillDrawImage(CanvasImageSource*) const final; - void FlushCanvas(FlushReason) override; + absl::optional<cc::PaintRecord> FlushCanvas(FlushReason) override; void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 7ad8e6c..a449d4cd 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -11,6 +11,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "cc/test/paint_op_matchers.h" #include "components/viz/test/test_context_provider.h" #include "components/viz/test/test_gles2_interface.h" #include "testing/gmock/include/gmock/gmock.h" @@ -43,6 +44,7 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style_test_utils.h" +#include "third_party/blink/renderer/modules/canvas/canvas2d/recording_test_utils.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h" #include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h" @@ -69,9 +71,26 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/modules/skcms/skcms.h" -using testing::_; -using testing::InSequence; -using testing::Mock; +using ::blink_testing::RecordedOpsAre; +using ::blink_testing::RecordedOpsView; +using ::cc::ClipRectOp; +using ::cc::DrawColorOp; +using ::cc::DrawImageRectOp; +using ::cc::DrawPathOp; +using ::cc::DrawRectOp; +using ::cc::PaintOpEq; +using ::cc::PaintOpIs; +using ::cc::RestoreOp; +using ::cc::SaveLayerOp; +using ::cc::SaveOp; +using ::cc::SetMatrixOp; +using ::cc::TranslateOp; +using ::testing::_; +using ::testing::Eq; +using ::testing::InSequence; +using ::testing::Message; +using ::testing::Mock; +using ::testing::Optional; namespace blink { @@ -359,6 +378,8 @@ return SkSurfaces::Raster(GetSkImageInfo()); } + MOCK_METHOD((void), RasterRecord, (cc::PaintRecord last_recording)); + MOCK_METHOD((scoped_refptr<StaticBitmapImage>), Snapshot, (FlushReason reason, ImageOrientation orientation)); @@ -377,393 +398,611 @@ //============================================================================ -class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge { - public: - MockImageBufferSurfaceForOverwriteTesting() {} - MOCK_METHOD0(WillOverwriteCanvas, void()); -}; - -//============================================================================ - -typedef std::unordered_set<BaseRenderingContext2D::OverdrawOp> - OverdrawHistogramBuckets; - -class CanvasRenderingContext2DOverdrawTest - : public CanvasRenderingContext2DTest { - public: - void ExpectNoOverdraw(); - void ExpectOverdraw( - std::initializer_list<BaseRenderingContext2D::OverdrawOp>); - void VerifyExpectations(); - - protected: - void SetUp() override; - void TearDown() override; - - private: - std::unique_ptr<base::HistogramTester> histogram_tester_; - raw_ptr<MockImageBufferSurfaceForOverwriteTesting, ExperimentalRenderer> - surface_ptr_; - OverdrawHistogramBuckets expected_buckets_; -}; - -void CanvasRenderingContext2DOverdrawTest::SetUp() { - CanvasRenderingContext2DTest::SetUp(); - histogram_tester_ = std::make_unique<base::HistogramTester>(); - CreateContext(kNonOpaque); - gfx::Size size(10, 10); - std::unique_ptr<MockImageBufferSurfaceForOverwriteTesting> mock_surface = - std::make_unique<MockImageBufferSurfaceForOverwriteTesting>(); - surface_ptr_ = mock_surface.get(); - CanvasElement().SetResourceProviderForTesting(nullptr, - std::move(mock_surface), size); - Context2D()->save(); -} - -INSTANTIATE_PAINT_TEST_SUITE_P(CanvasRenderingContext2DOverdrawTest); - -void CanvasRenderingContext2DOverdrawTest::TearDown() { - NonThrowableExceptionState exception_state; - Context2D()->restore(exception_state); - - histogram_tester_.reset(); - surface_ptr_ = nullptr; - expected_buckets_.clear(); - - CanvasRenderingContext2DTest::TearDown(); -} - -void CanvasRenderingContext2DOverdrawTest::ExpectNoOverdraw() { - EXPECT_CALL(*surface_ptr_, WillOverwriteCanvas()).Times(0); -} - -void CanvasRenderingContext2DOverdrawTest::ExpectOverdraw( - std::initializer_list<BaseRenderingContext2D::OverdrawOp> - expected_buckets) { - EXPECT_CALL(*surface_ptr_, WillOverwriteCanvas()).Times(1); - expected_buckets_ = expected_buckets; - EXPECT_FALSE(expected_buckets_.empty()); - // Validate that all buckets are valid (and that kMaxValue is up to date). - for (auto bucket : expected_buckets_) { - EXPECT_LE(bucket, BaseRenderingContext2D::OverdrawOp::kMaxValue); - } -} - -void CanvasRenderingContext2DOverdrawTest::VerifyExpectations() { - // Verify that WillOverwriteCanvas was call the expected number of times. - Mock::VerifyAndClearExpectations(surface_ptr_); - - // Verify that the expected histogram buckets received hits. +MATCHER_P(OverdrawOpAreMatcher, expected_overdraw_ops, "") { constexpr int last_bucket = static_cast<int>(BaseRenderingContext2D::OverdrawOp::kMaxValue); for (int bucket = 0; bucket <= last_bucket; ++bucket) { - histogram_tester_->ExpectBucketCount( + SCOPED_TRACE(Message() << "Checking overdraw bucket: " << bucket); + arg.ExpectBucketCount( "Blink.Canvas.OverdrawOp", bucket, - static_cast<base::HistogramBase::Count>(expected_buckets_.count( + static_cast<base::HistogramBase::Count>(expected_overdraw_ops.count( static_cast<BaseRenderingContext2D::OverdrawOp>(bucket)))); } + return true; } -//============================================================================ +template <typename... Args> +testing::Matcher<base::HistogramTester> OverdrawOpAre(Args... args) { + return OverdrawOpAreMatcher( + std::unordered_set<BaseRenderingContext2D::OverdrawOp>{args...}); +} -TEST_P(CanvasRenderingContext2DOverdrawTest, FillRect_FullCoverage) { +cc::PaintFlags DrawRectFlags() { + cc::PaintFlags rect_flags; + rect_flags.setAntiAlias(true); + rect_flags.setFilterQuality(cc::PaintFlags::FilterQuality::kLow); + return rect_flags; +} + +cc::PaintFlags ClearRectFlags() { + cc::PaintFlags clear_flags; + clear_flags.setBlendMode(SkBlendMode::kClear); + return clear_flags; +} + +TEST_P(CanvasRenderingContext2DTest, FillRect_FullCoverage) { // Fill rect no longer supports overdraw optimizations // Reason: low real world incidence not worth the test overhead. - ExpectNoOverdraw(); + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + Context2D()->fillRect(3, 3, 1, 1); Context2D()->fillRect(-1, -1, 12, 12); - VerifyExpectations(); + + EXPECT_THAT( + Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 1, 1), DrawRectFlags()), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(-1, -1, 12, 12), + DrawRectFlags())))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DisableOverdrawOptimization) { +TEST_P(CanvasRenderingContext2DTest, DisableOverdrawOptimization) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(kDisableCanvasOverdrawOptimization); - ExpectNoOverdraw(); + + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT( + Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 1, 1), DrawRectFlags()), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(0, 0, 10, 10), + ClearRectFlags())))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_ExactCoverage) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - }); +TEST_P(CanvasRenderingContext2DTest, ClearRect_ExactCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpEq<DrawRectOp>( + SkRect::MakeXYWH(0, 0, 10, 10), ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_PartialCoverage) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, ClearRect_PartialCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 9, 9); - VerifyExpectations(); + + EXPECT_THAT( + Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 1, 1), DrawRectFlags()), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(0, 0, 9, 9), + ClearRectFlags())))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_GlobalAlpha) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - }); +TEST_P(CanvasRenderingContext2DTest, ClearRect_GlobalAlpha) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + Context2D()->setGlobalAlpha(0.5f); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpEq<DrawRectOp>( + SkRect::MakeXYWH(0, 0, 10, 10), ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_TransparentGradient) { +TEST_P(CanvasRenderingContext2DTest, ClearRect_TransparentGradient) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + auto* script_state = GetScriptState(); ScriptState::Scope script_state_scope(script_state); - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - }); SetFillStyleHelper(Context2D(), script_state, AlphaGradient().Get()); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpEq<DrawRectOp>( + SkRect::MakeXYWH(0, 0, 10, 10), ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_Filter) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - }); +TEST_P(CanvasRenderingContext2DTest, ClearRect_Filter) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + V8UnionCanvasFilterOrString* filter = MakeGarbageCollected<V8UnionCanvasFilterOrString>("blur(4px)"); Context2D()->setFilter(ToScriptStateForMainWorld(GetDocument().GetFrame()), filter); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpEq<DrawRectOp>( + SkRect::MakeXYWH(0, 0, 10, 10), ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, - ClearRect_TransformPartialCoverage) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, ClearRect_TransformPartialCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + Context2D()->translate(1, 1); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT( + Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpIs<TranslateOp>(), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 1, 1), DrawRectFlags()), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(0, 0, 10, 10), + ClearRectFlags())))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, - ClearRect_TransformCompleteCoverage) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - BaseRenderingContext2D::OverdrawOp::kHasTransform, - }); +TEST_P(CanvasRenderingContext2DTest, ClearRect_TransformCompleteCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + Context2D()->translate(1, 1); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(-1, -1, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpEq<SetMatrixOp>(SkM44(1, 0, 0, 1, // + 0, 1, 0, 1, // + 0, 0, 1, 0, // + 0, 0, 0, 1)), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(-1, -1, 10, 10), + ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect, + BaseRenderingContext2D::OverdrawOp::kHasTransform)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_IgnoreCompositeOp) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kClearRect, - }); +TEST_P(CanvasRenderingContext2DTest, ClearRect_IgnoreCompositeOp) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + Context2D()->setGlobalCompositeOperation(String("destination-in")); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpEq<DrawRectOp>( + SkRect::MakeXYWH(0, 0, 10, 10), ClearRectFlags())))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kClearRect)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, ClearRect_Clipped) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, ClearRect_Clipped) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + Context2D()->rect(0, 0, 5, 5); Context2D()->clip(); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->clearRect(0, 0, 10, 10); - VerifyExpectations(); + + EXPECT_THAT( + Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpIs<ClipRectOp>(), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 1, 1), DrawRectFlags()), + PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(0, 0, 10, 10), + ClearRectFlags())))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_ExactCoverage) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kDrawImage, - }); +TEST_P(CanvasRenderingContext2DTest, DrawImage_ExactCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kDrawImage)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_Magnified) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kDrawImage, - }); +TEST_P(CanvasRenderingContext2DTest, DrawImage_Magnified) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 1, 1, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kDrawImage)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_GlobalAlpha) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_GlobalAlpha) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; Context2D()->setGlobalAlpha(0.5f); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_TransparentBitmap) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_TransparentBitmap) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&alpha_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_Filter) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_Filter) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; V8UnionCanvasFilterOrString* filter = MakeGarbageCollected<V8UnionCanvasFilterOrString>("blur(4px)"); Context2D()->setFilter(ToScriptStateForMainWorld(GetDocument().GetFrame()), filter); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + // Composited DrawRectOp: + PaintOpIs<SetMatrixOp>(), PaintOpIs<SaveLayerOp>(), + PaintOpIs<SetMatrixOp>(), PaintOpIs<DrawRectOp>(), + PaintOpIs<RestoreOp>(), PaintOpIs<SetMatrixOp>(), + // Composited DrawImageRectOp: + PaintOpIs<SetMatrixOp>(), PaintOpIs<SaveLayerOp>(), + PaintOpIs<SetMatrixOp>(), PaintOpIs<DrawImageRectOp>(), + PaintOpIs<RestoreOp>(), PaintOpIs<SetMatrixOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_PartialCoverage1) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_PartialCoverage1) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 1, 0, 10, 10, exception_state); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawImageRectOp>()))); EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_PartialCoverage2) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_PartialCoverage2) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 9, 9, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_FullCoverage) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kDrawImage, - }); +TEST_P(CanvasRenderingContext2DTest, DrawImage_FullCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 11, 11, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kDrawImage)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_TransformFullCoverage) { - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kDrawImage, - BaseRenderingContext2D::OverdrawOp::kHasTransform, - }); - NonThrowableExceptionState exception_state; - Context2D()->translate(-1, 0), - Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 1, 0, 10, 10, - exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); -} +TEST_P(CanvasRenderingContext2DTest, DrawImage_TransformFullCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); -TEST_P(CanvasRenderingContext2DOverdrawTest, - DrawImage_TransformPartialCoverage) { - ExpectNoOverdraw(); NonThrowableExceptionState exception_state; - Context2D()->translate(-1, 0), - Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, - exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); -} - -TEST_P(CanvasRenderingContext2DOverdrawTest, - DrawImage_TransparenBitmapOpaqueGradient) { - auto* script_state = GetScriptState(); - ScriptState::Scope script_state_scope(script_state); - ExpectNoOverdraw(); - NonThrowableExceptionState exception_state; - SetFillStyleHelper(Context2D(), GetScriptState(), OpaqueGradient().Get()); - Context2D()->drawImage(&alpha_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, - exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); -} - -TEST_P(CanvasRenderingContext2DOverdrawTest, - DrawImage_OpaqueBitmapTransparentGradient) { - auto* script_state = GetScriptState(); - ScriptState::Scope script_state_scope(script_state); - ExpectOverdraw({ - BaseRenderingContext2D::OverdrawOp::kTotal, - BaseRenderingContext2D::OverdrawOp::kDrawImage, - }); - NonThrowableExceptionState exception_state; - SetFillStyleHelper(Context2D(), GetScriptState(), AlphaGradient().Get()); - Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, - exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); -} - -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_CopyPartialCoverage) { - // The 'copy' blend mode no longer trigger the overdraw optimization - // Reason: low real-world incidence, test overhead not justified. - ExpectNoOverdraw(); - NonThrowableExceptionState exception_state; - Context2D()->setGlobalCompositeOperation(String("copy")); + Context2D()->translate(-1, 0); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 1, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<SetMatrixOp>(), + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kDrawImage, + BaseRenderingContext2D::OverdrawOp::kHasTransform)); } -TEST_P(CanvasRenderingContext2DOverdrawTest, - DrawImage_CopyTransformPartialCoverage) { +TEST_P(CanvasRenderingContext2DTest, DrawImage_TransformPartialCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + NonThrowableExceptionState exception_state; + Context2D()->translate(-1, 0); + Context2D()->fillRect(3, 3, 1, 1); + Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, + exception_state); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<TranslateOp>(), // + PaintOpIs<DrawRectOp>(), // + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); +} + +TEST_P(CanvasRenderingContext2DTest, DrawImage_TransparenBitmapOpaqueGradient) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + auto* script_state = GetScriptState(); + ScriptState::Scope script_state_scope(script_state); + NonThrowableExceptionState exception_state; + SetFillStyleHelper(Context2D(), GetScriptState(), OpaqueGradient().Get()); + Context2D()->fillRect(3, 3, 1, 1); + Context2D()->drawImage(&alpha_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, + exception_state); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); +} + +TEST_P(CanvasRenderingContext2DTest, + DrawImage_OpaqueBitmapTransparentGradient) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + auto* script_state = GetScriptState(); + ScriptState::Scope script_state_scope(script_state); + NonThrowableExceptionState exception_state; + SetFillStyleHelper(Context2D(), GetScriptState(), AlphaGradient().Get()); + Context2D()->fillRect(3, 3, 1, 1); + Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, + exception_state); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, + OverdrawOpAre(BaseRenderingContext2D::OverdrawOp::kTotal, + BaseRenderingContext2D::OverdrawOp::kDrawImage)); +} + +TEST_P(CanvasRenderingContext2DTest, DrawImage_CopyPartialCoverage) { + // The 'copy' blend mode no longer trigger the overdraw optimization + // Reason: low real-world incidence, test overhead not justified. + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + NonThrowableExceptionState exception_state; + Context2D()->setGlobalCompositeOperation(String("copy")); + Context2D()->fillRect(3, 3, 1, 1); + Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 1, 0, 10, 10, + exception_state); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + // Copy composite op clears the frame before each draw ops. + PaintOpIs<DrawColorOp>(), PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawColorOp>(), PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); +} + +TEST_P(CanvasRenderingContext2DTest, DrawImage_CopyTransformPartialCoverage) { // Overdraw optimizations with the 'copy' composite operation are no longer // supported. Reason: low real-world incidence, test overhead not justified. - ExpectNoOverdraw(); + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; Context2D()->setGlobalCompositeOperation(String("copy")); Context2D()->translate(1, 1); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 1, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre( + PaintOpIs<TranslateOp>(), + // Copy composite op clears the frame before each draw ops. + PaintOpIs<DrawColorOp>(), PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawColorOp>(), PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, DrawImage_Clipped) { - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, DrawImage_Clipped) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + NonThrowableExceptionState exception_state; Context2D()->rect(0, 0, 5, 5); Context2D()->clip(); + Context2D()->fillRect(3, 3, 1, 1); Context2D()->drawImage(&opaque_bitmap_, 0, 0, 10, 10, 0, 0, 10, 10, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<ClipRectOp>(), // + PaintOpIs<DrawRectOp>(), // + PaintOpIs<DrawImageRectOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, PutImageData_FullCoverage) { - // PutImageData no longer supports overdraw optimizations. - // Reason: low real-world incidence, test overhead not justified - ExpectNoOverdraw(); +TEST_P(CanvasRenderingContext2DTest, PutImageData_FullCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + gfx::Size size = CanvasElement().Size(); + auto provider = std::make_unique<FakeCanvasResourceProvider>( + SkImageInfo::MakeN32Premul(size.width(), size.height()), + RasterModeHint::kPreferGPU, &CanvasElement()); + + // The recording will be cleared, so nothing will be rastered before + // `WritePixels` is called. + InSequence s; + EXPECT_CALL(*provider, RasterRecord).Times(0); + EXPECT_CALL(*provider, WritePixels).Times(1); + + CanvasElement().SetResourceProviderForTesting( + std::move(provider), std::make_unique<Canvas2DLayerBridge>(), size); + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); Context2D()->putImageData(full_image_data_.Get(), 0, 0, exception_state); - EXPECT_FALSE(exception_state.HadException()); - VerifyExpectations(); + + // `putImageData` isn't included in the recording, keeping it empty. + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Eq(absl::nullopt)); + + // `putImageData` overdraw isn't handled by + // `BaseRenderingContext2D::CheckOverdraw` like other draw operations, so the + // histograms aren't updated. + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } -TEST_P(CanvasRenderingContext2DOverdrawTest, Path_FullCoverage) { +TEST_P(CanvasRenderingContext2DTest, PutImageData_PartialCoverage) { + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + gfx::Size size = CanvasElement().Size(); + auto provider = std::make_unique<FakeCanvasResourceProvider>( + SkImageInfo::MakeN32Premul(size.width(), size.height()), + RasterModeHint::kPreferGPU, &CanvasElement()); + + // `putImageData` forces a flush, so the `fillRect` will get rasterized before + // `WritePixels` is called. + InSequence s; + EXPECT_CALL(*provider, RasterRecord(RecordedOpsAre(PaintOpIs<DrawRectOp>()))) + .Times(1); + EXPECT_CALL(*provider, WritePixels).Times(1); + + CanvasElement().SetResourceProviderForTesting( + std::move(provider), std::make_unique<Canvas2DLayerBridge>(), size); + + // `putImageData` forces a flush, which clears the recording. + NonThrowableExceptionState exception_state; + Context2D()->fillRect(3, 3, 1, 1); + Context2D()->putImageData(partial_image_data_.Get(), 0, 0, exception_state); + + // `putImageData` isn't included in the recording, keeping it empty. + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Eq(absl::nullopt)); + + // `putImageData` overdraw isn't handled by + // `BaseRenderingContext2D::CheckOverdraw` like other draw operations, so the + // histograms aren't updated. + EXPECT_THAT(histogram_tester, OverdrawOpAre()); +} + +TEST_P(CanvasRenderingContext2DTest, Path_FullCoverage) { // This case is an overdraw but the current detection logic rejects all // paths. - ExpectNoOverdraw(); + base::HistogramTester histogram_tester; + CreateContext(kNonOpaque); + CanvasElement().SetSize(gfx::Size(10, 10)); + + Context2D()->fillRect(3, 3, 1, 1); Context2D()->rect(-1, -1, 12, 12); Context2D()->fill(); - VerifyExpectations(); + + EXPECT_THAT(Context2D()->FlushCanvas(FlushReason::kTesting), + Optional(RecordedOpsAre(PaintOpIs<DrawRectOp>(), + PaintOpIs<DrawPathOp>()))); + EXPECT_THAT(histogram_tester, OverdrawOpAre()); } //==============================================================================
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc index 4915467..bf85c63 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -457,10 +457,13 @@ } } -void OffscreenCanvasRenderingContext2D::FlushCanvas(FlushReason reason) { - if (GetCanvasResourceProvider()) { - GetCanvasResourceProvider()->FlushCanvas(reason); +absl::optional<cc::PaintRecord> OffscreenCanvasRenderingContext2D::FlushCanvas( + FlushReason reason) { + if (CanvasResourceProvider* provider = GetCanvasResourceProvider(); + provider != nullptr) { + return provider->FlushCanvas(reason); } + return absl::nullopt; } OffscreenCanvas* OffscreenCanvasRenderingContext2D::HostAsOffscreenCanvas()
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h index df2143e..75d2dee 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -143,7 +143,7 @@ return identifiability_study_helper_.encountered_partially_digested_image(); } - void FlushCanvas(FlushReason) override; + absl::optional<cc::PaintRecord> FlushCanvas(FlushReason) override; protected: OffscreenCanvas* HostAsOffscreenCanvas() const final;
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc index 85f0e3a..87e0fd4f 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/identity_credential.cc
@@ -103,6 +103,15 @@ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); + if (!resolver->GetExecutionContext()->IsFeatureEnabled( + mojom::blink::PermissionsPolicyFeature::kIdentityCredentialsGet)) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, + "The 'identity-credentials-get` feature is not enabled in this " + "document.")); + return promise; + } + if (!options->hasConfigURL()) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "configURL is required"));
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h index 4e9d5f4d..b02a2f5c 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
@@ -91,7 +91,9 @@ void resetTransform() final; void reset() final; - void FlushCanvas(FlushReason) final {} + absl::optional<cc::PaintRecord> FlushCanvas(FlushReason) final { + return absl::nullopt; + } PaintRecord GetRecord();
diff --git a/third_party/blink/renderer/modules/notifications/notification_manager.cc b/third_party/blink/renderer/modules/notifications/notification_manager.cc index ce8b587..47831b20 100644 --- a/third_party/blink/renderer/modules/notifications/notification_manager.cc +++ b/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/task/single_thread_task_runner.h" @@ -180,10 +179,6 @@ size_t author_data_size = notification_data->data.has_value() ? notification_data->data->size() : 0; - base::UmaHistogramCounts1000( - "Notifications.AuthorDataSize", - base::saturated_cast<base::HistogramBase::Sample>(author_data_size)); - if (author_data_size > mojom::blink::NotificationData::kMaximumDeveloperDataSize) { RecordPersistentNotificationDisplayResult(
diff --git a/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc b/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc index 4dabfbe..cd33d63 100644 --- a/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc +++ b/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc
@@ -11,22 +11,10 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" +#include "v8/include/v8.h" namespace blink { -namespace { - -void ClearContinuationPreservedEmbedderData(v8::Isolate* isolate) { - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = - V8PerIsolateData::From(isolate)->EnsureScriptRegexpContext(); - v8::Context::Scope context_scope(context); - context->SetContinuationPreservedEmbedderData(v8::Local<v8::Value>()); -} - -} // namespace - ScriptWrappableTaskState::ScriptWrappableTaskState( scheduler::TaskAttributionInfo* task, AbortSignal* abort_source, @@ -46,23 +34,17 @@ ScriptWrappableTaskState* ScriptWrappableTaskState::GetCurrent( ScriptState* script_state) { DCHECK(script_state); - if (!script_state->ContextIsValid()) { - return nullptr; - } - - ScriptState::Scope scope(script_state); - v8::Local<v8::Context> context = script_state->GetContext(); - DCHECK(!context.IsEmpty()); - v8::Local<v8::Value> v8_value = - context->GetContinuationPreservedEmbedderData(); - if (v8_value->IsNullOrUndefined()) { - return nullptr; - } v8::Isolate* isolate = script_state->GetIsolate(); DCHECK(isolate); if (isolate->IsExecutionTerminating()) { return nullptr; } + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Value> v8_value = + isolate->GetContinuationPreservedEmbedderData(); + if (v8_value->IsNullOrUndefined()) { + return nullptr; + } // If not empty, the value must be a `ScriptWrappableTaskState`. NonThrowableExceptionState exception_state; ScriptWrappableTaskState* task_state = @@ -83,31 +65,21 @@ return; } CHECK(!ScriptForbiddenScope::IsScriptForbidden()); - if (!script_state->ContextIsValid()) { - // TODO(crbug.com/1351643): This is a temporary workaround for detached - // contexts while transitioning to per-isolate CPED. When v8 switches to - // per-isolate CPED, we won't restore the previous value if the context is - // detached, which can result in propagating the wrong value or leaking the - // context. - // - // The following prevents this by clearing the CPED on an arbitrary context - // associated with the isolate. Before the v8 API changes, this is a no-op - // (aside from potentially creating the context). After it changes, this - // will clear the per-isolate CPED since - // Context::SetContinuationPreservedEmbedderData() will delegate to - // Isolate::SetContinuationPreservedEmbedderData(). - ClearContinuationPreservedEmbedderData(isolate); - return; - } - ScriptState::Scope scope(script_state); - v8::Local<v8::Context> context = script_state->GetContext(); - DCHECK(!context.IsEmpty()); - if (task_state) { - context->SetContinuationPreservedEmbedderData( + // `task_state` will be null when leaving the top-level task scope, at which + // point we want to clear the isolate's CPED and reference to the related + // context. We don't need to distinguish between null and undefined values, + // and V8 has a fast path if the CPED is undefined, so treat null `task_state` + // as undefined. + // + // TODO(crbug.com/1351643): Since the context no longer matters, change this + // to a utility context that will always be valid. + if (!script_state->ContextIsValid() || !task_state) { + isolate->SetContinuationPreservedEmbedderData(v8::Undefined(isolate)); + } else { + ScriptState::Scope scope(script_state); + isolate->SetContinuationPreservedEmbedderData( ToV8Traits<ScriptWrappableTaskState>::ToV8(script_state, task_state) .ToLocalChecked()); - } else { - context->SetContinuationPreservedEmbedderData(v8::Local<v8::Value>()); } }
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc index 136f27f..9440f6ac 100644 --- a/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc +++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc
@@ -205,11 +205,13 @@ } void SerialPortUnderlyingSink::OnFlushOrDrain() { - DCHECK(pending_operation_); - - pending_operation_->Resolve(); - pending_operation_ = nullptr; - serial_port_->UnderlyingSinkClosed(); + // If pending_operation_ is nullptr, that means SignalError happened before + // flush finished and SerialPort::UnderlyingSinkClosed has been called. + if (pending_operation_) { + pending_operation_->Resolve(); + pending_operation_ = nullptr; + serial_port_->UnderlyingSinkClosed(); + } } void SerialPortUnderlyingSink::WriteData() {
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 5b21544..88f3a17 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -63,6 +63,7 @@ #include "third_party/blink/renderer/platform/language.h" #include "third_party/blink/renderer/platform/loader/fetch/url_loader/url_loader_factory.h" #include "third_party/blink/renderer/platform/scheduler/common/simple_main_thread_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h" #include "third_party/blink/renderer/platform/scheduler/public/main_thread.h" #include "third_party/blink/renderer/platform/scheduler/public/non_main_thread.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -139,54 +140,6 @@ Platform::~Platform() = default; -namespace { - -class SimpleMainThread : public MainThread { - public: - SimpleMainThread() = default; - - // We rely on base::SingleThreadTaskRunner::CurrentDefaultHandle for tasks - // posted on the main thread. The task runner handle may not be available on - // Blink's startup (== on SimpleMainThread's construction), because some tests - // like blink_platform_unittests do not set up a global task environment. In - // those cases, a task environment is set up on a test fixture's creation, and - // GetTaskRunner() returns the right task runner during a test. - // - // If GetTaskRunner() can be called from a non-main thread (including a worker - // thread running Mojo callbacks), we need to somehow get a task runner for - // the main thread. This is not possible with - // SingleThreadTaskRunner::CurrentDefaultHandle. We currently deal with this - // issue by setting the main thread task runner on the test startup and - // clearing it on the test tear-down. This is what - // SetMainThreadTaskRunnerForTesting() for. This function is called from - // Platform::SetMainThreadTaskRunnerForTesting() and - // Platform::UnsetMainThreadTaskRunnerForTesting(). - - ThreadScheduler* Scheduler() override { return &scheduler_; } - - scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( - MainThreadTaskRunnerRestricted) const override { - if (main_thread_task_runner_for_testing_) - return main_thread_task_runner_for_testing_; - DCHECK(WTF::IsMainThread()); - return base::SingleThreadTaskRunner::GetCurrentDefault(); - } - - void SetMainThreadTaskRunnerForTesting( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - main_thread_task_runner_for_testing_ = std::move(task_runner); - } - - private: - bool IsSimpleMainThread() const override { return true; } - - scheduler::SimpleMainThreadScheduler scheduler_; - scoped_refptr<base::SingleThreadTaskRunner> - main_thread_task_runner_for_testing_; -}; - -} // namespace - WebThemeEngine* Platform::ThemeEngine() { return WebThemeEngineHelper::GetNativeThemeEngine(); } @@ -216,7 +169,7 @@ DCHECK(platform); g_platform = platform; InitializeBlink(); - InitializeMainThreadCommon(platform, std::make_unique<SimpleMainThread>()); + InitializeMainThreadCommon(platform, scheduler::CreateSimpleMainThread()); } void Platform::InitializeMainThreadCommon( @@ -280,22 +233,19 @@ void Platform::CreateMainThreadForTesting() { DCHECK(!Thread::MainThread()); - MainThread::SetMainThread(std::make_unique<SimpleMainThread>()); + MainThread::SetMainThread(scheduler::CreateSimpleMainThread()); } void Platform::SetMainThreadTaskRunnerForTesting() { DCHECK(WTF::IsMainThread()); DCHECK(Thread::MainThread()->IsSimpleMainThread()); - static_cast<SimpleMainThread*>(Thread::MainThread()) - ->SetMainThreadTaskRunnerForTesting( - base::SingleThreadTaskRunner::GetCurrentDefault()); + scheduler::SetMainThreadTaskRunnerForTesting(); } void Platform::UnsetMainThreadTaskRunnerForTesting() { DCHECK(WTF::IsMainThread()); DCHECK(Thread::MainThread()->IsSimpleMainThread()); - static_cast<SimpleMainThread*>(Thread::MainThread()) - ->SetMainThreadTaskRunnerForTesting(nullptr); + scheduler::UnsetMainThreadTaskRunnerForTesting(); } Platform* Platform::Current() {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index a4fa9be..9b85d39a 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -399,6 +399,12 @@ settable_from_internals: true, }, { + // If enabled, lazy loaded images can be auto sized if the sizes + // attribute is missing or set to auto. + name: "AutoSizeLazyLoadedImages", + status: "test", + }, + { name: "BackdropInheritOriginating", status: "experimental", }, @@ -1091,6 +1097,7 @@ { // https://drafts.csswg.org/css-scroll-snap-2/#snap-events name: "CSSSnapChangingEvent", + status: "test", }, { name: "CSSSnapContainerQueries", @@ -2176,9 +2183,11 @@ // This is enabled by features::kLazyInitializeMediaControls. }, { + // If enabled, the lazy load image observer will use a scroll margin in + // its init dictionary instead of a root margin. name: "LazyLoadScrollMargin", public: true, - status: "test", + status: "experimental", }, { name: "LCPAnimatedImagesWebExposed", @@ -2518,7 +2527,13 @@ status: "experimental", base_feature: "none", }, - // Origin trial to experiment with No-Vary-Search in Prefetch Cache + // Origin trial to experiment with No-Vary-Search in Prefetch Cache. + // The functionality in this Origin Trial is now enabled by default in the + // browser by network::features::kPrefetchNoVarySearchShippedByDefault + // feature parameter of network::features::kPrefetchNoVarySearch. + // This runtime enabled feature is ignored as long as the feature + // parameter network::features::kPrefetchNoVarySearchShippedByDefault is + // not disabled via Finch. // See crbug.com/1378075. Depends on SpeculationRulesPrefetchProxy to be // enabled. // On the browser side, the trial needs features::kPrefetchUseContentRefactor @@ -2940,6 +2955,12 @@ name:"PrettyPrintJSONDocument", status: "experimental", }, + { + // Privacy intervention to disable reading the system accent-color via + // images. + name: "PreventReadingSystemAccentColor", + status: "stable", + }, // The RTE feature encompasses multiple APIs, including: Attribution // Reporting, FLEDGE, Topics and Fenced Frames. { @@ -3491,9 +3512,15 @@ }, { name: "SpeculationRulesNoVarySearchHint", - base_feature: "none", origin_trial_feature_name: "NoVarySearchPrefetch", }, + // The "expects_no_vary_search" hint is enabled if it is enabled: + // * through an origin trial token (NoVarySearchPrefetch) or + // * by default (SpeculationRulesNoVarySearchHintShippedByDefault) + { + name: "SpeculationRulesNoVarySearchHintShippedByDefault", + status: "stable" + }, { name: "SpeculationRulesPointerDownHeuristics", base_feature_status: "enabled",
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc index b1f0c92..3b4d02a 100644 --- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc +++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -3,10 +3,12 @@ // found in the LICENSE file. #include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h" +#include <memory> #include "base/memory/raw_ptr.h" #include "base/task/single_thread_task_runner.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/renderer/platform/scheduler/common/simple_main_thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" @@ -29,6 +31,12 @@ AgentGroupScheduler* CreateDummyAgentGroupSchedulerWithIsolate( v8::Isolate* isolate); +std::unique_ptr<FrameScheduler> CreateDummyFrameSchedulerWithIsolate( + v8::Isolate* isolate); + +std::unique_ptr<PageScheduler> CreateDummyPageSchedulerWithIsolate( + v8::Isolate* isolate); + class DummyWidgetScheduler final : public WidgetScheduler { public: DummyWidgetScheduler() = default; @@ -64,7 +72,8 @@ class DummyFrameScheduler : public FrameScheduler { public: - DummyFrameScheduler() : page_scheduler_(CreateDummyPageScheduler()) {} + explicit DummyFrameScheduler(v8::Isolate* isolate) + : page_scheduler_(CreateDummyPageSchedulerWithIsolate(isolate)) {} ~DummyFrameScheduler() override = default; DummyFrameScheduler(const DummyFrameScheduler&) = delete; @@ -158,8 +167,9 @@ class DummyPageScheduler : public PageScheduler { public: - DummyPageScheduler() - : agent_group_scheduler_(CreateDummyAgentGroupScheduler()) {} + explicit DummyPageScheduler(v8::Isolate* isolate) + : agent_group_scheduler_( + CreateDummyAgentGroupSchedulerWithIsolate(isolate)) {} ~DummyPageScheduler() override = default; DummyPageScheduler(const DummyPageScheduler&) = delete; @@ -169,7 +179,8 @@ FrameScheduler::Delegate* delegate, bool is_in_embedded_frame_tree, FrameScheduler::FrameType) override { - return CreateDummyFrameScheduler(); + return CreateDummyFrameSchedulerWithIsolate( + agent_group_scheduler_->Isolate()); } void OnTitleOrFaviconUpdated() override {} @@ -199,26 +210,66 @@ Persistent<AgentGroupScheduler> agent_group_scheduler_; }; -// TODO(altimin,yutak): Merge with SimpleThread in platform.cc. -class SimpleThread : public MainThread { +class SimpleMainThread : public MainThread { public: - explicit SimpleThread(ThreadScheduler* scheduler) : scheduler_(scheduler) {} - ~SimpleThread() override {} + // We rely on base::SingleThreadTaskRunner::CurrentDefaultHandle for tasks + // posted on the main thread. The task runner handle may not be available on + // Blink's startup (== on SimpleMainThread's construction), because some tests + // like blink_platform_unittests do not set up a global task environment. In + // those cases, a task environment is set up on a test fixture's creation, and + // GetTaskRunner() returns the right task runner during a test. + // + // If GetTaskRunner() can be called from a non-main thread (including a worker + // thread running Mojo callbacks), we need to somehow get a task runner for + // the main thread. This is not possible with + // SingleThreadTaskRunner::CurrentDefaultHandle. We currently deal with this + // issue by setting the main thread task runner on the test startup and + // clearing it on the test tear-down. This is what + // SetMainThreadTaskRunnerForTesting() for. This function is called from + // Platform::SetMainThreadTaskRunnerForTesting() and + // Platform::UnsetMainThreadTaskRunnerForTesting(). - SimpleThread(const SimpleThread&) = delete; - SimpleThread& operator=(const SimpleThread&) = delete; + explicit SimpleMainThread(ThreadScheduler* scheduler) + : scheduler_ptr_(scheduler) {} + ~SimpleMainThread() override = default; + + SimpleMainThread(const SimpleMainThread&) = delete; + SimpleMainThread& operator=(const SimpleMainThread&) = delete; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( MainThreadTaskRunnerRestricted) const override { + if (main_thread_task_runner_for_testing_) { + return main_thread_task_runner_for_testing_; + } + DCHECK(WTF::IsMainThread()); return base::SingleThreadTaskRunner::GetCurrentDefault(); } - ThreadScheduler* Scheduler() override { return scheduler_; } + ThreadScheduler* Scheduler() override { return scheduler_ptr_; } bool IsCurrentThread() const { return WTF::IsMainThread(); } + void SetMainThreadTaskRunnerForTesting( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + main_thread_task_runner_for_testing_ = std::move(task_runner); + } + private: - raw_ptr<ThreadScheduler, ExperimentalRenderer> scheduler_; + bool IsSimpleMainThread() const override { return true; } + + raw_ptr<ThreadScheduler, ExperimentalRenderer> scheduler_ptr_; + scoped_refptr<base::SingleThreadTaskRunner> + main_thread_task_runner_for_testing_; +}; + +class SimpleMainThreadWithScheduler : public SimpleMainThread { + public: + SimpleMainThreadWithScheduler() : SimpleMainThread(nullptr) {} + + ThreadScheduler* Scheduler() override { return &scheduler_; } + + private: + scheduler::SimpleMainThreadScheduler scheduler_; }; class DummyWebMainThreadScheduler : public WebThreadScheduler, @@ -271,7 +322,7 @@ } std::unique_ptr<MainThread> CreateMainThread() override { - return std::make_unique<SimpleThread>(this); + return std::make_unique<SimpleMainThread>(this); } AgentGroupScheduler* CreateAgentGroupScheduler() override { @@ -328,12 +379,14 @@ std::unique_ptr<PageScheduler> CreatePageScheduler( PageScheduler::Delegate*) override { - return CreateDummyPageScheduler(); + return CreateDummyPageSchedulerWithIsolate(Isolate()); } scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override { + DCHECK(WTF::IsMainThread()); return base::SingleThreadTaskRunner::GetCurrentDefault(); } scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override { + DCHECK(WTF::IsMainThread()); return base::SingleThreadTaskRunner::GetCurrentDefault(); } WebThreadScheduler& GetMainThreadScheduler() override { @@ -357,14 +410,24 @@ return MakeGarbageCollected<DummyAgentGroupScheduler>(isolate); } +std::unique_ptr<FrameScheduler> CreateDummyFrameSchedulerWithIsolate( + v8::Isolate* isolate) { + return std::make_unique<DummyFrameScheduler>(isolate); +} + +std::unique_ptr<PageScheduler> CreateDummyPageSchedulerWithIsolate( + v8::Isolate* isolate) { + return std::make_unique<DummyPageScheduler>(isolate); +} + } // namespace std::unique_ptr<FrameScheduler> CreateDummyFrameScheduler() { - return std::make_unique<DummyFrameScheduler>(); + return CreateDummyFrameSchedulerWithIsolate(/*isolate=*/nullptr); } std::unique_ptr<PageScheduler> CreateDummyPageScheduler() { - return std::make_unique<DummyPageScheduler>(); + return CreateDummyPageSchedulerWithIsolate(/*isolate=*/nullptr); } AgentGroupScheduler* CreateDummyAgentGroupScheduler() { @@ -375,5 +438,20 @@ return std::make_unique<DummyWebMainThreadScheduler>(); } +std::unique_ptr<MainThread> CreateSimpleMainThread() { + return std::make_unique<SimpleMainThreadWithScheduler>(); +} + +void SetMainThreadTaskRunnerForTesting() { + static_cast<SimpleMainThread*>(Thread::MainThread()) + ->SetMainThreadTaskRunnerForTesting( + base::SingleThreadTaskRunner::GetCurrentDefault()); +} + +void UnsetMainThreadTaskRunnerForTesting() { + static_cast<SimpleMainThread*>(Thread::MainThread()) + ->SetMainThreadTaskRunnerForTesting(nullptr); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h b/third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h index 8cbd533..522f67ce3 100644 --- a/third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h +++ b/third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h
@@ -13,6 +13,7 @@ class FrameScheduler; class PageScheduler; class AgentGroupScheduler; +class MainThread; namespace scheduler { class WebThreadScheduler; @@ -37,6 +38,26 @@ PLATFORM_EXPORT std::unique_ptr<WebThreadScheduler> CreateDummyWebMainThreadScheduler(); +// This sets up a minimally viable implementation of blink::Thread without +// changing the current Platform. This is essentially a workaround for the +// initialization order in ScopedUnittestsEnvironmentSetup, and nobody else +// should use this. +PLATFORM_EXPORT std::unique_ptr<MainThread> CreateSimpleMainThread(); + +// These are dirty workaround for tests requiring the main thread task runner +// from a non-main thread. These functions are not thread safe, and the caller +// should ensure proper synchronization with MainThread()->GetTaskRunner(), e.g. +// if your test needs base::TaskEnvironment and a non-main thread may call +// MainThread()->GetTaskRunner(), call SetMainThreadTaskRunnerForTesting() in +// your test fixture's SetUp() before any task is posted, and call +// UnsetMainThreadTaskRunnerForTesting() in TearDown() after all tasks +// completed. +// +// TODO(crbug.com/1315595): These should be packed in a custom test fixture +// along with TaskEnvironment for reusability. +PLATFORM_EXPORT void SetMainThreadTaskRunnerForTesting(); +PLATFORM_EXPORT void UnsetMainThreadTaskRunnerForTesting(); + } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py index b386693..a70b891 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -675,20 +675,8 @@ adds new expectation lines to TestExpectations and downloads new baselines based on the try job results. """ - _log.info('Adding test expectations lines to TestExpectations.') - tests_to_rebaseline = set() - - to_rebaseline, self.new_test_expectations = ( + tests_to_rebaseline, self.new_test_expectations = ( self.expectations_updater.update_expectations()) - tests_to_rebaseline.update(to_rebaseline) - - flag_spec_options = self.host.builders.all_flag_specific_options() - for flag_specific in sorted(flag_spec_options): - _log.info('Adding test expectations lines for %s', flag_specific) - to_rebaseline, _ = self.expectations_updater.update_expectations( - flag_specific) - tests_to_rebaseline.update(to_rebaseline) - # commit local changes so that rebaseline tool will be happy if self.project_git.has_working_directory_changes(): message = 'Update test expectations' @@ -696,7 +684,6 @@ self.expectations_updater.download_text_baselines( list(tests_to_rebaseline)) - self.rebaselined_tests = sorted(tests_to_rebaseline) def _get_last_imported_wpt_revision(self):
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py index cbc0b440..aa2aa41 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater.py
@@ -11,8 +11,8 @@ import argparse import logging import re -from collections import defaultdict, namedtuple -from typing import List, Optional, Set, Tuple +from collections import defaultdict +from typing import Collection, List, Optional, Set, Tuple from blinkpy.common.memoized import memoized from blinkpy.common.net.git_cl import BuildStatuses, GitCL @@ -28,21 +28,19 @@ BuildResolver, UnresolvedBuildException, ) +from blinkpy.web_tests.port.base import Port from blinkpy.web_tests.models.test_expectations import ( ExpectationsChange, ParseError, SystemConfigurationEditor, TestExpectations, + TestExpectationsCache, ) from blinkpy.web_tests.models.typ_types import ResultType _log = logging.getLogger(__name__) -SimpleTestResult = namedtuple('SimpleTestResult', ['expected', 'actual', 'bug']) -DesktopConfig = namedtuple('DesktopConfig', ['port_name']) - - class WPTExpectationsUpdater: MARKER_COMMENT = '# ====== New tests from wpt-importer added here ======' UMBRELLA_BUG = 'crbug.com/626703' @@ -138,19 +136,17 @@ 'This command line argument can be used to mark tests ' 'as flaky.') - def suites_for_builder(self, - builder: str, - flag_specific: Optional[str] = None) -> List[str]: - suites = [] + def suites_for_builder(self, builder: str) -> Set[str]: + # TODO(crbug.com/1502294): Make everything a suite name (i.e., without + # the `(with patch)` suffix) to be consistent. + suites = set() for step in self.host.builders.step_names_for_builder(builder): - if self.host.builders.flag_specific_option(builder, - step) == flag_specific: - suite_match = re.match(r'(?P<suite>[\w_-]*wpt_tests)', step) - if suite_match: - suites.append(suite_match['suite']) + suite_match = re.match(r'(?P<suite>[\w_-]*wpt_tests)', step) + if suite_match: + suites.add(step) return suites - def update_expectations(self, flag_specific: Optional[str] = None): + def update_expectations(self): """Adds test expectations lines. Returns: @@ -177,29 +173,39 @@ 'No try job information was collected.') from error tests_to_rebaseline, results = self._fetch_results_for_update( - build_to_status, flag_specific) - test_expectations = {} + build_to_status) + # TODO(crbug.com/1475013): Decide how to organize Android expectations. + results_by_path = defaultdict(list) for suite_results in results: - test_expectations = self.merge_dicts( - test_expectations, - self.generate_failing_results_dict(suite_results)) + port = self._port_for_build_step(suite_results.builder_name, + suite_results.step_name()) + flag_specific = port.flag_specific_config_name() + if flag_specific: + path = port.path_to_flag_specific_expectations_file( + flag_specific) + elif port.name() == 'chrome': + path = self.finder.path_from_web_tests( + 'ChromeTestExpectations') + else: + path = port.path_to_generic_test_expectations_file() + results_by_path[path].append(suite_results) - # At this point, test_expectations looks like: { - # 'test-with-failing-result': { - # config1: SimpleTestResult, - # config2: SimpleTestResult, - # config3: AnotherSimpleTestResult - # } - # } - - exp_lines_dict = self.write_to_test_expectations( - test_expectations, flag_specific) + exp_lines_dict = defaultdict(list) + for path in sorted(results_by_path, key=self._update_order): + for test, lines in self.write_to_test_expectations( + results_by_path[path], path).items(): + exp_lines_dict[test].extend(lines) return sorted(tests_to_rebaseline), exp_lines_dict + def _update_order(self, path: str) -> int: + # Update generic expectations first. + if path == self.port.path_to_generic_test_expectations_file(): + return 0 + return 1 + def _fetch_results_for_update( self, build_to_status: BuildStatuses, - flag_specific: Optional[str] = None ) -> Tuple[Set[str], List[WebTestResults]]: completed_results, missing_results, final_results = [], [], [] tests_to_rebaseline = set() @@ -207,11 +213,7 @@ fetcher = self.host.results_fetcher incomplete_builds = GitCL.filter_incomplete(build_to_status) for build, job_status in build_to_status.items(): - if (job_status.result == 'SUCCESS' - and not self.options.include_unexpected_pass): - continue - for suite in self.suites_for_builder(build.builder_name, - flag_specific): + for suite in self.suites_for_builder(build.builder_name): # `exclude_exonerations=(not include_unexpected_pass)` will # leave out unexpected passes as well as other kinds of # exonerations (e.g., experimental build). This is good enough @@ -249,8 +251,9 @@ def os_name(port_name): return self.host.port_factory.get(port_name).operating_system() - missing_port = self.host.builders.port_name_for_builder_name( - missing_results.builder_name) + missing_port = self._port_for_build_step(missing_results.builder_name, + missing_results.step_name()) + # When a config has no results, we try to guess at what its results are # based on other results. We prefer to use results from other builds on # the same OS, but fallback to all other builders otherwise (eg: there @@ -261,8 +264,7 @@ _log.warning('No results for %s on %s, inheriting from other builds', missing_results.step_name(), missing_results.builder_name) for test_name in self._tests(completed_results): - if self.host.builders.version_specifier_for_port_name( - missing_port) in self.skipped_specifiers(test_name): + if missing_port.skips_test(test_name): continue # The union of all other actual statuses is used when there is # no similar OS to inherit from (eg: no results on Linux, and @@ -280,7 +282,7 @@ union_actual_all.update(result.actual_results()) completed_port = self.host.builders.port_name_for_builder_name( completed_suite_results.builder_name) - if os_name(completed_port) == os_name(missing_port): + if os_name(completed_port) == os_name(missing_port.name()): union_actual_sameos.update(result.actual_results()) statuses = union_actual_sameos or union_actual_all @@ -379,41 +381,6 @@ builder_name=test_results.builder_name) return tests_to_rebaseline, results_to_update - def generate_failing_results_dict(self, web_test_results): - """Makes a dict with results for one platform. - - Args: - web_test_results: A list of WebTestResult objects. - - Returns: - A dictionary with the structure: { - 'test-name': { - ('full-port-name',): SimpleTestResult - } - } - """ - test_dict = {} - port_name = self.host.builders.port_name_for_builder_name( - web_test_results.builder_name) - config = DesktopConfig(port_name=port_name) - for result in web_test_results.didnt_run_as_expected_results(): - test_name = result.test_name() - statuses = set(result.actual_results()) - test_dict[test_name] = { - config: - # Note: we omit `expected` so that existing expectation lines - # don't prevent us from merging current results across platform. - # Eg: if a test FAILs everywhere, it should not matter that it - # has a pre-existing TIMEOUT expectation on Win7. This code is - # not currently capable of updating that existing expectation. - SimpleTestResult(expected='', - actual=' '.join(sorted(statuses)), - bug=' '.join( - sorted(result.bugs - or {self.UMBRELLA_BUG}))) - } - return test_dict - def _is_wpt_test(self, test_name): """Check if a web test is a WPT tests. @@ -426,172 +393,106 @@ the web_tests directory.""" return self.port.is_wpt_test(test_name) - def merge_dicts(self, target, source, path=None): - """Recursively merges nested dictionaries. - - Args: - target: First dictionary, which is updated based on source. - source: Second dictionary, not modified. - path: A list of keys, only used for making error messages. - - Returns: - The updated target dictionary. - """ - path = path or [] - for key in source: - if key in target: - if (isinstance(target[key], dict)) and isinstance( - source[key], dict): - self.merge_dicts(target[key], source[key], - path + [str(key)]) - elif target[key] == source[key]: - pass - else: - # We have two different SimpleTestResults for the same test - # from two different builders. This can happen when a CQ bot - # and a blink-rel bot run on the same platform. We union the - # actual statuses from both builders. - _log.info( - "Joining differing results for path %s, key %s\n target:%s\nsource:%s" - % (path, key, target[key], source[key])) - target[key] = SimpleTestResult( - expected=target[key].expected, - actual='%s %s' % - (target[key].actual, source[key].actual), - bug=target[key].bug) - else: - target[key] = source[key] - return target - - def get_expectations(self, result, test_name=''): - """Returns a set of test expectations based on the result of a test. - - Returns a set of one or more test expectations based on the expected - and actual results of a given test name. This function is to decide - expectations for tests that could not be rebaselined. - - Args: - result: A SimpleTestResult. - test_name: The test name string (optional). - - Returns: - A set of one or more test expectation strings with the first letter - capitalized. Example: {'Failure', 'Timeout'}. - """ - actual_results = set(result.actual.split()) - - # If the result is MISSING, this implies that the test was not - # rebaselined and has an actual result but no baseline. We can't - # add a Missing expectation (this is not allowed), but no other - # expectation is correct. - if 'MISSING' in actual_results: - return {ResultType.Skip} - expectations = set() - failure_types = {'TEXT', 'IMAGE+TEXT', 'IMAGE', 'AUDIO', 'FAIL'} - other_types = {'TIMEOUT', 'CRASH', 'PASS'} - for actual in actual_results: - if actual in failure_types: - expectations.add(ResultType.Failure) - if actual in other_types: - expectations.add(actual) - return expectations - - def skipped_specifiers(self, test_name): - """Returns a list of platform specifiers for which the test is skipped.""" - specifiers = [] - for port in self.all_try_builder_ports(): - if port.skips_test(test_name): - specifiers.append( - self.host.builders.version_specifier_for_port_name( - port.name())) - return specifiers - - @memoized - def all_try_builder_ports(self): - """Returns a list of Port objects for all try builders.""" - return [ - self.host.port_factory.get_from_builder_name(name) - for name in self._get_try_bots() - ] - - def _platform_specifiers_covered_by_try_bots( - self, flag_specific: Optional[str] = None): - all_platform_specifiers = set() - for builder_name in self._get_try_bots(flag_specific): - all_platform_specifiers.add( - self.host.builders.platform_specifier_for_builder( - builder_name).lower()) - return frozenset(all_platform_specifiers) + def _platform_specifiers(self, test: str, + ports: Collection[Port]) -> Set[str]: + return { + self.host.builders.version_specifier_for_port_name( + port.name()).lower() + for port in ports if not port.skips_test(test) + } def write_to_test_expectations(self, - test_expectations, - flag_specific: Optional[str] = None): + results: Collection[WebTestResults], + path: Optional[str] = None): """Writes the given lines to the TestExpectations file. The place in the file where the new lines are inserted is after a marker comment line. If this marker comment line is not found, then everything including the marker line is appended to the end of the file. - Args: - test_expectations: A dictionary mapping test names to a dictionary - mapping platforms and test results. + Arguments: + results: A collection of `WebTestResults` from builder/step pairs + that run the same tests and comprise the supported platforms + for the file. + path: Path to the test expectations file to write to. Every port + must include this file. + Returns: Dictionary mapping test names to lists of test expectation strings. """ - covered_versions = self._platform_specifiers_covered_by_try_bots( - flag_specific) - port = self.host.port_factory.get() - if flag_specific: - port.set_option_default('flag_specific', flag_specific) - path = port.path_to_flag_specific_expectations_file(flag_specific) - else: - path = port.path_to_generic_test_expectations_file() - expectations, change = TestExpectations(port), ExpectationsChange() - for test in sorted(filter(self._is_wpt_test, test_expectations)): - skipped_versions = { - version.lower() - for version in self.skipped_specifiers(test) - } + path = path or self.port.path_to_generic_test_expectations_file() + port_by_results = { + suite_results: + self._port_for_build_step(suite_results.builder_name, + suite_results.step_name()) + for suite_results in results + } + for port in port_by_results.values(): + assert path in port.expectations_dict(), ( + f'{path!r} not in {list(port.expectations_dict())!r} for {port!r}' + ) + rel_path = self.host.filesystem.relpath(path, + self.port.web_tests_dir()) + _log.info(f'Updating {rel_path!r}') + + exp_by_port = TestExpectationsCache() + # These expectations are for writing to the file. The exact port doesn't + # matter, since they should use the same files. + port_for_file = min(port_by_results.values(), key=Port.name) + expectations = exp_by_port.load(port_for_file) + change = ExpectationsChange() + for test in sorted(filter(self._is_wpt_test, self._tests(results))): # Find version specifiers needed to promote versions to their OS # (covered versions that are not skipped). For flag-specific # expectations, there should only be one covered version at most # that will automatically be promoted to a generic line. macros = { - os: [ - version for version in versions - if version in covered_versions - skipped_versions - ] + os: set(versions) + & self._platform_specifiers(test, port_by_results.values()) for os, versions in - self.port.configuration_specifier_macros().items() + port_for_file.configuration_specifier_macros().items() } editor = SystemConfigurationEditor(expectations, path, macros) - for config, result in test_expectations[test].items(): + for suite_results, port in port_by_results.items(): version = self.host.builders.version_specifier_for_port_name( - config.port_name) - if not version: + port.name()) + result = suite_results.result_for_test(test) + if not version or not result: continue - statuses = self.get_expectations(result, test) - # Avoid writing flag-specific expectations redundant with - # generic ones. - if flag_specific and statuses == expectations.get_expectations( - test).results: + statuses = frozenset(result.actual_results()) + # Avoid writing flag- or product-specific expectations redundant + # with generic ones. + exp_for_port = exp_by_port.load(port) + if statuses == exp_for_port.get_expectations(test).results: continue change += editor.update_versions( test, {version}, statuses, - reason=result.bug, + reason=' '.join(result.bugs or {self.UMBRELLA_BUG}), marker=self.MARKER_COMMENT[len('# '):]) change += editor.merge_versions(test) + if not change.lines_added: - _log.info( - 'No lines to write to %s.', - self.host.filesystem.relpath(path, self.port.web_tests_dir())) + _log.info(f'No lines to write to {rel_path}.') expectations.commit_changes() new_lines = defaultdict(list) for line in change.lines_added: new_lines[line.test].append(line.to_string()) return {test: sorted(lines) for test, lines in new_lines.items()} + @memoized + def _port_for_build_step(self, builder: str, step: str) -> Port: + """"Get the port used to run a build step in CQ/CI.""" + builders = self.host.builders + product = builders.product_for_build_step(builder, step) + if product != 'content_shell': + return self.host.port_factory.get(product) + port_name = builders.port_name_for_builder_name(builder) + port = self.host.port_factory.get(port_name) + port.set_option_default('flag_specific', + builders.flag_specific_option(builder, step)) + return port + def skip_slow_timeout_tests(self, port): """Skip any Slow and Timeout tests found in TestExpectations. """
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py index b069ebbd..2458d9f 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import contextlib import json import textwrap import unittest @@ -15,8 +16,7 @@ from blinkpy.common.system.executive import ScriptError from blinkpy.common.system.log_testing import LoggingTestCase -from blinkpy.w3c.wpt_expectations_updater import ( - WPTExpectationsUpdater, SimpleTestResult, DesktopConfig) +from blinkpy.w3c.wpt_expectations_updater import WPTExpectationsUpdater from blinkpy.w3c.wpt_manifest import ( WPTManifest, BASE_MANIFEST_NAME, MANIFEST_NAME) @@ -177,11 +177,12 @@ }) updater = WPTExpectationsUpdater(host) - self.assertEqual(sorted(updater.suites_for_builder('MOCK Try Trusty')), - ['blink_wpt_tests', 'webdriver_wpt_tests']) self.assertEqual( - updater.suites_for_builder('MOCK Try Trusty', 'fake-flag'), - ['fake_flag_blink_wpt_tests']) + updater.suites_for_builder('MOCK Try Trusty'), { + 'blink_wpt_tests', + 'webdriver_wpt_tests', + 'fake_flag_blink_wpt_tests', + }) def test_run_single_platform_failure(self): """Tests the main run method in a case where one test fails on one platform.""" @@ -190,8 +191,12 @@ # Fill in an initial value for TestExpectations expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() - host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + host.filesystem.write_text_file( + expectations_path, + textwrap.dedent(f"""\ + # tags: [ Mac10.10 Mac10.11 Mac Trusty Precise Linux Win7 Win10 Win ] + # results: [ Pass Timeout ] + """)) # Set up fake try job results. updater = WPTExpectationsUpdater(host) @@ -230,15 +235,19 @@ self.assertEqual(0, updater.run()) self.assertEqual( host.filesystem.read_text_file(expectations_path), - '# ====== New tests from wpt-importer added here ======\n' - 'crbug.com/626703 [ Mac10.10 ] external/wpt/test/path.html [ Timeout ]\n' - ) + textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac Trusty Precise Linux Win7 Win10 Win ] + # results: [ Pass Timeout ] + + # ====== New tests from wpt-importer added here ====== + crbug.com/626703 [ Mac10.10 ] external/wpt/test/path.html [ Timeout ] + """)) def test_run_chrome_only_failure(self): host = self.mock_host() host.builders = BuilderList({ 'MOCK Try Chrome': { - 'port_name': 'test-linux-trusty', + 'port_name': 'chrome', 'specifiers': ['Chrome', 'Release'], 'is_try_builder': True, 'steps': { @@ -246,30 +255,22 @@ 'webdriver_wpt_tests': {}, }, }, - 'MOCK Try Trusty': { - 'port_name': 'test-linux-trusty', - 'specifiers': ['Trusty', 'Release'], - 'is_try_builder': True, - 'steps': { - 'blink_wpt_tests': {}, - }, - }, }) - - expectations_path = \ - host.port_factory.get().path_to_generic_test_expectations_file() - host.filesystem.write_text_file( - expectations_path, WPTExpectationsUpdater.MARKER_COMMENT + '\n') - updater = WPTExpectationsUpdater(host) + expectations_path = updater.finder.path_from_web_tests( + 'ChromeTestExpectations') + host.filesystem.write_text_file( + expectations_path, + textwrap.dedent(f"""\ + # results: [ Timeout ] + {WPTExpectationsUpdater.MARKER_COMMENT} + """)) + updater.git_cl = MockGitCL( updater.host, { - Build('MOCK Try Trusty', 222, 'Build-3'): - TryJobStatus('COMPLETED', 'SUCCESS'), Build('MOCK Try Chrome', 333, 'Build-4'): TryJobStatus('COMPLETED', 'FAILURE'), }) - host.results_fetcher.set_results( Build('MOCK Try Chrome', 333, 'Build-4'), WebTestResults.from_rdb_responses( @@ -287,13 +288,86 @@ builder_name='MOCK Try Chrome', step_name='webdriver_wpt_tests')) - self.assertEqual(0, updater.run()) + with self._mock_chrome_port(updater): + self.assertEqual(0, updater.run()) self.assertEqual( host.filesystem.read_text_file(expectations_path), - '# ====== New tests from wpt-importer added here ======\n' - 'crbug.com/626703 [ Chrome ] external/wpt/test/path.html [ Timeout ]\n' - 'crbug.com/626703 [ Chrome ] external/wpt/webdriver/test.py [ Timeout ]\n' - ) + textwrap.dedent("""\ + # results: [ Timeout ] + # ====== New tests from wpt-importer added here ====== + crbug.com/626703 external/wpt/test/path.html [ Timeout ] + crbug.com/626703 external/wpt/webdriver/test.py [ Timeout ] + """)) + + def test_no_chrome_expectation_redundant_with_generic(self): + host = self.mock_host() + host.builders = BuilderList({ + 'MOCK Try Chrome': { + 'port_name': 'chrome', + 'specifiers': ['Chrome', 'Release'], + 'is_try_builder': True, + 'steps': { + 'chrome_wpt_tests': {}, + }, + }, + }) + updater = WPTExpectationsUpdater(host) + expectations_path = updater.finder.path_from_web_tests( + 'ChromeTestExpectations') + host.filesystem.write_text_file( + updater.port.path_to_generic_test_expectations_file(), + textwrap.dedent("""\ + # results: [ Timeout ] + external/wpt/test/path.html [ Timeout ] + """)) + host.filesystem.write_text_file( + expectations_path, + textwrap.dedent(f"""\ + # results: [ Timeout ] + # ====== New tests from wpt-importer added here ====== + """)) + + updater.git_cl = MockGitCL( + updater.host, { + Build('MOCK Try Chrome', 333, 'Build-4'): + TryJobStatus('COMPLETED', 'FAILURE'), + }) + host.results_fetcher.set_results( + Build('MOCK Try Chrome', 333, 'Build-4'), + WebTestResults.from_rdb_responses( + {'external/wpt/test/path.html': [{ + 'status': 'ABORT' + }] * 3}, + builder_name='MOCK Try Chrome', + step_name='chrome_wpt_tests')) + + with self._mock_chrome_port(updater): + self.assertEqual(0, updater.run()) + self.assertEqual( + host.filesystem.read_text_file(expectations_path), + textwrap.dedent(f"""\ + # results: [ Timeout ] + # ====== New tests from wpt-importer added here ====== + """)) + + @contextlib.contextmanager + def _mock_chrome_port(self, updater): + chrome_port = updater.host.port_factory.get('test-linux-trusty') + chrome_port.set_option_default('additional_expectations', [ + updater.finder.path_from_web_tests('ChromeTestExpectations'), + ]) + with contextlib.ExitStack() as mocks: + mocks.enter_context( + mock.patch.object(chrome_port, 'name', return_value='chrome')) + mocks.enter_context( + mock.patch.object(chrome_port, + 'configuration_specifier_macros', + return_value={'chrome': ['chrome']})) + mocks.enter_context( + mock.patch.object(updater.host.port_factory, + 'get', + return_value=chrome_port)) + yield def test_run_inherited_results(self): host = self.mock_host() @@ -415,7 +489,7 @@ step_name='fake_flag_blink_wpt_tests')) # `updater.run` does not update flag-specific expectations. - updater.update_expectations('fake-flag') + updater.update_expectations() self.assertEqual( host.filesystem.read_text_file(expectations_path), '# ====== New tests from wpt-importer added here ======\n' @@ -490,55 +564,6 @@ _, filtered_results = updater.filter_results_for_update(results) self.assertEqual(0, len(filtered_results)) - def test_get_expectations(self): - updater = WPTExpectationsUpdater(self.mock_host()) - # Positional arguments of SimpleTestResult: (expected, actual, bug) - self.assertEqual( - updater.get_expectations(SimpleTestResult('FAIL', 'PASS', 'bug')), - {'PASS'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('FAIL', 'PASS PASS', 'bug')), {'PASS'}) - self.assertEqual( - updater.get_expectations(SimpleTestResult('FAIL', 'TIMEOUT', - 'bug')), {'TIMEOUT'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('FAIL', 'TIMEOUT TIMEOUT', 'bug')), - {'TIMEOUT'}) - self.assertEqual( - updater.get_expectations(SimpleTestResult('TIMEOUT', 'PASS', - 'bug')), {'PASS'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('TIMEOUT', 'PASS PASS', 'bug')), {'PASS'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('PASS', 'TEXT PASS', 'bug')), - {'PASS', 'FAIL'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('PASS', 'TIMEOUT CRASH TEXT', 'bug')), - {'CRASH', 'FAIL', 'TIMEOUT'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('SLOW CRASH FAIL TIMEOUT', 'PASS', 'bug')), - {'PASS'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('PASS', 'IMAGE+TEXT IMAGE IMAGE', 'bug')), - {'FAIL'}) - self.assertEqual( - updater.get_expectations(SimpleTestResult('PASS', 'MISSING', - 'bug')), {'SKIP'}) - self.assertEqual( - updater.get_expectations( - SimpleTestResult('PASS', 'MISSING MISSING', 'bug')), {'SKIP'}) - self.assertEqual( - updater.get_expectations(SimpleTestResult('PASS', 'FAIL', 'bug'), - test_name='external/wpt/webdriver/foo/a'), - {'FAIL'}) - @mock.patch.object(WPTExpectationsUpdater, 'UMBRELLA_BUG', 'crbug.com/123') def test_remove_configurations(self): host = self.mock_host() @@ -600,7 +625,7 @@ # another one has non-match results, and the last one has no # corresponding line in generic test expectations. host = self.mock_host() - port = host.port_factory.get() + port = host.port_factory.get('test-linux-trusty') # Fill in an initial value for TestExpectations expectations_path = port.path_to_generic_test_expectations_file() @@ -629,7 +654,7 @@ builder_name='MOCK Try Trusty', step_name='fake_flag_blink_wpt_tests')) - updater.update_expectations('fake-flag') + updater.update_expectations() port.set_option_default('flag_specific', 'fake-flag') expectations = TestExpectations(port) self.assertEqual( @@ -709,24 +734,24 @@ self.assertEqual(line2.tags, {'trusty'}) self.assertEqual(line2.results, {ResultType.Timeout}) + @mock.patch.object(WPTExpectationsUpdater, 'UMBRELLA_BUG', 'crbug.com/123') def test_create_line_dict_with_asterisks(self): # Literal asterisks in test names need to be escaped in expectations. updater = WPTExpectationsUpdater(self.mock_host()) - results = { - 'external/wpt/html/dom/interfaces.https.html?exclude=(Document.*|HTML.*)': + results = WebTestResults.from_rdb_responses( { - DesktopConfig(port_name='test-linux-trusty'): - SimpleTestResult(expected='PASS', - actual='FAIL', - bug='crbug.com/123'), + 'external/wpt/html/dom/interfaces.https.html?exclude=(Document.*|HTML.*)': + [{ + 'status': 'FAIL', + }] * 3 }, - } - line_dict = updater.write_to_test_expectations(results) + builder_name='MOCK Try Trusty') + line_dict = updater.write_to_test_expectations([results]) self.assertEqual( line_dict, { 'external/wpt/html/dom/interfaces.https.html?exclude=(Document.*|HTML.*)': [ - 'crbug.com/123 [ Trusty ] external/wpt/html/dom/' + 'crbug.com/123 external/wpt/html/dom/' 'interfaces.https.html?exclude=(Document.\*|HTML.\*) ' '[ Failure ]', ], @@ -768,21 +793,6 @@ path, 'external/wpt/x/z.html') self.assertEqual(line1.tags | line2.tags, {'win7', 'mac10.10'}) - def test_skipped_specifiers_when_test_is_skip(self): - host = self.mock_host() - expectations_path = MOCK_WEB_TESTS + 'NeverFixTests' - host.filesystem.write_text_file( - expectations_path, - ('# tags: [ Linux ]\n' - '# results: [ Skip ]\n' - 'crbug.com/111 [ Linux ] external/wpt/test.html [ Skip ]\n')) - host.filesystem.write_text_file( - MOCK_WEB_TESTS + 'external/wpt/test.html', '') - updater = WPTExpectationsUpdater(host) - self.assertEqual(updater.skipped_specifiers('external/wpt/test.html'), - ['Precise', 'Trusty']) - - @mock.patch.object(WPTExpectationsUpdater, 'UMBRELLA_BUG', 'crbug.com/123') def test_specifiers_can_extend_to_all_platforms(self): host = self.mock_host() expectations_path = MOCK_WEB_TESTS + 'NeverFixTests' @@ -900,105 +910,6 @@ path, 'external/wpt/x/z.html') self.assertEqual(line.tags, {'win'}) - def test_merge_dicts_with_differing_status_is_merged(self): - updater = WPTExpectationsUpdater(self.mock_host()) - # Both dicts here have the key "one", and the value is not equal. The - # actual fields get joined together. - result = updater.merge_dicts( - { - 'external/wpt/test/path.html': { - 'one': SimpleTestResult('FAIL', 'PASS', 'bug'), - 'two': SimpleTestResult('FAIL', 'TIMEOUT', 'bug'), - 'three': SimpleTestResult('FAIL', 'PASS', 'bug'), - }, - }, { - 'external/wpt/test/path.html': { - 'one': SimpleTestResult('FAIL', 'TIMEOUT', 'bug'), - } - }) - expected_result = { - 'external/wpt/test/path.html': { - 'one': SimpleTestResult('FAIL', 'PASS TIMEOUT', 'bug'), - 'two': SimpleTestResult('FAIL', 'TIMEOUT', 'bug'), - 'three': SimpleTestResult('FAIL', 'PASS', 'bug'), - }, - } - self.assertEqual(result, expected_result) - - def test_merge_dicts_merges_second_dict_into_first(self): - updater = WPTExpectationsUpdater(self.mock_host()) - one = { - 'fake/test/path.html': { - 'one': { - 'expected': 'FAIL', - 'actual': 'PASS' - }, - 'two': { - 'expected': 'FAIL', - 'actual': 'PASS' - }, - } - } - two = { - 'external/wpt/test/path.html': { - 'one': { - 'expected': 'FAIL', - 'actual': 'PASS' - }, - 'two': { - 'expected': 'FAIL', - 'actual': 'TIMEOUT' - }, - 'three': { - 'expected': 'FAIL', - 'actual': 'PASS' - }, - } - } - three = { - 'external/wpt/test/path.html': { - 'four': { - 'expected': 'FAIL', - 'actual': 'PASS' - }, - } - } - - output = updater.merge_dicts(one, three) - self.assertEqual(output, one) - output = updater.merge_dicts(two, three) - self.assertEqual(output, two) - - def test_generate_failing_results_dict(self): - updater = WPTExpectationsUpdater(self.mock_host()) - web_test_list = WebTestResults.from_json( - { - "tests": { - "external/wpt/test/name.html": { - "expected": "bar", - "actual": "foo", - "is_unexpected": True, - "has_stderr": True - } - } - }, - step_name='blink_wpt_tests', - builder_name='MOCK Try Mac10.10') - - self.assertEqual( - updater.generate_failing_results_dict( - web_test_list), { - 'external/wpt/test/name.html': { - DesktopConfig(port_name='test-mac-mac10.10'): - SimpleTestResult( - expected='', - actual='foo', - bug='crbug.com/626703', - ) - } - } - ) - def test_no_expectations_to_write(self): host = self.mock_host() updater = self.mock_updater(host) @@ -1042,6 +953,7 @@ WPTExpectationsUpdater.MARKER_COMMENT + '\n' + '[ linux ] external/wpt/fake/new.html?HelloWorld [ Failure ]\n')) + @mock.patch.object(WPTExpectationsUpdater, 'UMBRELLA_BUG', 'crbug.com/123') def test_clean_expectations_for_deleted_test_harness(self): host = self.mock_host() port = host.port_factory.get() @@ -1085,18 +997,15 @@ updater._relative_to_web_test_dir = lambda test_path: test_path updater.cleanup_test_expectations_files() - test_expectations = { - 'external/wpt/fake/file/path.html': { - DesktopConfig(port_name='test-linux-trusty'): - SimpleTestResult(actual='PASS', - expected='', - bug='crbug.com/123') - } - } + results = WebTestResults.from_rdb_responses( + {'external/wpt/fake/file/path.html': [{ + 'status': 'FAIL', + }] * 3}, + builder_name='MOCK Try Trusty') skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations([results]) value = host.filesystem.read_text_file(expectations_path) self.assertMultiLineEqual( value, @@ -1105,11 +1014,12 @@ # results: [ Pass Failure ] # ====== New tests from wpt-importer added here ====== - crbug.com/123 [ Trusty ] external/wpt/fake/file/path.html [ Pass ] + crbug.com/123 external/wpt/fake/file/path.html [ Failure ] """)) skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) + @mock.patch.object(WPTExpectationsUpdater, 'UMBRELLA_BUG', 'crbug.com/123') def test_write_to_test_expectations_and_cleanup_expectations(self): host = self.mock_host() expectations_path = \ @@ -1136,25 +1046,22 @@ updater._relative_to_web_test_dir = lambda test_path: test_path updater.cleanup_test_expectations_files() - test_expectations = { - 'external/wpt/fake/file/path.html': { - DesktopConfig(port_name='test-linux-trusty'): - SimpleTestResult(actual='PASS', - expected='', - bug='crbug.com/123') - } - } + results = WebTestResults.from_rdb_responses( + {'external/wpt/fake/file/path.html': [{ + 'status': 'FAIL', + }] * 3}, + builder_name='MOCK Try Trusty') skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) - updater.write_to_test_expectations(test_expectations) + updater.write_to_test_expectations([results]) value = host.filesystem.read_text_file(expectations_path) self.assertMultiLineEqual( - value, ('# tags: [ Linux ]\n' + - '# results: [ Pass Failure ]\n' + - WPTExpectationsUpdater.MARKER_COMMENT + '\n' + - 'crbug.com/123 [ Trusty ] external/wpt/fake/file/path.html [ Pass ]\n' + - '[ linux ] external/wpt/fake/new.html?HelloWorld [ Failure ]\n')) + value, + ('# tags: [ Linux ]\n' + '# results: [ Pass Failure ]\n' + + WPTExpectationsUpdater.MARKER_COMMENT + '\n' + + 'crbug.com/123 external/wpt/fake/file/path.html [ Failure ]\n' + + '[ linux ] external/wpt/fake/new.html?HelloWorld [ Failure ]\n')) skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) @@ -1178,8 +1085,13 @@ host = self.mock_host() expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() - host.filesystem.write_text_file(expectations_path, - WPTExpectationsUpdater.MARKER_COMMENT + '\n') + host.filesystem.write_text_file( + expectations_path, + textwrap.dedent(f"""\ + # tags: [ Trusty ] + # results: [ Timeout ] + {WPTExpectationsUpdater.MARKER_COMMENT} + """)) updater = self.mock_updater(host) host.results_fetcher.set_results( Build('MOCK Try Trusty', 222, 'Build-3'), @@ -1194,10 +1106,14 @@ skip_path = host.port_factory.get().path_to_never_fix_tests_file() skip_value_origin = host.filesystem.read_text_file(skip_path) value = host.filesystem.read_text_file(expectations_path) - self.assertMultiLineEqual( + self.assertEqual( value, - (WPTExpectationsUpdater.MARKER_COMMENT + '\n' - 'crbug.com/123 [ Trusty ] external/wpt/x/y.html [ Timeout ]\n')) + textwrap.dedent(f"""\ + # tags: [ Trusty ] + # results: [ Timeout ] + {WPTExpectationsUpdater.MARKER_COMMENT} + crbug.com/123 [ Trusty ] external/wpt/x/y.html [ Timeout ] + """)) skip_value = host.filesystem.read_text_file(skip_path) self.assertMultiLineEqual(skip_value, skip_value_origin) @@ -1206,11 +1122,14 @@ host = self.mock_host() expectations_path = \ host.port_factory.get().path_to_generic_test_expectations_file() - raw_exps = '# tags: [ Trusty ]\n# results: [ Pass Failure ]\n' host.filesystem.write_text_file( expectations_path, - raw_exps + '\n' + - 'crbug.com/111 [ Trusty ] foo/bar.html [ Failure ]\n') + textwrap.dedent("""\ + # tags: [ Trusty ] + # results: [ Pass Failure Timeout ] + + crbug.com/111 [ Trusty ] foo/bar.html [ Failure ] + """)) updater = self.mock_updater(host) host.results_fetcher.set_results( Build('MOCK Try Trusty', 222, 'Build-3'), @@ -1229,7 +1148,7 @@ value, textwrap.dedent("""\ # tags: [ Trusty ] - # results: [ Pass Failure ] + # results: [ Pass Failure Timeout ] crbug.com/111 [ Trusty ] foo/bar.html [ Failure ]
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py index c744f15..04b5d28 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -666,8 +666,7 @@ expected_subpath = self.port.output_filename( result.name, test_failures.FILENAME_SUFFIX_EXPECTED, '.txt') if result.testharness_results: - actual_text = format_testharness_baseline( - result.get_result(), '/html/dom/reflection' in result.name) + actual_text = format_testharness_baseline(result.get_result()) artifacts.CreateArtifact('actual_text', actual_subpath, actual_text.encode()) if self.reset_results and self._iteration == 0 and result.actual not in {
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py index aa9d2e8..689428b6 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor_unittest.py
@@ -479,7 +479,6 @@ 'variant_foo=baz-actual.txt')), textwrap.dedent("""\ This is a testharness.js-based test. - [PASS] passing subtest (include for now) [FAIL] subtest actual-message Harness: the test ran to completion. @@ -582,7 +581,6 @@ 'variant_foo=baz-expected.txt')), textwrap.dedent("""\ This is a testharness.js-based test. - [PASS] passing subtest Harness: the test ran to completion. """))
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py index ff6817a..fc3d3264 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -797,7 +797,7 @@ self._cache: Dict[Tuple[str, Optional[str]], TestExpectations] = {} def load(self, port: 'Port') -> TestExpectations: - cache_key = port.port_name, port.get_option('flag_specific') + cache_key = port.name(), port.get_option('flag_specific') expectations = self._cache.get(cache_key) if not expectations: self._cache[cache_key] = expectations = TestExpectations(port)
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/testharness_results.py b/third_party/blink/tools/blinkpy/web_tests/models/testharness_results.py index 6b8c6f7d..e87447b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/testharness_results.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/testharness_results.py
@@ -105,53 +105,7 @@ return lines -def compact_test_output(lines: List[TestharnessLine]) -> List[TestharnessLine]: - """Returns a compact output for reflection test results. - - The reflection tests contain a large number of tests. - This test output merges PASS lines to make baselines smaller. - """ - def maybe_append_pass_line(compact_lines, prefix, subtest, passes): - if passes > 1: - compact_lines.append( - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - f'{prefix}: {passes} tests')) - elif passes == 1: - compact_lines.append( - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - subtest)) - - compact_lines = [] - prev_prefix = None - prev_subtest = None - prev_passes = 0 - for line in lines: - if (line.line_type != LineType.SUBTEST - or line.statuses != set([Status.PASS]) - or ':' not in line.subtest): - maybe_append_pass_line(compact_lines, prev_prefix, prev_subtest, - prev_passes) - prev_passes = 0 - compact_lines.append(line) - continue - - # We get a PASS subtest with ':' in test name - prefix, suffix = line.subtest.split(':', 1) - if prefix != prev_prefix: - maybe_append_pass_line(compact_lines, prev_prefix, prev_subtest, - prev_passes) - prev_prefix, prev_subtest = prefix, line.subtest - prev_passes = 1 - else: - prev_passes += 1 - - maybe_append_pass_line(compact_lines, prev_prefix, prev_subtest, - prev_passes) - return compact_lines - - -def format_testharness_baseline(lines: List[TestharnessLine], - do_compact: bool) -> str: +def format_testharness_baseline(lines: List[TestharnessLine]) -> str: """Format testharness.js results in the same way as [0]. [0]: //third_party/blink/web_tests/resources/testharnessreport.js @@ -170,17 +124,15 @@ except ValueError: pass - if do_compact: - lines = compact_test_output(lines) - for line in lines: if line.line_type is LineType.SUBTEST: assert line.subtest and line.statuses, line statuses = ' '.join(sorted(status.name for status in line.statuses)) - content += f'[{statuses}] {_escape(line.subtest)}\n' - if line.message: - content += f'{_MESSAGE_PREFIX}{_escape(line.message)}\n' + if statuses != 'PASS': + content += f'[{statuses}] {_escape(line.subtest)}\n' + if line.message: + content += f'{_MESSAGE_PREFIX}{_escape(line.message)}\n' elif line.line_type is LineType.HARNESS_ERROR: (status, ) = line.statuses assert isinstance(status.value, int), line @@ -198,10 +150,10 @@ if (line.line_type is LineType.TESTHARNESS_HEADER and status_counts[Status.PASS] < total and total >= _COUNT_THRESHOLD): - content += f'Found {total} tests; ' - content += ', '.join( - f'{count} {status.name}' - for status, count in status_counts.items()) + '.\n' + content += 'Found ' + content += ', '.join(f'{count} {status.name}' + for status, count in status_counts.items() + if status.name != 'PASS') + '.\n' return content @@ -267,18 +219,15 @@ """Checks whether |content_text| is a passing testharness output. Under a relatively loose/accepting definition of passing - testharness output, we consider any output with at least one - PASS result and no FAIL result (or TIMEOUT or NOTRUN). + testharness output, we consider any output without FAIL result + (or TIMEOUT or NOTRUN). """ - at_least_one_pass = False for line in parse_testharness_baseline(content_text): if line.line_type is LineType.HARNESS_ERROR or line.statuses - { Status.PASS }: return False - if line.line_type is LineType.ALL_PASS or Status.PASS in line.statuses: - at_least_one_pass = True - return at_least_one_pass + return True def has_other_useful_output(content_text: str) -> bool:
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/testharness_results_unittest.py b/third_party/blink/tools/blinkpy/web_tests/models/testharness_results_unittest.py index 0e97b844..ce096393 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/testharness_results_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/testharness_results_unittest.py
@@ -91,24 +91,11 @@ 'Harness: the test ran to completion.')) def test_is_test_output_passing_empty_content(self): - self.assertFalse( + self.assertTrue( testharness_results.is_test_output_passing( 'This is a testharness.js-based test.\n' ' Harness: the test ran to completion.')) - def test_is_test_output_passing_no_pass(self): - # If there are no PASS lines, then the test is not considered to pass. - self.assertFalse( - testharness_results.is_test_output_passing( - 'This is a testharness.js-based test.\n' - ' \n' - ' Harness: the test ran to completion.')) - self.assertFalse( - testharness_results.is_test_output_passing( - 'This is a testharness.js-based test.\n' - ' Foo bar \n' - ' Harness: the test ran to completion.')) - def test_is_test_output_passing_with_pass_and_random_text(self): self.assertTrue( testharness_results.is_test_output_passing( @@ -142,7 +129,7 @@ 'Harness: the test ran to completion.')) def test_is_test_output_passing_with_console_messages(self): - self.assertFalse( + self.assertTrue( testharness_results.is_test_output_passing( 'This is a testharness.js-based test.\n' ' CONSOLE ERROR: BLAH \n' @@ -179,12 +166,12 @@ self.assertFalse( testharness_results.is_test_output_passing( 'This is a testharness.js-based test.\n' - ' TIMEOUT: bah \n' + '[TIMEOUT] bah \n' ' Harness: the test ran to completion.')) self.assertFalse( testharness_results.is_test_output_passing( 'This is a testharness.js-based test.\n' - ' NOTRUN: bah \n' + '[NOTRUN] bah \n' ' Harness: the test ran to completion.')) def test_has_other_useful_output_positive_cases(self): @@ -293,54 +280,6 @@ self.assertIsNone(results[5].subtest) self.assertIsNone(results[5].message) - def test_compact_test_output(self): - lines = [ - TestharnessLine(LineType.TESTHARNESS_HEADER), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test1: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test1: b'), - TestharnessLine(LineType.FOOTER), - ] - expected_lines = [ - TestharnessLine(LineType.TESTHARNESS_HEADER), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - 'Test1: 2 tests'), - TestharnessLine(LineType.FOOTER), - ] - self.assertEqual(expected_lines, - testharness_results.compact_test_output(lines)) - - lines = [ - TestharnessLine(LineType.HARNESS_ERROR, {Status.ERROR}, - 'SyntaxError'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test1: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test2: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test2: b'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test3: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test3: b'), - TestharnessLine(LineType.SUBTEST, {Status.FAIL}, None, 'Test3: c'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4: b'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4: c'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4: d'), - ] - expected_lines = [ - TestharnessLine(LineType.HARNESS_ERROR, {Status.ERROR}, - 'SyntaxError'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test1: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - 'Test2: 2 tests'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - 'Test3: 2 tests'), - TestharnessLine(LineType.SUBTEST, {Status.FAIL}, None, 'Test3: c'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4: a'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, 'Test4'), - TestharnessLine(LineType.SUBTEST, {Status.PASS}, None, - 'Test4: 3 tests'), - ] - self.assertEqual(expected_lines, - testharness_results.compact_test_output(lines)) - def test_format_testharness_baseline(self): lines = [ TestharnessLine(LineType.CONSOLE_WARNING, @@ -355,7 +294,7 @@ TestharnessLine(LineType.FOOTER), ] self.assertEqual( - testharness_results.format_testharness_baseline(lines, False), + testharness_results.format_testharness_baseline(lines), textwrap.dedent("""\ CONSOLE WARNING: warning before test This is a testharness.js-based test. @@ -377,10 +316,9 @@ # to detect that this is an all-pass baseline, and possibly not write # it. self.assertEqual( - testharness_results.format_testharness_baseline(lines, False), + testharness_results.format_testharness_baseline(lines), textwrap.dedent("""\ This is a testharness.js-based test. - [PASS] subtest Harness: the test ran to completion. """)) @@ -395,6 +333,6 @@ TestharnessLine(LineType.FOOTER), ] self.assertIn( - 'Found 50 tests; 0 PASS, 50 FAIL, 0 TIMEOUT, 0 NOTRUN.', + 'Found 50 FAIL, 0 TIMEOUT, 0 NOTRUN.', testharness_results.format_testharness_baseline( - lines, False).splitlines()) + lines).splitlines())
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/chrome.py b/third_party/blink/tools/blinkpy/web_tests/port/chrome.py index 83fee5af..b8139368 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/chrome.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/chrome.py
@@ -41,6 +41,9 @@ FALLBACK_PATHS['chrome'] = ( ['linux-chrome'] + linux.LinuxPort.latest_platform_fallback_path()) + def configuration_specifier_macros(self): + return {self.port_name: list(self.SUPPORTED_VERSIONS)} + def default_expectations_files(self): """Returns a list of paths to expectations files that apply by default.
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/linux.py b/third_party/blink/tools/blinkpy/web_tests/port/linux.py index 2c6f93a1..00568b2e 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/linux.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/linux.py
@@ -82,6 +82,11 @@ ] return flags + def configuration_specifier_macros(self): + if self.flag_specific_config_name(): + return {self.port_name: list(self.SUPPORTED_VERSIONS)} + return super().configuration_specifier_macros() + def check_build(self, needs_http, printer): result = super(LinuxPort, self).check_build(needs_http, printer)
diff --git a/third_party/blink/web_tests/ASANExpectations b/third_party/blink/web_tests/ASANExpectations index 6c76b821..9f495421d 100644 --- a/third_party/blink/web_tests/ASANExpectations +++ b/third_party/blink/web_tests/ASANExpectations
@@ -21,7 +21,7 @@ # ==17332== ERROR: AddressSanitizer: heap-use-after-free on address 0x7f48e8a05a58 # WRITE of size 1 at 0x7f48e8a05a58 thread T0 # #0 0x7f48eb06f7c5 in DocumentOpenInDestroyStream::NPP_DestroyStream -crbug.com/166932 [ Linux ] plugins/embed-attributes-setting.html [ Skip ] +crbug.com/166932 [ Linux ] ppapi/plugins/embed-attributes-setting.html [ Skip ] crbug.com/166932 [ Linux ] plugins/embed-attributes-style.html [ Skip ] # Stack use-after-return detection
diff --git a/third_party/blink/web_tests/ChromeTestExpectations b/third_party/blink/web_tests/ChromeTestExpectations index eab008d..10abf29 100644 --- a/third_party/blink/web_tests/ChromeTestExpectations +++ b/third_party/blink/web_tests/ChromeTestExpectations
@@ -33,10 +33,8 @@ crbug.com/1499775 external/wpt/css/css-text/text-transform/text-transform-capitalize-014.html [ Failure Pass ] crbug.com/1499775 external/wpt/html/semantics/forms/the-selectlist-element/selectlist-option-arbitrary-content-not-displayed.tentative.html [ Failure Pass ] crbug.com/1499775 external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-base-url-2.html [ Failure ] -crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-button-border-left-color-001.html [ Failure ] crbug.com/1499775 external/wpt/editing/other/join-pre-and-other-block.html?method=forwarddelete&block=blockquote [ Timeout ] crbug.com/1499775 external/wpt/editing/other/join-pre-and-other-block.html?method=forwarddelete&block=p [ Pass Timeout ] -crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-inline-start-color-001.html [ Failure ] crbug.com/1499775 external/wpt/document-policy/font-display/override-to-optional.tentative.html [ Failure ] crbug.com/1499775 external/wpt/css/css-layout-api/fallback-layout/constructor-error.https.html [ Failure ] crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-block-position-drop-over-ruby.html [ Failure ] @@ -53,6 +51,7 @@ crbug.com/1499775 external/wpt/css/css-images/object-view-box-fit-fill-img.html [ Failure ] crbug.com/1499775 external/wpt/css/css-inline/initial-letter/initial-letter-with-tab.html [ Failure ] crbug.com/1499775 external/wpt/css/css-layout-api/fallback-intrinsic-sizes/constructor-error.https.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-masking/clip-path/clip-path-inline-002.html [ Failure Pass ] crbug.com/1499775 external/wpt/css/css-masking/clip-path/clip-path-inline-003.html [ Failure ] crbug.com/1499775 external/wpt/css/css-overflow/scrollable-overflow-input-001.html [ Failure ] crbug.com/1499775 external/wpt/css/css-overflow/scrollable-overflow-input-002.html [ Failure ] @@ -64,6 +63,10 @@ crbug.com/1499775 external/wpt/css/css-pseudo/highlight-painting-004.html [ Failure ] crbug.com/1499775 external/wpt/css/css-ruby/ruby-text-combine-upright-002a.html [ Failure ] crbug.com/1499775 external/wpt/css/css-shapes/shape-outside/values/shape-outside-ellipse-004.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] # Reftest image failure +crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-button-border-left-color-001.html [ Failure ] +crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-border-left-color-001.html [ Failure Pass ] +crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-generated/kind-of-widget-fallback-input-search-text-border-inline-start-color-001.html [ Failure ] crbug.com/1499775 external/wpt/css/printing/input-file-print.html [ Failure ] crbug.com/1499775 external/wpt/mathml/presentation-markup/operators/operator-dictionary-arabic-002.html [ Failure ] crbug.com/1499775 external/wpt/svg/linking/reftests/view-viewbox-override.html [ Failure ] @@ -234,7 +237,6 @@ crbug.com/1499775 external/wpt/css/css-transforms/backface-visibility-001.html [ Failure ] # Reftest image failure crbug.com/1499775 external/wpt/css/css-transforms/backface-visibility-hidden-animated-002.html [ Failure ] # Reftest image failure crbug.com/1499775 external/wpt/css/css-transforms/ttwf-css-3d-polygon-cycle.html [ Failure ] # Reftest image failure -crbug.com/1499775 external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html [ Failure ] # Reftest image failure crbug.com/1499775 external/wpt/css/css-ui/text-overflow-027.html [ Failure ] # Reftest image failure crbug.com/1499775 external/wpt/css/css-ui/text-overflow-028.html [ Failure ] # Reftest image failure crbug.com/1499775 external/wpt/css/css-will-change/will-change-transform-zero-size-child-overflow-visible.html [ Failure ] # Reftest image failure
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 2d93e08..5a8f916 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -714,7 +714,7 @@ crbug.com/874695 paint/invalidation/filters/filter-repaint-accelerated-child-with-filter-child.html [ Slow ] crbug.com/874695 paint/invalidation/filters/filter-repaint-accelerated-on-accelerated-filter.html [ Slow ] crbug.com/874695 paint/invalidation/filters/filter-repaint-on-accelerated-layer.html [ Slow ] -crbug.com/874695 plugins/plugin-document-back-forward.html [ Slow ] +crbug.com/874695 ppapi/plugins/plugin-document-back-forward.html [ Slow ] crbug.com/874695 pointer-lock/locked-element-iframe-removed-from-dom.html [ Slow ] crbug.com/874695 [ Debug Linux ] printing/webgl-oversized-printing.html [ Slow ] crbug.com/874695 [ Linux Release ] printing/webgl-oversized-printing.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b4b443b0..b6a983e 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1,4 +1,4 @@ -# tags: [ Chrome Fuchsia Linux Mac Mac10.15 Mac11 Mac11-arm64 Mac12 Mac12-arm64 Mac13 Mac13-arm64 Win Win10.20h2 Win11 Win11-arm64 iOS16-simulator] +# tags: [ Fuchsia Linux Mac Mac10.15 Mac11 Mac11-arm64 Mac12 Mac12-arm64 Mac13 Mac13-arm64 Win Win10.20h2 Win11 Win11-arm64 iOS16-simulator ] # tags: [ Release Debug ] # results: [ Timeout Crash Pass Failure Skip ] @@ -3365,7 +3365,6 @@ crbug.com/626703 external/wpt/css/css-will-change/will-change-abspos-cb-001.html [ Failure ] crbug.com/892337 external/wpt/resource-timing/content-type-parsing.html [ Failure Timeout ] -crbug.com/1147998 external/wpt/pointerevents/pointerevent_after_target_appended.html?mouse [ Failure Timeout ] crbug.com/1147674 external/wpt/pointerevents/pointerevent_after_target_appended.html?pen [ Failure Timeout ] crbug.com/1147674 external/wpt/pointerevents/pointerevent_after_target_appended.html?touch [ Failure Timeout ] crbug.com/1147674 external/wpt/pointerevents/pointerevent_after_target_removed.html?pen [ Failure ] @@ -3739,9 +3738,9 @@ crbug.com/930297 external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html?include=workers [ Skip Timeout ] crbug.com/676229 plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ] -crbug.com/742670 plugins/iframe-plugin-bgcolor.html [ Failure Pass ] +crbug.com/742670 ppapi/plugins/iframe-plugin-bgcolor.html [ Failure Pass ] crbug.com/780398 [ Mac ] plugins/mouse-capture-inside-shadow.html [ Failure Pass ] -crbug.com/1331239 [ Mac ] plugins/plugin-remove-subframe.html [ Crash Pass ] +crbug.com/1331239 [ Mac ] ppapi/plugins/plugin-remove-subframe.html [ Crash Pass ] crbug.com/678493 http/tests/permissions/chromium/test-request-window.html [ Pass Timeout ] @@ -5059,7 +5058,7 @@ crbug.com/1223601 [ Linux ] fast/scrolling/reset-scroll-in-onscroll.html [ Failure Pass ] # Sheriff 2021-06-29 -crbug.com/1197464 [ Mac ] plugins/refcount-leaks.html [ Failure Pass ] +crbug.com/1197464 [ Mac ] ppapi/plugins/refcount-leaks.html [ Failure Pass ] # Sheriff 2021-07-12 crbug.com/1228432 [ Linux ] external/wpt/video-rvfc/request-video-frame-callback-before-xr-session.https.html [ Pass Timeout ] @@ -5324,7 +5323,8 @@ # Sheriff 2021-11-29 crbug.com/1274458 external/wpt/audio-output/selectAudioOutput-permissions-policy.https.sub.html [ Failure Pass ] -crbug.com/1239485 [ Mac Release ] fast/frames/iframe-plugin-load-remove-document-crash.html [ Failure Pass ] +crbug.com/1239485 [ Mac Release ] ppapi/fast/frames/iframe-plugin-load-remove-document-crash.html [ Failure Pass ] +crbug.com/1239485 [ Mac Release ] ppapi/plugins/plugin-scroll.html [ Failure Pass ] # Sheriff 2021-12-01 crbug.com/1275658 http/tests/misc/script-after-slow-stylesheet-removed.html [ Failure Pass ] @@ -5342,7 +5342,7 @@ # Sheriff 2021-12-21 crbug.com/1281792 external/wpt/event-timing/min-duration-threshold.html [ Failure Pass ] -crbug.com/1285857 plugins/plugin-destroyed-enumerate.html [ Failure Pass ] +crbug.com/1285857 ppapi/plugins/plugin-destroyed-enumerate.html [ Failure Pass ] # Sheriff 2021-12-22 crbug.com/1283295 [ Mac ] fast/text-autosizing/hackernews-comments.html [ Failure Pass ] @@ -5458,7 +5458,7 @@ crbug.com/1312164 webaudio/internals/audiocontext-gc.html [ Failure Skip ] # Sheriff 2022-03-21: More flaky tests. -crbug.com/1450306 [ Mac ] plugins/plugin-document-back-forward.html [ Failure Pass ] +crbug.com/1450306 [ Mac ] ppapi/plugins/plugin-document-back-forward.html [ Failure Pass ] # Tests that need updates due to rounding math in layout crbug.com/1309975 http/tests/devtools/console/console-viewport-indices.js [ Failure ] @@ -5702,7 +5702,7 @@ crbug.com/1358333 [ Mac ] external/wpt/webmessaging/event.origin.sub.htm [ Failure Pass ] # Sheriff 2022-08-31 -crbug.com/1306304 [ Mac ] plugins/multiple-plugins.html [ Failure Pass ] +crbug.com/1306304 [ Mac ] ppapi/plugins/multiple-plugins.html [ Failure Pass ] # Sheriff 2022-09-06 crbug.com/1358298 external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ] @@ -6450,7 +6450,7 @@ crbug.com/webrtc/14889 external/wpt/webrtc/simulcast/vp9.https.html [ Skip Timeout ] #Sheriff 2023-02-21 -crbug.com/1308826 fast/loader/reload-zero-byte-plugin.html [ Failure Pass Timeout ] +crbug.com/1308826 ppapi/fast/loader/reload-zero-byte-plugin.html [ Failure Pass Timeout ] # Sheriff 2023-03-23 crbug.com/952717 [ Win10.20h2 ] http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/TestLists/Default.txt b/third_party/blink/web_tests/TestLists/Default.txt index 7eb980df..00d3b91 100644 --- a/third_party/blink/web_tests/TestLists/Default.txt +++ b/third_party/blink/web_tests/TestLists/Default.txt
@@ -830,7 +830,6 @@ paint/selection/selection-drag-image-in-iframe.html payments/payment-request-in-iframe-allowed.html permissionclient/storage-permission.html -plugins/instance-available-before-stylesheets-loaded.html pointer-lock/lock-already-locked.html pointer-lock/mouse-event-api.html pointer-lock/pointerlockelement-null-when-pending.html
diff --git a/third_party/blink/web_tests/TestLists/MacOld.txt b/third_party/blink/web_tests/TestLists/MacOld.txt index bcf03dc..7cc8050 100644 --- a/third_party/blink/web_tests/TestLists/MacOld.txt +++ b/third_party/blink/web_tests/TestLists/MacOld.txt
@@ -62,7 +62,6 @@ http/tests/navigation/location-change-repeated-from-blank.html inspector-protocol/layout-fonts/lang-fallback.js media/controls/doubletap-to-toggle-fullscreen.html -plugins/refcount-leaks.html scrollbars/custom-scrollbar-thumb-width-changed-on-inactive-pseudo.html scrollbars/hidden-scrollbars-invisible.html tables/mozilla_expected_failures/bugs/bug89315.html
diff --git a/third_party/blink/web_tests/TestLists/ppapi b/third_party/blink/web_tests/TestLists/ppapi new file mode 100644 index 0000000..b5cca1a4 --- /dev/null +++ b/third_party/blink/web_tests/TestLists/ppapi
@@ -0,0 +1,2 @@ +http/tests/security/mixedContent/insecure-plugin-in-iframe.html +ppapi/ \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/historical.https-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/historical.https-expected.txt index 15d817e..4e77d4d 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/historical.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/FileAPI/historical.https-expected.txt
@@ -1,17 +1,5 @@ This is a testharness.js-based test. -[PASS] "toNativeLineEndings" should not be supported -[PASS] "FileError" should not be supported -[PASS] "FileException" should not be supported -[PASS] "FileHandle" should not be supported -[PASS] "FileRequest" should not be supported -[PASS] "MutableFile" should not be supported -[PASS] Blob should not support slice prefixed -[PASS] BlobBuilder should not be supported. -[PASS] createFor method should not be supported -[PASS] Blob.close() should not be supported [FAIL] File's lastModifiedDate should not be supported assert_false: expected false got true -[PASS] Service worker test setup -[PASS] "FileReaderSync" should not be supported in service workers Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any-expected.txt index f2b00a5..b9adde79 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any-expected.txt
@@ -1,6 +1,5 @@ This is a testharness.js-based test. [FAIL] events are dispatched in the correct order for an empty blob assert_equals: Expected load event, but got progress event instead expected "load" but got "progress" -[PASS] events are dispatched in the correct order for a non-empty blob Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any.worker-expected.txt index f2b00a5..b9adde79 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/FileAPI/reading-data-section/filereader_events.any.worker-expected.txt
@@ -1,6 +1,5 @@ This is a testharness.js-based test. [FAIL] events are dispatched in the correct order for an empty blob assert_equals: Expected load event, but got progress event instead expected "load" but got "progress" -[PASS] events are dispatched in the correct order for a non-empty blob Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt index cb43067..44409cd 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt +++ b/third_party/blink/web_tests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt
@@ -1,47 +1,13 @@ This is a testharness.js-based test. -[PASS] Generated Blob URLs are unique -[PASS] Blob URL starts with "blob:" -[PASS] Blob URL starts with "blob:" for Files -[PASS] Origin of Blob URL matches our origin -[PASS] Blob URL parses correctly -[PASS] Origin of Blob URL matches our origin for Files -[PASS] Blob URLs can be used in <script> tags [FAIL] Blob URLs can be used in iframes, and are treated same origin Failed to read a named property 'test_result' from 'Window': Blocked a frame with origin "null" from accessing a cross-origin frame. [FAIL] Blob URL fragment is implemented. Failed to set a named property 'onscroll' on 'Window': Blocked a frame with origin "null" from accessing a cross-origin frame. -[PASS] Blob URLs can be used in XHR -[PASS] XHR with a fragment should succeed -[PASS] XHR of a revoked URL should fail -[PASS] Only exact matches should revoke URLs, using XHR -[PASS] Appending a query string should cause XHR to fail -[PASS] Appending a path should cause XHR to fail -[PASS] XHR with method "HEAD" should fail -[PASS] XHR with method "POST" should fail -[PASS] XHR with method "DELETE" should fail -[PASS] XHR with method "OPTIONS" should fail -[PASS] XHR with method "PUT" should fail -[PASS] XHR with method "CUSTOM" should fail -[PASS] XHR should return Content-Type from Blob [FAIL] Revoke blob URL after open(), will fetch assert_unreached: Got unexpected error event Reached unreachable code -[PASS] Blob URLs can be used in fetch -[PASS] fetch with a fragment should succeed -[PASS] fetch of a revoked URL should fail -[PASS] Only exact matches should revoke URLs, using fetch -[PASS] Appending a query string should cause fetch to fail -[PASS] Appending a path should cause fetch to fail -[PASS] fetch with method "HEAD" should fail -[PASS] fetch with method "POST" should fail -[PASS] fetch with method "DELETE" should fail -[PASS] fetch with method "OPTIONS" should fail -[PASS] fetch with method "PUT" should fail -[PASS] fetch with method "CUSTOM" should fail -[PASS] fetch should return Content-Type from Blob [FAIL] Revoke blob URL after creating Request, will fetch promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch" [FAIL] Revoke blob URL after creating Request, then clone Request, will fetch promise_test: Unhandled rejection with value: object "ReferenceError: garbageCollect is not defined" -[PASS] Revoke blob URL after calling fetch, fetch should succeed Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/url/url-reload.window-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/url/url-reload.window-expected.txt index 40b3339..a7c84080 100644 --- a/third_party/blink/web_tests/external/wpt/FileAPI/url/url-reload.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/FileAPI/url/url-reload.window-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -[PASS] Reloading a blob URL succeeds. [FAIL] Reloading a blob URL succeeds even if the URL was revoked. Failed to read a named property 'test_result' from 'Window': Blocked a frame with origin "http://web-platform.test:8001" from accessing a cross-origin frame. Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt index c0204752..6c24f78f 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any-expected.txt
@@ -1,11 +1,4 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] X25519 key derivation checks for all-zero value result with a key of order 0 -[PASS] X25519 key derivation checks for all-zero value result with a key of order 1 -[PASS] X25519 key derivation checks for all-zero value result with a key of order 8 -[PASS] X25519 key derivation checks for all-zero value result with a key of order p-1 (order 2) -[PASS] X25519 key derivation checks for all-zero value result with a key of order p (=0, order 4) -[PASS] X25519 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) [FAIL] X448 key derivation checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true [FAIL] X448 key derivation checks for all-zero value result with a key of order 1 @@ -16,20 +9,8 @@ assert_false: Private key should be valid. expected false got true [FAIL] X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true -[PASS] X25519 good parameters -[PASS] X25519 mixed case parameters -[PASS] X25519 with null length -[PASS] X25519 short result -[PASS] X25519 non-multiple of 8 bits -[PASS] X25519 missing public property -[PASS] X25519 public property of algorithm is not a CryptoKey [FAIL] X25519 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': EcdhKeyDeriveParams: public: Must be a CryptoKey expected "InvalidAccessError" but got "TypeError" -[PASS] X25519 no deriveBits usage for base key -[PASS] X25519 base key is not a private key -[PASS] X25519 public property value is a private key -[PASS] X25519 public property value is a secret key -[PASS] X25519 asking for too many bits [FAIL] X448 good parameters assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 mixed case parameters @@ -40,8 +21,6 @@ assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 non-multiple of 8 bits assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code -[PASS] X448 missing public property -[PASS] X448 public property of algorithm is not a CryptoKey [FAIL] X448 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. expected "InvalidAccessError" but got "TypeError" [FAIL] X448 no deriveBits usage for base key
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt index c0204752..6c24f78f 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.worker-expected.txt
@@ -1,11 +1,4 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] X25519 key derivation checks for all-zero value result with a key of order 0 -[PASS] X25519 key derivation checks for all-zero value result with a key of order 1 -[PASS] X25519 key derivation checks for all-zero value result with a key of order 8 -[PASS] X25519 key derivation checks for all-zero value result with a key of order p-1 (order 2) -[PASS] X25519 key derivation checks for all-zero value result with a key of order p (=0, order 4) -[PASS] X25519 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) [FAIL] X448 key derivation checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true [FAIL] X448 key derivation checks for all-zero value result with a key of order 1 @@ -16,20 +9,8 @@ assert_false: Private key should be valid. expected false got true [FAIL] X448 key derivation checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true -[PASS] X25519 good parameters -[PASS] X25519 mixed case parameters -[PASS] X25519 with null length -[PASS] X25519 short result -[PASS] X25519 non-multiple of 8 bits -[PASS] X25519 missing public property -[PASS] X25519 public property of algorithm is not a CryptoKey [FAIL] X25519 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': EcdhKeyDeriveParams: public: Must be a CryptoKey expected "InvalidAccessError" but got "TypeError" -[PASS] X25519 no deriveBits usage for base key -[PASS] X25519 base key is not a private key -[PASS] X25519 public property value is a private key -[PASS] X25519 public property value is a secret key -[PASS] X25519 asking for too many bits [FAIL] X448 good parameters assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 mixed case parameters @@ -40,8 +21,6 @@ assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 non-multiple of 8 bits assert_unreached: deriveBits failed with error TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code -[PASS] X448 missing public property -[PASS] X448 public property of algorithm is not a CryptoKey [FAIL] X448 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveBits' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. expected "InvalidAccessError" but got "TypeError" [FAIL] X448 no deriveBits usage for base key
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt index 7916a9c1..e55f422 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any-expected.txt
@@ -1,11 +1,4 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 0 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 1 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 8 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p-1 (order 2) -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p (=0, order 4) -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) [FAIL] X448 deriveBits checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true [FAIL] X448 deriveBits checks for all-zero value result with a key of order 1 @@ -16,25 +9,14 @@ assert_false: Private key should be valid. expected false got true [FAIL] X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true -[PASS] Key derivation using a X25519 generated keys. [FAIL] Key derivation using a X448 generated keys. assert_unreached: Threw an unexpected error: NotSupportedError: Failed to execute 'generateKey' on 'SubtleCrypto': Algorithm: Unrecognized name - Reached unreachable code -[PASS] X25519 good parameters -[PASS] X25519 mixed case parameters -[PASS] X25519 missing public property -[PASS] X25519 public property of algorithm is not a CryptoKey [FAIL] X25519 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': EcdhKeyDeriveParams: public: Must be a CryptoKey expected "InvalidAccessError" but got "TypeError" -[PASS] X25519 no deriveKey usage for base key -[PASS] X25519 base key is not a private key -[PASS] X25519 public property value is a private key -[PASS] X25519 public property value is a secret key [FAIL] X448 good parameters assert_unreached: deriveKey failed with error TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 mixed case parameters assert_unreached: deriveKey failed with error TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code -[PASS] X448 missing public property -[PASS] X448 public property of algorithm is not a CryptoKey [FAIL] X448 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. expected "InvalidAccessError" but got "TypeError" [FAIL] X448 no deriveKey usage for base key
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt index 7916a9c1..e55f422 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.worker-expected.txt
@@ -1,11 +1,4 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 0 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 1 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order 8 -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p-1 (order 2) -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p (=0, order 4) -[PASS] X25519 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) [FAIL] X448 deriveBits checks for all-zero value result with a key of order 0 assert_false: Private key should be valid. expected false got true [FAIL] X448 deriveBits checks for all-zero value result with a key of order 1 @@ -16,25 +9,14 @@ assert_false: Private key should be valid. expected false got true [FAIL] X448 deriveBits checks for all-zero value result with a key of order p+1 (=1, order 1) assert_false: Private key should be valid. expected false got true -[PASS] Key derivation using a X25519 generated keys. [FAIL] Key derivation using a X448 generated keys. assert_unreached: Threw an unexpected error: NotSupportedError: Failed to execute 'generateKey' on 'SubtleCrypto': Algorithm: Unrecognized name - Reached unreachable code -[PASS] X25519 good parameters -[PASS] X25519 mixed case parameters -[PASS] X25519 missing public property -[PASS] X25519 public property of algorithm is not a CryptoKey [FAIL] X25519 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': EcdhKeyDeriveParams: public: Must be a CryptoKey expected "InvalidAccessError" but got "TypeError" -[PASS] X25519 no deriveKey usage for base key -[PASS] X25519 base key is not a private key -[PASS] X25519 public property value is a private key -[PASS] X25519 public property value is a secret key [FAIL] X448 good parameters assert_unreached: deriveKey failed with error TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code [FAIL] X448 mixed case parameters assert_unreached: deriveKey failed with error TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. Reached unreachable code -[PASS] X448 missing public property -[PASS] X448 public property of algorithm is not a CryptoKey [FAIL] X448 mismatched algorithms assert_equals: Should throw correct error, not TypeError: Failed to execute 'deriveKey' on 'SubtleCrypto': parameter 2 is not of type 'CryptoKey'. expected "InvalidAccessError" but got "TypeError" [FAIL] X448 no deriveKey usage for base key
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any-expected.txt index 6ca1541..1714d0cd 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any-expected.txt
@@ -1,49 +1,9 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] P-521 good parameters -[PASS] P-521 mixed case parameters [FAIL] P-521 with null length assert_true: Derived correct bits expected true got false -[PASS] P-521 short result -[PASS] P-521 non-multiple of 8 bits -[PASS] P-521 missing public curve -[PASS] P-521 public property of algorithm is not a CryptoKey -[PASS] P-521 mismatched curves -[PASS] P-521 public property of algorithm is not an ECDSA public key -[PASS] P-521 no deriveBits usage for base key -[PASS] P-521 base key is not a private key -[PASS] P-521 public property value is a private key -[PASS] P-521 public property value is a secret key -[PASS] P-521 asking for too many bits -[PASS] P-256 good parameters -[PASS] P-256 mixed case parameters [FAIL] P-256 with null length assert_true: Derived correct bits expected true got false -[PASS] P-256 short result -[PASS] P-256 non-multiple of 8 bits -[PASS] P-256 missing public curve -[PASS] P-256 public property of algorithm is not a CryptoKey -[PASS] P-256 mismatched curves -[PASS] P-256 public property of algorithm is not an ECDSA public key -[PASS] P-256 no deriveBits usage for base key -[PASS] P-256 base key is not a private key -[PASS] P-256 public property value is a private key -[PASS] P-256 public property value is a secret key -[PASS] P-256 asking for too many bits -[PASS] P-384 good parameters -[PASS] P-384 mixed case parameters [FAIL] P-384 with null length assert_true: Derived correct bits expected true got false -[PASS] P-384 short result -[PASS] P-384 non-multiple of 8 bits -[PASS] P-384 missing public curve -[PASS] P-384 public property of algorithm is not a CryptoKey -[PASS] P-384 mismatched curves -[PASS] P-384 public property of algorithm is not an ECDSA public key -[PASS] P-384 no deriveBits usage for base key -[PASS] P-384 base key is not a private key -[PASS] P-384 public property value is a private key -[PASS] P-384 public property value is a secret key -[PASS] P-384 asking for too many bits Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.worker-expected.txt index 6ca1541..1714d0cd 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/ecdh_bits.https.any.worker-expected.txt
@@ -1,49 +1,9 @@ This is a testharness.js-based test. -[PASS] setup - define tests -[PASS] P-521 good parameters -[PASS] P-521 mixed case parameters [FAIL] P-521 with null length assert_true: Derived correct bits expected true got false -[PASS] P-521 short result -[PASS] P-521 non-multiple of 8 bits -[PASS] P-521 missing public curve -[PASS] P-521 public property of algorithm is not a CryptoKey -[PASS] P-521 mismatched curves -[PASS] P-521 public property of algorithm is not an ECDSA public key -[PASS] P-521 no deriveBits usage for base key -[PASS] P-521 base key is not a private key -[PASS] P-521 public property value is a private key -[PASS] P-521 public property value is a secret key -[PASS] P-521 asking for too many bits -[PASS] P-256 good parameters -[PASS] P-256 mixed case parameters [FAIL] P-256 with null length assert_true: Derived correct bits expected true got false -[PASS] P-256 short result -[PASS] P-256 non-multiple of 8 bits -[PASS] P-256 missing public curve -[PASS] P-256 public property of algorithm is not a CryptoKey -[PASS] P-256 mismatched curves -[PASS] P-256 public property of algorithm is not an ECDSA public key -[PASS] P-256 no deriveBits usage for base key -[PASS] P-256 base key is not a private key -[PASS] P-256 public property value is a private key -[PASS] P-256 public property value is a secret key -[PASS] P-256 asking for too many bits -[PASS] P-384 good parameters -[PASS] P-384 mixed case parameters [FAIL] P-384 with null length assert_true: Derived correct bits expected true got false -[PASS] P-384 short result -[PASS] P-384 non-multiple of 8 bits -[PASS] P-384 missing public curve -[PASS] P-384 public property of algorithm is not a CryptoKey -[PASS] P-384 mismatched curves -[PASS] P-384 public property of algorithm is not an ECDSA public key -[PASS] P-384 no deriveBits usage for base key -[PASS] P-384 base key is not a private key -[PASS] P-384 public property value is a private key -[PASS] P-384 public property value is a secret key -[PASS] P-384 asking for too many bits Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1-1000-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1-1000-expected.txt index 77a9f7cb..724bd093 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1-1000-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1-1000-expected.txt
@@ -1,1071 +1,136 @@ This is a testharness.js-based test. -Found 1001 tests; 935 PASS, 66 FAIL, 0 TIMEOUT, 0 NOTRUN. -[PASS] setup - define tests -[PASS] short derivedKey, normal salt, SHA-384, with normal info -[PASS] short derivedKey, normal salt, SHA-384, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key +Found 66 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-384, with normal info with missing salt -[PASS] short derivedKey, normal salt, SHA-384, with normal info with missing info [FAIL] short derivedKey, normal salt, SHA-384, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-384, with normal info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] short derivedKey, normal salt, SHA-384, with normal info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-384, with empty info -[PASS] short derivedKey, normal salt, SHA-384, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-384, with empty info with missing salt -[PASS] short derivedKey, normal salt, SHA-384, with empty info with missing info [FAIL] short derivedKey, normal salt, SHA-384, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-384, with empty info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] short derivedKey, normal salt, SHA-384, with empty info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-512, with normal info -[PASS] short derivedKey, normal salt, SHA-512, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-512, with normal info with missing salt -[PASS] short derivedKey, normal salt, SHA-512, with normal info with missing info [FAIL] short derivedKey, normal salt, SHA-512, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-512, with normal info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] short derivedKey, normal salt, SHA-512, with normal info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-512, with empty info -[PASS] short derivedKey, normal salt, SHA-512, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-512, with empty info with missing salt -[PASS] short derivedKey, normal salt, SHA-512, with empty info with missing info [FAIL] short derivedKey, normal salt, SHA-512, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-512, with empty info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] short derivedKey, normal salt, SHA-512, with empty info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-1, with normal info -[PASS] short derivedKey, normal salt, SHA-1, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-1, with normal info with missing salt -[PASS] short derivedKey, normal salt, SHA-1, with normal info with missing info [FAIL] short derivedKey, normal salt, SHA-1, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-1, with normal info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] short derivedKey, normal salt, SHA-1, with normal info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-1, with empty info -[PASS] short derivedKey, normal salt, SHA-1, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-1, with empty info with missing salt -[PASS] short derivedKey, normal salt, SHA-1, with empty info with missing info [FAIL] short derivedKey, normal salt, SHA-1, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-1, with empty info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] short derivedKey, normal salt, SHA-1, with empty info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-256, with normal info -[PASS] short derivedKey, normal salt, SHA-256, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-256, with normal info with missing salt -[PASS] short derivedKey, normal salt, SHA-256, with normal info with missing info [FAIL] short derivedKey, normal salt, SHA-256, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-256, with normal info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] short derivedKey, normal salt, SHA-256, with normal info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-256, with empty info -[PASS] short derivedKey, normal salt, SHA-256, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, SHA-256, with empty info with missing salt -[PASS] short derivedKey, normal salt, SHA-256, with empty info with missing info [FAIL] short derivedKey, normal salt, SHA-256, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, normal salt, SHA-256, with empty info with non-multiple of 8 length -[PASS] short derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] short derivedKey, normal salt, SHA-256, with empty info with missing deriveBits usage -[PASS] short derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] short derivedKey, normal salt, PBKDF2, with normal info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, PBKDF2, with normal info -[PASS] short derivedKey, normal salt, PBKDF2, with empty info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, normal salt, PBKDF2, with empty info -[PASS] short derivedKey, empty salt, SHA-384, with normal info -[PASS] short derivedKey, empty salt, SHA-384, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-384, with normal info with missing salt -[PASS] short derivedKey, empty salt, SHA-384, with normal info with missing info [FAIL] short derivedKey, empty salt, SHA-384, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-384, with normal info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] short derivedKey, empty salt, SHA-384, with normal info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-384, with empty info -[PASS] short derivedKey, empty salt, SHA-384, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-384, with empty info with missing salt -[PASS] short derivedKey, empty salt, SHA-384, with empty info with missing info [FAIL] short derivedKey, empty salt, SHA-384, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-384, with empty info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] short derivedKey, empty salt, SHA-384, with empty info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-512, with normal info -[PASS] short derivedKey, empty salt, SHA-512, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-512, with normal info with missing salt -[PASS] short derivedKey, empty salt, SHA-512, with normal info with missing info [FAIL] short derivedKey, empty salt, SHA-512, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-512, with normal info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] short derivedKey, empty salt, SHA-512, with normal info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-512, with empty info -[PASS] short derivedKey, empty salt, SHA-512, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-512, with empty info with missing salt -[PASS] short derivedKey, empty salt, SHA-512, with empty info with missing info [FAIL] short derivedKey, empty salt, SHA-512, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-512, with empty info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] short derivedKey, empty salt, SHA-512, with empty info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-1, with normal info -[PASS] short derivedKey, empty salt, SHA-1, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-1, with normal info with missing salt -[PASS] short derivedKey, empty salt, SHA-1, with normal info with missing info [FAIL] short derivedKey, empty salt, SHA-1, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-1, with normal info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] short derivedKey, empty salt, SHA-1, with normal info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-1, with empty info -[PASS] short derivedKey, empty salt, SHA-1, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1001-2000-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1001-2000-expected.txt index 0697c161..11d046d 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1001-2000-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_1001-2000-expected.txt
@@ -1,1069 +1,132 @@ This is a testharness.js-based test. -Found 1001 tests; 937 PASS, 64 FAIL, 0 TIMEOUT, 0 NOTRUN. -[PASS] setup - define tests -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key +Found 64 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-1, with empty info with missing salt -[PASS] short derivedKey, empty salt, SHA-1, with empty info with missing info [FAIL] short derivedKey, empty salt, SHA-1, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-1, with empty info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] short derivedKey, empty salt, SHA-1, with empty info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-256, with normal info -[PASS] short derivedKey, empty salt, SHA-256, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-256, with normal info with missing salt -[PASS] short derivedKey, empty salt, SHA-256, with normal info with missing info [FAIL] short derivedKey, empty salt, SHA-256, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-256, with normal info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] short derivedKey, empty salt, SHA-256, with normal info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-256, with empty info -[PASS] short derivedKey, empty salt, SHA-256, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, SHA-256, with empty info with missing salt -[PASS] short derivedKey, empty salt, SHA-256, with empty info with missing info [FAIL] short derivedKey, empty salt, SHA-256, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] short derivedKey, empty salt, SHA-256, with empty info with non-multiple of 8 length -[PASS] short derivedKey, empty salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] short derivedKey, empty salt, SHA-256, with empty info with missing deriveBits usage -[PASS] short derivedKey, empty salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] short derivedKey, empty salt, PBKDF2, with normal info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, PBKDF2, with normal info -[PASS] short derivedKey, empty salt, PBKDF2, with empty info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 192 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 192 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 192 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 192 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using short derivedKey, empty salt, PBKDF2, with empty info -[PASS] long derivedKey, normal salt, SHA-384, with normal info -[PASS] long derivedKey, normal salt, SHA-384, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-384, with normal info with missing salt -[PASS] long derivedKey, normal salt, SHA-384, with normal info with missing info [FAIL] long derivedKey, normal salt, SHA-384, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-384, with normal info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] long derivedKey, normal salt, SHA-384, with normal info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-384, with empty info -[PASS] long derivedKey, normal salt, SHA-384, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-384, with empty info with missing salt -[PASS] long derivedKey, normal salt, SHA-384, with empty info with missing info [FAIL] long derivedKey, normal salt, SHA-384, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-384, with empty info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] long derivedKey, normal salt, SHA-384, with empty info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-512, with normal info -[PASS] long derivedKey, normal salt, SHA-512, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-512, with normal info with missing salt -[PASS] long derivedKey, normal salt, SHA-512, with normal info with missing info [FAIL] long derivedKey, normal salt, SHA-512, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-512, with normal info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] long derivedKey, normal salt, SHA-512, with normal info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-512, with empty info -[PASS] long derivedKey, normal salt, SHA-512, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-512, with empty info with missing salt -[PASS] long derivedKey, normal salt, SHA-512, with empty info with missing info [FAIL] long derivedKey, normal salt, SHA-512, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-512, with empty info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-512, with empty info with bad hash name SHA512 -[PASS] long derivedKey, normal salt, SHA-512, with empty info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-512, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-1, with normal info -[PASS] long derivedKey, normal salt, SHA-1, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-1, with normal info with missing salt -[PASS] long derivedKey, normal salt, SHA-1, with normal info with missing info [FAIL] long derivedKey, normal salt, SHA-1, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-1, with normal info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-1, with normal info with bad hash name SHA1 -[PASS] long derivedKey, normal salt, SHA-1, with normal info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-1, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-1, with empty info -[PASS] long derivedKey, normal salt, SHA-1, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-1, with empty info with missing salt -[PASS] long derivedKey, normal salt, SHA-1, with empty info with missing info [FAIL] long derivedKey, normal salt, SHA-1, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-1, with empty info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-1, with empty info with bad hash name SHA1 -[PASS] long derivedKey, normal salt, SHA-1, with empty info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-1, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-256, with normal info -[PASS] long derivedKey, normal salt, SHA-256, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-256, with normal info with missing salt -[PASS] long derivedKey, normal salt, SHA-256, with normal info with missing info [FAIL] long derivedKey, normal salt, SHA-256, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-256, with normal info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-256, with normal info with bad hash name SHA256 -[PASS] long derivedKey, normal salt, SHA-256, with normal info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-256, with normal info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-256, with empty info -[PASS] long derivedKey, normal salt, SHA-256, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, SHA-256, with empty info with missing salt -[PASS] long derivedKey, normal salt, SHA-256, with empty info with missing info [FAIL] long derivedKey, normal salt, SHA-256, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, normal salt, SHA-256, with empty info with non-multiple of 8 length -[PASS] long derivedKey, normal salt, SHA-256, with empty info with bad hash name SHA256 -[PASS] long derivedKey, normal salt, SHA-256, with empty info with missing deriveBits usage -[PASS] long derivedKey, normal salt, SHA-256, with empty info with wrong (ECDH) key -[PASS] long derivedKey, normal salt, PBKDF2, with normal info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, PBKDF2, with normal info -[PASS] long derivedKey, normal salt, PBKDF2, with empty info with non-digest algorithm PBKDF2 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, normal salt, PBKDF2, with empty info -[PASS] long derivedKey, empty salt, SHA-384, with normal info -[PASS] long derivedKey, empty salt, SHA-384, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with normal info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] long derivedKey, empty salt, SHA-384, with normal info with missing salt -[PASS] long derivedKey, empty salt, SHA-384, with normal info with missing info [FAIL] long derivedKey, empty salt, SHA-384, with normal info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, empty salt, SHA-384, with normal info with non-multiple of 8 length -[PASS] long derivedKey, empty salt, SHA-384, with normal info with bad hash name SHA384 -[PASS] long derivedKey, empty salt, SHA-384, with normal info with missing deriveBits usage -[PASS] long derivedKey, empty salt, SHA-384, with normal info with wrong (ECDH) key -[PASS] long derivedKey, empty salt, SHA-384, with empty info -[PASS] long derivedKey, empty salt, SHA-384, with empty info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with empty info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-1 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-256 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-384 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with empty info -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with missing deriveKey usage -[PASS] Derived key of type name: HMAC hash: SHA-512 length: 256 using long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key -[PASS] long derivedKey, empty salt, SHA-384, with empty info with missing salt -[PASS] long derivedKey, empty salt, SHA-384, with empty info with missing info [FAIL] long derivedKey, empty salt, SHA-384, with empty info with null length assert_unreached: null length should have thrown an OperationError Reached unreachable code -[PASS] long derivedKey, empty salt, SHA-384, with empty info with non-multiple of 8 length -[PASS] long derivedKey, empty salt, SHA-384, with empty info with bad hash name SHA384 -[PASS] long derivedKey, empty salt, SHA-384, with empty info with missing deriveBits usage -[PASS] long derivedKey, empty salt, SHA-384, with empty info with wrong (ECDH) key Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_2001-3000-expected.txt b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_2001-3000-expected.txt index a8d3367b..734e9fe 100644 --- a/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_2001-3000-expected.txt +++ b/third_party/blink/web_tests/external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.worker_2001-3000-expected.txt
@@ -1,1071 +1,136 @@ This is a testharness.js-based test. -Found 1001 tests; 935 PASS, 66 FAIL, 0 TIMEOUT, 0 NOTRUN. -[PASS] setup - define tests -[PASS] long derivedKey, empty salt, SHA-512, with normal info -[PASS] long derivedKey, empty salt, SHA-512, with normal info with 0 length -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 128 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key +Found 66 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 192 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CBC length: 256 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 128 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 192 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-CTR length: 256 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 128 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 192 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-GCM length: 256 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 128 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key [FAIL] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-512, with normal info assert_unreached: deriveKey failed with error OperationError: 192-bit AES keys are not supported Reached unreachable code -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-512, with normal info with bad hash name SHA512 -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-512, with normal info with missing deriveKey usage -[PASS] Derived key of type name: AES-KW length: 192 using long derivedKey, empty salt, SHA-512, with normal info with wrong (ECDH) key -[PASS] Derived key of type name: AES-KW length: 256 using long derivedKey, empty salt, SHA-512, with normal info -[PASS] D