diff --git a/DEPS b/DEPS index 6a3a448..da5d5eb 100644 --- a/DEPS +++ b/DEPS
@@ -303,15 +303,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f0987bd082ac9bc3d5ed6257c9ecfad18d9b0467', + 'skia_revision': 'd0f09ad481f7d8afd73259b1f46ad0dc8d8a1e6b', # 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': '3970923e265f3f8a2420cefd55ee1bdabe44e6a4', + 'v8_revision': 'fccd7efb786d611b5d6d2903e6900c562aaa7dd4', # 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': 'e3600abb810666033b35b8e98043869fb1c10603', + 'angle_revision': '82c95b3012573f46a99f7f32d2a93c3671c0e8b9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -394,7 +394,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': '5fad45b99a7ca290b0e36ca81f0074589ee2ef9b', + 'devtools_frontend_revision': 'd7571848c16a0ff89d4964c838dc44e0ce915049', # 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. @@ -418,7 +418,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '667f56eab3feb5ed6aa40dd9b2319b3fb784f1f6', + 'dawn_revision': '4d6794a7625867209adaaf3839b6969578acea2f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -818,7 +818,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '93f409484e269c3df9017ba14dc28a6ccd84bf2d', + 'e1d0bc7ff99b302fe11d5a7563481e3fb42c14e2', 'condition': 'checkout_android and checkout_src_internal', }, @@ -847,7 +847,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'c4c73b5452c7efca23db99cde8746d36e0ed107a', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '00fac7e67918c03a47eb79b5e65d7a5aa6cbf70f', 'condition': 'checkout_ios', }, @@ -980,7 +980,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'uEy3v9aofzAf6VZm5g6ymQ4FcurxX2k_KCqjHOw47NoC', + 'version': 'aX7aKt_tQj6cTy5WGXiiPYsjab9D2DZwSQc5xPUW0KUC', }, ], 'condition': 'checkout_android', @@ -1190,13 +1190,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '390005586bde14be9b55fde71ca4ae2107021ac9', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '007dd45a94b8fe400fb69113f7999fed185cb5c1', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '7a46eb1458616c7271b7aa5787a8ae89c800bc34', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'c41591023f94b09a395d82d1c8bf571ead6895b2', 'condition': 'checkout_src_internal', }, @@ -1294,11 +1294,6 @@ 'condition': 'checkout_win', }, - 'src/third_party/gvr-android-sdk/src': { - 'url': Var('chromium_git') + '/external/github.com/googlevr/gvr-android-sdk.git' + '@' + '233e7fe922a543e0bc55382d64cacd047307d0e7', - 'condition': 'checkout_android', - }, - 'src/third_party/cardboard/src' : { 'url': Var('chromium_git') + '/external/github.com/googlevr/cardboard/' + '@' + '5c9f3066dc14962d1dec9a32ec9d3668641c408d', 'condition': 'checkout_android', @@ -1661,7 +1656,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '905fb0a0357086378dc057f82a2e6926bf1341be', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '7a68d15808c7e9714206112aaecbcd90ca1f1c18', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1846,7 +1841,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'f20c5f7b8f53904edaa98651d764e1b8305d7c14', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b2e9babeb7aac43e3e27bb7f211b8bf994128720', + Var('webrtc_git') + '/src.git' + '@' + 'f698a39eecd1c58108d56d0b541430deebc74a25', # 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. @@ -3949,7 +3944,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - '2e8649b36bd3e4e0ae00efabffc0e5a512316a2c', + 'd6d170dc380770ce81ad2f7ea55435c98fe4083a', 'condition': 'checkout_src_internal', }, @@ -4009,7 +4004,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '6ab4b39499215991e1d58a879aec026c6f54a925', + 'ac06513c41078df3c7e5c292bbfdd2423dc61741', 'condition': 'checkout_ios and checkout_src_internal', }, @@ -4958,30 +4953,6 @@ '--gs_url_base=chromeos-prebuilt/afdo-job/llvm', ], }, - { - 'name': 'gvr_static_shim_android', - 'pattern': '\\.sha1', - 'condition': 'checkout_android', - 'action': [ 'python3', - 'src/third_party/depot_tools/download_from_google_storage.py', - '--no_resume', - '--no_auth', - '--bucket', 'chromium-gvr-static-shim', - '-d', 'src/third_party/gvr-android-sdk', - ], - }, - { - 'name': 'vr_controller_test_api', - 'pattern': '\\.sha1', - 'condition': 'checkout_android', - 'action': [ 'python3', - 'src/third_party/depot_tools/download_from_google_storage.py', - '--no_resume', - '--no_auth', - '--bucket', 'chromium-gvr-static-shim/controller_test_api', - '-s', 'src/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1', - ], - }, # Download and unpack MediaPipe Integration tests. { 'name': 'mediapipe_integration_testdata', @@ -4990,15 +4961,6 @@ 'src/content/test/gpu/gpu_tests/mediapipe_update.py', ], }, - # Download VR test APKs only if the environment variable is set - { - 'name': 'vr_test_apks', - 'pattern': '.', - 'condition': 'checkout_android', - 'action': [ 'python3', - 'src/third_party/gvr-android-sdk/test-apks/update.py', - ], - }, # DOWNLOAD AR test APKs only if the environment variable is set { 'name': 'ar_test_apks',
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc index 8eab837..d038806 100644 --- a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc +++ b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
@@ -17,13 +17,13 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/content/browser/threat_details.h" #include "components/safe_browsing/content/browser/triggers/trigger_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/utils.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/base_safe_browsing_error_ui.h" #include "components/security_interstitials/core/safe_browsing_quiet_error_ui.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -106,7 +106,7 @@ // enhanced protection is supported on aw. BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options = BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( - IsMainPageLoadBlocked(unsafe_resources), + IsMainPageLoadPending(unsafe_resources), safe_browsing::IsExtendedReportingOptInAllowed(*pref_service), browser_context->IsOffTheRecord(), safe_browsing::IsExtendedReportingEnabled(*pref_service), @@ -126,7 +126,8 @@ // committed interstitials, it can be cleaned up when removing non-committed // interstitials. content::NavigationEntry* entry = - GetNavigationEntryForResource(unsafe_resource); + safe_browsing::unsafe_resource_util::GetNavigationEntryForResource( + unsafe_resource); GURL url = (main_frame_url.is_empty() && entry) ? entry->GetURL() : main_frame_url;
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc index 8ce8a14..9d22870 100644 --- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc +++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
@@ -18,10 +18,10 @@ #include "base/path_service.h" #include "components/safe_browsing/content/browser/base_ui_manager.h" #include "components/safe_browsing/content/browser/safe_browsing_network_context.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safebrowsing_constants.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h" @@ -71,7 +71,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource); // Check the size of the view UIManagerClient* client = UIManagerClient::FromWebContents(web_contents); if (!client || !client->CanShowInterstitial()) {
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc index eef29ee..73ffcd915 100644 --- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc +++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
@@ -21,12 +21,12 @@ #include "base/android/jni_android.h" #include "base/feature_list.h" #include "base/functional/bind.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/web_ui_constants.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "components/security_interstitials/core/urls.h" #include "content/public/browser/browser_task_traits.h" @@ -193,7 +193,7 @@ const security_interstitials::UnsafeResource& resource, const AwWebResourceRequest& request) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource); security_interstitials::SecurityInterstitialTabHelper* security_interstitial_tab_helper = security_interstitials:: @@ -229,7 +229,7 @@ SafeBrowsingAction action, bool reporting) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource); // |web_contents| can be null after RenderFrameHost is destroyed. if (!web_contents) return; @@ -240,7 +240,9 @@ browser_context->SetExtendedReportingAllowed(false); } - content::NavigationEntry* entry = GetNavigationEntryForResource(resource); + content::NavigationEntry* entry = + safe_browsing::unsafe_resource_util::GetNavigationEntryForResource( + resource); // TODO(ntfschr): fully handle reporting once we add support (crbug/688629) bool proceed; @@ -303,7 +305,7 @@ scoped_refptr<AwSafeBrowsingUIManager> ui_manager, const security_interstitials::UnsafeResource& resource) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource); if (web_contents) { ui_manager->DisplayBlockingPage(resource); return;
diff --git a/ash/clipboard/views/clipboard_history_text_item_view.cc b/ash/clipboard/views/clipboard_history_text_item_view.cc index 5b28e74..eb9aa71c 100644 --- a/ash/clipboard/views/clipboard_history_text_item_view.cc +++ b/ash/clipboard/views/clipboard_history_text_item_view.cc
@@ -67,8 +67,8 @@ views::Builder<views::BoxLayoutView>() .SetOrientation(views::BoxLayout::Orientation::kVertical) .SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kStart) - .SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification().WithWeight(1)) + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()) .AddChild(views::Builder<views::Label>( std::make_unique<ClipboardHistoryLabel>( container->text_, display_text_elide_behavior,
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index ed194c26..3ccf45c 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1347,11 +1347,15 @@ base::FEATURE_DISABLED_BY_DEFAULT); // Enables new on-device recognition for legacy handwriting input. +// This flag should be OVERRIDDEN for devices which do not have on-device +// handwriting (b/316981973). Please check before using this flag. BASE_FEATURE(kHandwritingLegacyRecognition, "HandwritingLegacyRecognition", base::FEATURE_ENABLED_BY_DEFAULT); // Enables downloading the handwriting libraries via DLC. +// This flag should be OVERRIDDEN for devices which do not have on-device +// handwriting (b/316981973). Please check before using this flag. BASE_FEATURE(kHandwritingLibraryDlc, "HandwritingLibraryDlc", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/ash/metrics/feature_discovery_duration_reporter_impl.cc b/ash/metrics/feature_discovery_duration_reporter_impl.cc index 00cc0597..bfeb0d3 100644 --- a/ash/metrics/feature_discovery_duration_reporter_impl.cc +++ b/ash/metrics/feature_discovery_duration_reporter_impl.cc
@@ -5,7 +5,6 @@ #include "ash/metrics/feature_discovery_duration_reporter_impl.h" #include "ash/public/cpp/feature_discovery_metric_util.h" -#include "ash/public/cpp/tablet_mode.h" #include "ash/shell.h" #include "base/containers/contains.h" #include "base/json/values_util.h" @@ -13,6 +12,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" +#include "ui/display/screen.h" namespace ash { @@ -134,7 +134,7 @@ // Record the current tablet mode if `feature`'s discovery duration data // should be separated by tablet mode. observed_feature_data.Set(kActivatedInTablet, - TabletMode::Get()->IsInTabletMode()); + display::Screen::GetScreen()->InTabletMode()); } ScopedDictPrefUpdate update(active_pref_service_, kObservedFeatures);
diff --git a/ash/public/cpp/tablet_mode.cc b/ash/public/cpp/tablet_mode.cc index 9401f7d..418f5295 100644 --- a/ash/public/cpp/tablet_mode.cc +++ b/ash/public/cpp/tablet_mode.cc
@@ -61,8 +61,4 @@ } } -bool TabletMode::IsInTabletMode() { - return display::Screen::GetScreen()->InTabletMode(); -} - } // namespace ash
diff --git a/ash/public/cpp/tablet_mode.h b/ash/public/cpp/tablet_mode.h index 18220b4f..3cb0199 100644 --- a/ash/public/cpp/tablet_mode.h +++ b/ash/public/cpp/tablet_mode.h
@@ -51,13 +51,6 @@ virtual void AddObserver(TabletModeObserver* observer) = 0; virtual void RemoveObserver(TabletModeObserver* observer) = 0; - // Deprecated, do NOT use this. Please use - // display::Screen::GetScreen()->InTabletMode() instead. - // TODO(crbug.com/1502114): Remove this. - // - // Returns true if TabletMode singleton exists and is in the tablet mode. - static bool IsInTabletMode(); - // Whether the events from the internal mouse/keyboard are blocked. virtual bool AreInternalInputDeviceEventsBlocked() const = 0;
diff --git a/ash/system/focus_mode/focus_mode_chip_carousel.cc b/ash/system/focus_mode/focus_mode_chip_carousel.cc index 20491c9..68d433b 100644 --- a/ash/system/focus_mode/focus_mode_chip_carousel.cc +++ b/ash/system/focus_mode/focus_mode_chip_carousel.cc
@@ -81,9 +81,7 @@ FocusModeChipCarousel::FocusModeChipCarousel( ChipPressedCallback on_chip_pressed) : on_chip_pressed_(std::move(on_chip_pressed)) { - SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded)); + SetProperty(views::kBoxLayoutFlexKey, views::BoxLayoutFlexSpecification()); SetBorder(views::CreateEmptyBorder(kCarouselInsets)); SetOrientation(views::BoxLayout::Orientation::kHorizontal); SetNotifyEnterExitOnChild(true);
diff --git a/ash/system/focus_mode/focus_mode_task_view.cc b/ash/system/focus_mode/focus_mode_task_view.cc index 7ef7cf26..7bf7456 100644 --- a/ash/system/focus_mode/focus_mode_task_view.cc +++ b/ash/system/focus_mode/focus_mode_task_view.cc
@@ -176,11 +176,8 @@ views::BoxLayout::CrossAxisAlignment::kCenter); textfield_container_->SetOrientation( views::BoxLayout::Orientation::kHorizontal); - textfield_container_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kUnbounded)); - + textfield_container_->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); radio_button_ = textfield_container_->AddChildView( std::make_unique<views::ImageButton>(base::BindRepeating( &FocusModeTaskView::OnCompleteTask, base::Unretained(this))));
diff --git a/ash/system/focus_mode/focus_mode_tray.cc b/ash/system/focus_mode/focus_mode_tray.cc index 67cf84c9..56366bec 100644 --- a/ash/system/focus_mode/focus_mode_tray.cc +++ b/ash/system/focus_mode/focus_mode_tray.cc
@@ -248,10 +248,8 @@ base::UTF8ToUTF16(controller->selected_task_title()), base::BindRepeating(&FocusModeTray::OnCompleteTask, weak_ptr_factory_.GetWeakPtr()))); - task_item_view_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kPreferred)); + task_item_view_->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); } bubble_ = std::make_unique<TrayBubbleWrapper>(this);
diff --git a/ash/system/holding_space/downloads_section.cc b/ash/system/holding_space/downloads_section.cc index 46f0cae1..4eae63c 100644 --- a/ash/system/holding_space/downloads_section.cc +++ b/ash/system/holding_space/downloads_section.cc
@@ -74,8 +74,8 @@ holding_space_ui::CreateSectionHeaderLabel( IDS_ASH_HOLDING_SPACE_DOWNLOADS_TITLE) .SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT) - .SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification().WithWeight(1)), + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()), views::Builder<views::ImageView>() .CopyAddressTo(&chevron_) .SetFlipCanvasOnPaintForRTLUI(true)
diff --git a/ash/system/holding_space/suggestions_section.cc b/ash/system/holding_space/suggestions_section.cc index e7e4354..6fac10a9 100644 --- a/ash/system/holding_space/suggestions_section.cc +++ b/ash/system/holding_space/suggestions_section.cc
@@ -64,8 +64,8 @@ holding_space_ui::CreateSuggestionsSectionHeaderLabel( IDS_ASH_HOLDING_SPACE_SUGGESTIONS_TITLE) .SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT) - .SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification().WithWeight(1)), + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()), views::Builder<views::ImageView>().CopyAddressTo(&chevron_).SetID( kHoldingSpaceSuggestionsChevronIconId)) .BuildChildren();
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc index a1ccf08..496e12d 100644 --- a/ash/system/message_center/ash_notification_view.cc +++ b/ash/system/message_center/ash_notification_view.cc
@@ -1711,10 +1711,8 @@ views::Builder<views::BoxLayoutView>() .CopyAddressTo(&snooze_button_spacer_) .SetMainAxisAlignment(MainAxisAlignment::kEnd) - .SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kUnbounded)) + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()) .Build()); auto snooze_button = std::make_unique<IconButton>(
diff --git a/ash/system/phonehub/app_stream_launcher_view.cc b/ash/system/phonehub/app_stream_launcher_view.cc index 4d9c312f..d46e7c6 100644 --- a/ash/system/phonehub/app_stream_launcher_view.cc +++ b/ash/system/phonehub/app_stream_launcher_view.cc
@@ -255,12 +255,8 @@ gfx::DirectionalityMode::DIRECTIONALITY_AS_URL)); title->SetMultiLine(true); title->SetAllowCharacterBreak(true); - title->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded, - /*adjust_height_for_width =*/true) - .WithWeight(1)); + title->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); title->SetHorizontalAlignment(gfx::ALIGN_LEFT); title->SetText( l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_APP_STREAM_LAUNCHER_TITLE));
diff --git a/ash/system/unified/feature_tile_pixeltest.cc b/ash/system/unified/feature_tile_pixeltest.cc index d1df21e9..9b49e1d 100644 --- a/ash/system/unified/feature_tile_pixeltest.cc +++ b/ash/system/unified/feature_tile_pixeltest.cc
@@ -263,10 +263,8 @@ views::Button::PressedCallback(), /*is_togglable=*/true, FeatureTile::TileType::kCompact)) ->GetWeakPtr(); - tile_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded)); + tile_->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); tile_->SetTooltipText(u"Tooltip"); tile_->SetVectorIcon(vector_icons::kDogfoodIcon); tile_->SetLabel(u"One-line label");
diff --git a/ash/system/unified/quick_settings_view_unittest.cc b/ash/system/unified/quick_settings_view_unittest.cc index f2721bc..8ff122b 100644 --- a/ash/system/unified/quick_settings_view_unittest.cc +++ b/ash/system/unified/quick_settings_view_unittest.cc
@@ -16,6 +16,7 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/display/screen.h" namespace ash { @@ -78,7 +79,7 @@ // Test that the cast tile is in its primary form when in clamshell mode, // when the auto-rotate tile is not visible. - EXPECT_FALSE(tablet_mode_controller->IsInTabletMode()); + EXPECT_FALSE(display::Screen::GetScreen()->InTabletMode()); tray->ShowBubble(); FeatureTile* cast_tile = GetTileById(VIEW_ID_CAST_MAIN_VIEW); @@ -93,7 +94,7 @@ // Test that cast and auto-rotate tiles are compact in tablet mode. tablet_mode_controller->SetEnabledForTest(true); - EXPECT_TRUE(tablet_mode_controller->IsInTabletMode()); + EXPECT_TRUE(display::Screen::GetScreen()->InTabletMode()); tray->ShowBubble();
diff --git a/ash/user_education/welcome_tour/welcome_tour_controller.cc b/ash/user_education/welcome_tour/welcome_tour_controller.cc index d0386fe..85daa2d 100644 --- a/ash/user_education/welcome_tour/welcome_tour_controller.cc +++ b/ash/user_education/welcome_tour/welcome_tour_controller.cc
@@ -13,7 +13,6 @@ #include "ash/public/cpp/system/scoped_toast_pause.h" #include "ash/public/cpp/system/system_nudge_pause_manager.h" #include "ash/public/cpp/system/toast_manager.h" -#include "ash/public/cpp/tablet_mode.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -394,7 +393,7 @@ // prevented provided that (a) the user is new, and (b) the device is not in // tablet mode. This is in keeping with existing first run behavior. base::ScopedClosureRunner maybe_launch_explore_app_async( - TabletMode::IsInTabletMode() + display::Screen::GetScreen()->InTabletMode() ? base::DoNothing() : base::BindOnce(&LaunchExploreAppAsync, UserEducationPrivateApiKey())); @@ -407,7 +406,7 @@ } // Welcome Tour is not supported in tablet mode. - if (TabletMode::IsInTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { welcome_tour_metrics::RecordTourPrevented( welcome_tour_metrics::PreventedReason::kTabletModeEnabled); return; @@ -536,7 +535,7 @@ // Attempt to launch the Explore app regardless of tour completion so long as // the device is not in tablet mode. This is in keeping with existing first // run behavior. - if (!TabletMode::IsInTabletMode()) { + if (!display::Screen::GetScreen()->InTabletMode()) { LaunchExploreAppAsync(UserEducationPrivateApiKey()); SetCurrentStep(welcome_tour_metrics::Step::kExploreAppWindow); }
diff --git a/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc b/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc index b66c8ee..34b57d9c 100644 --- a/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc +++ b/ash/user_education/welcome_tour/welcome_tour_controller_unittest.cc
@@ -448,7 +448,7 @@ LaunchSystemWebAppAsync( Eq(primary_account_id), Eq(ash::SystemWebAppType::HELP), Eq(display::Screen::GetScreen()->GetPrimaryDisplay().id()))) - .Times(TabletMode::IsInTabletMode() ? 0u : 1u); + .Times(display::Screen::GetScreen()->InTabletMode() ? 0u : 1u); std::move(ended_callback).Run(); Mock::VerifyAndClearExpectations(&observer); Mock::VerifyAndClearExpectations(user_education_delegate);
diff --git a/ash/webui/settings/public/constants/routes.mojom b/ash/webui/settings/public/constants/routes.mojom index 0b7ea5d..5023ddd 100644 --- a/ash/webui/settings/public/constants/routes.mojom +++ b/ash/webui/settings/public/constants/routes.mojom
@@ -155,6 +155,7 @@ kInput = 1205, kEditDictionary = 1206, kJapaneseManageUserDictionary = 1207, + kAppLanguages = 1208, // Files section. kNetworkFileShares = 1300, @@ -309,6 +310,7 @@ const string kEditDictionarySubpagePath = "osLanguages/editDictionary"; const string kJapaneseManageUserDictionarySubpagePath = "osLanguages/japaneseManageUserDictionary"; +const string kAppLanguagesSubpagePath = "osLanguages/languages/appLanguages"; // Files section. const string kFilesSectionPath = "files";
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc index 547f7ee..11291322 100644 --- a/ash/wm/client_controlled_state.cc +++ b/ash/wm/client_controlled_state.cc
@@ -369,12 +369,18 @@ << ", state=" << state_type_ << ", next_state=" << next_state_type; + const gfx::Rect snapped_bounds = GetSnappedWindowBoundsInParent( + window, next_state_type, next_snap_ratio); + + // The snap ratio of `snapped_bounds` may be different from the requested + // snap ratio (e.g., if the window has a minimum size requirement or the + // opposite side of splitview is partial-snapped). + window_state->ForceUpdateSnapRatio(snapped_bounds); + // Then ask delegate to set the desired bounds for the snap state. - delegate_->HandleBoundsRequest( - window_state, next_state_type, - GetSnappedWindowBoundsInParent(window, next_state_type, - next_snap_ratio), - window_state->GetDisplay().id()); + delegate_->HandleBoundsRequest(window_state, next_state_type, + snapped_bounds, + window_state->GetDisplay().id()); } } else if (next_state_type == WindowStateType::kFloated) { if (chromeos::wm::CanFloatWindow(window)) {
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc index 6b4a6ff..f3b36ab 100644 --- a/ash/wm/client_controlled_state_unittest.cc +++ b/ash/wm/client_controlled_state_unittest.cc
@@ -140,6 +140,33 @@ } }; +void VerifySnappedBounds(aura::Window* window, float expected_snap_ratio) { + const WindowState* window_state = WindowState::Get(window); + // `window` must be in any snapped state to use this method. + ASSERT_TRUE(window_state->IsSnapped()); + + const bool in_tablet = display::Screen::GetScreen()->InTabletMode(); + const auto* screen = display::Screen::GetScreen(); + const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); + const bool is_primary = + window_state->GetStateType() == WindowStateType::kPrimarySnapped; + + const gfx::Size expected_size( + work_area.width() * expected_snap_ratio - + (in_tablet ? kSplitviewDividerShortSideLength / 2 : 0), + work_area.height()); + const gfx::Point expected_origin( + is_primary ? work_area.x() : work_area.right() - expected_size.width(), + work_area.y()); + + const gfx::Rect bounds = window->GetTargetBounds(); + constexpr int eps = 1; // Allow 1px rounding errors for partial snap. + EXPECT_NEAR(expected_size.width(), bounds.width(), eps); + EXPECT_EQ(expected_size.height(), bounds.height()); + EXPECT_NEAR(expected_origin.x(), bounds.x(), eps); + EXPECT_EQ(expected_origin.y(), bounds.y()); +} + } // namespace class ClientControlledStateTest : public AshTestBase { @@ -209,6 +236,24 @@ widget()->SetBounds(delegate()->requested_bounds()); state()->set_bounds_locally(false); } + void ClickOnOverviewItem(aura::Window* window) { + auto* const overview_controller = OverviewController::Get(); + ASSERT_TRUE(overview_controller->InOverviewSession()); + auto* const overview_item = GetOverviewItemForWindow(window); + + auto* const event_generator = GetEventGenerator(); + event_generator->set_current_screen_location( + gfx::ToRoundedPoint(overview_item->target_bounds().CenterPoint())); + event_generator->ClickLeftButton(); + } + void SimulateUnminimizeViaShelfIcon(views::Widget* widget) { + // When clicking an app icon on the hotseat to unminimize the window, + // `ChromeShelfController` shows and activates the widget. + // We here simulate the behavior because //ash should not use any component + // from //chrome/browser/ui. + widget->Show(); + widget->Activate(); + } private: raw_ptr<ClientControlledState, DanglingUntriaged | ExperimentalAsh> state_ = @@ -614,6 +659,135 @@ EXPECT_EQ(resized_bounds, delegate()->requested_bounds()); } +// Tests that auto snapping from maximized/minimized via overview/shelf works +// for ClientControlledState. +TEST_F(ClientControlledStateTest, AutoSnap) { + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + ASSERT_TRUE(display::Screen::GetScreen()->InTabletMode()); + + // Snap enabled. + widget_delegate()->EnableSnap(); + ASSERT_TRUE(window_state()->CanResize()); + ASSERT_TRUE(window_state()->CanSnap()); + + // Create a normal (non-client-controlled) window in addition to `window()` + // (client-controlled window) to fill the one side of the split view. + auto non_client_controlled_window = CreateAppWindow(); + + // Snap `non_client_controlled_window` to left. + const WindowSnapWMEvent snap_primary(WM_EVENT_SNAP_PRIMARY); + WindowState::Get(non_client_controlled_window.get()) + ->OnWMEvent(&snap_primary); + + // Click `window()`'s overview item to snap to right. + ClickOnOverviewItem(window()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kDefaultSnapRatio); + + // Minimize `window()`. + const WMEvent minimize(WM_EVENT_MINIMIZE); + window_state()->OnWMEvent(&minimize); + state()->EnterNextState(window_state(), delegate()->new_state()); + EXPECT_TRUE(window_state()->IsMinimized()); + EXPECT_FALSE(window()->IsVisible()); + + // Click `window()`'s overview item to snap to right. + ClickOnOverviewItem(window()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kDefaultSnapRatio); + + // Minimize `window()`. + window_state()->OnWMEvent(&minimize); + state()->EnterNextState(window_state(), delegate()->new_state()); + EXPECT_TRUE(window_state()->IsMinimized()); + EXPECT_FALSE(window()->IsVisible()); + + // Unminimize `window()` by clicking the app icon on the shelf. + SimulateUnminimizeViaShelfIcon(widget()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kDefaultSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kDefaultSnapRatio); +} + +// Tests that auto partial-snapping from maximized/minimized via overview/shelf +// works for ClientControlledState. +TEST_F(ClientControlledStateTest, AutoPartialSnap) { + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + ASSERT_TRUE(display::Screen::GetScreen()->InTabletMode()); + + // Snap enabled. + widget_delegate()->EnableSnap(); + ASSERT_TRUE(window_state()->CanResize()); + ASSERT_TRUE(window_state()->CanSnap()); + + // Create a normal (non-client-controlled) window in addition to `window()` + // (client-controlled window) to fill the one side of the split view. + auto non_client_controlled_window = CreateAppWindow(); + + // Snap `non_client_controlled_window` to 1/3 left. + const WindowSnapWMEvent snap_primary(WM_EVENT_SNAP_PRIMARY, + chromeos::kOneThirdSnapRatio); + WindowState::Get(non_client_controlled_window.get()) + ->OnWMEvent(&snap_primary); + + // Click `window()`'s overview item to snap to 2/3 right. + ClickOnOverviewItem(window()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kOneThirdSnapRatio); + + // Minimize `window()`. + const WMEvent minimize(WM_EVENT_MINIMIZE); + window_state()->OnWMEvent(&minimize); + state()->EnterNextState(window_state(), delegate()->new_state()); + EXPECT_TRUE(window_state()->IsMinimized()); + EXPECT_FALSE(window()->IsVisible()); + + // Click `window()`'s overview item to snap to 2/3 right. + ClickOnOverviewItem(window()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kOneThirdSnapRatio); + + // Minimize `window()`. + window_state()->OnWMEvent(&minimize); + state()->EnterNextState(window_state(), delegate()->new_state()); + EXPECT_TRUE(window_state()->IsMinimized()); + EXPECT_FALSE(window()->IsVisible()); + + // Unminimize `window()` by clicking the app icon on the shelf. + SimulateUnminimizeViaShelfIcon(widget()); + + state()->EnterNextState(window_state(), delegate()->new_state()); + ApplyPendingRequestedBounds(); + EXPECT_EQ(WindowStateType::kSecondarySnapped, window_state()->GetStateType()); + VerifySnappedBounds(window(), chromeos::kTwoThirdSnapRatio); + VerifySnappedBounds(non_client_controlled_window.get(), + chromeos::kOneThirdSnapRatio); +} + // Pin events should not be applied immediately. The request should be sent // to delegate. TEST_F(ClientControlledStateTest, Pinned) {
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index 8f82d3d..8a695590 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -8145,85 +8145,74 @@ TEST_F(SplitViewOverviewSessionTest, SnappedWindowBoundsWithMinimumSizeTest) { const gfx::Rect bounds(400, 400); std::unique_ptr<aura::Window> window1(CreateTestWindow(bounds)); - const int work_area_length = + const gfx::Rect work_area = screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( - Shell::GetPrimaryRootWindow()) - .width(); + window1.get()); std::unique_ptr<aura::Window> window2(CreateWindowWithMinimumSize( - bounds, gfx::Size(work_area_length / 3 + 20, 0))); + bounds, gfx::Size(work_area.width() / 3 + 20, 0))); + // Snap `window1` in split view, then resize it to 1/3 the work area, which is + // less than the minimum size of `window2`. ToggleOverview(); split_view_controller()->SnapWindow(window1.get(), SnapPosition::kPrimary); split_view_divider()->StartResizeWithDivider( GetSplitViewDividerBounds(/*is_dragging=*/false).CenterPoint()); split_view_divider()->EndResizeWithDivider( - gfx::Point(work_area_length / 3, 10)); - SkipDividerSnapAnimation(); - // Use |EXPECT_NEAR| for reasons related to rounding and divider thickness. - EXPECT_NEAR( - work_area_length / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR(work_area_length / 2, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR( - work_area_length * 2 / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR(work_area_length * 2 / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width(), - 8); + gfx::Point(work_area.width() / 3, 10)); + ASSERT_TRUE(GetOverviewController()->InOverviewSession()); + ASSERT_TRUE(split_view_controller()->InSplitViewMode()); + // Use `EXPECT_NEAR` for reasons related to rounding and divider thickness. + constexpr int kDividerWidth = kSplitviewDividerShortSideLength; + ASSERT_NEAR(work_area.width() / 3, window1->GetBoundsInScreen().width(), + kDividerWidth); + + // Long press to start a drag on `item2` to the left, on top of `window1`, to + // show the left highlight preview. + auto* item2 = GetOverviewItemForWindow(window2.get()); + const gfx::Point drag_starting_point( + gfx::ToRoundedPoint(item2->GetTransformedBounds().CenterPoint())); + ui::test::EventGenerator* generator = GetEventGenerator(); + LongGestureTap(drag_starting_point, generator, /*release_touch=*/false); + DragItemToPoint(item2, gfx::Point(0, 0), generator, + /*by_touch_gestures=*/true, /*drop=*/false); + ASSERT_TRUE(GetOverviewController()->InOverviewSession()); + ASSERT_TRUE(split_view_controller()->InSplitViewMode()); + + // Test that the highlight bounds are 1/2 the work area, since that's the + // closest fixed divider ratio for `window2`. + gfx::Rect left_highlight_bounds(work_area); + left_highlight_bounds.set_width(work_area.width() / 2 - kDividerWidth / 2); + left_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp); + auto* overview_grid = + GetOverviewSession()->GetGridWithRootWindow(window1->GetRootWindow()); + EXPECT_EQ(left_highlight_bounds, overview_grid->split_view_drag_indicators() + ->GetLeftHighlightViewBounds()); + + // Drop `item2` back at its starting point. + generator->MoveTouch(drag_starting_point); + generator->ReleaseTouch(); + + // Now resize `window1` where `window2` can't fit in the secondary position. split_view_divider()->StartResizeWithDivider( GetSplitViewDividerBounds(/*is_dragging=*/false).CenterPoint()); split_view_divider()->EndResizeWithDivider( - gfx::Point(work_area_length * 2 / 3, 10)); - EXPECT_NEAR( - work_area_length * 2 / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR(work_area_length * 2 / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kPrimary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR( - work_area_length / 3, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width(), - 8); - EXPECT_NEAR(work_area_length / 2, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width(), - 8); + gfx::Point(work_area.width() * 2 / 3, 10)); + ASSERT_NEAR(work_area.width() * 2 / 3, window1->GetBoundsInScreen().width(), + kDividerWidth); + + // Drag `window2` to show the right highlight preview. + DragItemToPoint(item2, work_area.top_right(), generator, + /*by_touch_gestures=*/false, /*drop=*/false); + + // Test that the highlight bounds are 1/2 the work area. + gfx::Rect right_highlight_bounds(work_area); + right_highlight_bounds.set_x(work_area.width() / 2 + kDividerWidth / 2); + right_highlight_bounds.set_width(work_area.width() / 2 - kDividerWidth / 2); + right_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp); + EXPECT_EQ(right_highlight_bounds, + overview_grid->split_view_drag_indicators() + ->GetRightHighlightViewBoundsForTesting()); + generator->ReleaseTouch(); } // Verify that if the split view divider is dragged all the way to the edge, the @@ -9332,68 +9321,65 @@ std::unique_ptr<aura::Window> window2( CreateWindowWithMinimumSize(bounds, gfx::Size(window2_minimum_size, 0))); + // Snap `window1` in split view, then resize it to `window1_size`, which is + // less than `window2_minimum_size`. ToggleOverview(); split_view_controller()->SnapWindow(window1.get(), SnapPosition::kPrimary); - ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), - window1.get()); - int divider_position = window1->GetBoundsInScreen().width(); - generator.MoveMouseTo(divider_position, 10); - divider_position = 300; - generator.DragMouseTo(divider_position, 10); - EXPECT_EQ(divider_position, split_view_controller() - ->GetSnappedWindowBoundsInScreen( - SnapPosition::kPrimary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width()); - EXPECT_EQ(window2_minimum_size, split_view_controller() - ->GetSnappedWindowBoundsInScreen( - SnapPosition::kPrimary, window2.get(), - chromeos::kDefaultSnapRatio) - .width()); - const int work_area_length = + ui::test::EventGenerator* generator = GetEventGenerator(); + ASSERT_TRUE(RootWindowController::ForWindow(window1.get()) + ->split_view_overview_session()); + generator->MoveMouseTo(window1->GetBoundsInScreen().width(), 10); + int window1_size = 300; + generator->DragMouseTo(window1_size, 10); + ASSERT_EQ(window1_size, window1->GetBoundsInScreen().width()); + + // Drag `window2` to the left, on top of `window1`, to show the left highlight + // preview. + const gfx::Rect work_area = screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer( - window1.get()) - .width(); - EXPECT_EQ( - work_area_length - divider_position, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width()); - EXPECT_EQ(work_area_length - divider_position, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width()); - divider_position = 500; - generator.DragMouseTo(divider_position, 10); - EXPECT_EQ(divider_position, split_view_controller() - ->GetSnappedWindowBoundsInScreen( - SnapPosition::kPrimary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width()); - EXPECT_EQ(divider_position, split_view_controller() - ->GetSnappedWindowBoundsInScreen( - SnapPosition::kPrimary, window2.get(), - chromeos::kDefaultSnapRatio) - .width()); - EXPECT_EQ( - work_area_length - divider_position, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - /*window_for_minimum_size=*/nullptr, - chromeos::kDefaultSnapRatio) - .width()); - EXPECT_EQ(window2_minimum_size, - split_view_controller() - ->GetSnappedWindowBoundsInScreen(SnapPosition::kSecondary, - window2.get(), - chromeos::kDefaultSnapRatio) - .width()); + window1.get()); + auto* item2 = GetOverviewItemForWindow(window2.get()); + const gfx::Point drag_starting_point( + gfx::ToRoundedPoint(item2->GetTransformedBounds().CenterPoint())); + DragItemToPoint(item2, gfx::Point(0, 0), generator, + /*by_touch_gestures=*/false, /*drop=*/false); + + // Test that the highlight bounds are adjusted for `window2_minimum_size`. + gfx::Rect left_highlight_bounds(work_area.x(), work_area.y(), + window2_minimum_size, work_area.height()); + left_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp); + auto* overview_grid = + GetOverviewSession()->GetGridWithRootWindow(window1->GetRootWindow()); + EXPECT_EQ(left_highlight_bounds, overview_grid->split_view_drag_indicators() + ->GetLeftHighlightViewBounds()); + + // Drop the `window2` item back at its starting point. + generator->MoveMouseTo(drag_starting_point); + generator->ReleaseLeftButton(); + ASSERT_TRUE(RootWindowController::ForWindow(window1.get()) + ->split_view_overview_session()); + + // Now resize `window1` where `window2` can't fit in the secondary position. + window1_size = 500; + generator->MoveMouseTo(window1->GetBoundsInScreen().width(), 10); + generator->DragMouseTo(window1_size, 0); + ASSERT_TRUE(RootWindowController::ForWindow(window1.get()) + ->split_view_overview_session()); + ASSERT_EQ(window1_size, window1->GetBoundsInScreen().width()); + + // Drag `window2` to show the right highlight preview. + DragItemToPoint(item2, work_area.top_right(), generator, + /*by_touch_gestures=*/false, /*drop=*/false); + + // Test that the highlight bounds are adjusted for `window2_minimum_size`. + gfx::Rect right_highlight_bounds(work_area.right() - window2_minimum_size, + work_area.y(), window2_minimum_size, + work_area.height()); + right_highlight_bounds.Inset(kHighlightScreenEdgePaddingDp); + EXPECT_EQ(right_highlight_bounds, + overview_grid->split_view_drag_indicators() + ->GetRightHighlightViewBoundsForTesting()); + generator->ReleaseLeftButton(); } // Tests that on a display in portrait orientation, clamshell split view still
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index b26fa20..8d596b2 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -218,18 +218,17 @@ split_view_controller->split_view_divider(); } -float GetCurrentSnapRatio(aura::Window* window) { +float GetCurrentSnapRatio(aura::Window* window, + const gfx::Rect& target_bounds) { gfx::Rect maximized_bounds = screen_util::GetMaximizedWindowBoundsInParent(window); const int divider_delta = ShouldConsiderDivider(window) ? kSplitviewDividerShortSideLength / 2 : 0; if (IsLayoutHorizontal(window)) { - return static_cast<float>(window->GetTargetBounds().width() + - divider_delta) / + return static_cast<float>(target_bounds.width() + divider_delta) / static_cast<float>(maximized_bounds.width()); } - return static_cast<float>(window->GetTargetBounds().height() + - divider_delta) / + return static_cast<float>(target_bounds.height() + divider_delta) / static_cast<float>(maximized_bounds.height()); } @@ -275,6 +274,15 @@ controller->SaveWindow(window_state); } +bool ShouldSetExplicitOpaqueRegionsForOcclusion(WindowState* window_state) { + // If the window manager manages the window opacity, set the opaque regions + // explicitly if the window must be transparent (e.g. has rounded corners). + return chromeos::ShouldWindowStateHaveRoundedCorners( + window_state->GetStateType()) && + window_state->window()->GetProperty( + ash::kWindowManagerManagesOpacityKey); +} + } // namespace constexpr base::TimeDelta WindowState::kBoundsChangeSlideDuration; @@ -665,7 +673,11 @@ void WindowState::UpdateSnapRatio() { if (!IsSnapped()) return; - snap_ratio_ = std::make_optional(GetCurrentSnapRatio(window_)); + ForceUpdateSnapRatio(window_->GetTargetBounds()); +} + +void WindowState::ForceUpdateSnapRatio(const gfx::Rect& target_bounds) { + snap_ratio_ = std::make_optional(GetCurrentSnapRatio(window_, target_bounds)); // If the snap ratio was adjusted, partial may have ended. MaybeRecordPartialDuration(); } @@ -926,9 +938,7 @@ if (window_->GetProperty(ash::kWindowManagerManagesOpacityKey)) { const gfx::Size& size = window_->bounds().size(); - // WindowManager manages the window opacity. Make it opaque unless - // the window has rounded corners. - if (chromeos::ShouldWindowStateHaveRoundedCorners(GetStateType())) { + if (ShouldSetExplicitOpaqueRegionsForOcclusion(this)) { window_->SetTransparent(true); window_->SetOpaqueRegionsForOcclusion({gfx::Rect(size)}); } else { @@ -1361,8 +1371,8 @@ const gfx::Rect& new_bounds, ui::PropertyChangeReason reason) { CHECK_EQ(window_, window); - if (window_->GetTransparent() && IsNormalStateType() && - window_->GetProperty(ash::kWindowManagerManagesOpacityKey)) { + if (window_->GetTransparent() && + ShouldSetExplicitOpaqueRegionsForOcclusion(this)) { window_->SetOpaqueRegionsForOcclusion({gfx::Rect(new_bounds.size())}); }
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index 9784f84..43f9baa 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -375,6 +375,12 @@ // snapped window. void UpdateSnapRatio(); + // Forcefully updates `snap_ratio` based on the given `target_bounds`. You + // usually should use `UpdateSnapRatio()` instead. This method does not check + // whether `window()` is in the snapped state, so the caller must be sure that + // `window()` is to-be-snapped. Use with care. + void ForceUpdateSnapRatio(const gfx::Rect& target_bounds); + // Gets/sets whether the shelf should be hidden when this window is // fullscreen. bool GetHideShelfWhenFullscreen() const;
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc index bbf74dc..8bf43a00 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
@@ -1788,18 +1788,24 @@ EXPECT_CHECK_DEATH(--protected_ptr); #if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR) - // An array type that should be more than a third the size of the available - // memory for the allocation such that incrementing a pointer to this type - // twice causes it to point to a memory location that is too small to fit a - // complete element of this type. - typedef int OverThirdArray[200 / sizeof(int)]; - raw_ptr<OverThirdArray> protected_arr_ptr = - reinterpret_cast<OverThirdArray*>(ptr); + // An array of a size that doesn't cleanly fit into the allocation. This is to + // check that one can't access elements that don't fully fit in the + // allocation. + const size_t kArraySize = 199; + ASSERT_LT(kArraySize, requested_size); + ASSERT_NE(requested_size % kArraySize, 0U); + typedef char FunkyArray[kArraySize]; + raw_ptr<FunkyArray, AllowPtrArithmetic> protected_arr_ptr = + reinterpret_cast<FunkyArray*>(ptr); - protected_arr_ptr++; + **protected_arr_ptr = 4; + protected_arr_ptr += requested_size / kArraySize; + EXPECT_CHECK_DEATH(** protected_arr_ptr = 4); + protected_arr_ptr--; **protected_arr_ptr = 4; protected_arr_ptr++; - EXPECT_DEATH_IF_SUPPORTED(** protected_arr_ptr = 4, ""); + EXPECT_CHECK_DEATH(** protected_arr_ptr = 4); + protected_arr_ptr = nullptr; #endif // BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR) protected_ptr = nullptr; @@ -1893,6 +1899,8 @@ allocator_.root()->Free(ptr2); } +volatile char g_volatile_char_to_ignore; + TEST_F(BackupRefPtrTest, IndexOperator) { size_t requested_size = GetRequestSizeThatFills512BSlot(); char* ptr = static_cast<char*>(allocator_.root()->Alloc(requested_size)); @@ -1900,10 +1908,11 @@ raw_ptr<char, AllowPtrArithmetic> array = ptr; std::ignore = array[0]; std::ignore = array[requested_size - 1]; - EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[-1], ""); - EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[requested_size + 1], ""); + EXPECT_CHECK_DEATH(std::ignore = array[-1]); + EXPECT_CHECK_DEATH(std::ignore = array[requested_size + 1]); #if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR) - EXPECT_DEATH_IF_SUPPORTED(std::ignore = array[requested_size], ""); + EXPECT_DEATH_IF_SUPPORTED(g_volatile_char_to_ignore = array[requested_size], + ""); #endif } allocator_.root()->Free(ptr); @@ -2138,22 +2147,18 @@ TEST_F(BackupRefPtrTest, SpatialAlgoCompat) { size_t requested_size = GetRequestSizeThatFills512BSlot(); size_t requested_elements = requested_size / sizeof(uint32_t); + uint32_t* ptr = reinterpret_cast<uint32_t*>(allocator_.root()->Alloc(requested_size)); uint32_t* ptr_end = ptr + requested_elements; - CountingRawPtr<uint32_t> protected_ptr = ptr; - CountingRawPtr<uint32_t> protected_ptr_end = - protected_ptr + requested_elements; - -#if BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR) - EXPECT_DEATH_IF_SUPPORTED(*protected_ptr_end = 1, ""); -#endif + CountingRawPtr<uint32_t> counting_ptr = ptr; + CountingRawPtr<uint32_t> counting_ptr_end = counting_ptr + requested_elements; RawPtrCountingImpl::ClearCounters(); uint32_t gen_val = 1; - std::generate(protected_ptr, protected_ptr_end, [&gen_val]() { + std::generate(counting_ptr, counting_ptr_end, [&gen_val]() { gen_val ^= gen_val + 1; return gen_val; }); @@ -2167,9 +2172,9 @@ RawPtrCountingImpl::ClearCounters(); - for (CountingRawPtr<uint32_t> protected_ptr_i = protected_ptr; - protected_ptr_i < protected_ptr_end; protected_ptr_i++) { - *protected_ptr_i ^= *protected_ptr_i + 1; + for (CountingRawPtr<uint32_t> counting_ptr_i = counting_ptr; + counting_ptr_i < counting_ptr_end; counting_ptr_i++) { + *counting_ptr_i ^= *counting_ptr_i + 1; } EXPECT_THAT((CountingRawPtrExpectations{ @@ -2181,9 +2186,9 @@ RawPtrCountingImpl::ClearCounters(); - for (CountingRawPtr<uint32_t> protected_ptr_i = protected_ptr; - protected_ptr_i < ptr_end; protected_ptr_i++) { - *protected_ptr_i ^= *protected_ptr_i + 1; + for (CountingRawPtr<uint32_t> counting_ptr_i = counting_ptr; + counting_ptr_i < ptr_end; counting_ptr_i++) { + *counting_ptr_i ^= *counting_ptr_i + 1; } EXPECT_THAT((CountingRawPtrExpectations{ @@ -2195,7 +2200,7 @@ RawPtrCountingImpl::ClearCounters(); - for (uint32_t* ptr_i = ptr; ptr_i < protected_ptr_end; ptr_i++) { + for (uint32_t* ptr_i = ptr; ptr_i < counting_ptr_end; ptr_i++) { *ptr_i ^= *ptr_i + 1; } @@ -2209,7 +2214,7 @@ RawPtrCountingImpl::ClearCounters(); size_t iter_cnt = 0; - for (uint32_t *ptr_i = protected_ptr, *ptr_i_end = protected_ptr_end; + for (uint32_t *ptr_i = counting_ptr, *ptr_i_end = counting_ptr_end; ptr_i < ptr_i_end; ptr_i++) { *ptr_i ^= *ptr_i + 1; iter_cnt++; @@ -2223,8 +2228,8 @@ }), CountersMatch()); - protected_ptr = nullptr; - protected_ptr_end = nullptr; + counting_ptr = nullptr; + counting_ptr_end = nullptr; allocator_.root()->Free(ptr); } @@ -2232,24 +2237,27 @@ TEST_F(BackupRefPtrTest, Duplicate) { size_t requested_size = allocator_.root()->AdjustSizeForExtrasSubtract(512); char* ptr = static_cast<char*>(allocator_.root()->Alloc(requested_size)); - raw_ptr<char> protected_ptr1 = ptr; + raw_ptr<char, AllowPtrArithmetic> protected_ptr1 = ptr; protected_ptr1 += requested_size; // Pointer should now be poisoned. // Duplicating a poisoned pointer should be allowed. - raw_ptr<char> protected_ptr2 = protected_ptr1; + raw_ptr<char, AllowPtrArithmetic> protected_ptr2 = protected_ptr1; // The poison bit should be propagated to the duplicate such that the OOB // access is disallowed: EXPECT_DEATH_IF_SUPPORTED(*protected_ptr2 = ' ', ""); // Assignment from a poisoned pointer should be allowed. - raw_ptr<char> protected_ptr3; + raw_ptr<char, AllowPtrArithmetic> protected_ptr3; protected_ptr3 = protected_ptr1; // The poison bit should be propagated via the assignment such that the OOB // access is disallowed: EXPECT_DEATH_IF_SUPPORTED(*protected_ptr3 = ' ', ""); + protected_ptr1 = nullptr; + protected_ptr2 = nullptr; + protected_ptr3 = nullptr; allocator_.root()->Free(ptr); } #endif // BUILDFLAG(BACKUP_REF_PTR_POISON_OOB_PTR)
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 637a1cd..1a7c4cb 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -208,6 +208,8 @@ "metrics/predictor_jank_tracker.h", "metrics/scroll_jank_dropped_frame_tracker.cc", "metrics/scroll_jank_dropped_frame_tracker.h", + "metrics/scroll_jank_ukm_reporter.cc", + "metrics/scroll_jank_ukm_reporter.h", "metrics/shared_metrics_buffer.h", "metrics/total_frame_counter.cc", "metrics/total_frame_counter.h", @@ -773,6 +775,7 @@ "metrics/jank_metrics_unittest.cc", "metrics/predictor_jank_tracker_unittest.cc", "metrics/scroll_jank_dropped_frame_tracker_unittest.cc", + "metrics/scroll_jank_ukm_reporter_unittest.cc", "metrics/total_frame_counter_unittest.cc", "metrics/video_playback_roughness_reporter_unittest.cc", "mojo_embedder/async_layer_tree_frame_sink_unittest.cc",
diff --git a/cc/metrics/compositor_frame_reporter.cc b/cc/metrics/compositor_frame_reporter.cc index 64f6f0ee..b9d3c439 100644 --- a/cc/metrics/compositor_frame_reporter.cc +++ b/cc/metrics/compositor_frame_reporter.cc
@@ -1519,6 +1519,9 @@ if (global_trackers_.scroll_jank_dropped_frame_tracker) { global_trackers_.scroll_jank_dropped_frame_tracker->OnScrollStarted(); } + if (global_trackers_.scroll_jank_ukm_reporter) { + global_trackers_.scroll_jank_ukm_reporter->EmitScrollJankUkm(); + } } TRACE_EVENT("input,input.scrolling", "PresentedFrameInformation",
diff --git a/cc/metrics/compositor_frame_reporter.h b/cc/metrics/compositor_frame_reporter.h index ea3a12c..a1783b6 100644 --- a/cc/metrics/compositor_frame_reporter.h +++ b/cc/metrics/compositor_frame_reporter.h
@@ -49,6 +49,7 @@ raw_ptr<PredictorJankTracker> predictor_jank_tracker = nullptr; raw_ptr<ScrollJankDroppedFrameTracker> scroll_jank_dropped_frame_tracker = nullptr; + raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter = nullptr; }; // This is used for tracing and reporting the duration of pipeline stages within
diff --git a/cc/metrics/compositor_frame_reporting_controller.cc b/cc/metrics/compositor_frame_reporting_controller.cc index ee4db3c..3efdc1d 100644 --- a/cc/metrics/compositor_frame_reporting_controller.cc +++ b/cc/metrics/compositor_frame_reporting_controller.cc
@@ -43,6 +43,7 @@ predictor_jank_tracker_(std::make_unique<PredictorJankTracker>()), scroll_jank_dropped_frame_tracker_( std::make_unique<ScrollJankDroppedFrameTracker>()), + scroll_jank_ukm_reporter_(std::make_unique<ScrollJankUkmReporter>()), previous_latency_predictions_main_(base::Microseconds(-1)), previous_latency_predictions_impl_(base::Microseconds(-1)), event_latency_predictions_( @@ -52,6 +53,12 @@ // UKM metrics should be reported if and only if `latency_ukm_reporter` is // set on `global_trackers_`. global_trackers_.latency_ukm_reporter = latency_ukm_reporter_.get(); + + global_trackers_.scroll_jank_ukm_reporter = scroll_jank_ukm_reporter_.get(); + predictor_jank_tracker_->set_scroll_jank_ukm_reporter( + scroll_jank_ukm_reporter_.get()); + scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter( + scroll_jank_ukm_reporter_.get()); } global_trackers_.predictor_jank_tracker = predictor_jank_tracker_.get(); global_trackers_.scroll_jank_dropped_frame_tracker = @@ -70,6 +77,9 @@ pair.reporter->TerminateFrame(FrameTerminationStatus::kDidNotPresentFrame, Now()); } + + predictor_jank_tracker_->set_scroll_jank_ukm_reporter(nullptr); + scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter(nullptr); } void CompositorFrameReportingController::SetVisible(bool visible) { @@ -815,6 +825,7 @@ void CompositorFrameReportingController::SetUkmManager(UkmManager* manager) { latency_ukm_reporter_->set_ukm_manager(manager); + scroll_jank_ukm_reporter_->set_ukm_manager(manager); } CompositorFrameReporter::SmoothThread
diff --git a/cc/metrics/compositor_frame_reporting_controller.h b/cc/metrics/compositor_frame_reporting_controller.h index b28824b..07d9657 100644 --- a/cc/metrics/compositor_frame_reporting_controller.h +++ b/cc/metrics/compositor_frame_reporting_controller.h
@@ -206,6 +206,7 @@ std::unique_ptr<PredictorJankTracker> predictor_jank_tracker_; std::unique_ptr<ScrollJankDroppedFrameTracker> scroll_jank_dropped_frame_tracker_; + std::unique_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_; std::unique_ptr<CompositorFrameReporter> reporters_[PipelineStage::kNumPipelineStages];
diff --git a/cc/metrics/predictor_jank_tracker.cc b/cc/metrics/predictor_jank_tracker.cc index 9967256..fb20385 100644 --- a/cc/metrics/predictor_jank_tracker.cc +++ b/cc/metrics/predictor_jank_tracker.cc
@@ -125,6 +125,9 @@ bool slow_scroll, std::optional<EventMetrics::TraceId> trace_id) { janky_frames_++; + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->IncrementPredictorJankyFrames(); + } TRACE_EVENT_INSTANT( "input.scrolling", "PredictorJankTracker::ReportJankyFrame", [&](perfetto::EventContext ctx) {
diff --git a/cc/metrics/predictor_jank_tracker.h b/cc/metrics/predictor_jank_tracker.h index bc6c6be..018655b 100644 --- a/cc/metrics/predictor_jank_tracker.h +++ b/cc/metrics/predictor_jank_tracker.h
@@ -9,6 +9,7 @@ #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/metrics/event_metrics.h" +#include "cc/metrics/scroll_jank_ukm_reporter.h" namespace cc { @@ -34,6 +35,11 @@ // as it should be comparing neighbouring frames only. void ResetCurrentScrollReporting(); + void set_scroll_jank_ukm_reporter( + raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter) { + scroll_jank_ukm_reporter_ = scroll_jank_ukm_reporter; + } + private: // The metric works by storing a sliding window of the previous two // frames, this function moves the sliding window storing the newer @@ -73,6 +79,8 @@ float total_frames_ = 0; float janky_frames_ = 0; + + raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_ = nullptr; }; } // namespace cc
diff --git a/cc/metrics/scroll_jank_dropped_frame_tracker.cc b/cc/metrics/scroll_jank_dropped_frame_tracker.cc index 81ea98fc..c86a5f40 100644 --- a/cc/metrics/scroll_jank_dropped_frame_tracker.cc +++ b/cc/metrics/scroll_jank_dropped_frame_tracker.cc
@@ -268,8 +268,21 @@ kVsyncCountsMax, kVsyncCountsBuckets); fixed_window_.missed_vsyncs += curr_frame_missed_vsyncs; per_scroll_->missed_vsyncs += curr_frame_missed_vsyncs; + + // TODO(b/306611560): If experimental per scroll logic is promoted to + // default, then UKM reporting will need to be recorded under the same + // conditions. + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->IncrementDelayedFrameCount(); + scroll_jank_ukm_reporter_->AddMissedVsyncs(curr_frame_missed_vsyncs); + } + if (curr_frame_missed_vsyncs > per_scroll_->max_missed_vsyncs) { per_scroll_->max_missed_vsyncs = curr_frame_missed_vsyncs; + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->set_max_missed_vsyncs( + curr_frame_missed_vsyncs); + } } if (curr_frame_missed_vsyncs > fixed_window_.max_missed_vsyncs) { fixed_window_.max_missed_vsyncs = curr_frame_missed_vsyncs; @@ -298,13 +311,22 @@ // Per scroll experimental_per_scroll_vsync_->missed_vsyncs += curr_frame_missed_vsyncs; experimental_per_scroll_vsync_->num_past_vsyncs += curr_frame_total_vsyncs; + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->AddVsyncs(curr_frame_total_vsyncs); + } } else { ++experimental_vsync_fixed_window_.num_past_vsyncs; ++experimental_per_scroll_vsync_->num_past_vsyncs; + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->AddVsyncs(1); + } } ++fixed_window_.num_presented_frames; ++per_scroll_->num_presented_frames; + if (scroll_jank_ukm_reporter_) { + scroll_jank_ukm_reporter_->IncrementFrameCount(); + } if (fixed_window_.num_presented_frames == kHistogramEmitFrequency) { EmitPerWindowHistogramsAndResetCounters();
diff --git a/cc/metrics/scroll_jank_dropped_frame_tracker.h b/cc/metrics/scroll_jank_dropped_frame_tracker.h index 80bf649..6acc173 100644 --- a/cc/metrics/scroll_jank_dropped_frame_tracker.h +++ b/cc/metrics/scroll_jank_dropped_frame_tracker.h
@@ -9,8 +9,10 @@ #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/metrics/event_metrics.h" +#include "cc/metrics/scroll_jank_ukm_reporter.h" namespace cc { +class ScrollJankUkmReporter; class CC_EXPORT ScrollJankDroppedFrameTracker { public: @@ -25,6 +27,11 @@ base::TimeDelta vsync_interval); void OnScrollStarted(); + void set_scroll_jank_ukm_reporter( + raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter) { + scroll_jank_ukm_reporter_ = scroll_jank_ukm_reporter; + } + static constexpr int kHistogramEmitFrequency = 64; static constexpr const char* kDelayedFramesWindowHistogram = "Event.ScrollJank.DelayedFramesPercentage.FixedWindow"; @@ -79,6 +86,8 @@ JankData experimental_vsync_fixed_window_; std::optional<JankData> per_scroll_; std::optional<JankData> experimental_per_scroll_vsync_; + + raw_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_ = nullptr; }; } // namespace cc
diff --git a/cc/metrics/scroll_jank_ukm_reporter.cc b/cc/metrics/scroll_jank_ukm_reporter.cc new file mode 100644 index 0000000..3be64d3a --- /dev/null +++ b/cc/metrics/scroll_jank_ukm_reporter.cc
@@ -0,0 +1,66 @@ +// 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 "cc/metrics/scroll_jank_ukm_reporter.h" + +#include "cc/trees/ukm_manager.h" +#include "services/metrics/public/cpp/metrics_utils.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" + +namespace cc { + +ScrollJankUkmReporter::ScrollJankUkmReporter() = default; +ScrollJankUkmReporter::~ScrollJankUkmReporter() { + EmitScrollJankUkm(); + ukm_manager_ = nullptr; +} + +void ScrollJankUkmReporter::IncrementFrameCount() { + num_frames_++; +} + +void ScrollJankUkmReporter::IncrementDelayedFrameCount() { + num_delayed_frames_++; +} + +void ScrollJankUkmReporter::AddVsyncs(int vsyncs) { + num_vsyncs_ += vsyncs; +} + +void ScrollJankUkmReporter::AddMissedVsyncs(int missed_vsyncs) { + num_missed_vsyncs_ += missed_vsyncs; +} + +void ScrollJankUkmReporter::IncrementPredictorJankyFrames() { + predictor_jank_frames_++; +} + +void ScrollJankUkmReporter::EmitScrollJankUkm() { + if (ukm_manager_) { + ukm::builders::Event_Scroll builder(ukm_manager_->source_id()); + builder.SetFrameCount( + ukm::GetExponentialBucketMinForCounts1000(num_frames_)); + builder.SetVsyncCount( + ukm::GetExponentialBucketMinForCounts1000(num_vsyncs_)); + builder.SetScrollJank_MissedVsyncsMax( + ukm::GetExponentialBucketMinForCounts1000(max_missed_vsyncs_)); + builder.SetScrollJank_MissedVsyncsSum( + ukm::GetExponentialBucketMinForCounts1000(num_missed_vsyncs_)); + builder.SetScrollJank_DelayedFrameCount( + ukm::GetExponentialBucketMinForCounts1000(num_delayed_frames_)); + builder.SetPredictorJankyFrameCount( + ukm::GetExponentialBucketMinForCounts1000(predictor_jank_frames_)); + builder.Record(ukm_manager_->recorder()); + } + + num_frames_ = 0; + num_vsyncs_ = 0; + num_missed_vsyncs_ = 0; + max_missed_vsyncs_ = 0; + num_delayed_frames_ = 0; + predictor_jank_frames_ = 0; +} + +} // namespace cc
diff --git a/cc/metrics/scroll_jank_ukm_reporter.h b/cc/metrics/scroll_jank_ukm_reporter.h new file mode 100644 index 0000000..362c97c --- /dev/null +++ b/cc/metrics/scroll_jank_ukm_reporter.h
@@ -0,0 +1,56 @@ +// 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 CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_ +#define CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_ + +#include <optional> +#include "base/memory/raw_ptr.h" +#include "cc/cc_export.h" + +// TODO(b/294040250): Add metrics for ScrollPredictor histogram. + +namespace cc { +class UkmManager; + +class CC_EXPORT ScrollJankUkmReporter { + public: + ScrollJankUkmReporter(); + ~ScrollJankUkmReporter(); + + ScrollJankUkmReporter(const ScrollJankUkmReporter&) = delete; + + void IncrementFrameCount(); + void IncrementDelayedFrameCount(); + void AddVsyncs(int vsyncs); + void AddMissedVsyncs(int missed_vsyncs); + void IncrementPredictorJankyFrames(); + + void EmitScrollJankUkm(); + + void set_max_missed_vsyncs(int max_missed_vsyncs) { + max_missed_vsyncs_ = max_missed_vsyncs; + } + + void set_ukm_manager(UkmManager* manager) { ukm_manager_ = manager; } + + private: + int num_frames_ = 0; + int num_vsyncs_ = 0; + int num_missed_vsyncs_ = 0; + int max_missed_vsyncs_ = 0; + int num_delayed_frames_ = 0; + int predictor_jank_frames_ = 0; + + // This is pointing to the LayerTreeHostImpl::ukm_manager_, which is + // initialized right after the LayerTreeHostImpl is created. So when this + // pointer is initialized, there should be no trackers yet. Moreover, the + // LayerTreeHostImpl::ukm_manager_ lives as long as the LayerTreeHostImpl, so + // this pointer should never be null as long as LayerTreeHostImpl is alive. + raw_ptr<UkmManager> ukm_manager_ = nullptr; +}; + +} // namespace cc + +#endif // CC_METRICS_SCROLL_JANK_UKM_REPORTER_H_
diff --git a/cc/metrics/scroll_jank_ukm_reporter_unittest.cc b/cc/metrics/scroll_jank_ukm_reporter_unittest.cc new file mode 100644 index 0000000..808087d17 --- /dev/null +++ b/cc/metrics/scroll_jank_ukm_reporter_unittest.cc
@@ -0,0 +1,304 @@ +// 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 "cc/metrics/scroll_jank_ukm_reporter.h" + +#include "base/test/simple_test_tick_clock.h" +#include "cc/metrics/predictor_jank_tracker.h" +#include "cc/metrics/scroll_jank_dropped_frame_tracker.h" +#include "cc/trees/ukm_manager.h" +#include "components/ukm/test_ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { +const char kTestUrl[] = "https://example.com/foo"; +const int64_t kTestSourceId = 100; +} // namespace + +class ScrollJankUkmReporterTest : public testing::Test { + public: + ScrollJankUkmReporterTest() = default; + + void SetUp() override { + base_time_ = base::TimeTicks::Now(); + + auto recorder = std::make_unique<ukm::TestAutoSetUkmRecorder>(); + test_ukm_recorder_ = recorder.get(); + ukm_manager_ = std::make_unique<UkmManager>(std::move(recorder)); + test_ukm_recorder_->UpdateSourceURL(kTestSourceId, GURL(kTestUrl)); + ukm_manager_->SetSourceId(kTestSourceId); + + scroll_jank_ukm_reporter_ = std::make_unique<ScrollJankUkmReporter>(); + scroll_jank_ukm_reporter_->set_ukm_manager(ukm_manager_.get()); + + scroll_jank_dropped_frame_tracker_ = + std::make_unique<ScrollJankDroppedFrameTracker>(); + scroll_jank_dropped_frame_tracker_->set_scroll_jank_ukm_reporter( + scroll_jank_ukm_reporter_.get()); + scroll_jank_dropped_frame_tracker_->OnScrollStarted(); + + predictor_jank_tracker_ = std::make_unique<PredictorJankTracker>(); + predictor_jank_tracker_->set_scroll_jank_ukm_reporter( + scroll_jank_ukm_reporter_.get()); + } + + void ReportFramesToScrollJankDroppedFrameTracker( + base::TimeTicks first_input_ts, + base::TimeTicks last_input_ts, + base::TimeTicks presentation_ts) { + base::SimpleTestTickClock tick_clock; + tick_clock.SetNowTicks(base::TimeTicks(first_input_ts)); + auto event = ScrollUpdateEventMetrics::CreateForTesting( + ui::ET_GESTURE_SCROLL_UPDATE, ui::ScrollInputType::kWheel, + /*is_inertial=*/false, + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + /*delta=*/10.0f, first_input_ts, base::TimeTicks(), &tick_clock, + /*trace_id=*/std::nullopt); + scroll_jank_dropped_frame_tracker_->ReportLatestPresentationData( + *event.get(), last_input_ts, presentation_ts, vsync_interval); + } + + void ReportFramesToPredictorJankTracker(double delta, + base::TimeTicks first_input_ts, + base::TimeTicks presentation_ts) { + base::SimpleTestTickClock tick_clock; + tick_clock.SetNowTicks(first_input_ts); + auto event = ScrollUpdateEventMetrics::CreateForTesting( + ui::ET_GESTURE_SCROLL_UPDATE, ui::ScrollInputType::kWheel, + /*is_inertial=*/false, + ScrollUpdateEventMetrics::ScrollUpdateType::kContinued, + /*delta=*/10.0f, first_input_ts, base::TimeTicks(), &tick_clock, + /*trace_id=*/std::nullopt); + predictor_jank_tracker_->ReportLatestScrollDelta( + delta, presentation_ts, vsync_interval, event->trace_id()); + } + + protected: + base::TimeTicks base_time_; + raw_ptr<ukm::TestUkmRecorder, DanglingUntriaged> test_ukm_recorder_; + std::unique_ptr<UkmManager> ukm_manager_; + std::unique_ptr<ScrollJankUkmReporter> scroll_jank_ukm_reporter_; + std::unique_ptr<ScrollJankDroppedFrameTracker> + scroll_jank_dropped_frame_tracker_; + std::unique_ptr<PredictorJankTracker> predictor_jank_tracker_; + + private: + constexpr static base::TimeDelta vsync_interval = base::Milliseconds(16); +}; + +TEST_F(ScrollJankUkmReporterTest, NoJankUkmRecorded) { + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 0); +} + +TEST_F(ScrollJankUkmReporterTest, NoJankyFrames) { + // Report one frame per vsync. + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(111), + base_time_ + base::Milliseconds(148)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(119), + base_time_ + base::Milliseconds(127), + base_time_ + base::Milliseconds(164)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 2); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 0); +} + +TEST_F(ScrollJankUkmReporterTest, JankyFrames) { + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(111), + base_time_ + base::Milliseconds(148)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(119), + base_time_ + base::Milliseconds(127), + base_time_ + base::Milliseconds(196)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(135), + base_time_ + base::Milliseconds(143), + base_time_ + base::Milliseconds(228)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kFrameCountName, 3); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_DelayedFrameCountName, 2); +} + +TEST_F(ScrollJankUkmReporterTest, NoMissedVsyncs) { + // Report one frame per vsync. + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(111), + base_time_ + base::Milliseconds(148)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(119), + base_time_ + base::Milliseconds(127), + base_time_ + base::Milliseconds(164)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 2); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 0); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 0); +} + +TEST_F(ScrollJankUkmReporterTest, OneMissedVsync) { + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(111), + base_time_ + base::Milliseconds(148)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(119), + base_time_ + base::Milliseconds(127), + base_time_ + base::Milliseconds(164)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(135), + base_time_ + base::Milliseconds(143), + base_time_ + base::Milliseconds(196)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 4); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 1); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 1); +} + +TEST_F(ScrollJankUkmReporterTest, MultipleMissedVsyncs) { + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(103), + base_time_ + base::Milliseconds(148)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(119), + base_time_ + base::Milliseconds(127), + base_time_ + base::Milliseconds(196)); + + ReportFramesToScrollJankDroppedFrameTracker( + base_time_ + base::Milliseconds(135), + base_time_ + base::Milliseconds(151), + base_time_ + base::Milliseconds(228)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), ukm::builders::Event_Scroll::kVsyncCountName, 6); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsMaxName, 2); + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kScrollJank_MissedVsyncsSumName, 3); +} + +TEST_F(ScrollJankUkmReporterTest, NoPredictorJank) { + ReportFramesToPredictorJankTracker(10, base_time_, + base_time_ + base::Milliseconds(103)); + ReportFramesToPredictorJankTracker(10, base_time_, + base_time_ + base::Milliseconds(119)); + ReportFramesToPredictorJankTracker(10, base_time_, + base_time_ + base::Milliseconds(135)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 0); +} + +TEST_F(ScrollJankUkmReporterTest, PredictorJank) { + ReportFramesToPredictorJankTracker(10, base_time_, + base_time_ + base::Milliseconds(103)); + ReportFramesToPredictorJankTracker(50, base_time_, + base_time_ + base::Milliseconds(135)); + ReportFramesToPredictorJankTracker(10, base_time_, + base_time_ + base::Milliseconds(151)); + + scroll_jank_ukm_reporter_->EmitScrollJankUkm(); + + auto entries = test_ukm_recorder_->GetEntriesByName( + ukm::builders::Event_Scroll::kEntryName); + EXPECT_EQ(1u, entries.size()); + + test_ukm_recorder_->ExpectEntryMetric( + entries.back(), + ukm::builders::Event_Scroll::kPredictorJankyFrameCountName, 1); +} + +} // namespace cc
diff --git a/cc/trees/ukm_manager.h b/cc/trees/ukm_manager.h index e61c14a4..2af22a3 100644 --- a/cc/trees/ukm_manager.h +++ b/cc/trees/ukm_manager.h
@@ -55,7 +55,9 @@ const CompositorFrameReporter::ProcessedVizBreakdown& processed_viz_breakdown) const; - ukm::UkmRecorder* recorder_for_testing() { return recorder_.get(); } + ukm::UkmRecorder* recorder() { return recorder_.get(); } + + ukm::SourceId source_id() { return source_id_; } private: ukm::SourceId source_id_ = ukm::kInvalidSourceId;
diff --git a/cc/trees/ukm_manager_unittest.cc b/cc/trees/ukm_manager_unittest.cc index 04c3832..2745178e 100644 --- a/cc/trees/ukm_manager_unittest.cc +++ b/cc/trees/ukm_manager_unittest.cc
@@ -129,7 +129,7 @@ } ukm::TestUkmRecorder* recorder() { - return static_cast<ukm::TestUkmRecorder*>(manager_->recorder_for_testing()); + return static_cast<ukm::TestUkmRecorder*>(manager_->recorder()); } std::unique_ptr<EventMetrics> SetupEventMetrics(
diff --git a/chrome/VERSION b/chrome/VERSION index 2e810774..f116613 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=122 MINOR=0 -BUILD=6196 +BUILD=6197 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java index a64497cc..77a2cc9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java
@@ -84,11 +84,10 @@ private static final String ENABLED_GROUP_SUFFIX = "_Enabled"; private static final String CONTROL_GROUP_SUFFIX = "_Control"; private static final String DEFAULT_ON_GROUP_NAME_PREFIX = "DefaultOn_"; - private static final String OPT_IN_GROUP_NAME_PREFIX = "OptIn_"; // This is used to lookup the name of a feature used to track a cohort of users who triggered // the global default experiment, or would have triggered for control groups. private static final String PARAM_GLOBAL_DEFAULTS_COHORT_ID = "global_setting_cohort_id"; - private static final int DEFAULT_GLOBAL_DEFAULTS_COHORT_ID = 0; + private static final int DEFAULT_GLOBAL_DEFAULTS_COHORT_ID = 1; private static final String GLOBAL_DEFAULTS_COHORT_NAME = "RequestDesktopSiteDefaultsCohort"; private static final String GLOBAL_DEFAULTS_ENABLED_COHORT_NAME = "RequestDesktopSiteDefaultsEnabledCohort"; @@ -982,12 +981,10 @@ return; } - // For backward compatibility. - if (cohortId == 0) { - maybeRegisterSyntheticFieldTrials(isControlGroup, screenSizeThreshold, isOptInArm); + if (isOptInArm) { + // Opt-in arm is not supported for the new cohort tracking. return; } - assert !isOptInArm : "Opt-in arm is not supported for the new cohort tracking."; String thresholdAsString = String.valueOf(screenSizeThreshold).replace('.', '_'); String baseGroupName = DEFAULT_ON_GROUP_NAME_PREFIX + thresholdAsString + "_" + cohortId; @@ -1016,37 +1013,6 @@ SyntheticTrialAnnotationMode.CURRENT_LOG); } - private static void maybeRegisterSyntheticFieldTrials( - boolean isControlGroup, double screenSizeThreshold, boolean isOptInArm) { - String thresholdAsString = String.valueOf(screenSizeThreshold).replace('.', '_'); - String baseGroupName = - (isOptInArm ? OPT_IN_GROUP_NAME_PREFIX : DEFAULT_ON_GROUP_NAME_PREFIX) - + thresholdAsString; - - String syntheticFeatureName = - isControlGroup - ? ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL_SYNTHETIC - : ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_SYNTHETIC; - if (isOptInArm) { - syntheticFeatureName = - isControlGroup - ? ChromeFeatureList.REQUEST_DESKTOP_SITE_OPT_IN_CONTROL_SYNTHETIC - : ChromeFeatureList.REQUEST_DESKTOP_SITE_OPT_IN_SYNTHETIC; - } - - if (!isControlGroup && !ChromeFeatureList.isEnabled(syntheticFeatureName)) { - UmaSessionStats.registerSyntheticFieldTrial( - syntheticFeatureName, - baseGroupName + ENABLED_GROUP_SUFFIX, - SyntheticTrialAnnotationMode.CURRENT_LOG); - } else if (isControlGroup && !ChromeFeatureList.isEnabled(syntheticFeatureName)) { - UmaSessionStats.registerSyntheticFieldTrial( - syntheticFeatureName, - baseGroupName + CONTROL_GROUP_SUFFIX, - SyntheticTrialAnnotationMode.CURRENT_LOG); - } - } - @VisibleForTesting static void onGlobalSettingOptInMessageClicked( Profile profile, ObservableSupplier<Tab> currentTabSupplier) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java index 9fe17d6..42fdcb0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
@@ -931,19 +931,6 @@ } @Test - public void testMaybeRegisterSyntheticFieldTrials_DefaultOnEnabled12Inches() { - RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 0, false); - Assert.assertEquals( - "Trial name is incorrect.", - "RequestDesktopSiteDefaultsSynthetic", - sGlobalDefaultsExperimentTrialName); - Assert.assertEquals( - "Group name is incorrect.", - "DefaultOn_12_0_Enabled", - sGlobalDefaultsExperimentGroupName); - } - - @Test public void testMaybeRegisterSyntheticFieldTrials_DefaultOnEnabled12Inches_WithCohortId() { RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 2, false); Assert.assertEquals( @@ -955,19 +942,6 @@ } @Test - public void testMaybeRegisterSyntheticFieldTrials_DefaultOnControl12Inches() { - RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(true, 12.0, 0, false); - Assert.assertEquals( - "Trial name is incorrect.", - "RequestDesktopSiteDefaultsControlSynthetic", - sGlobalDefaultsExperimentTrialName); - Assert.assertEquals( - "Group name is incorrect.", - "DefaultOn_12_0_Control", - sGlobalDefaultsExperimentGroupName); - } - - @Test public void testMaybeRegisterSyntheticFieldTrials_DefaultOnControl12Inches_WithCohortId() { RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(true, 12.0, 2, false); Assert.assertEquals( @@ -979,29 +953,6 @@ } @Test - public void testMaybeRegisterSyntheticFieldTrials_OptInEnabled10Inches() { - RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 10.0, 0, true); - Assert.assertEquals( - "Trial name is incorrect.", - "RequestDesktopSiteOptInSynthetic", - sGlobalDefaultsExperimentTrialName); - Assert.assertEquals( - "Group name is incorrect.", - "OptIn_10_0_Enabled", - sGlobalDefaultsExperimentGroupName); - } - - @Test - public void testMaybeRegisterSyntheticFieldTrials_DoNothingWhenExperimentIsActive() { - enableFeatureWithParams("RequestDesktopSiteDefaultsSynthetic", null, true); - RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 0, false); - Assert.assertTrue( - "Synthetic trial should not be registered.", - sGlobalDefaultsExperimentTrialName == null - && sGlobalDefaultsExperimentGroupName == null); - } - - @Test public void testMaybeRegisterSyntheticFieldTrials_ExperimentIsActive_WithCohortId() { enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort2", null, true); RequestDesktopUtils.maybeRegisterSyntheticFieldTrials(false, 12.0, 2, false); @@ -1807,10 +1758,8 @@ private void disableGlobalDefaultsExperimentFeatures() { enableFeatureWithParams("RequestDesktopSiteDefaults", null, false); enableFeatureWithParams("RequestDesktopSiteDefaultsControl", null, false); - enableFeatureWithParams("RequestDesktopSiteDefaultsControlSynthetic", null, false); - enableFeatureWithParams("RequestDesktopSiteDefaultsSynthetic", null, false); - enableFeatureWithParams("RequestDesktopSiteOptInControlSynthetic", null, false); - enableFeatureWithParams("RequestDesktopSiteOptInSynthetic", null, false); + enableFeatureWithParams("RequestDesktopSiteDefaultsControlCohort1", null, false); + enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort1", null, false); enableFeatureWithParams("RequestDesktopSiteDefaultsControlCohort2", null, false); enableFeatureWithParams("RequestDesktopSiteDefaultsEnabledCohort2", null, false); }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b4da2225..8534f64 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -9106,32 +9106,32 @@ </message> <!-- Strings for tab organization --> - <message name="IDS_TOOLTIP_TAB_ORGANIZE" desc="The tooltip for the Tab Organization button." translateable="false"> + <message name="IDS_TOOLTIP_TAB_ORGANIZE" desc="The tooltip for the Tab Organization button."> Organize tabs? </message> - <message name="IDS_TAB_ORGANIZE" desc="The text label of the Tab Organization button." translateable="false"> + <message name="IDS_TAB_ORGANIZE" desc="The text label of the Tab Organization button."> Organize tabs? </message> - <message name="IDS_TOOLTIP_TAB_ORGANIZE_CLOSE" desc="The tooltip for the close button within the Tab Organization button." translateable="false"> + <message name="IDS_TOOLTIP_TAB_ORGANIZE_CLOSE" desc="The tooltip for the close button within the Tab Organization button."> Dismiss suggestion </message> - <message name="IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER" desc="Placeholder text for the Tab Organization feedback dialog." translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER" desc="Placeholder text for the Tab Organization feedback dialog."> Send feedback for Suggested Groups </message> <if expr="use_titlecase"> - <message name="IDS_TAB_ORGANIZE_MENU" desc="In Title Case: The text label for the tab organization app menu item." translateable="false"> + <message name="IDS_TAB_ORGANIZE_MENU" desc="In Title Case: The text label for the tab organization app menu item."> Organize Tabs </message> </if> <if expr="not use_titlecase"> - <message name="IDS_TAB_ORGANIZE_MENU" desc="The text label for the tab organization app menu item." translateable="false"> + <message name="IDS_TAB_ORGANIZE_MENU" desc="The text label for the tab organization app menu item."> Organize tabs </message> </if> - <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH" desc="The body text of the IPH describing how to interact with a tab group resulting from tab organization." translateable="false"> + <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH" desc="The body text of the IPH describing how to interact with a tab group resulting from tab organization."> Right-click on the tab group name to edit this group or click to collapse </message> - <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH_SCREENREADER" desc="The screen reader text of the IPH describing how to interact with a tab group resulting from tab organization." translateable="false"> + <message name="IDS_TAB_ORGANIZATION_SUCCESS_IPH_SCREENREADER" desc="The screen reader text of the IPH describing how to interact with a tab group resulting from tab organization." is_accessibility_with_no_ui="true"> Select the tab group and activate the context menu to edit </message> @@ -9320,7 +9320,7 @@ <message name="IDS_ACCNAME_TAB_SEARCH" desc="The accessible name for the Tab Search bubble."> Search tabs </message> - <message name="IDS_ACCNAME_TAB_ORGANIZE" desc="The accessible name for the Tab Organization button." translateable="false"> + <message name="IDS_ACCNAME_TAB_ORGANIZE" desc="The accessible name for the Tab Organization button." is_accessibility_with_no_ui="true"> Group related tabs </message> <message name="IDS_ACCNAME_TAB_SCROLL_LEADING" desc="The accessible name for the TabStrip leading scroll button."> @@ -10428,7 +10428,7 @@ <message name="IDS_TAB_CXMENU_MOVETOANOTHERNEWWINDOW" desc="The label for the Tab context item to move items to a new window from the 'Move tabs to another window' submenu."> New window </message> - <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="The label of the 'Organize tabs' Tab context menu item." translateable="false"> + <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="The label of the 'Organize tabs' Tab context menu item."> Organize similar tabs </message> <message name="IDS_TAB_CXMENU_FOLLOW_SITE" desc="The label of the tab context menu item @@ -10531,7 +10531,7 @@ <message name="IDS_TAB_CXMENU_MOVETOANOTHERNEWWINDOW" desc="In Title Case: The label for the Tab context item to move items to a new window from the 'Move tabs to another window' submenu."> New Window </message> - <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="In Title Case: The label of the 'Organize tabs' Tab context menu item." translateable="false"> + <message name="IDS_TAB_CXMENU_ORGANIZE_TABS" desc="In Title Case: The label of the 'Organize tabs' Tab context menu item."> Organize Similar Tabs </message> <message name="IDS_TAB_CXMENU_FOLLOW_SITE" desc="In Title Case: The label of the tab context menu item for following a site."> @@ -10635,10 +10635,10 @@ <message name="IDS_TAB_SEARCH_COLLAPSE_RECENTLY_CLOSED" desc="The tooltip for the RECENTLY CLOSED button when it's expanded"> Collapse recently closed </message> - <message name="IDS_TAB_SEARCH_TAB_NAME" desc="The tab title for tab search in the tab search bubble" translateable="false"> + <message name="IDS_TAB_SEARCH_TAB_NAME" desc="The tab title for tab search in the tab search bubble"> All tabs </message> - <message name="IDS_TAB_ORGANIZATION_TAB_NAME" desc="The tab title for tab organization in the tab search bubble" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_TAB_NAME" desc="The tab title for tab organization in the tab search bubble"> Organize tabs </message> <message name="IDS_TAB_ORGANIZATION_CREATE_GROUP" desc="The label for the button that creates a tab group in the tab organization UI"> @@ -10647,100 +10647,100 @@ <message name="IDS_TAB_ORGANIZATION_DISMISS" desc="The label for the button that dismisses the tab organization UI"> Dismiss </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE" desc="The header text for the not started state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE" desc="The header text for the not started state in the tab organization UI"> Check if tabs can be organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE" desc="The header text for the first run experience of the not started state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE" desc="The header text for the first run experience of the not started state in the tab organization UI"> Let Chrome organize your tabs </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY" desc="The body text for the not started state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY" desc="The body text for the not started state in the tab organization UI"> You can check for tab group suggestions at any time </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE" desc="The body text for the first run experience of the not started state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE" desc="The body text for the first run experience of the not started state in the tab organization UI"> You'll get tab group suggestions that group similar tabs to help you stay organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT" desc="The body text for the not started state in the tab organization UI, when not signed in" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT" desc="The body text for the not started state in the tab organization UI, when not signed in"> Sign in and turn on sync to let Chrome suggest tab groups and keep your tabs organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED" desc="The body text for the not started state in the tab organization UI, when signed in but unsynced" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED" desc="The body text for the not started state in the tab organization UI, when signed in but unsynced"> Turn on sync to let Chrome suggest tab groups and keep your tabs organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY" desc="The body text for the not started state in the tab organization UI, when history sync is disabled" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY" desc="The body text for the not started state in the tab organization UI, when history sync is disabled"> Turn on History sync in Settings to let Chrome suggest tab groups and keep your tabs organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED" desc="The body text for the not started state in the tab organization UI, sync is paused" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED" desc="The body text for the not started state in the tab organization UI, sync is paused"> Sign in to let Chrome suggest tab groups and keep your tabs organized </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON" desc="The label for the button in the not started state of the tab organization UI, when synced" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON" desc="The label for the button in the not started state of the tab organization UI, when synced"> Check now </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE" desc="The first run experience label for the button in the not started state of the tab organization UI, when synced" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE" desc="The first run experience label for the button in the not started state of the tab organization UI, when synced"> Let's go </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED" desc="The label for the button in the not started state of the tab organization UI, when not signed in or signed in but unsynced" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED" desc="The label for the button in the not started state of the tab organization UI, when not signed in or signed in but unsynced"> Turn on sync </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY" desc="The label for the button in the not started state of the tab organization UI, when history sync is disabled" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY" desc="The label for the button in the not started state of the tab organization UI, when history sync is disabled"> Settings </message> - <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED" desc="The label for the button in the not started state of the tab organization UI, when sync is paused" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED" desc="The label for the button in the not started state of the tab organization UI, when sync is paused"> Sign in </message> - <message name="IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE" desc="The header text for the in progress state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE" desc="The header text for the in progress state in the tab organization UI"> Organizing into a tab group… </message> - <message name="IDS_TAB_ORGANIZATION_SUCCESS_TITLE" desc="The header text for the success state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_SUCCESS_TITLE" desc="The header text for the success state in the tab organization UI"> Tab group suggestion </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC" desc="The header text for the generic failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC" desc="The header text for the generic failure state in the tab organization UI"> Something went wrong </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING" desc="The header text for the grouping failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING" desc="The header text for the grouping failure state in the tab organization UI"> No groups found </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK" desc="The pre-link body text for the generic failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK" desc="The pre-link body text for the generic failure state in the tab organization UI. This should form a sentence when followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK."> Tab group suggestions are currently unavailable. You can </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK" desc="The link body text for the generic failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK" desc="The link body text for the generic failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK and followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK."> refresh now </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK" desc="The post-link body text for the generic failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK" desc="The post-link body text for the generic failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK."> or try again later. </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK" desc="The pre-link body text for the grouping failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK" desc="The pre-link body text for the grouping failure state in the tab organization UI. This should form a sentence when followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK."> You can </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK" desc="The link body text for the grouping failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK" desc="The link body text for the grouping failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK and followed by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK."> refresh now </message> - <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK" desc="The post-link body text for the grouping failure state in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK" desc="The post-link body text for the grouping failure state in the tab organization UI. This should form a sentence when preceded by IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK and IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK."> or try again later after you open new similar tabs. </message> - <message name="IDS_TAB_ORGANIZATION_TIP_TITLE" desc="The bolded text at the start of the tip in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_TIP_TITLE" desc="The bolded text at the start of the tip in the tab organization UI"> Tip: </message> - <message name="IDS_TAB_ORGANIZATION_TIP_BODY" desc="The main text of the tip in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_TIP_BODY" desc="The main text of the tip in the tab organization UI"> You can create your own tab group. </message> - <message name="IDS_TAB_ORGANIZATION_TIP_ACTION" desc="The actionable text of the tip in the tab organization UI" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_TIP_ACTION" desc="The actionable text of the tip in the tab organization UI"> Show me how </message> - <message name="IDS_TAB_ORGANIZATION_TIP_ARIA_DESCRIPTION" desc="The a11y description of the tip in the tab organization UI" translateable="false" is_accessibility_with_no_ui="true"> + <message name="IDS_TAB_ORGANIZATION_TIP_ARIA_DESCRIPTION" desc="The a11y description of the tip in the tab organization UI" is_accessibility_with_no_ui="true"> Launch tab group tutorial </message> - <message name="IDS_TAB_ORGANIZATION_DISCLAIMER" desc="The disclaimer text in the tab organization UI results state for getting more information" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_DISCLAIMER" desc="The disclaimer text in the tab organization UI results state for getting more information"> This is an experimental AI feature and won't always get it right. </message> - <message name="IDS_TAB_ORGANIZATION_LEARN_MORE" desc="The actionable text in the tab organization UI results state for getting more information" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_LEARN_MORE" desc="The actionable text in the tab organization UI results state for getting more information"> Learn more </message> - <message name="IDS_TAB_ORGANIZATION_CLOSE_TAB" desc="The accessible label in the tab organization UI results state for removing a tab" translateable="false" is_accessibility_with_no_ui="true"> + <message name="IDS_TAB_ORGANIZATION_CLOSE_TAB" desc="The accessible label in the tab organization UI results state for removing a tab" is_accessibility_with_no_ui="true"> Remove <ph name="TAB_TITLE">$1<ex>New Tab</ex></ph> from tab group </message> - <message name="IDS_TAB_ORGANIZATION_REJECT_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current suggestion" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_REJECT_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current suggestion"> Refresh </message> - <message name="IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current (and final) suggestion" translateable="false"> + <message name="IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION" desc="The button text in the tab organization UI results state for rejecting the current (and final) suggestion"> Clear </message>
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1 new file mode 100644 index 0000000..c4610b87 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_CXMENU_ORGANIZE_TABS.png.sha1
@@ -0,0 +1 @@ +4496b3c76fc1f14929491b8ff0911276dee22b5f \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1 index e1333e5..c1bcfb9a 100644 --- a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_CREATE_GROUP.png.sha1
@@ -1 +1 @@ -f54132a5f004928712119e0367b7f58d77f1dbc7 \ No newline at end of file +4f599c7f3dbb17f3c40cbeba78cfb2841fd033ce \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1 new file mode 100644 index 0000000..7f0ee12 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_DISCLAIMER.png.sha1
@@ -0,0 +1 @@ +7786d7ac7758cc3d1d61de53965fd9e6cec09983 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1 new file mode 100644 index 0000000..e3e934d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_LINK.png.sha1
@@ -0,0 +1 @@ +d948ede26072e039e12bbe510fba21f03a377485 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1 new file mode 100644 index 0000000..e3e934d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_POST_LINK.png.sha1
@@ -0,0 +1 @@ +d948ede26072e039e12bbe510fba21f03a377485 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1 new file mode 100644 index 0000000..e3e934d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GENERIC_PRE_LINK.png.sha1
@@ -0,0 +1 @@ +d948ede26072e039e12bbe510fba21f03a377485 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1 new file mode 100644 index 0000000..9b63e69f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_LINK.png.sha1
@@ -0,0 +1 @@ +a20d651a3346ac62951076befe514b6e2211bb5c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1 new file mode 100644 index 0000000..9b63e69f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_POST_LINK.png.sha1
@@ -0,0 +1 @@ +a20d651a3346ac62951076befe514b6e2211bb5c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1 new file mode 100644 index 0000000..9b63e69f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_BODY_GROUPING_PRE_LINK.png.sha1
@@ -0,0 +1 @@ +a20d651a3346ac62951076befe514b6e2211bb5c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1 new file mode 100644 index 0000000..e3e934d --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GENERIC.png.sha1
@@ -0,0 +1 @@ +d948ede26072e039e12bbe510fba21f03a377485 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1 new file mode 100644 index 0000000..9b63e69f --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FAILURE_TITLE_GROUPING.png.sha1
@@ -0,0 +1 @@ +a20d651a3346ac62951076befe514b6e2211bb5c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1 new file mode 100644 index 0000000..bdf645f6 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_FEEDBACK_PLACEHOLDER.png.sha1
@@ -0,0 +1 @@ +08fad7898a5da3ecf26eade4fd9cc8ff0c54cf17 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1 new file mode 100644 index 0000000..b3133cb --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_IN_PROGRESS_TITLE.png.sha1
@@ -0,0 +1 @@ +48f6b91c6dc42f6e2b142baa880569dfe0902392 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..7f0ee12 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +7786d7ac7758cc3d1d61de53965fd9e6cec09983 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1 new file mode 100644 index 0000000..a479520 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY.png.sha1
@@ -0,0 +1 @@ +3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1 new file mode 100644 index 0000000..9b04a8c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_FRE.png.sha1
@@ -0,0 +1 @@ +7d7533129e5e7faaf06cad184cd1a3a46a35de1c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1 new file mode 100644 index 0000000..3cce170 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SIGNED_OUT.png.sha1
@@ -0,0 +1 @@ +229d5d94f765211db84552b420734b2b414350c6 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1 new file mode 100644 index 0000000..acecd83 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_SYNC_PAUSED.png.sha1
@@ -0,0 +1 @@ +aefddc2ca85392563aac0b8b121109b4bb8983b4 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1 new file mode 100644 index 0000000..738a73b9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED.png.sha1
@@ -0,0 +1 @@ +9db679e9293cdc7b8abe42195e49f6ef183348cf \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1 new file mode 100644 index 0000000..4107492 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BODY_UNSYNCED_HISTORY.png.sha1
@@ -0,0 +1 @@ +2242a9208af02e6f0ca4e650c967b96df8e08a54 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1 new file mode 100644 index 0000000..a479520 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON.png.sha1
@@ -0,0 +1 @@ +3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1 new file mode 100644 index 0000000..9b04a8c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_FRE.png.sha1
@@ -0,0 +1 @@ +7d7533129e5e7faaf06cad184cd1a3a46a35de1c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1 new file mode 100644 index 0000000..acecd83 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_SYNC_PAUSED.png.sha1
@@ -0,0 +1 @@ +aefddc2ca85392563aac0b8b121109b4bb8983b4 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1 new file mode 100644 index 0000000..738a73b9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED.png.sha1
@@ -0,0 +1 @@ +9db679e9293cdc7b8abe42195e49f6ef183348cf \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1 new file mode 100644 index 0000000..4107492 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_BUTTON_UNSYNCED_HISTORY.png.sha1
@@ -0,0 +1 @@ +2242a9208af02e6f0ca4e650c967b96df8e08a54 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1 new file mode 100644 index 0000000..a479520 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE.png.sha1
@@ -0,0 +1 @@ +3c5b7abff4bef5b7e0ab0c03c40ef6a745e5cf77 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1 new file mode 100644 index 0000000..9b04a8c --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_NOT_STARTED_TITLE_FRE.png.sha1
@@ -0,0 +1 @@ +7d7533129e5e7faaf06cad184cd1a3a46a35de1c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1 new file mode 100644 index 0000000..d8404e83 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_FINAL_SUGGESTION.png.sha1
@@ -0,0 +1 @@ +9a83acb21eb6287fbeb691f10de7efc85f930bc3 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1 new file mode 100644 index 0000000..d9cfd8e --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_REJECT_SUGGESTION.png.sha1
@@ -0,0 +1 @@ +03f218e3948a30a60e0f5a67ce91c77b9bc0c782 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1 new file mode 100644 index 0000000..d81e1ff9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_IPH.png.sha1
@@ -0,0 +1 @@ +6f2741643cb6879b42ae222a728c84d4148f568d \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1 new file mode 100644 index 0000000..c1bcfb9a --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_SUCCESS_TITLE.png.sha1
@@ -0,0 +1 @@ +4f599c7f3dbb17f3c40cbeba78cfb2841fd033ce \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1 index 86cb60c..d80a79c7 100644 --- a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TAB_NAME.png.sha1
@@ -1 +1 @@ -4716f0245f707b5e8f26d23e72273beb4d95d0fa \ No newline at end of file +ec79cd1e1022c32bd901b6713d9cd646633b1c18 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1 new file mode 100644 index 0000000..f847279aa --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_ACTION.png.sha1
@@ -0,0 +1 @@ +b805bebaa5a201834cf3c5086cc5a6cdea9cc951 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1 new file mode 100644 index 0000000..f847279aa --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_BODY.png.sha1
@@ -0,0 +1 @@ +b805bebaa5a201834cf3c5086cc5a6cdea9cc951 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1 new file mode 100644 index 0000000..f847279aa --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZATION_TIP_TITLE.png.sha1
@@ -0,0 +1 @@ +b805bebaa5a201834cf3c5086cc5a6cdea9cc951 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1 new file mode 100644 index 0000000..f24af764 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE.png.sha1
@@ -0,0 +1 @@ +c2f8891aa44d1e6a1ad8602945a76d7ef619994d \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1 new file mode 100644 index 0000000..afe3dbf9 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_ORGANIZE_MENU.png.sha1
@@ -0,0 +1 @@ +a91f660cf6938db71beec1287af71e3de44c9a8e \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1 new file mode 100644 index 0000000..d80a79c7 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TAB_SEARCH_TAB_NAME.png.sha1
@@ -0,0 +1 @@ +ec79cd1e1022c32bd901b6713d9cd646633b1c18 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1 new file mode 100644 index 0000000..c9648a0 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE.png.sha1
@@ -0,0 +1 @@ +cedfb58841265e3a1582ce49dc09bfe2edd81b99 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1 new file mode 100644 index 0000000..22144c90 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_TAB_ORGANIZE_CLOSE.png.sha1
@@ -0,0 +1 @@ +9b6af533672c540f591bc088bfd73c93ad244ba9 \ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index e5183b54..41ca89eb 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -1150,6 +1150,9 @@ <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_PREDICTIVE_WRITING_ALT2" desc="Text for search result item which, when clicked, navigates the user to suggestions settings, with a section having a toggle to enable/disable showing predictive writing suggestions after a user types a word."> Next word prediction </message> + <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES" desc="Text for search result item which, when clicked, navigates the user to app language settings, with a list of apps which language can be customized."> + App languages + </message> <!-- Files section. --> <message name="IDS_OS_SETTINGS_TAG_FILES" desc="Text for search result item which, when clicked, navigates the user to files settings.">
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1 new file mode 100644 index 0000000..e3381f3 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES.png.sha1
@@ -0,0 +1 @@ +53a6cbbca23b8f15e287998723c8e81f704a0403 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9606430..73cfd680 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5768,6 +5768,10 @@ {"files-trash-drive", flag_descriptions::kFilesTrashDriveName, flag_descriptions::kFilesTrashDriveDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kFilesTrashDrive)}, + {"file-system-provider-content-cache", + flag_descriptions::kFileSystemProviderContentCacheName, + flag_descriptions::kFileSystemProviderContentCacheDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFileSystemProviderContentCache)}, {"force-resync-drive", flag_descriptions::kForceReSyncDriveName, flag_descriptions::kForceReSyncDriveDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kForceReSyncDrive)},
diff --git a/chrome/browser/ash/app_list/app_list_client_impl.cc b/chrome/browser/ash/app_list/app_list_client_impl.cc index 40b504d..69eef55af 100644 --- a/chrome/browser/ash/app_list/app_list_client_impl.cc +++ b/chrome/browser/ash/app_list/app_list_client_impl.cc
@@ -14,7 +14,6 @@ #include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/new_window_delegate.h" -#include "ash/public/cpp/tablet_mode.h" #include "ash/shell.h" #include "ash/system/federated/federated_service_controller_impl.h" #include "base/feature_list.h" @@ -73,10 +72,6 @@ constexpr base::TimeDelta kTimeMetricsMax = base::Days(7); constexpr int kTimeMetricsBucketCount = 100; -bool IsTabletMode() { - return ash::TabletMode::IsInTabletMode(); -} - // Returns whether the session is active. bool IsSessionActive() { return session_manager::SessionManager::Get()->session_state() == @@ -167,7 +162,7 @@ // Prefer the function to the macro because the usage data is recorded no // more than once per second. - if (IsTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { base::UmaHistogramEnumeration( "Apps.AppListUsageByNewUsers.TabletMode", AppListUsageStateByNewUsers::kNotUsedBeforeDestruction); @@ -220,7 +215,8 @@ if (!state_for_new_user_->first_search_result_recorded && state_for_new_user_->started_search && trimmed_query.empty()) { state_for_new_user_->first_search_result_recorded = true; - RecordFirstSearchResult(ash::NO_RESULT, IsTabletMode()); + RecordFirstSearchResult(ash::NO_RESULT, + display::Screen::GetScreen()->InTabletMode()); } else if (!trimmed_query.empty()) { state_for_new_user_->started_search = true; } @@ -278,7 +274,7 @@ } if (launched_from == ash::AppListLaunchedFrom::kLaunchedFromSearchBox) { - if (IsTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { base::UmaHistogramCounts100("Apps.AppListSearchQueryLengthV2.TabletMode", last_query_length); } else { @@ -294,8 +290,9 @@ result->display_type(), ash::AppListNotifier::Result(result_id, result->metrics_type())); - RecordSearchResultOpenTypeHistogram(launched_from, result->metrics_type(), - IsTabletMode()); + RecordSearchResultOpenTypeHistogram( + launched_from, result->metrics_type(), + display::Screen::GetScreen()->InTabletMode()); if (launch_as_default) { RecordDefaultSearchResultOpenTypeHistogram(result->metrics_type()); @@ -315,7 +312,8 @@ if (state_for_new_user_ && state_for_new_user_->started_search && !state_for_new_user_->first_search_result_recorded) { state_for_new_user_->first_search_result_recorded = true; - RecordFirstSearchResult(result->metrics_type(), IsTabletMode()); + RecordFirstSearchResult(result->metrics_type(), + display::Screen::GetScreen()->InTabletMode()); } // OpenResult may cause |result| to be deleted. @@ -438,7 +436,8 @@ if (state_for_new_user_ && state_for_new_user_->started_search && !state_for_new_user_->first_search_result_recorded) { state_for_new_user_->first_search_result_recorded = true; - RecordFirstSearchResult(ash::NO_RESULT, IsTabletMode()); + RecordFirstSearchResult(ash::NO_RESULT, + display::Screen::GetScreen()->InTabletMode()); } } } @@ -469,7 +468,7 @@ if (!state_for_new_user_->showing_recorded) { // We assume that the previous user before switching was new if // `state_for_new_user_` is not null. - if (IsTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { base::UmaHistogramEnumeration( "Apps.AppListUsageByNewUsers.TabletMode", AppListUsageStateByNewUsers::kNotUsedBeforeSwitchingAccounts); @@ -795,7 +794,8 @@ } state_for_new_user_->showing_recorded = true; - state_for_new_user_->shown_in_tablet_mode = IsTabletMode(); + state_for_new_user_->shown_in_tablet_mode = + display::Screen::GetScreen()->InTabletMode(); CHECK(new_user_session_activation_time_.has_value()); const base::TimeDelta opening_duration = @@ -879,7 +879,7 @@ } state_for_new_user_->action_recorded = true; - if (IsTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { base::UmaHistogramEnumeration("Apps.NewUserFirstLauncherAction.TabletMode", launched_from); } else { @@ -893,7 +893,7 @@ if (launcher_action_duration >= base::TimeDelta()) { // `base::Time` may skew. Therefore only record when the time duration is // non-negative. - if (IsTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { UMA_HISTOGRAM_CUSTOM_TIMES( /*name=*/ "Apps.TimeBetweenNewUserSessionActivationAndFirstLauncherAction."
diff --git a/chrome/browser/ash/app_list/app_list_sort_unittest.cc b/chrome/browser/ash/app_list/app_list_sort_unittest.cc index 2e18512..b99e794 100644 --- a/chrome/browser/ash/app_list/app_list_sort_unittest.cc +++ b/chrome/browser/ash/app_list/app_list_sort_unittest.cc
@@ -14,6 +14,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/crx_file/id_util.h" #include "components/sync/test/fake_sync_change_processor.h" +#include "ui/display/test/test_screen.h" namespace app_list { @@ -61,6 +62,8 @@ } private: + display::test::TestScreen test_screen_{/*create_dispay=*/true, + /*register_screen=*/true}; std::unique_ptr<test::TestAppListController> app_list_controller_; };
diff --git a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc index e922af6..3163c67b 100644 --- a/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ash/app_list/chrome_app_list_model_updater.cc
@@ -14,7 +14,6 @@ #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_controller.h" #include "ash/public/cpp/app_list/app_list_metrics.h" -#include "ash/public/cpp/tablet_mode.h" #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/strings/utf_string_conversions.h" @@ -32,6 +31,7 @@ #include "components/feature_engagement/public/tracker.h" #include "extensions/common/constants.h" #include "ui/base/models/menu_model.h" +#include "ui/display/screen.h" namespace { @@ -1268,9 +1268,8 @@ order_delegate_->SetAppListPreferredOrder(ash::AppListSortOrder::kCustom); - // The tablet mode controller may not exist in tests. - if (ash::TabletMode::Get()) - ReportPrefOrderClearAction(event, ash::TabletMode::Get()->IsInTabletMode()); + ReportPrefOrderClearAction(event, + display::Screen::GetScreen()->InTabletMode()); } void ChromeAppListModelUpdater::MaybeUpdatePositionWhenIconColorChange(
diff --git a/chrome/browser/ash/arc/window_predictor/window_predictor.cc b/chrome/browser/ash/arc/window_predictor/window_predictor.cc index 6935881..e9ddfdf 100644 --- a/chrome/browser/ash/arc/window_predictor/window_predictor.cc +++ b/chrome/browser/ash/arc/window_predictor/window_predictor.cc
@@ -149,7 +149,7 @@ window_info->display_id, &disp); } - if (ash::TabletMode::Get()->IsInTabletMode()) { + if (display::Screen::GetScreen()->InTabletMode()) { // TODO: Figure out why setting kMaximized doesn't work. window_info->state = static_cast<int32_t>(chromeos::WindowStateType::kDefault);
diff --git a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc index 94d39a4e..ad2bfa5 100644 --- a/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc +++ b/chrome/browser/ash/input_method/ui/indexed_suggestion_candidate_button.cc
@@ -97,11 +97,8 @@ views::LayoutAlignment::kCenter); candidate_wrapper_layout->SetMainAxisAlignment( views::LayoutAlignment::kCenter); - candidate_wrapper->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum, - views::MaximumFlexSizeRule::kUnbounded, false) - .WithAlignment(views::LayoutAlignment::kCenter)); + candidate_wrapper->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); candidate_wrapper->SetPreferredSize( gfx::Size(kCandidateSquareSide, kCandidateSquareSide)); candidate_wrapper->AddChildView(
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 c86c5f7f..35d0288 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
@@ -16,7 +16,6 @@ #include "ash/constants/ash_features.h" #include "ash/controls/contextual_tooltip.h" #include "ash/public/cpp/image_util.h" -#include "ash/public/cpp/tablet_mode.h" #include "ash/public/cpp/wallpaper/google_photos_wallpaper_params.h" #include "ash/public/cpp/wallpaper/online_wallpaper_params.h" #include "ash/public/cpp/wallpaper/online_wallpaper_variant.h" @@ -62,6 +61,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/aura/window.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/display/screen.h" #include "ui/gfx/codec/jpeg_codec.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image.h" @@ -777,7 +777,7 @@ void PersonalizationAppWallpaperProviderImpl::IsInTabletMode( IsInTabletModeCallback callback) { - std::move(callback).Run(ash::TabletMode::IsInTabletMode()); + std::move(callback).Run(display::Screen::GetScreen()->InTabletMode()); } void PersonalizationAppWallpaperProviderImpl::ConfirmPreviewWallpaper() {
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc index 991208c..bfe757c1 100644 --- a/chrome/browser/autofill/autofill_server_browsertest.cc +++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -242,9 +242,9 @@ std::string data_present; if (base::FeatureList::IsEnabled( features::kAutofillEnableSupportForHonorificPrefixes)) { - data_present = "1f7e0003f80000080004000001c424180002"; + data_present = "1f7e0003f80000080004000001c424780002"; } else { - data_present = "1f7e0003f80000080004000001c420180002"; + data_present = "1f7e0003f80000080004000001c420780002"; } // TODO(crbug.com/1311937): Additional phone number trunk types are present @@ -255,8 +255,6 @@ data_present.rbegin()[5] = '7'; } upload->set_data_present(data_present); - - upload->set_passwords_revealed(false); upload->set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_HTML_FORM_SUBMISSION); upload->set_has_form_tag(true);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index eeeab70..4d9d5994 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5412,24 +5412,6 @@ #endif } -void ChromeContentBrowserClient::OverridePageVisibilityState( - RenderFrameHost* render_frame_host, - content::PageVisibilityState* visibility_state) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - WebContents* web_contents = - WebContents::FromRenderFrameHost(render_frame_host); - DCHECK(web_contents); - - prerender::NoStatePrefetchManager* no_state_prefetch_manager = - prerender::NoStatePrefetchManagerFactory::GetForBrowserContext( - web_contents->GetBrowserContext()); - if (no_state_prefetch_manager && - no_state_prefetch_manager->IsWebContentsPrefetching(web_contents)) { - *visibility_state = content::PageVisibilityState::kHidden; - } -} - void ChromeContentBrowserClient::InitOnUIThread() { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index efc041c..1d2098c5 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -492,9 +492,6 @@ bool IsPluginAllowedToUseDevChannelAPIs( content::BrowserContext* browser_context, const GURL& url) override; - void OverridePageVisibilityState( - content::RenderFrameHost* render_frame_host, - content::PageVisibilityState* visibility_state) override; #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) void GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line,
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 8ea70a5..4123228 100644 --- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -15,6 +15,7 @@ #include "ash/public/cpp/keyboard/keyboard_types.h" #include "ash/webui/settings/public/constants/routes.mojom-forward.h" #include "base/check.h" +#include "base/command_line.h" #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/metrics/user_metrics.h" @@ -27,6 +28,7 @@ #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/crosapi/mojom/clipboard_history.mojom.h" +#include "chromeos/services/machine_learning/public/cpp/ml_switches.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/audio_service.h" #include "content/public/browser/browser_thread.h" @@ -174,6 +176,33 @@ return router; } +// Returns whether the `ondevice_handwriting` USE flag has been set. +// Adapted from +// `//chromeos/services/machine_learning/cpp/ash/handwriting_model_loader.cc`. +// This flag is set from the CrOS side in +// https://crsrc.org/o/src/platform2/login_manager/chrome_setup.cc;l=1014;drc=e44a81d180823c2a0758c52f0520862d0545b98d +bool IsOndeviceHandwritingEnabledViaCommandLine() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + return command_line->HasSwitch(::switches::kOndeviceHandwritingSwitch) && + command_line->GetSwitchValueASCII( + ::switches::kOndeviceHandwritingSwitch) == "use_rootfs"; +} + +bool IsHandwritingLegacyRecognitionEnabled() { + // Disable handwriting DLC flags if device does not have on-device handwriting + // (see b/316981973). + return IsOndeviceHandwritingEnabledViaCommandLine() && + base::FeatureList::IsEnabled( + ash::features::kHandwritingLegacyRecognition); +} + +bool IsHandwritingLibraryDlcEnabled() { + // Disable handwriting DLC flags if device does not have on-device handwriting + // (see b/316981973). + return IsOndeviceHandwritingEnabledViaCommandLine() && + base::FeatureList::IsEnabled(ash::features::kHandwritingLibraryDlc); +} + } // namespace namespace extensions { @@ -498,10 +527,8 @@ features.Append(GenerateFeatureFlag( "handwritinggesture", base::FeatureList::IsEnabled(features::kHandwritingGesture))); - features.Append( - GenerateFeatureFlag("handwritinglegacyrecognition", - base::FeatureList::IsEnabled( - ash::features::kHandwritingLegacyRecognition))); + features.Append(GenerateFeatureFlag("handwritinglegacyrecognition", + IsHandwritingLegacyRecognitionEnabled())); features.Append(GenerateFeatureFlag( "hindiinscriptlayout", base::FeatureList::IsEnabled(ash::features::kHindiInscriptLayout))); @@ -527,9 +554,8 @@ features.Append(GenerateFeatureFlag( "autocorrectparamstuning", base::FeatureList::IsEnabled(ash::features::kAutocorrectParamsTuning))); - features.Append(GenerateFeatureFlag( - "handwritinglibrarydlc", - base::FeatureList::IsEnabled(ash::features::kHandwritingLibraryDlc))); + features.Append(GenerateFeatureFlag("handwritinglibrarydlc", + IsHandwritingLibraryDlcEnabled())); features.Append( GenerateFeatureFlag("jelly", chromeos::features::IsJellyEnabled())); features.Append(GenerateFeatureFlag(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 52fe2ae..480875af 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4243,6 +4243,11 @@ "expiry_milestone": 123 }, { + "name": "file-system-provider-content-cache", + "owners": [ "benreich@chromium.org", "cassycc@chromium.org", "simmonsjosh@google.com" ], + "expiry_milestone": 130 + }, + { "name": "file-transfer-enterprise-connector", "owners": [ "sseckler@google.com", "marcgrimme@chromium.org", "poromov@chromium.org" ], "expiry_milestone": 130
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index a35c252..20a40658 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -6374,6 +6374,12 @@ const char kFilesTrashDriveDescription[] = "Enable trash for Drive volume in Files App."; +const char kFileSystemProviderContentCacheName[] = + "Enable content caching for FileSystemProvider extensions."; +const char kFileSystemProviderContentCacheDescription[] = + "Enable the ability for individual FileSystemProvider extensions to " + "leverage a content cache."; + const char kFilesGoogleDriveSettingsPageName[] = "Enable Google Drive settings page"; const char kFilesGoogleDriveSettingsPageDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 852fcb3..c0b4654 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -3662,6 +3662,9 @@ extern const char kFilesTrashDriveName[]; extern const char kFilesTrashDriveDescription[]; +extern const char kFileSystemProviderContentCacheName[]; +extern const char kFileSystemProviderContentCacheDescription[]; + extern const char kFilesGoogleDriveSettingsPageName[]; extern const char kFilesGoogleDriveSettingsPageDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 1aefac8b..a6c028d 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -247,14 +247,10 @@ &kRequestDesktopSiteDefaultsControlCohort2, &kRequestDesktopSiteDefaultsControlCohort3, &kRequestDesktopSiteDefaultsControlCohort4, - &kRequestDesktopSiteDefaultsControlSynthetic, &kRequestDesktopSiteDefaultsEnabledCohort1, &kRequestDesktopSiteDefaultsEnabledCohort2, &kRequestDesktopSiteDefaultsEnabledCohort3, &kRequestDesktopSiteDefaultsEnabledCohort4, - &kRequestDesktopSiteDefaultsSynthetic, - &kRequestDesktopSiteOptInControlSynthetic, - &kRequestDesktopSiteOptInSynthetic, &kRequestDesktopSiteDefaultsDowngrade, &kRequestDesktopSiteDefaultsLogging, &kRestoreTabsOnFRE, @@ -756,10 +752,6 @@ "RequestDesktopSiteDefaultsControlCohort4", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kRequestDesktopSiteDefaultsControlSynthetic, - "RequestDesktopSiteDefaultsControlSynthetic", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort1, "RequestDesktopSiteDefaultsEnabledCohort1", base::FEATURE_DISABLED_BY_DEFAULT); @@ -776,18 +768,6 @@ "RequestDesktopSiteDefaultsEnabledCohort4", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kRequestDesktopSiteDefaultsSynthetic, - "RequestDesktopSiteDefaultsSynthetic", - base::FEATURE_DISABLED_BY_DEFAULT); - -BASE_FEATURE(kRequestDesktopSiteOptInControlSynthetic, - "RequestDesktopSiteOptInControlSynthetic", - base::FEATURE_DISABLED_BY_DEFAULT); - -BASE_FEATURE(kRequestDesktopSiteOptInSynthetic, - "RequestDesktopSiteOptInSynthetic", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kRequestDesktopSiteDefaultsDowngrade, "RequestDesktopSiteDefaultsDowngrade", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 57730cd..afa0fe4 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -124,14 +124,10 @@ BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort2); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort3); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlCohort4); -BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsControlSynthetic); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort1); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort2); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort3); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsEnabledCohort4); -BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsSynthetic); -BASE_DECLARE_FEATURE(kRequestDesktopSiteOptInControlSynthetic); -BASE_DECLARE_FEATURE(kRequestDesktopSiteOptInSynthetic); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsDowngrade); BASE_DECLARE_FEATURE(kRequestDesktopSiteDefaultsLogging); BASE_DECLARE_FEATURE(kRestoreTabsOnFRE);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 6a54432..f563b457 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -361,18 +361,10 @@ public static final String REQUEST_DESKTOP_SITE_DEFAULTS = "RequestDesktopSiteDefaults"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL = "RequestDesktopSiteDefaultsControl"; - public static final String REQUEST_DESKTOP_SITE_DEFAULTS_CONTROL_SYNTHETIC = - "RequestDesktopSiteDefaultsControlSynthetic"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS_DOWNGRADE = "RequestDesktopSiteDefaultsDowngrade"; public static final String REQUEST_DESKTOP_SITE_DEFAULTS_LOGGING = "RequestDesktopSiteDefaultsLogging"; - public static final String REQUEST_DESKTOP_SITE_DEFAULTS_SYNTHETIC = - "RequestDesktopSiteDefaultsSynthetic"; - public static final String REQUEST_DESKTOP_SITE_OPT_IN_CONTROL_SYNTHETIC = - "RequestDesktopSiteOptInControlSynthetic"; - public static final String REQUEST_DESKTOP_SITE_OPT_IN_SYNTHETIC = - "RequestDesktopSiteOptInSynthetic"; public static final String SAFE_BROWSING_DELAYED_WARNINGS = "SafeBrowsingDelayedWarnings"; public static final String SAFE_BROWSING_NEW_GMS_API_FOR_BROWSE_URL_DATABASE_CHECK = "SafeBrowsingNewGmsApiForBrowseUrlDatabaseCheck";
diff --git a/chrome/browser/lacros/input_method_lacros_browsertest.cc b/chrome/browser/lacros/input_method_lacros_browsertest.cc index df04496..e65e823 100644 --- a/chrome/browser/lacros/input_method_lacros_browsertest.cc +++ b/chrome/browser/lacros/input_method_lacros_browsertest.cc
@@ -101,6 +101,9 @@ ->GetNativeWindow() ->GetRootWindow()); EXPECT_TRUE(browser_test_util::WaitForWindowCreation(window_id)); + EXPECT_TRUE(BrowserView::GetBrowserViewForBrowser(browser) + ->contents_web_view() + ->HasFocus()); return true; } @@ -581,12 +584,14 @@ IN_PROC_BROWSER_TEST_P(InputMethodLacrosBrowserTest, CommitTextUpdatesSurroundingText) { + const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + mojo::Remote<InputMethodTestInterface> input_method = BindInputMethodTestInterface(GetParam()); if (!input_method.is_bound()) { GTEST_SKIP() << "Unsupported ash version"; } - const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + InputMethodTestInterfaceAsyncWaiter input_method_async_waiter( input_method.get()); input_method_async_waiter.WaitForFocus(); @@ -874,15 +879,16 @@ EXPECT_FALSE(event_listener.HasMessages()); } -// TODO(crbug.com/1510768): Reenable once fixed. IN_PROC_BROWSER_TEST_P(InputMethodLacrosBrowserTest, - DISABLED_SetCompositionUpdatesSurroundingText) { + SetCompositionUpdatesSurroundingText) { + const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + mojo::Remote<InputMethodTestInterface> input_method = BindInputMethodTestInterface(GetParam()); if (!input_method.is_bound()) { GTEST_SKIP() << "Unsupported ash version"; } - const std::string id = RenderAutofocusedInputFieldInLacros(browser()); + InputMethodTestInterfaceAsyncWaiter input_method_async_waiter( input_method.get()); input_method_async_waiter.WaitForFocus();
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc index 2113fc05..7f9b501d 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_notice_browsertest.cc
@@ -105,6 +105,15 @@ {tpcd::experiment::kForceEligibleForTestingName, "true"}}}; } +base::test::FeatureRefAndParams ControlFeaturesWithSilentOnboarding() { + return {features::kCookieDeprecationFacilitatedTesting, + { + {tpcd::experiment::kDisable3PCookiesName, "false"}, + {tpcd::experiment::kForceEligibleForTestingName, "true"}, + {tpcd::experiment::kEnableSilentOnboardingName, "true"}, + }}; +} + std::vector<base::test::FeatureRefAndParams> HatsImmediateControlFeatures() { return { ControlFeatures(), @@ -114,6 +123,16 @@ {"tracking-protection-control-immediate-trigger-id", "trigger-1"}}}}; } +std::vector<base::test::FeatureRefAndParams> +HatsImmediateControlFeaturesWithSilentOnboarding() { + return { + ControlFeaturesWithSilentOnboarding(), + {features::kTrackingProtectionSentimentSurvey, + {{"tracking-protection-immediate-over-delayed-probability", "1"}, + {"tracking-protection-control-immediate-probability", "1.0"}, + {"tracking-protection-control-immediate-trigger-id", "trigger-1"}}}}; +} + std::vector<base::test::FeatureRefAndParams> HatsDelayedControlFeatures() { return {ControlFeatures(), {features::kTrackingProtectionSentimentSurvey, @@ -1134,6 +1153,7 @@ bool has_topics_enabled = false; bool has_fledge_enabled = false; bool has_measurement_enabled = false; + std::optional<bool> should_silently_onboard = std::nullopt; std::optional<NoticeAction> ack_action = std::nullopt; base::TimeDelta to_start_survey; base::TimeDelta after_end_of_survey; @@ -1222,6 +1242,14 @@ prefs::kPrivacySandboxM1AdMeasurementEnabled, params.has_measurement_enabled); + if (params.should_silently_onboard) { + { + base::subtle::ScopedTimeClockOverrides override([]() { return Now(); }, + nullptr, nullptr); + onboarding_service()->MaybeMarkSilentEligible(); + onboarding_service()->SilentOnboardingNoticeShown(); + } + } // Ack if necessary. if (params.ack_action.has_value()) { // Onboarding first @@ -1347,6 +1375,19 @@ .trigger_id = kHatsSurveyTriggerTrackingProtectionControlImmediate, .group = SentimentSurveyGroup::kControlImmediate, }, + // Immediate Control with silent onbaording. No Ads API Enabled + TrackingProtectionSurveyTestData{ + .features = HatsImmediateControlFeaturesWithSilentOnboarding(), + .has_cookie_controls_3pc_blocked = true, + .has_topics_enabled = false, + .has_fledge_enabled = false, + .has_measurement_enabled = false, + .should_silently_onboard = true, + .to_start_survey = base::Minutes(5), + .after_end_of_survey = base::Minutes(65), + .trigger_id = kHatsSurveyTriggerTrackingProtectionControlImmediate, + .group = SentimentSurveyGroup::kControlImmediate, + }, // Delayed Control No Ads API Enabled TrackingProtectionSurveyTestData{ .features = HatsDelayedControlFeatures(),
diff --git a/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc b/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc index 58a59389..6674ba15 100644 --- a/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc +++ b/chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.cc
@@ -7,6 +7,7 @@ #include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_selections.h" +#include "chrome/browser/tpcd/experiment/tpcd_experiment_features.h" #include "chrome/common/channel_info.h" TrackingProtectionOnboardingFactory* @@ -35,5 +36,6 @@ Profile* profile = Profile::FromBrowserContext(context); return std::make_unique<privacy_sandbox::TrackingProtectionOnboarding>( - profile->GetPrefs(), chrome::GetChannel()); + profile->GetPrefs(), chrome::GetChannel(), + tpcd::experiment::kEnableSilentOnboarding.Get()); }
diff --git a/chrome/browser/resources/ash/settings/device_page/audio.html b/chrome/browser/resources/ash/settings/device_page/audio.html index 6dde84f..8b0c63e 100644 --- a/chrome/browser/resources/ash/settings/device_page/audio.html +++ b/chrome/browser/resources/ash/settings/device_page/audio.html
@@ -199,7 +199,8 @@ </div> <cr-toggle id="audioInputNoiseCancellationToggle" checked="{{isNoiseCancellationEnabled_}}" - aria-labelledby="audioInputNoiseCancellationLabel"> + aria-labelledby="audioInputNoiseCancellationLabel" + on-change="toggleNoiseCancellationEnabled_"> </cr-toggle> </div> <div id="audioInputAllowAGCSubsection" class="settings-box"
diff --git a/chrome/browser/resources/ash/settings/device_page/audio.ts b/chrome/browser/resources/ash/settings/device_page/audio.ts index 40004b0..89a0ff0 100644 --- a/chrome/browser/resources/ash/settings/device_page/audio.ts +++ b/chrome/browser/resources/ash/settings/device_page/audio.ts
@@ -77,8 +77,6 @@ isNoiseCancellationEnabled_: { type: Boolean, - observer: - SettingsAudioElement.prototype.onNoiseCancellationEnabledChanged, }, isNoiseCancellationSupported_: { @@ -228,22 +226,6 @@ this.crosAudioConfig_.setActiveDevice(BigInt(inputDeviceSelect.value)); } - /** Handles updates to noise cancellation state. */ - protected onNoiseCancellationEnabledChanged( - enabled: SettingsAudioElement['isNoiseCancellationEnabled_'], - previousEnabled: SettingsAudioElement['isNoiseCancellationEnabled_']): - void { - // Polymer triggers change event on all assignment to - // `isNoiseCancellationEnabled_` even if the value is logically unchanged. - // Check previous value before calling `setNoiseCancellationEnabled` to test - // if value actually updated. - if (previousEnabled === undefined || previousEnabled === enabled) { - return; - } - - this.crosAudioConfig_.setNoiseCancellationEnabled(enabled); - } - /** Handles updates to force respect ui gains state. */ protected onAllowAGCEnabledChanged( enabled: SettingsAudioElement['isAllowAGCEnabled'], @@ -417,6 +399,10 @@ this.i18n('audioOutputMuteButtonAriaLabelNotMuted'); } + private toggleNoiseCancellationEnabled_(e: CustomEvent<boolean>): void { + this.crosAudioConfig_.setNoiseCancellationEnabled(e.detail); + } + private toggleStartupSoundEnabled_(e: CustomEvent<boolean>): void { this.audioAndCaptionsBrowserProxy_.setStartupSoundEnabled(e.detail); }
diff --git a/chrome/browser/resources/ash/settings/device_page/display.html b/chrome/browser/resources/ash/settings/device_page/display.html index 6b879454..7932649 100644 --- a/chrome/browser/resources/ash/settings/device_page/display.html +++ b/chrome/browser/resources/ash/settings/device_page/display.html
@@ -76,8 +76,7 @@ <template is="dom-if" if="[[showMirror(unifiedDesktopMode_, displays)]]" restamp> <!-- Mirror display toggle button --> - <template is="dom-if" - if="[[isRevampWayfindingEnabled_]]" restamp> + <template is="dom-if" if="[[isRevampWayfindingEnabled_]]"> <div id="mirrorDisplayToggleButton" class="text-area"> <div id="mirrorDisplayToggleLabel" class="start"> [[getDisplayMirrorText_(displays)]] @@ -92,8 +91,7 @@ </template> <!-- Mirror display checkbox --> - <template is="dom-if" - if="[[!isRevampWayfindingEnabled_]]" restamp> + <template is="dom-if" if="[[!isRevampWayfindingEnabled_]]"> <div class="secondary self-start"> <cr-checkbox id="displayMirrorCheckbox" checked="[[isMirrored(displays)]]"
diff --git a/chrome/browser/resources/ash/settings/device_page/display.ts b/chrome/browser/resources/ash/settings/device_page/display.ts index e874731..cfdc19b8 100644 --- a/chrome/browser/resources/ash/settings/device_page/display.ts +++ b/chrome/browser/resources/ash/settings/device_page/display.ts
@@ -92,6 +92,7 @@ value: () => { return isRevampWayfindingEnabled(); }, + readOnly: true, }, selectedModePref_: { @@ -262,7 +263,7 @@ private displaySettingsProvider: DisplaySettingsProviderInterface; private displayTabNames_: string[]; private invalidDisplayId_: string; - private isRevampWayfindingEnabled_: boolean; + private readonly isRevampWayfindingEnabled_: boolean; private isTabletMode_: boolean; private listAllDisplayModes_: boolean; private logicalResolutionText_: string;
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts index d76ff8f..3ad9367 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_page_v2.ts
@@ -38,7 +38,7 @@ import {RouteObserverMixin} from '../common/route_observer_mixin.js'; import {recordSettingChange} from '../metrics_recorder.js'; import {Setting} from '../mojom-webui/setting.mojom-webui.js'; -import {Route, routes} from '../router.js'; +import {Route, Router, routes} from '../router.js'; import {LanguagesMetricsProxyImpl, LanguagesPageInteraction} from './languages_metrics_proxy.js'; import {LanguageHelper, LanguagesModel, LanguageState} from './languages_types.js'; @@ -199,7 +199,7 @@ * Navigates to app languages subpage. */ private onAppLanguagesClick_(): void { - // TODO(b/261200827): Route to App Languages page. + Router.getInstance().navigateTo(routes.OS_LANGUAGES_APP_LANGUAGES); } /**
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html index 6af5919..b6058b3 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
@@ -21,6 +21,14 @@ </os-settings-subpage> </template> + <!-- "App Languages" sub-page. --> + <template is="dom-if" route-path="/osLanguages/languages/appLanguages"> + <os-settings-subpage page-title="$i18n{appLanguagesTitle}"> + <os-settings-app-languages-page prefs="{{prefs}}"> + </os-settings-app-languages-page> + </os-settings-subpage> + </template> + <!-- "Input" page. --> <template is="dom-if" route-path="/osLanguages/input"> <os-settings-subpage page-title="$i18n{inputPageTitle}">
diff --git a/chrome/browser/resources/ash/settings/os_settings_routes.ts b/chrome/browser/resources/ash/settings/os_settings_routes.ts index 853f8f0..af1691c 100644 --- a/chrome/browser/resources/ash/settings/os_settings_routes.ts +++ b/chrome/browser/resources/ash/settings/os_settings_routes.ts
@@ -184,6 +184,7 @@ ONE_DRIVE: Route; OS_ACCESSIBILITY: Route; OS_LANGUAGES: Route; + OS_LANGUAGES_APP_LANGUAGES: Route; OS_LANGUAGES_EDIT_DICTIONARY: Route; OS_LANGUAGES_JAPANESE_MANAGE_USER_DICTIONARY: Route; OS_LANGUAGES_INPUT: Route; @@ -556,6 +557,11 @@ r.OS_LANGUAGES_LANGUAGES = createSubpage( r.SYSTEM_PREFERENCES, routesMojom.LANGUAGES_SUBPAGE_PATH, Subpage.kLanguages); + if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) { + r.OS_LANGUAGES_APP_LANGUAGES = createSubpage( + r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH, + Subpage.kAppLanguages); + } // Search and Assistant subpages. r.SEARCH_SUBPAGE = createSubpage( @@ -657,6 +663,11 @@ r.OS_LANGUAGES_INPUT, routesMojom.JAPANESE_MANAGE_USER_DICTIONARY_SUBPAGE_PATH, Subpage.kJapaneseManageUserDictionary); + if (loadTimeData.getBoolean('isPerAppLanguageEnabled')) { + r.OS_LANGUAGES_APP_LANGUAGES = createSubpage( + r.OS_LANGUAGES_LANGUAGES, routesMojom.APP_LANGUAGES_SUBPAGE_PATH, + Subpage.kAppLanguages); + } // Reset section. if (isPowerwashAllowed()) {
diff --git a/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html b/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html index a00754d..0439532 100644 --- a/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html +++ b/chrome/browser/resources/ash/settings/system_preferences_page/system_preferences_page.html
@@ -84,6 +84,14 @@ </os-settings-subpage> </template> + <!-- "App Languages" sub-page. --> + <template is="dom-if" route-path="/osLanguages/languages/appLanguages"> + <os-settings-subpage page-title="$i18n{appLanguagesTitle}"> + <os-settings-app-languages-page prefs="{{prefs}}"> + </os-settings-app-languages-page> + </os-settings-subpage> + </template> + <!-- Search and Assistant subpages --> <template is="dom-if" if="[[shouldShowQuickAnswersSettings_]]"> <template is="dom-if" route-path="/osSearch/search">
diff --git a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts index df7931a4..5c71825 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts +++ b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
@@ -33,6 +33,10 @@ private proxy: CloudUploadBrowserProxy = CloudUploadBrowserProxy.getInstance(); + // Save reference to listener so it can be removed from the document in + // disconnectedCallback(). + private boundKeyDownListener_: (e: KeyboardEvent) => void; + constructor() { super(); const shadowRoot = this.attachShadow({mode: 'open'}); @@ -40,19 +44,36 @@ shadowRoot.innerHTML = getTemplate(); const openButton = this.$<CrButtonElement>('.action-button'); const cancelButton = this.$<CrButtonElement>('.cancel-button'); - const header = this.$<HTMLDialogElement>('#header'); assert(openButton); assert(cancelButton); - assert(header); openButton.disabled = true; openButton.addEventListener('click', () => this.onOpenButtonClick()); cancelButton.addEventListener('click', () => this.onCancelButtonClick()); - header.addEventListener('keydown', this.handleKeyDown.bind(this)); + this.boundKeyDownListener_ = this.handleKeyDown.bind(this); this.initDynamicContent(); } + // Initialises the scrollable content styles and add document event listeners. + connectedCallback(): void { + const contentElement = this.$<HTMLElement>('#content')!; + window.requestAnimationFrame(() => { + this.updateContentFade(contentElement); + }); + contentElement.addEventListener( + 'scroll', this.updateContentFade.bind(undefined, contentElement), + {passive: true}); + contentElement.addEventListener('keydown', this.boundKeyDownListener_); + + document.addEventListener('keydown', this.boundKeyDownListener_); + } + + // Remove document event listeners. + disconnectedCallback(): void { + document.removeEventListener('keydown', this.boundKeyDownListener_); + } + $<T extends HTMLElement>(query: string): T { return this.shadowRoot!.querySelector(query)!; } @@ -188,18 +209,6 @@ 'click', () => this.selectCard(localHandlerCard)); } - // Initialises the scrollable content styles. - connectedCallback(): void { - const contentElement = this.$<HTMLElement>('#content')!; - window.requestAnimationFrame(() => { - this.updateContentFade(contentElement); - }); - contentElement.addEventListener( - 'scroll', this.updateContentFade.bind(undefined, contentElement), - {passive: true}); - contentElement.addEventListener('keydown', this.handleKeyDown.bind(this)); - } - private selectCard(card: FileHandlerCardElement) { assert(card.style.display != 'none', 'Attempting to select a hidden card'); for (const providerCard of this.cloudProviderCards) { @@ -248,6 +257,14 @@ } handleKeyDown(e: KeyboardEvent): void { + if (e.key === 'Escape') { + // Handle Escape as a "cancel". + e.stopImmediatePropagation(); + e.preventDefault(); + this.onCancelButtonClick(); + return; + } + // Prevent scroll on spacebar. if (e.key === ' ') { e.preventDefault();
diff --git a/chrome/browser/resources/chromeos/emoji_picker/app.ts b/chrome/browser/resources/chromeos/emoji_picker/app.ts index 0dba58baa..75c9c12 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/app.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/app.ts
@@ -296,8 +296,7 @@ // After initial data is loaded, if the GIF nudge is not shown before, show // the GIF nudge. - if (this.gifSupport && - !GifNudgeHistoryStore.getInstance().hasNudgeShown()) { + if (this.gifSupport && !GifNudgeHistoryStore.hasNudgeShown()) { this.showGifNudgeOverlay = true; } @@ -1103,7 +1102,7 @@ return []; } - return this.categoriesHistory[category]?.data?.history?.map( + return this.categoriesHistory[category]?.getHistory().map( emoji => ({ base: { string: emoji.base.string, @@ -1241,8 +1240,7 @@ * @returns {boolean} True for empty history. */ private isCategoryHistoryEmpty(category: CategoryEnum) { - return this.incognito || - (this.categoriesHistory[category]?.data?.history?.length ?? 0) === 0; + return this.incognito || this.categoriesHistory[category]?.isHistoryEmpty(); } /** @@ -1320,7 +1318,7 @@ return this.incognito ? {} : // ! is safe as categories history must contain // entries for all categories. - this.categoriesHistory[category]!.data.preference; + this.categoriesHistory[category]!.getPreferenceMapping(); } private onShowEmojiVariants(ev: events.EmojiVariantsShownEvent) { @@ -1590,7 +1588,7 @@ this.showGifNudgeOverlay = false; } - GifNudgeHistoryStore.getInstance().setNudgeShown(true); + GifNudgeHistoryStore.setNudgeShown(true); } }
diff --git a/chrome/browser/resources/chromeos/emoji_picker/store.ts b/chrome/browser/resources/chromeos/emoji_picker/store.ts index bb53144..9a35079 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/store.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/store.ts
@@ -8,37 +8,64 @@ const MAX_RECENTS = 10; -/** - * @param {string} keyName Keyname of the object stored in storage - * @return {{history:!Array<EmojiVariants>, preference:Object<string,string>}} - * recently used emoji, most recent first. - */ -function load(keyName: string) { - const stored = window.localStorage.getItem(keyName); - if (!stored) { - return {history: [], preference: {}}; +class Store<T> { + data: T; + + /** + * @param storageKey The key to use in local storage. + * @param defaultData The initial data for this store. A new copy should + * be passed for each `Store` instance. + */ + constructor(private readonly storageKey: string, defaultData: T) { + this.data = this.load(defaultData); } - const parsed = /** @type {?} */ (JSON.parse(stored)); - // Throw out any old data - return {history: parsed.history || [], preference: parsed.preference || {}}; + + /** + * @param defaultData The initial data for this store. A new copy should + * be passed each time this is called. + * @return The data from local storage if it exists, otherwise a reference + * to `defaultData`. + */ + private load(defaultData: T): T { + const stored = window.localStorage.getItem(this.storageKey); + + if (!stored) { + return defaultData; + } + + const parsed = JSON.parse(stored); + + // Checking for null because values of type 'object' can still be null. + if (typeof defaultData !== 'object' || defaultData === null || + typeof parsed !== 'object' || parsed === null) { + return parsed; + } + + // Throw out any old data. + const filteredEntries = + Object.entries(parsed).filter(([key, _]) => key in defaultData); + + return {...defaultData, ...Object.fromEntries(filteredEntries)}; + } + + /** + * Saves the existing data to local storage. + */ + save() { + window.localStorage.setItem(this.storageKey, JSON.stringify(this.data)); + } } -/** - * @param {{history:!Array<EmojiVariants>, preference:Object<string,string>}} - * data recently used emoji, most recent first. - */ -function save( - keyName: string, - data: {history: EmojiVariants[], preference: {[index: string]: string}}) { - window.localStorage.setItem(keyName, JSON.stringify(data)); +interface RecentlyUsed { + history: EmojiVariants[]; + preference: {[index: string]: string}; } export class RecentlyUsedStore { - storeName: string; - data: {history: EmojiVariants[], preference: {[index: string]: string}}; + private store: Store<RecentlyUsed>; + constructor(name: string) { - this.storeName = name; - this.data = load(name); + this.store = new Store(name, {history: [], preference: {}}); } /** @@ -51,42 +78,53 @@ return false; } + const preference = this.store.data.preference; + // Base emoji must not be set as preference. So, store it only // if variant and baseEmoji are different and remove it from preference // otherwise. if (baseEmoji !== variant && variant) { - this.data.preference[baseEmoji] = variant; - } else if (baseEmoji in this.data.preference) { - delete this.data.preference[baseEmoji]; + preference[baseEmoji] = variant; + } else if (baseEmoji in preference) { + delete preference[baseEmoji]; } else { return false; } - save(this.storeName, this.data); + this.store.save(); return true; } - getPreferenceMapping() { - return this.data.preference; + getHistory(): EmojiVariants[] { + return this.store.data.history; + } + + isHistoryEmpty(): boolean { + return this.store.data.history.length === 0; + } + + getPreferenceMapping(): {[index: string]: string} { + return this.store.data.preference; } clearRecents() { - this.data.history = []; - save(this.storeName, this.data); + this.store.data.history = []; + this.store.save(); } clearItem(category: CategoryEnum, item: EmojiVariants) { + const history = this.store.data.history; + if (category === CategoryEnum.GIF) { - this.data.history = this.data.history.filter( - x => - (x.base.visualContent && - x.base.visualContent.id !== item.base.visualContent?.id)); + this.store.data.history = history.filter( + x => + (x.base.visualContent && + x.base.visualContent.id !== item.base.visualContent?.id)); } else { - this.data.history = this.data.history.filter( - x => - (x.base.string && x.base.string !== item.base.string)); + this.store.data.history = history.filter( + x => (x.base.string && x.base.string !== item.base.string)); } - save(this.storeName, this.data); + this.store.save(); } /** @@ -94,45 +132,49 @@ * it did not previously exist. */ bumpItem(category: CategoryEnum, newItem: EmojiVariants) { + const history = this.store.data.history; + // Find and remove newItem from array if it previously existed. // Note, this explicitly allows for multiple recent item entries for the // same "base" emoji just with a different variant. let oldIndex; if (category === CategoryEnum.GIF) { - oldIndex = this.data.history.findIndex( + oldIndex = history.findIndex( x => (x.base.visualContent && x.base.visualContent.id === newItem.base.visualContent?.id)); } else { - oldIndex = this.data.history.findIndex( + oldIndex = history.findIndex( x => (x.base.string && x.base.string === newItem.base.string)); } if (oldIndex !== -1) { - this.data.history.splice(oldIndex, 1); + history.splice(oldIndex, 1); } // insert newItem to the front of the array. - this.data.history.unshift(newItem); + history.unshift(newItem); // slice from end of array if it exceeds MAX_RECENTS. - if (this.data.history.length > MAX_RECENTS) { + if (history.length > MAX_RECENTS) { // setting length is sufficient to truncate an array. - this.data.history.length = MAX_RECENTS; + history.length = MAX_RECENTS; } - save(this.storeName, this.data); + this.store.save(); } /** * Removes invalid GIFs from history. */ async validate(apiProxy: EmojiPickerApiProxy): Promise<boolean> { - if (this.data.history.length === 0) { + const history = this.store.data.history; + + if (history.length === 0) { // No GIFs to validate. return false; } // This function is only called on history items with visual content (i.e. // GIFs) so we can be confident an id will always exist. - const ids = this.data.history.map(x => x.base.visualContent!.id); + const ids = history.map(x => x.base.visualContent!.id); const {selectedGifs} = await apiProxy.getGifsByIds(ids); const map = new Map<string, VisualContent>(); @@ -141,30 +183,27 @@ }); const validGifHistory = - this.data.history.filter(item => map.has(item.base.visualContent!.id)); - const updated = (validGifHistory.length !== this.data.history.length); + history.filter(item => map.has(item.base.visualContent!.id)); + const updated = (validGifHistory.length !== history.length); if (updated) { - this.data.history = validGifHistory; - save(this.storeName, this.data); + this.store.data.history = validGifHistory; + this.store.save(); } return updated; } } -const GIF_NUDGE_SHOWN_KEY = 'emoji-picker-gif-nudge-shown'; - export class GifNudgeHistoryStore { - hasNudgeShown(): boolean { - return window.localStorage.getItem(GIF_NUDGE_SHOWN_KEY) === true.toString(); + private static store = new Store('emoji-picker-gif-nudge-shown', false); + + static hasNudgeShown(): boolean { + return GifNudgeHistoryStore.store.data; } - setNudgeShown(value: boolean): void { - window.localStorage.setItem(GIF_NUDGE_SHOWN_KEY, value.toString()); - } - - static getInstance(): GifNudgeHistoryStore { - return new GifNudgeHistoryStore(); + static setNudgeShown(value: boolean): void { + GifNudgeHistoryStore.store.data = value; + GifNudgeHistoryStore.store.save(); } }
diff --git a/chrome/browser/resources/chromeos/login/login.gni b/chrome/browser/resources/chromeos/login/login.gni index 2624c84c..58cd79c 100644 --- a/chrome/browser/resources/chromeos/login/login.gni +++ b/chrome/browser/resources/chromeos/login/login.gni
@@ -142,7 +142,7 @@ "screens/common/gesture_navigation.js", "screens/common/guest_tos.js", "screens/common/hw_data_collection.js", - "screens/common/local_state_error.js", + "screens/common/local_state_error.ts", "screens/common/managed_terms_of_service.js", "screens/common/marketing_opt_in.js", "screens/common/multidevice_setup.js",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn index e0e1c41..f53d559 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
@@ -39,7 +39,6 @@ ":gesture_navigation", ":guest_tos", ":hw_data_collection", - ":local_state_error", ":managed_terms_of_service", ":marketing_opt_in", ":offline_ad_login", @@ -223,18 +222,6 @@ extra_deps = [ ":web_components" ] } -js_library("local_state_error") { - sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js" ] - deps = [ - "../../components/behaviors:login_screen_behavior", - "../../components/behaviors:oobe_dialog_host_behavior", - "../../components/behaviors:oobe_i18n_behavior", - "../../components/dialogs:oobe_adaptive_dialog", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] - extra_deps = [ ":web_components" ] -} - js_library("managed_terms_of_service") { sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/managed_terms_of_service.js" ] deps = [
diff --git a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js deleted file mode 100644 index d3f7c4a..0000000 --- a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.js +++ /dev/null
@@ -1,67 +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. - -/** - * @fileoverview Polymer element for displaying local state error screen. - */ - -import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; -import '../../components/oobe_icons.html.js'; -import '../../components/buttons/oobe_text_button.js'; -import '../../components/common_styles/oobe_common_styles.css.js'; -import '../../components/common_styles/oobe_dialog_host_styles.css.js'; -import '../../components/dialogs/oobe_adaptive_dialog.js'; - -import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; - -import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; -import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js'; -import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; -import {OOBE_UI_STATE} from '../../components/display_manager_types.js'; - -import {getTemplate} from './local_state_error.html.js'; - - -/** - * @constructor - * @extends {PolymerElement} - * @implements {LoginScreenBehaviorInterface} - * @implements {OobeI18nBehaviorInterface} - */ -const LocalStateErrorBase = mixinBehaviors( - [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior], - PolymerElement); - -/** - * @polymer - */ -class LocalStateError extends LocalStateErrorBase { - static get is() { - return 'local-state-error-element'; - } - - static get template() { - return getTemplate(); - } - - static get properties() { - return {}; - } - - ready() { - super.ready(); - this.initializeLoginScreen('LocalStateErrorScreen'); - } - - /** Initial UI State for screen */ - getOobeUIInitialState() { - return OOBE_UI_STATE.BLOCKING; - } - - onRestartAndPowerwash_() { - this.userActed('restart-and-powerwash'); - } -} - -customElements.define(LocalStateError.is, LocalStateError);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts new file mode 100644 index 0000000..95f9d355 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/local_state_error.ts
@@ -0,0 +1,70 @@ +// 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. + +/** + * @fileoverview Polymer element for displaying local state error screen. + */ + +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '../../components/oobe_icons.html.js'; +import '../../components/buttons/oobe_text_button.js'; +import '../../components/common_styles/oobe_common_styles.css.js'; +import '../../components/common_styles/oobe_dialog_host_styles.css.js'; +import '../../components/dialogs/oobe_adaptive_dialog.js'; + +import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js'; +import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; +import {OobeDialogHostBehavior, OobeDialogHostBehaviorInterface} from '../../components/behaviors/oobe_dialog_host_behavior.js'; +import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; +import {OOBE_UI_STATE} from '../../components/display_manager_types.js'; + +import {getTemplate} from './local_state_error.html.js'; + +export const LocalStateErrorBase = + mixinBehaviors( + [OobeI18nBehavior, LoginScreenBehavior, OobeDialogHostBehavior], + PolymerElement) as { + new (): PolymerElement & OobeI18nBehaviorInterface & + LoginScreenBehaviorInterface & OobeDialogHostBehaviorInterface, + }; + + +export class LocalStateError extends LocalStateErrorBase { + static get is() { + return 'local-state-error-element' as const; + } + + static get template(): HTMLTemplateElement { + return getTemplate(); + } + + static get properties(): PolymerElementProperties { + return {}; + } + + override ready(): void { + super.ready(); + this.initializeLoginScreen('LocalStateErrorScreen'); + } + + /** Initial UI State for screen */ + // eslint-disable-next-line @typescript-eslint/naming-convention + override getOobeUIInitialState(): OOBE_UI_STATE { + return OOBE_UI_STATE.BLOCKING; + } + + private onRestartAndPowerwash_(): void { + this.userActed('restart-and-powerwash'); + } +} + +declare global { + interface HTMLElementTagNameMap { + [LocalStateError.is]: LocalStateError; + } +} + +customElements.define(LocalStateError.is, LocalStateError);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html b/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html index c2d9c724..fa2f716 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html +++ b/chrome/browser/resources/chromeos/login/screens/common/remote_activity_notification.html
@@ -7,7 +7,7 @@ <style include="oobe-dialog-host-styles"></style> <oobe-adaptive-dialog role="dialog"> <iron-icon slot="icon" icon="oobe-32:enterprise"></iron-icon> - <h1 slot="title"> + <h1 slot="title" aria-live="polite"> [[i18nDynamic(locale, 'localStateNotificationTitle')]] </h1> <div slot="subtitle"> @@ -22,4 +22,4 @@ id="cancelButton"> </oobe-text-button> </div> -</oobe-adaptive-dialog> \ No newline at end of file +</oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/side_panel/commerce/history_graph.ts b/chrome/browser/resources/side_panel/commerce/history_graph.ts index 845741a..8e538d0 100644 --- a/chrome/browser/resources/side_panel/commerce/history_graph.ts +++ b/chrome/browser/resources/side_panel/commerce/history_graph.ts
@@ -62,10 +62,14 @@ private points: Array<{date: Date, price: number}>; private isGraphInteracted_: boolean = false; private currentPricePointIndex_?: number; + private resizeObserver_: ResizeObserver; + private currentWidth_: number; + private graphSvg_: any; private dateTopMarginPx_ = 8; private priceRightMarginPx_ = 4; private bubbleHorizontalPaddingPx_ = 4; - private bubbleVerticalPaddingPx_ = 4; + private bubbleTopPaddingPx_ = 4; + private bubbleBottomPaddingPx_ = 4; private bubbleCornerRadiusPx_ = 3; override connectedCallback() { @@ -75,13 +79,22 @@ this.dateTopMarginPx_ = 12; this.priceRightMarginPx_ = 8; this.bubbleHorizontalPaddingPx_ = 6; - this.bubbleVerticalPaddingPx_ = 2; + this.bubbleTopPaddingPx_ = 3; + this.bubbleBottomPaddingPx_ = 2; } this.points = this.data.map( d => ({date: this.stringToDate_(d.date), price: d.price})); this.drawHistoryGraph_(); + + this.currentWidth_ = this.$.historyGraph.offsetWidth; + this.resizeObserver_ = new ResizeObserver(this.onResize_.bind(this)); + this.resizeObserver_.observe(this.$.historyGraph); + } + + override disconnectedCallback() { + this.resizeObserver_.disconnect(); } private stringToDate_(s: string): Date { @@ -94,6 +107,14 @@ return new Date(year, month - 1, day); } + private onResize_() { + if (this.$.historyGraph.offsetWidth !== this.currentWidth_) { + this.currentWidth_ = this.$.historyGraph.offsetWidth; + this.graphSvg_.remove(); + this.drawHistoryGraph_(); + } + } + private getTooltipText_(i: number): string { let formattedDate = d3.timeFormat('%b %-d')(this.points[i].date); @@ -118,7 +139,7 @@ this.getLabelSize_(formattedTicks[formattedTicks.length - 1]); const graphMarginTopPx = GRAPH_BUBBLE_BOTTOM_MARGIN_PX + - 2 * this.bubbleVerticalPaddingPx_ + tooltipHeight; + this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ + tooltipHeight; const graphMarginBottomPx = this.dateTopMarginPx_ + labelHeight; const graphHeightPx = LINE_AREA_HEIGHT_PX + graphMarginTopPx + graphMarginBottomPx; @@ -130,6 +151,7 @@ .attr('width', '100%') .attr('height', graphHeightPx) .attr('background-color', 'transparent'); + this.graphSvg_ = svg; const node = svg.node(); assert(node); const graphWidthPx = node.getBoundingClientRect().width; @@ -199,7 +221,10 @@ // Set up bubble and mouse listeners. const verticalLine = svg.append('line') - .attr('y1', 2 * this.bubbleVerticalPaddingPx_ + tooltipHeight) + .attr( + 'y1', + this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ + + tooltipHeight) .attr('y2', graphHeightPx - graphMarginBottomPx) .attr('opacity', 0) .classed(CssClass.DASH_LINE, true); @@ -211,25 +236,30 @@ if (document.documentElement.hasAttribute('chrome-refresh-2023')) { this.bubbleCornerRadiusPx_ = - this.bubbleVerticalPaddingPx_ + tooltipHeight / 2; + (this.bubbleTopPaddingPx_ + this.bubbleBottomPaddingPx_ + + tooltipHeight) / + 2; } - const bubble = - svg.append('rect') - .attr('opacity', 0) - .attr('y', 0) - .attr('height', 2 * this.bubbleVerticalPaddingPx_ + tooltipHeight) - .attr('rx', this.bubbleCornerRadiusPx_) - .attr('ry', this.bubbleCornerRadiusPx_) - .classed(CssClass.BUBBLE, true); + const bubble = svg.append('rect') + .attr('opacity', 0) + .attr('y', 0) + .attr( + 'height', + this.bubbleTopPaddingPx_ + + this.bubbleBottomPaddingPx_ + tooltipHeight) + .attr('rx', this.bubbleCornerRadiusPx_) + .attr('ry', this.bubbleCornerRadiusPx_) + .classed(CssClass.BUBBLE, true); - const tooltip = - svg.append('text') - .attr('y', this.bubbleVerticalPaddingPx_ + tooltipHeight / 2) - .attr('dominant-baseline', 'middle') - .attr('opacity', 0) - .attr('aria-hidden', 'true'); + const tooltip = svg.append('text') + .attr('y', this.bubbleTopPaddingPx_ + tooltipHeight / 2) + .attr('dominant-baseline', 'middle') + .attr('opacity', 0) + .attr('aria-hidden', 'true'); - const initialIndex = this.points.length - 1; + const initialIndex = this.currentPricePointIndex_ == null ? + this.points.length - 1 : + this.currentPricePointIndex_; this.showTooltip_( verticalLine, circle, bubble, tooltip, initialIndex, xScale(this.points[initialIndex].date),
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index e317e16..4118ac2 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -43,7 +43,6 @@ "//components/resources:components_resources_grit", "//components/safe_browsing:buildflags", "//components/safe_browsing/content/browser", - "//components/safe_browsing/content/browser:client_report_util", "//components/safe_browsing/content/browser:client_side_detection", "//components/safe_browsing/content/browser:client_side_detection_service", "//components/safe_browsing/content/browser/triggers:suspicious_site_trigger",
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 7da85cd8..d451e8a 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -60,6 +60,7 @@ #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/browser/db/database_manager.h" @@ -72,7 +73,6 @@ #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/safe_browsing/core/common/safebrowsing_constants.h" #include "components/safe_browsing/core/common/utils.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "components/signin/public/base/consent_level.h" #include "components/signin/public/identity_manager/account_info.h"
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc index d4ba433..26b875dfd 100644 --- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc +++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
@@ -54,7 +54,7 @@ safe_browsing::UpdatePrefsBeforeSecurityInterstitial(prefs); security_interstitials::BaseSafeBrowsingErrorUI::SBErrorDisplayOptions - display_options(BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources), + display_options(BaseBlockingPage::IsMainPageLoadPending(unsafe_resources), is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), IsExtendedReportingEnabled(*prefs),
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index d5cec9f..6ba8309 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -31,6 +31,7 @@ #include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/content/browser/client_side_phishing_model.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/test_database_manager.h" @@ -38,7 +39,6 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "components/signin/public/identity_manager/identity_test_environment.h" #include "content/public/browser/back_forward_cache.h" @@ -545,7 +545,7 @@ EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type); EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source); EXPECT_EQ(web_contents(), - security_interstitials::GetWebContentsForResource(resource)); + unsafe_resource_util::GetWebContentsForResource(resource)); // Make sure the client object will be deleted. content::GetIOThreadTaskRunner({})->PostTask( @@ -616,7 +616,7 @@ EXPECT_EQ(SB_THREAT_TYPE_URL_CLIENT_SIDE_PHISHING, resource.threat_type); EXPECT_EQ(ThreatSource::CLIENT_SIDE_DETECTION, resource.threat_source); EXPECT_EQ(web_contents(), - security_interstitials::GetWebContentsForResource(resource)); + unsafe_resource_util::GetWebContentsForResource(resource)); // Make sure the client object will be deleted. content::GetIOThreadTaskRunner({})->PostTask(
diff --git a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc index e0e12d4..86c7e67 100644 --- a/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc +++ b/chrome/browser/safe_browsing/phishy_interaction_tracker_unittest.cc
@@ -18,8 +18,8 @@ #include "chrome/common/url_constants.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_browser_process.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/common/features.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_render_process_host.h" @@ -229,8 +229,8 @@ safe_browsing::SBThreatType threat_type; EXPECT_TRUE(ui_manager_->IsUrlAllowlistedOrPendingForWebContents( resource.url, resource.is_subresource, /*entry=*/nullptr, - security_interstitials::GetWebContentsForResource(resource), true, - &threat_type)); + safe_browsing::unsafe_resource_util::GetWebContentsForResource(resource), + true, &threat_type)); const std::string phishy_interaction_histogram = "SafeBrowsing.PhishySite."; const int kExpectedClickEventCount = 3;
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 145ee08..59e0b3c 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -75,6 +75,7 @@ #include "components/safe_browsing/content/browser/safe_browsing_blocking_page_factory.h" #include "components/safe_browsing/content/browser/threat_details.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/fake_database_manager.h" @@ -89,7 +90,6 @@ #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/content/ssl_blocking_page.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/controller_client.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -550,7 +550,7 @@ IsSafeBrowsingSurveysEnabled(*prefs); BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options( - BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources), + BaseBlockingPage::IsMainPageLoadPending(unsafe_resources), is_extended_reporting_opt_in_allowed, web_contents->GetBrowserContext()->IsOffTheRecord(), IsExtendedReportingEnabled(*prefs),
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc index 631bffff..2d1393c 100644 --- a/chrome/browser/safe_browsing/threat_details_unittest.cc +++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -25,11 +25,11 @@ #include "components/safe_browsing/content/browser/threat_details.h" #include "components/safe_browsing/content/browser/threat_details_history.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/core/browser/referrer_chain_provider.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/global_routing_id.h"
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc index bbc7a99..3bf8558a 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -18,11 +18,11 @@ #include "components/safe_browsing/buildflags.h" #include "components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_entry.h" @@ -58,7 +58,7 @@ bool is_main_frame, scoped_refptr<SafeBrowsingUIManager> ui_manager) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); // Don't delay the interstitial for prerender pages. if (!web_contents || prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc index 9c48516..8849501 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc +++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
@@ -62,6 +62,10 @@ TRACE_EVENT("browser", "BoundSessionRegistrationFetcherImpl::Start", perfetto::Flow::FromPointer(this), "endpoint", registration_params_.RegistrationEndpoint()); + CHECK(!registration_duration_.has_value()); + CHECK(!callback_); + CHECK(!registration_token_helper_); + registration_duration_.emplace(); // Starts the timer. callback_ = std::move(callback); // base::Unretained() is safe since `this` owns // `registration_token_helper_`. @@ -70,7 +74,7 @@ registration_params_.RegistrationEndpoint(), base::BindOnce( &BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated, - base::Unretained(this))); + base::Unretained(this), base::ElapsedTimer())); registration_token_helper_->Start(); } @@ -138,10 +142,15 @@ } void BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated( + base::ElapsedTimer generate_registration_token_timer, absl::optional<RegistrationTokenHelper::Result> result) { TRACE_EVENT("browser", "BoundSessionRegistrationFetcherImpl::OnRegistrationTokenCreated", perfetto::Flow::FromPointer(this), "success", result.has_value()); + base::UmaHistogramMediumTimes( + "Signin.BoundSessionCredentials." + "SessionRegistrationGenerateRegistrationTokenDuration", + generate_registration_token_timer.Elapsed()); if (!result.has_value()) { RunCallbackAndRecordMetrics( base::unexpected(RegistrationError::kGenerateRegistrationTokenFailed)); @@ -234,6 +243,11 @@ base::UmaHistogramEnumeration( "Signin.BoundSessionCredentials.SessionRegistrationResult", error_for_metrics); + CHECK(registration_duration_.has_value()); + base::UmaHistogramMediumTimes( + "Signin.BoundSessionCredentials.SessionRegistrationTotalDuration", + registration_duration_->Elapsed()); + registration_duration_.reset(); std::move(callback_).Run( params_or_error.has_value()
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h index f36ee884..b56e9cd9 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h +++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
@@ -13,6 +13,7 @@ #include "base/functional/callback.h" #include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" +#include "base/timer/elapsed_timer.h" #include "base/types/expected.h" #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service.h" #include "chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_param.h" @@ -20,6 +21,7 @@ #include "components/unexportable_keys/service_error.h" #include "components/unexportable_keys/unexportable_key_id.h" #include "services/network/public/cpp/simple_url_loader.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" namespace network { @@ -81,6 +83,7 @@ void OnURLLoaderComplete(std::unique_ptr<std::string> response_body); void OnRegistrationTokenCreated( + base::ElapsedTimer generate_registration_token_timer, absl::optional<RegistrationTokenHelper::Result> result); void StartFetchingRegistration(const std::string& registration_token); @@ -101,6 +104,7 @@ // Non-null after a fetch has started. std::unique_ptr<network::SimpleURLLoader> url_loader_; + absl::optional<base::ElapsedTimer> registration_duration_; const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; std::unique_ptr<RegistrationTokenHelper> registration_token_helper_;
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc index 6bcb817..6b058319 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc +++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
@@ -193,9 +193,15 @@ scoped_key_provider_.emplace<crypto::ScopedNullUnexportableKeyProvider>(); } - void ExpectRecordedResultHistogram(RegistrationError error) { + void ExpectRecordedMetrics(RegistrationError error) { histogram_tester_.ExpectUniqueSample( "Signin.BoundSessionCredentials.SessionRegistrationResult", error, 1); + histogram_tester_.ExpectTotalCount( + "Signin.BoundSessionCredentials.SessionRegistrationTotalDuration", 1); + histogram_tester_.ExpectTotalCount( + "Signin.BoundSessionCredentials." + "SessionRegistrationGenerateRegistrationTokenDuration", + 1); } private: @@ -252,7 +258,7 @@ testing::Optional(base::test::EqualsProto( CreateTestBoundSessionParams(future.Get()->wrapped_key())))); - ExpectRecordedResultHistogram(RegistrationError::kNone); + ExpectRecordedMetrics(RegistrationError::kNone); // Verify the wrapped key. std::string wrapped_key = future.Get<>()->wrapped_key(); @@ -302,7 +308,7 @@ EXPECT_TRUE(future.IsReady()); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram(RegistrationError::kParseJsonFailed); + ExpectRecordedMetrics(RegistrationError::kParseJsonFailed); } TEST_F(BoundSessionRegistrationFetcherImplTest, @@ -315,7 +321,7 @@ RunBackgroundTasks(); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram(RegistrationError::kRequiredFieldMissing); + ExpectRecordedMetrics(RegistrationError::kRequiredFieldMissing); } TEST_F(BoundSessionRegistrationFetcherImplTest, @@ -328,7 +334,7 @@ RunBackgroundTasks(); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram(RegistrationError::kRequiredFieldMissing); + ExpectRecordedMetrics(RegistrationError::kRequiredFieldMissing); } TEST_F(BoundSessionRegistrationFetcherImplTest, @@ -355,8 +361,7 @@ RunBackgroundTasks(); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram( - RegistrationError::kRequiredCredentialFieldMissing); + ExpectRecordedMetrics(RegistrationError::kRequiredCredentialFieldMissing); } TEST_F(BoundSessionRegistrationFetcherImplTest, NonOkHttpResponseCode) { @@ -368,7 +373,7 @@ RunBackgroundTasks(); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram(RegistrationError::kServerError); + ExpectRecordedMetrics(RegistrationError::kServerError); } TEST_F(BoundSessionRegistrationFetcherImplTest, NetworkError) { @@ -380,7 +385,7 @@ RunBackgroundTasks(); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram(RegistrationError::kNetworkError); + ExpectRecordedMetrics(RegistrationError::kNetworkError); } TEST_F(BoundSessionRegistrationFetcherImplTest, NoKeyProvider) { @@ -393,8 +398,7 @@ EXPECT_FALSE(WasRequestSent()); EXPECT_EQ(future.Get<>(), absl::nullopt); - ExpectRecordedResultHistogram( - RegistrationError::kGenerateRegistrationTokenFailed); + ExpectRecordedMetrics(RegistrationError::kGenerateRegistrationTokenFailed); } TEST_F(BoundSessionRegistrationFetcherImplTest, ParseCredentials) {
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client.cc b/chrome/browser/ui/ash/download_status/notification_display_client.cc index c884506..c358b34 100644 --- a/chrome/browser/ui/ash/download_status/notification_display_client.cc +++ b/chrome/browser/ui/ash/download_status/notification_display_client.cc
@@ -43,9 +43,8 @@ constexpr char kNotificationOrigin[] = "chrome://downloads"; // The commands supported by notification buttons. -// TODO(http://b/316368295): Support pause and resume. -constexpr std::array<CommandType, 2> kButtonCommands = {CommandType::kCancel, - CommandType::kPause}; +constexpr std::array<CommandType, 3> kButtonCommands = { + CommandType::kCancel, CommandType::kPause, CommandType::kResume}; // DownloadNotificationDelegate ------------------------------------------------
diff --git a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc index f13b9c7d..ebdd6f0 100644 --- a/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc +++ b/chrome/browser/ui/ash/download_status/notification_display_client_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <set> #include <string> #include <utility> @@ -418,8 +419,9 @@ EXPECT_THAT(GetDisplayedNotificationIds(), Not(Contains(notification_id))); } -// Verifies pausing download from a notification. -IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, PauseDownload) { +// Verifies pausing and resuming download from a notification. +IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, + PauseAndResumeDownload) { // Add a pausable download. Cache the notification ID. Profile* const profile = ProfileManager::GetActiveUserProfile(); std::string notification_id; @@ -433,25 +435,34 @@ /*received_bytes=*/0, /*target_bytes=*/1024); download->pausable = true; + download->resumable = false; Update(download->Clone()); Mock::VerifyAndClearExpectations(&service_observer()); + // The notification of a pausable download should not have a resume button. + AshNotificationView* const popup_view = + GetPopupView(profile, notification_id); + ASSERT_TRUE(popup_view); + std::vector<views::LabelButton*> action_buttons = + popup_view->GetActionButtonsForTest(); + const std::u16string resume_button_text = + l10n_util::GetStringUTF16(GetCommandTextId(CommandType::kResume)); + auto resume_button_iter = base::ranges::find( + action_buttons, resume_button_text, &views::LabelButton::GetText); + EXPECT_EQ(resume_button_iter, action_buttons.end()); + // Implement download pause for the mock client. ON_CALL(download_status_updater_client(), Pause(download->guid, _)) .WillByDefault([&](const std::string& guid, crosapi::MockDownloadStatusUpdaterClient::PauseCallback callback) { download->pausable = false; + download->resumable = true; Update(download->Clone()); std::move(callback).Run(/*handled=*/true); }); // Get the pause button. - AshNotificationView* const popup_view = - GetPopupView(profile, notification_id); - ASSERT_TRUE(popup_view); - std::vector<views::LabelButton*> action_buttons = - popup_view->GetActionButtonsForTest(); const std::u16string pause_button_text = l10n_util::GetStringUTF16(GetCommandTextId(CommandType::kPause)); auto pause_button_iter = base::ranges::find(action_buttons, pause_button_text, @@ -459,14 +470,15 @@ ASSERT_NE(pause_button_iter, action_buttons.end()); // Click on the pause button and wait until download is paused. - base::RunLoop run_loop; + auto run_loop = std::make_unique<base::RunLoop>(); EXPECT_CALL(service_observer(), OnNotificationDisplayed) .WillOnce(WithArg<0>( [&run_loop](const message_center::Notification& notification) { - run_loop.Quit(); + run_loop->Quit(); })); test::Click(*pause_button_iter, ui::EF_NONE); - run_loop.Run(); + run_loop->Run(); + Mock::VerifyAndClearExpectations(&service_observer()); // After pausing, `popup_view` is hidden. Therefore, get the notification view // from the notification center bubble. @@ -481,6 +493,34 @@ pause_button_iter = base::ranges::find(action_buttons, pause_button_text, &views::LabelButton::GetText); EXPECT_EQ(pause_button_iter, action_buttons.end()); + + // The resume button should show. + resume_button_iter = base::ranges::find(action_buttons, resume_button_text, + &views::LabelButton::GetText); + ASSERT_NE(resume_button_iter, action_buttons.end()); + + // Implement download resume for the mock client. + ON_CALL(download_status_updater_client(), Resume(download->guid, _)) + .WillByDefault( + [&](const std::string& guid, + crosapi::MockDownloadStatusUpdaterClient::ResumeCallback + callback) { + download->pausable = true; + download->resumable = false; + Update(download->Clone()); + std::move(callback).Run(/*handled=*/true); + }); + + // Click on the resume button and wait until download is resumed. + run_loop = std::make_unique<base::RunLoop>(); + EXPECT_CALL(service_observer(), OnNotificationDisplayed) + .WillOnce(WithArg<0>( + [&run_loop](const message_center::Notification& notification) { + run_loop->Quit(); + })); + test::Click(*resume_button_iter, ui::EF_NONE); + run_loop->Run(); + Mock::VerifyAndClearExpectations(&service_observer()); } } // namespace ash::download_status
diff --git a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc index 12c2330..f6b9b07 100644 --- a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
@@ -5,9 +5,9 @@ #include "chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h" #include "ash/display/screen_orientation_controller.h" -#include "ash/public/cpp/tablet_mode.h" #include "ash/shell.h" #include "content/public/browser/web_contents.h" +#include "ui/display/screen.h" namespace { @@ -60,7 +60,7 @@ bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported( content::WebContents* web_contents) { - return ash::TabletMode::IsInTabletMode(); + return display::Screen::GetScreen()->InTabletMode(); } void ScreenOrientationDelegateChromeos::Unlock(
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index 44b97de..3b3f185 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -1945,8 +1945,8 @@ std::unique_ptr<ScopedJitChromeBrowserClientOverride> scoped_client_override_; }; -typedef HostedAppJitTestBase<false> HostedAppJitTestBaseDefaultEnabled; -typedef HostedAppJitTestBase<true> HostedAppJitTestBaseDefaultDisabled; +using HostedAppJitTestBaseDefaultEnabled = HostedAppJitTestBase<false>; +using HostedAppJitTestBaseDefaultDisabled = HostedAppJitTestBase<true>; IN_PROC_BROWSER_TEST_P(HostedAppJitTestBaseDefaultEnabled, JITDisabledTest) { JitTestInternal();
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc index 9dcd9dec..c5e091d3 100644 --- a/chrome/browser/ui/page_info/page_info_unittest.cc +++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -1114,8 +1114,8 @@ }; for (const auto& test : kTestCases) { - ResetMockUI(); ClearPageInfo(); + ResetMockUI(); security_level_ = test.security_level; visible_security_state_.url = GURL("https://scheme-is-cryptographic.test"); visible_security_state_.certificate = cert(); @@ -1818,8 +1818,8 @@ base::HistogramTester histograms; SetURL("https://example.test"); visible_security_state_.safety_tip_info = test.safety_tip_info; - ResetMockUI(); ClearPageInfo(); + ResetMockUI(); SetDefaultUIExpectations(mock_ui()); histograms.ExpectTotalCount(kGenericHistogram, 0); @@ -1912,8 +1912,8 @@ EXPECT_FALSE(showing_setting(last_permission_info_list())); // Reset state. - ResetMockUI(); ClearPageInfo(); + ResetMockUI(); SetDefaultUIExpectations(mock_ui()); // Now, explicitly set site activation metadata to simulate activation on
diff --git a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc index 6667135..c5e7a56 100644 --- a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc +++ b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc
@@ -203,10 +203,8 @@ nickname_textfield_->set_controller(this); nickname_textfield_->SetPlaceholderText( l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_IBAN_PLACEHOLDER)); - nickname_textfield_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kScaleToMaximum)); + nickname_textfield_->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); nickname_textfield_->SetHorizontalAlignment(gfx::ALIGN_LEFT); nickname_textfield_->SetBorder(views::NullBorder());
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc index 108c3200f..e8e4208 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -153,9 +153,6 @@ CHECK(!base::FeatureList::IsEnabled( extensions_features::kExtensionsMenuAccessControl)); - views::FlexSpecification stretch_specification = - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded); auto builder = views::Builder<ExtensionMenuItemView>(this) // Set so the extension button receives enter/exit on children to @@ -168,7 +165,10 @@ std::make_unique<ExtensionsMenuButton>(browser_, controller_.get())) .CopyAddressTo(&primary_action_button_) - .SetProperty(views::kFlexBehaviorKey, stretch_specification), + .SetProperty(views::kFlexBehaviorKey, + views::FlexSpecification( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)), views::Builder<HoverButton>( std::make_unique<HoverButton>( views::Button::PressedCallback(), std::u16string())) @@ -225,9 +225,6 @@ CHECK(base::FeatureList::IsEnabled( extensions_features::kExtensionsMenuAccessControl)); - views::FlexSpecification stretch_specification = - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded); ChromeLayoutProvider* const provider = ChromeLayoutProvider::Get(); const int icon_size = provider->GetDistanceMetric(DISTANCE_EXTENSIONS_MENU_EXTENSION_ICON_SIZE); @@ -258,7 +255,8 @@ .SetNotifyEnterExitOnChild(true) .SetOrientation(views::LayoutOrientation::kVertical) .SetCrossAxisAlignment(views::LayoutAlignment::kStretch) - .SetProperty(views::kFlexBehaviorKey, stretch_specification) + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()) .AddChildren( // Main row. views::Builder<views::FlexLayoutView>() @@ -275,7 +273,9 @@ controller_.get())) .CopyAddressTo(&primary_action_button_) .SetProperty(views::kFlexBehaviorKey, - stretch_specification), + views::FlexSpecification( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)), // Site access toggle. views::Builder<views::ToggleButton>() .CopyAddressTo(&site_access_toggle_)
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc index 7d3bf72..af14b31f 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -535,7 +535,8 @@ .SetInteriorMargin(gfx::Insets::TLBR(dialog_insets.top(), dialog_insets.left(), 0, dialog_insets.right())) - .SetProperty(views::kFlexBehaviorKey, stretch_specification) + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()) .SetVisible(true) .AddChildren( views::Builder<views::FlexLayoutView>()
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc index aff7e68..bc950cd 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_site_permissions_page_view.cc
@@ -257,7 +257,8 @@ .SetInteriorMargin(gfx::Insets::TLBR(dialog_insets.top(), dialog_insets.left(), 0, dialog_insets.right())) - .SetProperty(views::kFlexBehaviorKey, stretch_specification) + .SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()) .AddChildren( // Back button. views::Builder<views::ImageButton>(
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc index 4c40c318..ac6a59b7 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_view.cc
@@ -138,10 +138,8 @@ label_wrapper->SetLayoutManager(std::make_unique<views::FlexLayout>()) ->SetOrientation(views::LayoutOrientation::kVertical) .SetMainAxisAlignment(views::LayoutAlignment::kCenter); - label_wrapper->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kUnbounded)); + label_wrapper->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); label_wrapper->SetProperty(views::kMarginsKey, gfx::Insets::VH(vertical_spacing, 0));
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index eaf00a59..508be728 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -40,7 +40,7 @@ #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/metrics/structured/event_logging_features.h" -// TODO(crbug/4925196): enable gn check once it learn about conditional includes +// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes #include "components/metrics/structured/structured_events.h" // nogncheck #endif
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc index 54d86f3c..e9a1394d 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
@@ -220,10 +220,8 @@ std::make_unique<views::BoxLayoutView>(); auto* password_label_ptr = password_label_with_eye_icon_view->AddChildView( std::move(password_label)); - password_label_ptr->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kScaleToMaximum)); + password_label_ptr->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); auto* eye_icon = password_label_with_eye_icon_view->AddChildView( CreateVectorToggleImageButton(views::Button::PressedCallback()));
diff --git a/chrome/browser/ui/views/passwords/password_add_username_view.cc b/chrome/browser/ui/views/passwords/password_add_username_view.cc index 7756d83..18f7997 100644 --- a/chrome/browser/ui/views/passwords/password_add_username_view.cc +++ b/chrome/browser/ui/views/passwords/password_add_username_view.cc
@@ -39,10 +39,8 @@ auto* password_label_ptr = password_label_with_eye_icon_view->AddChildView( std::move(password_label)); password_label_ptr->SetTextStyle(views::style::STYLE_PRIMARY); - password_label_ptr->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kScaleToMaximum)); + password_label_ptr->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); auto* eye_icon = password_label_with_eye_icon_view->AddChildView( CreateVectorToggleImageButton(views::Button::PressedCallback()));
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 645c793..d677797 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -627,11 +627,8 @@ // The |edit_button| is on the right and has fixed width. if (edit_button) { - edit_button->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kPreferred) - .WithOrder(2)); + edit_button->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); views::View* edit_button_container = profile_background_container_->AddChildView( std::make_unique<views::View>());
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc index 6d27d6e..4c9d3153 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -11,7 +11,6 @@ #include <utility> #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/cpp/tablet_mode.h" #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/location.h" @@ -50,6 +49,7 @@ #include "ui/base/base_window.h" #include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/color/color_provider.h" +#include "ui/display/screen.h" #include "ui/gfx/color_palette.h" #include "ui/shell_dialogs/select_file_policy.h" #include "ui/shell_dialogs/selected_file_info.h" @@ -452,7 +452,8 @@ owner.android_task_id.has_value() || owner.lacros_window_id.has_value(); - can_resize_ = !ash::TabletMode::IsInTabletMode() && !is_for_capture_mode; + can_resize_ = + !display::Screen::GetScreen()->InTabletMode() && !is_for_capture_mode; // Obtain BaseWindow and WebContents if the owner window is browser. if (!skip_finding_browser)
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc index 9157f2f..d49a6e7 100644 --- a/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc +++ b/chrome/browser/ui/views/sync/bubble_sync_promo_signin_button_view.cc
@@ -66,11 +66,8 @@ if (orientation == views::BoxLayout::Orientation::kHorizontal) { button_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); - hover_button->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kUnbounded) - .WithAlignment(views::LayoutAlignment::kStart)); + hover_button->SetProperty(views::kBoxLayoutFlexKey, + views::BoxLayoutFlexSpecification()); } views::Builder<BubbleSyncPromoSigninButtonView>(this)
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc index 74673fa..69451a3 100644 --- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc +++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -152,6 +152,7 @@ #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h" +#include "chromeos/constants/chromeos_features.h" #else #include "chrome/browser/ui/webui/app_home/app_home.mojom.h" #include "chrome/browser/ui/webui/app_home/app_home_page_handler.h" @@ -1153,6 +1154,10 @@ } void WebAppIntegrationTestDriver::EnterFullScreenApp() { +// TODO(crbug.com/1481727): Fullscreen is flaky on Lacros. +#if BUILDFLAG(IS_CHROMEOS_LACROS) + GTEST_SKIP() << "Flaky on Lacros (crbug.com/1481727)"; +#else if (!BeforeStateChangeAction(__FUNCTION__)) { return; } @@ -1164,9 +1169,14 @@ fullscreen_observer.Wait(); ASSERT_TRUE(fullscreen_controller->IsFullscreenForBrowser()); AfterStateChangeAction(); +#endif // IS_CHROMEOS_LACROS } void WebAppIntegrationTestDriver::ExitFullScreenApp() { +// TODO(crbug.com/1481727): Fullscreen is flaky on Lacros. +#if BUILDFLAG(IS_CHROMEOS_LACROS) + GTEST_SKIP() << "Flaky on Lacros (crbug.com/1481727)"; +#else if (!BeforeStateChangeAction(__FUNCTION__)) { return; } @@ -1178,6 +1188,7 @@ fullscreen_observer.Wait(); ASSERT_FALSE(fullscreen_controller->IsFullscreenForBrowser()); AfterStateChangeAction(); +#endif // IS_CHROMEOS_LACROS } void WebAppIntegrationTestDriver::DisableFileHandling(Site site) { @@ -1198,11 +1209,20 @@ void WebAppIntegrationTestDriver::CreateShortcut(Site site, WindowOptions options) { + bool open_in_window = options == WindowOptions::kWindowed; + +#if BUILDFLAG(IS_CHROMEOS) + if (chromeos::features::IsCrosShortstandEnabled() && open_in_window) { + GTEST_SKIP() << "With project Shortstand, users are no longer allowed to " + "create shortcut and open in window."; + } +#endif + if (!BeforeStateChangeAction(__FUNCTION__)) { return; } MaybeNavigateTabbedBrowserInScope(site); - bool open_in_window = options == WindowOptions::kWindowed; + SetAutoAcceptWebAppDialogForTesting( /*auto_accept=*/true, /*auto_open_in_window=*/open_in_window); @@ -3771,6 +3791,9 @@ if (testing::Test::HasFatalFailure() && !in_tear_down_) { return false; } + if (testing::Test::IsSkipped() && !in_tear_down_) { + return false; + } LOG(INFO) << "BeforeStateChangeAction: " << std::string(executing_action_level_, ' ') << function; ++executing_action_level_; @@ -3864,6 +3887,9 @@ if (testing::Test::HasFatalFailure() && !in_tear_down_) { return false; } + if (testing::Test::IsSkipped() && !in_tear_down_) { + return false; + } ++executing_action_level_; provider()->command_manager().AwaitAllCommandsCompleteForTesting(); LOG(INFO) << "BeforeStateCheckAction: "
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index fefc67f..9f2e1187 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -134,7 +134,7 @@ #include "ui/views/test/dialog_test.h" #include "ui/views/widget/any_widget_observer.h" #include "ui/views/widget/widget.h" -// TODO(crbug/4925196): enable gn check once it learn about conditional includes +// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes #include "components/metrics/structured/structured_events.h" // nogncheck #endif
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc index 57edf00..edbb5575 100644 --- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -37,7 +37,7 @@ #if BUILDFLAG(IS_CHROMEOS) #include "chrome/browser/metrics/structured/event_logging_features.h" -// TODO(crbug/4925196): enable gn check once it learn about conditional includes +// TODO(crbug.com/1125897): Enable gn check once it handles conditional includes #include "components/metrics/structured/structured_events.h" // nogncheck #endif
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc index 31ca2cb..3fc7c9b 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
@@ -1179,6 +1179,8 @@ cloud_open_metrics_->LogTaskResult( OfficeTaskResult::kCancelledAtConfirmation); } else { + // TODO(b/315727684): mark an empty user response case NOTREACHED() once + // Escape is handled for all dialogs. cloud_open_metrics_->LogTaskResult(OfficeTaskResult::kLocalFileTask); LaunchLocalFileTask(user_response); } @@ -1319,10 +1321,13 @@ } bool CloudUploadDialog::ShouldCloseDialogOnEscape() const { - // The One Drive setup dialog handles escape in the webui as it needs to - // display a confirmation dialog on cancellation. + // TODO(b/315727684): Handle escape for all dialogs to ensure dialog is + // properly closed. + // The One Drive setup and File Handler dialogs handle escape. CHECK(dialog_args_); - return !dialog_args_->dialog_specific_args->is_one_drive_setup_dialog_args(); + return !( + dialog_args_->dialog_specific_args->is_one_drive_setup_dialog_args() || + dialog_args_->dialog_specific_args->is_file_handler_dialog_args()); } bool CloudUploadDialog::ShouldShowCloseButton() const {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc index 4cfe7bb..53c88c7 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.cc
@@ -28,6 +28,7 @@ namespace ash::settings { namespace mojom { +using ::chromeos::settings::mojom::kAppLanguagesSubpagePath; using ::chromeos::settings::mojom::kLanguagesAndInputSectionPath; using ::chromeos::settings::mojom::kLanguagesSubpagePath; using ::chromeos::settings::mojom::kSystemPreferencesSectionPath; @@ -68,6 +69,18 @@ return *tags; } +const std::vector<SearchConcept>& GetAppLanguagesPageSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_LANGUAGES_APP_LANGUAGES, + mojom::kAppLanguagesSubpagePath, + mojom::SearchResultIcon::kLanguage, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kAppLanguages}}, + }); + return *tags; +} + void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"deviceLanguageTitle", IDS_OS_SETTINGS_LANGUAGES_DEVICE_LANGUAGE_TITLE}, @@ -160,6 +173,9 @@ : std::nullopt) { SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); updater.AddSearchTags(GetLanguagesPageSearchConceptsV2()); + if (IsPerAppLanguageEnabled(profile)) { + updater.AddSearchTags(GetAppLanguagesPageSearchConcepts()); + } } LanguagesSection::~LanguagesSection() = default; @@ -237,6 +253,16 @@ RegisterNestedSettingBulk(mojom::Subpage::kLanguages, kLanguagesPageSettings, generator); + if (IsPerAppLanguageEnabled(profile())) { + // App language subpage. + generator->RegisterNestedSubpage( + IDS_OS_SETTINGS_LANGUAGES_APP_LANGUAGES_TITLE, + mojom::Subpage::kAppLanguages, mojom::Subpage::kLanguages, + mojom::SearchResultIcon::kLanguage, + mojom::SearchResultDefaultRank::kMedium, + mojom::kAppLanguagesSubpagePath); + } + // Inputs subsection exists only when the OsSettingsRevampWayfinding feature // is disabled. It is part of the Device section when the feature is enabled. if (!ash::features::IsOsSettingsRevampWayfindingEnabled()) {
diff --git a/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc b/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc index 4949ad29..bdc2c53 100644 --- a/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc +++ b/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc
@@ -4,30 +4,39 @@ #include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager.h" +#include "ash/components/arc/arc_features.h" +#include "ash/components/arc/test/arc_util_test_support.h" #include "ash/constants/ash_features.h" #include "ash/webui/settings/public/constants/routes.mojom.h" +#include "base/command_line.h" #include "base/containers/contains.h" #include "base/metrics/histogram_base.h" #include "base/test/metrics/histogram_enum_reader.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs_factory.h" +#include "chrome/browser/ash/arc/arc_util.h" #include "chrome/browser/ash/eche_app/eche_app_manager_factory.h" #include "chrome/browser/ash/kerberos/kerberos_credentials_manager_factory.h" +#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h" #include "chrome/browser/ash/phonehub/phone_hub_manager_factory.h" #include "chrome/browser/ash/printing/cups_printers_manager_factory.h" +#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/webui/ash/settings/constants/constants_util.h" #include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h" #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h" #include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_factory.h" #include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h" #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h" #include "chromeos/ash/components/local_search_service/search_metrics_reporter.h" +#include "components/account_id/account_id.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/user_manager/user_manager.h" +#include "components/user_manager/user_names.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/ash/mock_input_method_manager.h" @@ -44,19 +53,32 @@ class OsSettingsManagerTest : public testing::Test { protected: OsSettingsManagerTest() - : profile_manager_(TestingBrowserProcess::GetGlobal()) {} + : fake_user_manager_(std::make_unique<ash::FakeChromeUserManager>()), + profile_manager_(TestingBrowserProcess::GetGlobal()) {} ~OsSettingsManagerTest() override = default; // testing::Test: void SetUp() override { scoped_feature_list_.InitWithFeatures( {ash::features::kInputDeviceSettingsSplit, - ash::features::kPeripheralCustomization}, + ash::features::kPeripheralCustomization, arc::kPerAppLanguage}, {}); ASSERT_TRUE(profile_manager_.SetUp()); - TestingProfile* profile = - profile_manager_.CreateTestingProfile("TestingProfile"); + Profile* profile = profile_manager_.CreateTestingProfile( + TestingProfile::kDefaultProfileUserName); + // Log in user to ensure ARC PlayStore can be enabled. + const AccountId account_id( + AccountId::FromUserEmailGaiaId(profile->GetProfileUserName(), "1234")); + fake_user_manager_->AddUser(account_id); + fake_user_manager_->LoginUser(account_id); + // Enables ARC for test profile. + arc::SetArcAvailableCommandLineForTesting( + base::CommandLine::ForCurrentProcess()); + arc::SetArcPlayStoreEnabledForProfile(profile, true); + + NearbySharingServiceFactory:: + SetIsNearbyShareSupportedForBrowserContextForTesting(false); local_search_service::SearchMetricsReporter::RegisterLocalStatePrefs( pref_service_.registry()); local_search_service::LocalSearchServiceProxyFactory::GetInstance() @@ -79,6 +101,8 @@ eche_app::EcheAppManagerFactory::GetForProfile(profile)); } + user_manager::TypedScopedUserManager<ash::FakeChromeUserManager> + fake_user_manager_; content::BrowserTaskEnvironment task_environment_; TestingPrefServiceSimple pref_service_; TestingProfileManager profile_manager_;
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index 892ddf2..9c1c2ac5 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -33,6 +33,7 @@ #include "components/lookalikes/core/lookalike_url_util.h" #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h" #include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/security_interstitials/content/bad_clock_blocking_page.h" @@ -41,7 +42,6 @@ #include "components/security_interstitials/content/insecure_form_blocking_page.h" #include "components/security_interstitials/content/mitm_software_blocking_page.h" #include "components/security_interstitials/content/security_interstitial_page.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/https_only_mode_metrics.h" #include "components/security_interstitials/core/ssl_error_options_mask.h" #include "components/security_interstitials/core/ssl_error_ui.h"
diff --git a/chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc b/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc similarity index 74% rename from chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc rename to chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc index ac3d825..66b3b00 100644 --- a/chrome/browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc +++ b/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
@@ -1,4 +1,4 @@ -// Copyright 2023 The Chromium Authors +// 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. @@ -11,11 +11,7 @@ #include "build/branding_buildflags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/performance_manager/public/user_tuning/battery_saver_mode_manager.h" -#include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/views/tabs/tab.h" -#include "chrome/browser/ui/views/tabs/tab_close_button.h" -#include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/webui/feedback/feedback_dialog.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" @@ -24,7 +20,6 @@ #include "components/performance_manager/public/features.h" #include "components/performance_manager/public/user_tuning/prefs.h" #include "content/public/test/browser_test.h" -#include "net/dns/mock_host_resolver.h" #include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -37,11 +32,9 @@ namespace { DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPerformanceSettingsPage); -DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kSecondTabContent); DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kButtonWasClicked); DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kElementRenders); DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kIronCollapseContentShows); -DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kExceptionDialogShows); constexpr char kCheckJsElementIsChecked[] = "(el) => { return el.checked; }"; constexpr char kCheckJsElementIsNotChecked[] = @@ -64,30 +57,13 @@ "settings-performance-page", "controlled-radio-button#enabledOnTimerButton"}; -const WebContentsInteractionTestUtil::DeepQuery kExceptionDialogEntry = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "tab-discard-exception-tabbed-add-dialog", - "tab-discard-exception-current-sites-list#list", - "settings-checkbox-list-entry"}; - -const WebContentsInteractionTestUtil::DeepQuery kExceptionDialogAddButton = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "tab-discard-exception-tabbed-add-dialog", - "cr-button#actionButton"}; - } // namespace -class MemorySaverSettingsInteractiveTest : public InteractiveBrowserTest { +class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest { public: - void SetUp() override { InteractiveBrowserTest::SetUp(); } + void SetUp() override { + InteractiveBrowserTest::SetUp(); + } void SetUpOnMainThread() override { InteractiveBrowserTest::SetUpOnMainThread(); @@ -103,22 +79,9 @@ InteractiveBrowserTest::TearDownOnMainThread(); } - auto WaitForElementToRender(const ui::ElementIdentifier& contents_id, - const DeepQuery& element) { - StateChange element_renders; - element_renders.event = kElementRenders; - element_renders.where = element; - element_renders.test_function = - "(el) => { if (el !== null) { let rect = el.getBoundingClientRect(); " - "return rect.width > 0 && rect.height > 0; } return false; }"; - - return WaitForStateChange(contents_id, element_renders); - } - auto ClickElement(const ui::ElementIdentifier& contents_id, const DeepQuery& element) { - return Steps(WaitForElementToRender(contents_id, element), - MoveMouseTo(contents_id, element), ClickMouse()); + return Steps(MoveMouseTo(contents_id, element), ClickMouse()); } auto CheckTabCount(int expected_tab_count) { @@ -161,6 +124,18 @@ return WaitForStateChange(contents_id, toggle_selection_change); } + auto WaitForElementToRender(const ui::ElementIdentifier& contents_id, + const DeepQuery& element) { + StateChange element_renders; + element_renders.event = kElementRenders; + element_renders.where = element; + element_renders.type = StateChange::Type::kExistsAndConditionTrue; + element_renders.test_function = + "(el) => { return el.clientWidth > 0 && el.clientHeight > 0; }"; + + return WaitForStateChange(contents_id, element_renders); + } + auto WaitForIronListCollapseStateChange(ui::ElementIdentifier webcontents_id, DeepQuery query) { StateChange iron_collapse_finish_animating; @@ -178,7 +153,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest, MemorySaverPrefChanged) { RunTestSequence( InstrumentTab(kPerformanceSettingsPage), @@ -201,7 +176,7 @@ CheckMemorySaverModePrefState(MemorySaverModeState::kEnabledOnTimer)); } -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest, MemorySaverLearnMoreLinkNavigates) { DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kLearnMorePage); const DeepQuery memory_saver_learn_more = {"settings-ui", @@ -222,7 +197,7 @@ GURL(chrome::kMemorySaverModeLearnMoreUrl))); } -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest, MemorySaverMetricsShouldLogOnToggle) { base::HistogramTester histogram_tester; @@ -251,7 +226,7 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) // TODO(http://b/281528238): reenable the test. -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest, DISABLED_MemorySaverSendFeedbackDialogOpens) { const DeepQuery memory_saver_feedback = { "settings-ui", "settings-main", "settings-basic-page", @@ -266,8 +241,8 @@ } #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) -class MemorySaverSettingsMultiStateModeInteractiveTest - : public MemorySaverSettingsInteractiveTest { +class PerformanceSettingsMultiStateModeInteractiveTest + : public PerformanceSettingsInteractiveTest { public: void SetUp() override { scoped_feature_list_.InitAndEnableFeature( @@ -282,6 +257,7 @@ StateChange toggle_selection_change; toggle_selection_change.event = kButtonWasClicked; toggle_selection_change.where = element; + toggle_selection_change.type = StateChange::Type::kExistsAndConditionTrue; toggle_selection_change.test_function = is_disabled ? "(el) => el.disabled === true" : "(el) => el.disabled === false"; @@ -293,7 +269,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest, MemorySaverPrefChanged) { RunTestSequence( InstrumentTab(kPerformanceSettingsPage), @@ -322,7 +298,7 @@ CheckMemorySaverModePrefState(MemorySaverModeState::kEnabled)); } -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest, MemorySaverMetricsShouldLogOnToggle) { base::HistogramTester histogram_tester; @@ -374,7 +350,7 @@ // Checks that the selected discard timer value is preserved as the high // efficiency mode gets toggled -IN_PROC_BROWSER_TEST_F(MemorySaverSettingsMultiStateModeInteractiveTest, +IN_PROC_BROWSER_TEST_F(PerformanceSettingsMultiStateModeInteractiveTest, DiscardTimerStateIsPreserved) { const DeepQuery discard_time_menu = { "settings-ui", "settings-main", "settings-basic-page", @@ -470,6 +446,9 @@ std::make_unique<base::test::TestSamplingEventSource>(); auto test_battery_level_provider = std::make_unique<base::test::TestBatteryLevelProvider>(); + + sampling_source_ = test_sampling_event_source.get(); + battery_level_provider_ = test_battery_level_provider.get(); test_battery_level_provider->SetBatteryState( base::test::TestBatteryLevelProvider::CreateBatteryState(1, true, 100)); @@ -540,6 +519,10 @@ } private: + raw_ptr<base::test::TestSamplingEventSource, DanglingUntriaged> + sampling_source_; + raw_ptr<base::test::TestBatteryLevelProvider, DanglingUntriaged> + battery_level_provider_; std::unique_ptr<base::BatteryStateSampler> battery_state_sampler_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -702,176 +685,3 @@ GURL("chrome://os-settings/power"))); } #endif // BUILDFLAG(IS_CHROMEOS_ASH) - -class TabDiscardExceptionsSettingsInteractiveTest - : public MemorySaverSettingsInteractiveTest { - public: - void SetUp() override { - scoped_feature_list_.InitAndEnableFeature( - performance_manager::features::kDiscardExceptionsImprovements); - - InteractiveBrowserTest::SetUp(); - } - - void SetUpOnMainThread() override { - host_resolver()->AddRule("*", "127.0.0.1"); - MemorySaverSettingsInteractiveTest::SetUpOnMainThread(); - } - - GURL GetTestingURL(std::string hostname) { - return embedded_test_server()->GetURL(hostname, "/title1.html"); - } - - auto WaitForElementToHide(const ui::ElementIdentifier& contents_id, - const DeepQuery& element) { - StateChange element_renders; - element_renders.event = kElementRenders; - element_renders.where = element; - element_renders.test_function = - "(el) => { let rect = el.getBoundingClientRect(); return rect.width " - "=== 0 && rect.height === 0; }"; - - return WaitForStateChange(contents_id, element_renders); - } - - auto OpenAddExceptionDialog(const ui::ElementIdentifier& contents_id) { - const WebContentsInteractionTestUtil::DeepQuery add_exceptions_button = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "cr-button#addButton"}; - - const WebContentsInteractionTestUtil::DeepQuery picker_dialog = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "tab-discard-exception-tabbed-add-dialog"}; - - const WebContentsInteractionTestUtil::DeepQuery tab_picker_tab = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "tab-discard-exception-tabbed-add-dialog", - "cr-tabs", - "div.tab"}; - - StateChange exceptions_dialog; - exceptions_dialog.event = kExceptionDialogShows; - exceptions_dialog.where = picker_dialog; - return Steps(ClickElement(contents_id, add_exceptions_button), - WaitForStateChange(contents_id, exceptions_dialog), - ClickElement(contents_id, tab_picker_tab)); - } - - auto WaitForDisabledStateChange(const ui::ElementIdentifier& contents_id, - const DeepQuery element, - bool is_disabled) { - StateChange toggle_selection_change; - toggle_selection_change.event = kButtonWasClicked; - toggle_selection_change.where = element; - toggle_selection_change.type = StateChange::Type::kExistsAndConditionTrue; - toggle_selection_change.test_function = - is_disabled ? "(el) => el.disabled === true" - : "(el) => el.disabled === false"; - - return WaitForStateChange(contents_id, toggle_selection_change); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest, - AddSiteToExceptionList) { - const WebContentsInteractionTestUtil::DeepQuery exception_entry = { - "settings-ui", - "settings-main", - "settings-basic-page", - "settings-performance-page", - "tab-discard-exception-list", - "tab-discard-exception-entry"}; - - RunTestSequence( - InstrumentTab(kPerformanceSettingsPage), - NavigateWebContents(kPerformanceSettingsPage, - GURL(chrome::kChromeUIPerformanceSettingsURL)), - WaitForWebContentsReady(kPerformanceSettingsPage, - GURL(chrome::kChromeUIPerformanceSettingsURL)), - AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")), - SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage), - OpenAddExceptionDialog(kPerformanceSettingsPage), - WaitForDisabledStateChange(kPerformanceSettingsPage, - kExceptionDialogAddButton, true), - ClickElement(kPerformanceSettingsPage, kExceptionDialogEntry), - WaitForDisabledStateChange(kPerformanceSettingsPage, - kExceptionDialogAddButton, false), - ClickElement(kPerformanceSettingsPage, kExceptionDialogAddButton), - WaitForElementToRender(kPerformanceSettingsPage, exception_entry)); -} - -// The high efficiency tab picker should live update when the user open or -// closes a tab that can be added to the exceptions list -IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest, - UpdatesEntryListLive) { - constexpr char tab_close_button[] = "tab_close_button"; - - RunTestSequence( - InstrumentTab(kPerformanceSettingsPage), - NavigateWebContents(kPerformanceSettingsPage, - GURL(chrome::kChromeUIPerformanceSettingsURL)), - // Make sure there is no entry in the tab picker since there are no other - // tabs open - OpenAddExceptionDialog(kPerformanceSettingsPage), - EnsureNotPresent(kPerformanceSettingsPage, kExceptionDialogEntry), - - // Dialog should show new entry when opening a new tab - AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")), - SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage), - WaitForElementToRender(kPerformanceSettingsPage, kExceptionDialogEntry), - - // Dialog entry should hide when its corresponding tab is closed - NameViewRelative(kTabStripElementId, tab_close_button, - base::BindOnce([](TabStrip* tab_strip) { - return tab_strip->tab_at(1)->close_button().get(); - })), - PressButton(tab_close_button), - WaitForElementToHide(kPerformanceSettingsPage, kExceptionDialogEntry)); -} - -// The high efficiency exceptions tab picker should only show sites that are -// non-chrome sites and have not been added to the exceptions list yet -IN_PROC_BROWSER_TEST_F(TabDiscardExceptionsSettingsInteractiveTest, - IgnoreIneligibleTabs) { - DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kThirdTabContent); - - RunTestSequence( - InstrumentTab(kPerformanceSettingsPage), - NavigateWebContents(kPerformanceSettingsPage, - GURL(chrome::kChromeUIPerformanceSettingsURL)), - // Open a new tab navigated to a non-chrome site - AddInstrumentedTab(kSecondTabContent, GetTestingURL("example.com")), - SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage), - - // Add the non-chrome site to the exceptions list - OpenAddExceptionDialog(kPerformanceSettingsPage), - ClickElement(kPerformanceSettingsPage, kExceptionDialogEntry), - WaitForDisabledStateChange(kPerformanceSettingsPage, - kExceptionDialogAddButton, false), - ClickElement(kPerformanceSettingsPage, kExceptionDialogAddButton), - - // Re-open the tab picker and verify that the excluded tab doesn't show - OpenAddExceptionDialog(kPerformanceSettingsPage), - EnsureNotPresent(kPerformanceSettingsPage, kExceptionDialogEntry), - - // Verify that opening a new tab navigated to a non-excluded site will - // produce a new entry in the tab picker - AddInstrumentedTab(kThirdTabContent, GetTestingURL("second.com")), - SelectTab(kTabStripElementId, 0), WaitForShow(kPerformanceSettingsPage), - WaitForElementToRender(kPerformanceSettingsPage, kExceptionDialogEntry)); -}
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 2d4cce63..468a69a 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -658,6 +658,9 @@ "//chrome/browser/ash/system_web_apps/types", ] } + if (is_chromeos) { + deps += [ "//chromeos/constants" ] + } } # This has to be a separate target to avoid circular dependencies with
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc index c72cc6de..eab28c3 100644 --- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -29,6 +29,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +#if BUILDFLAG(IS_CHROMEOS) +#include "chromeos/constants/chromeos_features.h" +#endif + namespace web_app { namespace test { @@ -86,32 +90,40 @@ std::unique_ptr<WebAppInstallInfo> web_app_info, bool overwrite_existing_manifest_fields, webapps::WebappInstallSource install_source) { + // Use InstallShortcut for Create Shortcut install source. + CHECK_NE(install_source, webapps::WebappInstallSource::MENU_CREATE_SHORTCUT); + // The sync system requires that sync entity name is never empty. if (web_app_info->title.empty()) web_app_info->title = u"WebAppInstallInfo App Name"; +#if BUILDFLAG(IS_CHROMEOS) + // In Shortstand, user-installed web app should always have a scope. + if (chromeos::features::IsCrosShortstandEnabled() && + web_app_info->scope.is_empty()) { + web_app_info->scope = web_app_info->start_url; + } +#endif + webapps::AppId app_id; - base::RunLoop run_loop; + base::test::TestFuture<const webapps::AppId&, webapps::InstallResultCode> + future; auto* provider = WebAppProvider::GetForTest(profile); DCHECK(provider); WaitUntilReady(provider); // In unit tests, we do not have Browser or WebContents instances. Hence we // use `InstallFromInfoCommand` instead of `FetchManifestAndInstallCommand` or // `WebAppInstallCommand` to install the web app. - provider->scheduler().InstallFromInfo( - std::move(web_app_info), overwrite_existing_manifest_fields, - install_source, - base::BindLambdaForTesting([&](const webapps::AppId& installed_app_id, - webapps::InstallResultCode code) { - EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall, code); - app_id = installed_app_id; - run_loop.Quit(); - })); + provider->scheduler().InstallFromInfo(std::move(web_app_info), + overwrite_existing_manifest_fields, + install_source, future.GetCallback()); - run_loop.Run(); + EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall, + future.Get<webapps::InstallResultCode>()); // Allow updates to be published to App Service listeners. base::RunLoop().RunUntilIdle(); - return app_id; + + return future.Get<webapps::AppId>(); } webapps::AppId InstallShortcut(Profile* profile,
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 88ba302..9f2b8ded1 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1703030261-3e81724e2d506c761ac86b6ed1f72bea16d31813.profdata +chrome-android32-main-1703051928-7709a5363b727067cafa77e72fc93fee3f027c89.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 996b3f61..49d9fcd 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1703030261-051082be6ecb7ab4cf24c3f74d66399611678cbf.profdata +chrome-android64-main-1703051928-8af698ea242be2dd48257b2f6857067311670b47.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 33fdd47..24e2298 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1703008763-9170b64889c50a5a466311742c287b2ffaf80184.profdata +chrome-linux-main-1703051928-d7054369ede80cf828e08659f213b7be6554a98d.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 7cf89de2..0a9fd20 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1703023000-e9a3d0c545f1db78e55693cd6d67e6d40ee762f9.profdata +chrome-mac-arm-main-1703066398-4c184c33dd2e61ddcbce228ebd3419a217eafa78.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 990fc63a..9a52284 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1703008763-aeb33e02834b2a86fa46ce77f8d0c513427fc6ca.profdata +chrome-mac-main-1703051928-cd57a5b874db8300c855b1ce22c65d86127ea377.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 9d1476cf..b8408a7 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1703008763-ecdc5bfcce46b47dc1830691a2c0277420a0b1d3.profdata +chrome-win-arm64-main-1703030261-e65c9ccbe5fc04c4c698e5ab479331b660bea4c1.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 855937aa..7b68c56 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1703008763-6a9fee6c9c61d020644b893a2a648bebf093e4d1.profdata +chrome-win64-main-1703051928-63c641bef4765ac151a13fa0ef435026758d0fbe.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 91bd5fd..a72f5e72 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -10543,6 +10543,10 @@ deps += [ "//extensions/browser" ] } + if (is_chromeos) { + deps += [ "//chromeos/constants" ] + } + if (is_chromeos_lacros) { deps += [ "//chromeos/lacros", @@ -10778,6 +10782,7 @@ "../browser/ui/webui/access_code_cast/access_code_cast_dialog_browsertest.cc", "../browser/ui/webui/access_code_cast/access_code_cast_handler_browsertest.cc", "../browser/ui/webui/downloads/downloads_page_interactive_uitest.cc", + "../browser/ui/webui/settings/performance_settings_interactive_uitest.cc", "../browser/ui/webui/settings/settings_interactive_uitest.cc", "../browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_interactive_uitest.cc", "../browser/webapps/web_app_offline_browsertest.cc", @@ -11057,7 +11062,6 @@ "../browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc", "../browser/ui/views/passwords/password_bubble_interactive_uitest.cc", "../browser/ui/views/performance_controls/memory_saver_interactive_ui_test.cc", - "../browser/ui/views/performance_controls/performance_settings_interactive_ui_test.cc", "../browser/ui/views/permissions/embedded_permission_prompt_interactive_uitest.cc", "../browser/ui/views/permissions/one_time_permission_interactive_ui_test.cc", "../browser/ui/views/permissions/permission_bubble_interactive_uitest.cc",
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts b/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts index 11c4c294..0c846825 100644 --- a/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts +++ b/chrome/test/data/webui/chromeos/cloud_upload/file_handler_page_test.ts
@@ -440,4 +440,62 @@ assertEquals(localTaskCard.style.display, 'none'); assertTrue(actionButton.disabled); }); + + /** + * Test that clicking the cancel button triggers the right + * `respondWithUserActionAndClose` mojo request. + */ + test('Cancel', async () => { + const numTasks = 5; + await setUp({ + fileNames: ['file.docx'], + officeWebAppInstalled: true, + installOfficeWebAppResult: false, + odfsMounted: false, + dialogSpecificArgs: { + fileHandlerDialogArgs: { + localTasks: createTasks(numTasks), + showGoogleWorkspaceTask: true, + showMicrosoftOfficeTask: true, + }, + }, + }); + + fileHandlerPageApp.$('.cancel-button').click(); + await testProxy.handler.whenCalled('respondWithUserActionAndClose'); + assertEquals( + 1, testProxy.handler.getCallCount('respondWithUserActionAndClose')); + assertDeepEquals( + [UserAction.kCancel], + testProxy.handler.getArgs('respondWithUserActionAndClose')); + }); + + /** + * Test that an Escape keydown triggers the right + * `respondWithUserActionAndClose` mojo request. + */ + test('Escape', async () => { + const numTasks = 5; + await setUp({ + fileNames: ['file.docx'], + officeWebAppInstalled: true, + installOfficeWebAppResult: false, + odfsMounted: false, + dialogSpecificArgs: { + fileHandlerDialogArgs: { + localTasks: createTasks(numTasks), + showGoogleWorkspaceTask: true, + showMicrosoftOfficeTask: true, + }, + }, + }); + + document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'})); + await testProxy.handler.whenCalled('respondWithUserActionAndClose'); + assertEquals( + 1, testProxy.handler.getCallCount('respondWithUserActionAndClose')); + assertDeepEquals( + [UserAction.kCancel], + testProxy.handler.getArgs('respondWithUserActionAndClose')); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts index d8872e5..7b423ad 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/bruschetta_subpage_test.ts
@@ -10,13 +10,11 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; -import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; +import {clearBody} from '../utils.js'; -let subpage: BruschettaSubpageElement; -let crostiniBrowserProxy: TestCrostiniBrowserProxy; +import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; interface PrefParams { sharedPaths?: {[key: string]: string[]}; @@ -26,38 +24,37 @@ bruschettaInstalled?: boolean; } -function setCrostiniPrefs(enabled: boolean, { - sharedPaths = {}, - forwardedPorts = [], - micAllowed = false, - arcEnabled = false, - bruschettaInstalled = false, -}: PrefParams = {}): void { - subpage.prefs = { - arc: { - enabled: {value: arcEnabled}, - }, - bruschetta: { - installed: { - value: bruschettaInstalled, - }, - }, - crostini: { - enabled: {value: enabled}, - mic_allowed: {value: micAllowed}, - port_forwarding: {ports: {value: forwardedPorts}}, - }, - guest_os: { - paths_shared_to_vms: {value: sharedPaths}, - }, - }; - flush(); -} - suite('<settings-bruschetta-subpage>', () => { - suiteSetup(() => { - disableAnimationsAndTransitions(); - }); + let subpage: BruschettaSubpageElement; + let crostiniBrowserProxy: TestCrostiniBrowserProxy; + + function setCrostiniPrefs(enabled: boolean, { + sharedPaths = {}, + forwardedPorts = [], + micAllowed = false, + arcEnabled = false, + bruschettaInstalled = false, + }: PrefParams = {}): void { + subpage.prefs = { + arc: { + enabled: {value: arcEnabled}, + }, + bruschetta: { + installed: { + value: bruschettaInstalled, + }, + }, + crostini: { + enabled: {value: enabled}, + mic_allowed: {value: micAllowed}, + port_forwarding: {ports: {value: forwardedPorts}}, + }, + guest_os: { + paths_shared_to_vms: {value: sharedPaths}, + }, + }; + flush(); + } setup(async () => { loadTimeData.overrideValues({ @@ -70,16 +67,15 @@ Router.getInstance().navigateTo(routes.BRUSCHETTA_DETAILS); + clearBody(); subpage = document.createElement('settings-bruschetta-subpage'); document.body.appendChild(subpage); setCrostiniPrefs(false, {bruschettaInstalled: true}); - flushTasks(); + await flushTasks(); }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); }); test('Navigate to shared USB devices', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts index 73aed526..96b6776 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_arc_adb_test.ts
@@ -11,10 +11,9 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {isVisible} from 'chrome://webui-test/test_util.js'; -let subpage: SettingsCrostiniArcAdbElement; +import {clearBody} from '../utils.js'; interface PrefParams { sharedPaths?: {[key: string]: string[]}; @@ -24,38 +23,36 @@ bruschettaInstalled?: boolean; } -function setCrostiniPrefs(enabled: boolean, { - sharedPaths = {}, - forwardedPorts = [], - micAllowed = false, - arcEnabled = false, - bruschettaInstalled = false, -}: PrefParams = {}): void { - subpage.prefs = { - arc: { - enabled: {value: arcEnabled}, - }, - bruschetta: { - installed: { - value: bruschettaInstalled, - }, - }, - crostini: { - enabled: {value: enabled}, - mic_allowed: {value: micAllowed}, - port_forwarding: {ports: {value: forwardedPorts}}, - }, - guest_os: { - paths_shared_to_vms: {value: sharedPaths}, - }, - }; - flush(); -} - suite('<settings-crostini-arc-adb>', () => { - suiteSetup(() => { - disableAnimationsAndTransitions(); - }); + let subpage: SettingsCrostiniArcAdbElement; + + function setCrostiniPrefs(enabled: boolean, { + sharedPaths = {}, + forwardedPorts = [], + micAllowed = false, + arcEnabled = false, + bruschettaInstalled = false, + }: PrefParams = {}): void { + subpage.prefs = { + arc: { + enabled: {value: arcEnabled}, + }, + bruschetta: { + installed: { + value: bruschettaInstalled, + }, + }, + crostini: { + enabled: {value: enabled}, + mic_allowed: {value: micAllowed}, + port_forwarding: {ports: {value: forwardedPorts}}, + }, + guest_os: { + paths_shared_to_vms: {value: sharedPaths}, + }, + }; + flush(); + } setup(async () => { loadTimeData.overrideValues({ @@ -65,6 +62,8 @@ }); Router.getInstance().navigateTo(routes.CROSTINI_ANDROID_ADB); + + clearBody(); subpage = document.createElement('settings-crostini-arc-adb'); document.body.appendChild(subpage); setCrostiniPrefs(true, {arcEnabled: true}); @@ -72,7 +71,6 @@ }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); });
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts index 01a908f..5097003 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_export_import_test.ts
@@ -12,45 +12,13 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {isVisible} from 'chrome://webui-test/test_util.js'; import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js'; +import {clearBody} from '../utils.js'; import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; -let subpage: SettingsCrostiniExportImportElement; -let guestOsBrowserProxy: TestGuestOsBrowserProxy; -let crostiniBrowserProxy: TestCrostiniBrowserProxy; - -const singleContainer: ContainerInfo[] = [ - { - id: { - vm_name: 'termina', - container_name: 'penguin', - }, - ipv4: '1.2.3.4', - }, -]; - -const multipleContainers: ContainerInfo[] = [ - { - id: { - vm_name: 'termina', - container_name: 'penguin', - }, - ipv4: '1.2.3.4', - }, - { - id: { - vm_name: 'not-termina', - container_name: 'not-penguin', - - }, - ipv4: '1.2.3.5', - }, -]; - interface PrefParams { sharedPaths?: {[key: string]: string[]}; forwardedPorts?: CrostiniPortSetting[]; @@ -59,48 +27,75 @@ bruschettaInstalled?: boolean; } -function setCrostiniPrefs(enabled: boolean, { - sharedPaths = {}, - forwardedPorts = [], - micAllowed = false, - arcEnabled = false, - bruschettaInstalled = false, -}: PrefParams = {}): void { - subpage.prefs = { - arc: { - enabled: {value: arcEnabled}, - }, - bruschetta: { - installed: { - value: bruschettaInstalled, - }, - }, - crostini: { - enabled: {value: enabled}, - mic_allowed: {value: micAllowed}, - port_forwarding: {ports: {value: forwardedPorts}}, - }, - guest_os: { - paths_shared_to_vms: {value: sharedPaths}, - }, - }; - flush(); -} - -function selectContainerByIndex( - select: ContainerSelectElement, index: number): void { - const mdSelect = select.shadowRoot!.querySelector<HTMLSelectElement>( - 'select#selectContainer.md-select'); - assertTrue(!!mdSelect); - mdSelect.selectedIndex = index; - mdSelect.dispatchEvent(new CustomEvent('change')); - flush(); -} - suite('<settings-crostini-export-import>', () => { - suiteSetup(() => { - disableAnimationsAndTransitions(); - }); + let subpage: SettingsCrostiniExportImportElement; + let guestOsBrowserProxy: TestGuestOsBrowserProxy; + let crostiniBrowserProxy: TestCrostiniBrowserProxy; + + const multipleContainers: ContainerInfo[] = [ + { + id: { + vm_name: 'termina', + container_name: 'penguin', + }, + ipv4: '1.2.3.4', + }, + { + id: { + vm_name: 'not-termina', + container_name: 'not-penguin', + + }, + ipv4: '1.2.3.5', + }, + ]; + const singleContainer: ContainerInfo[] = [ + { + id: { + vm_name: 'termina', + container_name: 'penguin', + }, + ipv4: '1.2.3.4', + }, + ]; + + function setCrostiniPrefs(enabled: boolean, { + sharedPaths = {}, + forwardedPorts = [], + micAllowed = false, + arcEnabled = false, + bruschettaInstalled = false, + }: PrefParams = {}): void { + subpage.prefs = { + arc: { + enabled: {value: arcEnabled}, + }, + bruschetta: { + installed: { + value: bruschettaInstalled, + }, + }, + crostini: { + enabled: {value: enabled}, + mic_allowed: {value: micAllowed}, + port_forwarding: {ports: {value: forwardedPorts}}, + }, + guest_os: { + paths_shared_to_vms: {value: sharedPaths}, + }, + }; + flush(); + } + + function selectContainerByIndex( + select: ContainerSelectElement, index: number): void { + const mdSelect = select.shadowRoot!.querySelector<HTMLSelectElement>( + 'select#selectContainer.md-select'); + assertTrue(!!mdSelect); + mdSelect.selectedIndex = index; + mdSelect.dispatchEvent(new CustomEvent('change')); + flush(); + } setup(async () => { loadTimeData.overrideValues({ @@ -113,7 +108,6 @@ arcAdbSideloadingSupported: true, showCrostiniExtraContainers: true, }); - crostiniBrowserProxy = new TestCrostiniBrowserProxy(); crostiniBrowserProxy.containerInfo = singleContainer; CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); @@ -121,6 +115,8 @@ GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); Router.getInstance().navigateTo(routes.CROSTINI_EXPORT_IMPORT); + + clearBody(); subpage = document.createElement('settings-crostini-export-import'); document.body.appendChild(subpage); setCrostiniPrefs(true, {arcEnabled: true}); @@ -136,10 +132,7 @@ }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); - guestOsBrowserProxy.reset(); }); test('Deep link to backup linux', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts index 5379dbb..af36452 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_extra_containers_subpage_test.ts
@@ -10,7 +10,8 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; + +import {clearBody} from '../utils.js'; import {SharedVmDevices, TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; @@ -18,10 +19,6 @@ let crostiniBrowserProxy: TestCrostiniBrowserProxy; let subpage: ExtraContainersElement; - suiteSetup(() => { - disableAnimationsAndTransitions(); - }); - setup(async () => { const allContainers: ContainerInfo[] = [ { @@ -54,12 +51,13 @@ ]; crostiniBrowserProxy = new TestCrostiniBrowserProxy(); - CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); crostiniBrowserProxy.containerInfo = allContainers; crostiniBrowserProxy.sharedVmDevices = sharedVmDevices; + CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); Router.getInstance().navigateTo(routes.CROSTINI_EXTRA_CONTAINERS); + clearBody(); subpage = document.createElement('settings-crostini-extra-containers'); subpage.prefs = { crostini: { @@ -75,9 +73,7 @@ }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); }); suite('CreateContainerDialog', () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts index dfcac79c..1cc925cc 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_page_test.ts
@@ -12,14 +12,15 @@ import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js'; +import {clearBody} from '../utils.js'; import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; -let crostiniPage: SettingsCrostiniPageElement; -let guestOsBrowserProxy: TestGuestOsBrowserProxy; -let crostiniBrowserProxy: TestCrostiniBrowserProxy; - suite('<settings-crostini-page>', () => { + let crostiniPage: SettingsCrostiniPageElement; + let guestOsBrowserProxy: TestGuestOsBrowserProxy; + let crostiniBrowserProxy: TestCrostiniBrowserProxy; + function setCrostiniPrefs(enabled: boolean, { sharedPaths = {}, forwardedPorts = [], @@ -59,13 +60,14 @@ GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); Router.getInstance().navigateTo(routes.CROSTINI); + + clearBody(); crostiniPage = document.createElement('settings-crostini-page'); document.body.appendChild(crostiniPage); flush(); }); teardown(() => { - crostiniPage.remove(); Router.getInstance().resetRouteForTesting(); });
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts index b48a25b..e0d4552 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_settings_card_test.ts
@@ -12,10 +12,10 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {eventToPromise} from 'chrome://webui-test/test_util.js'; import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js'; +import {clearBody} from '../utils.js'; import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; @@ -66,22 +66,13 @@ } async function createCrostiniSettingsCard(): Promise<void> { + clearBody(); crostiniSettingsCard = document.createElement('crostini-settings-card'); document.body.appendChild(crostiniSettingsCard); - disableAnimationsAndTransitions(); - setCrostiniPrefs(false); await flushTasks(); } - suiteSetup(() => { - crostiniBrowserProxy = new TestCrostiniBrowserProxy(); - CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); - - guestOsBrowserProxy = new TestGuestOsBrowserProxy(); - GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); - }); - setup(() => { loadTimeData.overrideValues({ isCrostiniAllowed: true, @@ -89,14 +80,17 @@ showBruschetta: false, }); + crostiniBrowserProxy = new TestCrostiniBrowserProxy(); + CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); + + guestOsBrowserProxy = new TestGuestOsBrowserProxy(); + GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); + Router.getInstance().navigateTo(hostRoute); }); teardown(() => { - crostiniSettingsCard.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); - guestOsBrowserProxy.reset(); }); test('NotSupported', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts index d385372..cc5402ee 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_shared_usb_devices_test.ts
@@ -9,64 +9,58 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js'; +import {clearBody} from '../utils.js'; import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; -let subpage: CrostiniSharedUsbDevicesElement; -let guestOsBrowserProxy: TestGuestOsBrowserProxy; -let crostiniBrowserProxy: TestCrostiniBrowserProxy; - -const multipleContainers: ContainerInfo[] = [ - { - id: { - vm_name: 'termina', - container_name: 'penguin', - }, - ipv4: '1.2.3.4', - }, - { - id: { - vm_name: 'not-termina', - container_name: 'not-penguin', - - }, - ipv4: '1.2.3.5', - }, -]; - suite('<settings-crostini-shared-usb-devices>', () => { + let subpage: CrostiniSharedUsbDevicesElement; + let guestOsBrowserProxy: TestGuestOsBrowserProxy; + let crostiniBrowserProxy: TestCrostiniBrowserProxy; + + const multipleContainers: ContainerInfo[] = [ + { + id: { + vm_name: 'termina', + container_name: 'penguin', + }, + ipv4: '1.2.3.4', + }, + { + id: { + vm_name: 'not-termina', + container_name: 'not-penguin', + + }, + ipv4: '1.2.3.5', + }, + ]; + async function initSubpage(): Promise<void> { + clearBody(); subpage = document.createElement('settings-crostini-shared-usb-devices'); document.body.appendChild(subpage); await flushTasks(); } - suiteSetup(() => { - disableAnimationsAndTransitions(); - - crostiniBrowserProxy = new TestCrostiniBrowserProxy(); - CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); - guestOsBrowserProxy = new TestGuestOsBrowserProxy(); - GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); - }); - setup(() => { loadTimeData.overrideValues({ isCrostiniAllowed: true, isCrostiniSupported: true, }); + crostiniBrowserProxy = new TestCrostiniBrowserProxy(); + CrostiniBrowserProxyImpl.setInstanceForTesting(crostiniBrowserProxy); + guestOsBrowserProxy = new TestGuestOsBrowserProxy(); + GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); + Router.getInstance().navigateTo(routes.CROSTINI_SHARED_USB_DEVICES); }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); - guestOsBrowserProxy.reset(); }); // Functionality is already tested in OSSettingsGuestOsSharedUsbDevicesTest,
diff --git a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts index b99cc92..a94bd4d 100644 --- a/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts +++ b/chrome/test/data/webui/settings/chromeos/crostini_page/crostini_subpage_test.ts
@@ -11,19 +11,13 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertGE, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; -import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js'; import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js'; import {TestGuestOsBrowserProxy} from '../guest_os/test_guest_os_browser_proxy.js'; +import {clearBody} from '../utils.js'; import {TestCrostiniBrowserProxy} from './test_crostini_browser_proxy.js'; -let subpage: SettingsCrostiniSubpageElement; -let guestOsBrowserProxy: TestGuestOsBrowserProxy; -let crostiniBrowserProxy: TestCrostiniBrowserProxy; - -const MIC_ALLOWED_PREF_PATH = 'prefs.crostini.mic_allowed.value'; - interface PrefParams { sharedPaths?: {[key: string]: string[]}; forwardedPorts?: CrostiniPortSetting[]; @@ -32,38 +26,40 @@ bruschettaInstalled?: boolean; } -function setCrostiniPrefs(enabled: boolean, { - sharedPaths = {}, - forwardedPorts = [], - micAllowed = false, - arcEnabled = false, - bruschettaInstalled = false, -}: PrefParams = {}): void { - subpage.prefs = { - arc: { - enabled: {value: arcEnabled}, - }, - bruschetta: { - installed: { - value: bruschettaInstalled, - }, - }, - crostini: { - enabled: {value: enabled}, - mic_allowed: {value: micAllowed}, - port_forwarding: {ports: {value: forwardedPorts}}, - }, - guest_os: { - paths_shared_to_vms: {value: sharedPaths}, - }, - }; - flush(); -} - suite('<settings-crostini-subpage>', () => { - suiteSetup(() => { - disableAnimationsAndTransitions(); - }); + let subpage: SettingsCrostiniSubpageElement; + let guestOsBrowserProxy: TestGuestOsBrowserProxy; + let crostiniBrowserProxy: TestCrostiniBrowserProxy; + + const MIC_ALLOWED_PREF_PATH = 'prefs.crostini.mic_allowed.value'; + + function setCrostiniPrefs(enabled: boolean, { + sharedPaths = {}, + forwardedPorts = [], + micAllowed = false, + arcEnabled = false, + bruschettaInstalled = false, + }: PrefParams = {}): void { + subpage.prefs = { + arc: { + enabled: {value: arcEnabled}, + }, + bruschetta: { + installed: { + value: bruschettaInstalled, + }, + }, + crostini: { + enabled: {value: enabled}, + mic_allowed: {value: micAllowed}, + port_forwarding: {ports: {value: forwardedPorts}}, + }, + guest_os: { + paths_shared_to_vms: {value: sharedPaths}, + }, + }; + flush(); + } setup(async () => { loadTimeData.overrideValues({ @@ -83,6 +79,8 @@ GuestOsBrowserProxyImpl.setInstanceForTesting(guestOsBrowserProxy); Router.getInstance().navigateTo(routes.CROSTINI_DETAILS); + + clearBody(); subpage = document.createElement('settings-crostini-subpage'); document.body.appendChild(subpage); setCrostiniPrefs(true, {arcEnabled: true}); @@ -90,10 +88,7 @@ }); teardown(() => { - subpage.remove(); Router.getInstance().resetRouteForTesting(); - crostiniBrowserProxy.reset(); - guestOsBrowserProxy.reset(); }); suite('Subpage default', () => {
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts index ce0f386..f9c0e6bb 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/device_page_test.ts
@@ -919,6 +919,10 @@ }); test('simulate noise cancellation', async () => { + const mockController = new MockController(); + const setNoiseCancellationEnabled = mockController.createFunctionMock( + crosAudioConfig, 'setNoiseCancellationEnabled'); + const noiseCancellationSubsection = audioPage.shadowRoot!.querySelector( '#audioInputNoiseCancellationSubsection'); const noiseCancellationToggle = @@ -934,6 +938,9 @@ assertTrue(isVisible(noiseCancellationSubsection)); assertTrue(noiseCancellationToggle.checked); + assertEquals( + /* expected_call_count */ 1, + setNoiseCancellationEnabled['calls_'].length); crosAudioConfig.setAudioSystemProperties( noiseCancellationNotSupportedAudioSystemProperties); @@ -991,7 +998,9 @@ assertTrue(outputSlider.disabled); }); - test('noise cancellation called twice with same value', async () => { + test('noise cancellation after system properties change', async () => { + // System properties change should not trigger setNoiseCancellationEnabled + // to be called. const mockController = new MockController(); const setNoiseCancellationEnabled = mockController.createFunctionMock( crosAudioConfig, 'setNoiseCancellationEnabled'); @@ -1013,7 +1022,7 @@ await flushTasks(); assertEquals( - /* expected_call_count */ 1, + /* expected_call_count */ 0, setNoiseCancellationEnabled['calls_'].length); });
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts index 93140c2f..ce1d561b 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/display_page_test.ts
@@ -6,8 +6,8 @@ import {CrLinkRowElement, DevicePageBrowserProxyImpl, displaySettingsProviderMojom, Router, routes, setDisplayApiForTesting, setDisplaySettingsProviderForTesting, SettingsDisplayElement, SettingsDropdownMenuElement, SettingsSliderElement, SettingsToggleButtonElement} from 'chrome://os-settings/os_settings.js'; import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js'; -import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js'; import {assert} from 'chrome://resources/js/assert.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {flush, microTask} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; @@ -23,6 +23,8 @@ const kDisplayIdPrefix = '123456789'; suite('<settings-display>', () => { + const isRevampWayfindingEnabled = + loadTimeData.getBoolean('isRevampWayfindingEnabled'); let displayPage: SettingsDisplayElement; let fakeSystemDisplay: FakeSystemDisplay; let browserProxy: any; @@ -476,10 +478,12 @@ assertEquals(90, displayPage.displays[1]!.rotation); // Mirror the displays. - const displayMirrorCheckbox = strictQuery( - '#displayMirrorCheckbox', displayPage.shadowRoot, HTMLElement); - assertTrue(!!displayMirrorCheckbox); - displayMirrorCheckbox.click(); + const mirrorDisplayControl = strictQuery( + isRevampWayfindingEnabled ? '#mirrorDisplayToggle' : + '#displayMirrorCheckbox', + displayPage.shadowRoot, HTMLElement); + assertTrue(!!mirrorDisplayControl); + mirrorDisplayControl.click(); flush(); fakeSystemDisplay.onDisplayChanged.callListeners(); @@ -559,12 +563,13 @@ assertEquals(2, displayPage.displays.length); assertTrue(displayPage.shouldShowArrangementSection()); - const deepLinkElement = - displayPage.shadowRoot!.querySelector('#displayMirrorCheckbox')! - .shadowRoot!.querySelector('#checkbox'); - await waitAfterNextRender(deepLinkElement as HTMLElement); + const deepLinkElement = displayPage.shadowRoot!.querySelector<HTMLElement>( + isRevampWayfindingEnabled ? '#mirrorDisplayToggle' : + '#displayMirrorCheckbox'); + assertTrue(!!deepLinkElement); + await waitAfterNextRender(deepLinkElement); assertEquals( - deepLinkElement, getDeepActiveElement(), + deepLinkElement, displayPage.shadowRoot!.activeElement, 'Display mirroring checkbox should be focused for settingId=428.'); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 488a90d..ece5fab 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -537,7 +537,24 @@ ] } ], - ['DevicePageDisplayPage', 'device_page/display_page_test.js'], + [ + 'DevicePageDisplayPage', + 'device_page/display_page_test.js', + { + disabled: [ + 'ash::features::kOsSettingsRevampWayfinding', + ], + }, + ], + [ + 'DevicePageDisplayPageRevamp', + 'device_page/display_page_test.js', + { + enabled: [ + 'ash::features::kOsSettingsRevampWayfinding', + ], + }, + ], [ 'DevicePageDisplaySettingsMojoInterfaceProvider', 'device_page/display_settings_mojo_interface_provider_test.js'
diff --git a/chrome/test/data/webui/settings/chromeos/utils.ts b/chrome/test/data/webui/settings/chromeos/utils.ts index e89e5ef..5acff50 100644 --- a/chrome/test/data/webui/settings/chromeos/utils.ts +++ b/chrome/test/data/webui/settings/chromeos/utils.ts
@@ -109,3 +109,10 @@ } return root.querySelector(lastSelector); } + +/** + * Clears the document body HTML. + */ +export function clearBody() { + document.body.innerHTML = window.trustedTypes!.emptyHTML; +}
diff --git a/chrome/updater/util/unit_test_util_win.cc b/chrome/updater/util/unit_test_util_win.cc index 8003962..6e1a8b8 100644 --- a/chrome/updater/util/unit_test_util_win.cc +++ b/chrome/updater/util/unit_test_util_win.cc
@@ -14,8 +14,12 @@ #include "base/files/scoped_temp_dir.h" #include "base/path_service.h" #include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/win/atl.h" #include "base/win/registry.h" #include "chrome/updater/updater_scope.h" +#include "chrome/updater/util/unit_test_util.h" #include "chrome/updater/util/win_util.h" #include "chrome/updater/win/win_constants.h" #include "testing/gtest/include/gtest/gtest.h" @@ -145,4 +149,26 @@ return service.IsValid() || ::GetLastError() == ERROR_SERVICE_EXISTS; } +CSecurityDesc GetEveryoneDaclSecurityDescriptor(ACCESS_MASK accessmask) { + CSecurityDesc sd; + CDacl dacl; + dacl.AddAllowedAce(Sids::System(), accessmask); + dacl.AddAllowedAce(Sids::Admins(), accessmask); + dacl.AddAllowedAce(Sids::Interactive(), accessmask); + + sd.SetDacl(dacl); + sd.MakeAbsolute(); + return sd; +} + +test::EventHolder CreateEveryoneWaitableEventForTest() { + const std::wstring event_name = + base::StrCat({base::UTF8ToWide(test::GetTestName()), + base::NumberToWString(::GetCurrentProcessId())}); + CSecurityAttributes sa(GetEveryoneDaclSecurityDescriptor(GENERIC_ALL)); + return {base::WaitableEvent(base::win::ScopedHandle( + ::CreateEvent(&sa, FALSE, FALSE, event_name.c_str()))), + event_name}; +} + } // namespace updater
diff --git a/chrome/updater/util/unit_test_util_win.h b/chrome/updater/util/unit_test_util_win.h index 6a94b07..63c9dd2 100644 --- a/chrome/updater/util/unit_test_util_win.h +++ b/chrome/updater/util/unit_test_util_win.h
@@ -9,8 +9,10 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" +#include "base/win/atl.h" #include "base/win/registry.h" #include "chrome/updater/updater_scope.h" +#include "chrome/updater/util/unit_test_util.h" namespace updater { @@ -68,6 +70,10 @@ [[nodiscard]] bool CreateService(const std::wstring& service_name, const std::wstring& display_name, const std::wstring& command_line); + +// Creates an event accessible to all authenticated users on the machine. +test::EventHolder CreateEveryoneWaitableEventForTest(); + } // namespace updater #endif // CHROME_UPDATER_UTIL_UNIT_TEST_UTIL_WIN_H_
diff --git a/chrome/updater/util/win_util_unittest.cc b/chrome/updater/util/win_util_unittest.cc index 74d6c89..a8ab2f0 100644 --- a/chrome/updater/util/win_util_unittest.cc +++ b/chrome/updater/util/win_util_unittest.cc
@@ -59,19 +59,6 @@ constexpr char kTestAppID[] = "{D07D2B56-F583-4631-9E8E-9942F63765BE}"; -// Allows access to all authenticated users on the machine. -CSecurityDesc GetEveryoneDaclSecurityDescriptor(ACCESS_MASK accessmask) { - CSecurityDesc sd; - CDacl dacl; - dacl.AddAllowedAce(Sids::System(), accessmask); - dacl.AddAllowedAce(Sids::Admins(), accessmask); - dacl.AddAllowedAce(Sids::Interactive(), accessmask); - - sd.SetDacl(dacl); - sd.MakeAbsolute(); - return sd; -} - } // namespace TEST(WinUtil, GetDownloadProgress) { @@ -177,22 +164,17 @@ // integrity. // The event is created with a security descriptor that allows the medium // integrity process to signal it. - const std::wstring event_name = - base::StrCat({L"WinUtil.RunDeElevated-", - base::NumberToWString(::GetCurrentProcessId())}); - CSecurityAttributes sa(GetEveryoneDaclSecurityDescriptor(GENERIC_ALL)); - base::WaitableEvent event(base::win::ScopedHandle( - ::CreateEvent(&sa, FALSE, FALSE, event_name.c_str()))); - ASSERT_NE(event.handle(), nullptr); + test::EventHolder event_holder(CreateEveryoneWaitableEventForTest()); + ASSERT_NE(event_holder.event.handle(), nullptr); base::CommandLine test_process_cmd_line = GetTestProcessCommandLine(GetTestScope(), test::GetTestName()); test_process_cmd_line.AppendSwitchNative(kTestEventToSignalIfMediumIntegrity, - event_name); + event_holder.name); EXPECT_HRESULT_SUCCEEDED( RunDeElevated(test_process_cmd_line.GetProgram().value(), test_process_cmd_line.GetArgumentsString())); - EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); + EXPECT_TRUE(event_holder.event.TimedWait(TestTimeouts::action_max_timeout())); EXPECT_TRUE(test::WaitFor( [&] { return test::FindProcesses(kTestProcessExecutableName).empty(); }));
diff --git a/chrome/updater/win/ui/progress_wnd.cc b/chrome/updater/win/ui/progress_wnd.cc index 9971aedc..baf3f2b 100644 --- a/chrome/updater/win/ui/progress_wnd.cc +++ b/chrome/updater/win/ui/progress_wnd.cc
@@ -9,13 +9,16 @@ #include "base/check.h" #include "base/check_op.h" +#include "base/logging.h" #include "base/notreached.h" #include "base/process/launch.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions_win.h" +#include "base/strings/string_util.h" #include "base/strings/string_util_win.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "base/win/scoped_localalloc.h" #include "chrome/updater/app/app_install_progress.h" #include "chrome/updater/util/win_util.h" #include "chrome/updater/win/ui/l10n_util.h" @@ -651,9 +654,31 @@ CHECK(SUCCEEDED(app_info.error_code)); CHECK(!app_info.is_noupdate); - auto process = base::LaunchProcess( - base::UTF8ToWide(app_info.post_install_launch_command_line), {}); - return process.IsValid() ? S_OK : HRESULTFromLastError(); + if (!IsElevatedWithUACOn()) { + auto process = base::LaunchProcess( + base::UTF8ToWide(app_info.post_install_launch_command_line), {}); + return process.IsValid() ? S_OK : HRESULTFromLastError(); + } + + std::wstring command_format = + base::UTF8ToWide(app_info.post_install_launch_command_line); + int num_args = 0; + base::win::ScopedLocalAllocTyped<wchar_t*> argv( + ::CommandLineToArgvW(&command_format[0], &num_args)); + if (!argv || num_args < 1) { + LOG(ERROR) << __func__ << "!argv || num_args < 1: " << num_args; + return E_INVALIDARG; + } + + return RunDeElevated(argv.get()[0], + base::JoinString( + [&]() -> std::vector<std::wstring> { + if (num_args <= 1) { + return {}; + } + return {argv.get() + 1, argv.get() + num_args}; + }(), + L" ")); } bool ProgressWnd::LaunchCmdLines(const ObserverCompletionInfo& info) {
diff --git a/chrome/updater/win/ui/progress_wnd.h b/chrome/updater/win/ui/progress_wnd.h index 48e70581..ed79416 100644 --- a/chrome/updater/win/ui/progress_wnd.h +++ b/chrome/updater/win/ui/progress_wnd.h
@@ -124,6 +124,7 @@ FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnWaitingRetryDownload); FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnPause); FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, OnComplete); + FRIEND_TEST_ALL_PREFIXES(ProgressWndTest, LaunchCmdLine); enum class States { STATE_INIT = 0,
diff --git a/chrome/updater/win/ui/progress_wnd_unittest.cc b/chrome/updater/win/ui/progress_wnd_unittest.cc index da30cbd..2066f9f 100644 --- a/chrome/updater/win/ui/progress_wnd_unittest.cc +++ b/chrome/updater/win/ui/progress_wnd_unittest.cc
@@ -6,8 +6,18 @@ #include <string> #include <vector> +#include "base/command_line.h" #include "base/memory/scoped_refptr.h" +#include "base/strings/utf_string_conversions.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" #include "base/time/time.h" +#include "chrome/updater/test_scope.h" +#include "chrome/updater/util/unit_test_util.h" +#include "chrome/updater/util/unit_test_util_win.h" +#include "chrome/updater/util/win_util.h" +#include "chrome/updater/win/test/test_executables.h" +#include "chrome/updater/win/test/test_strings.h" #include "chrome/updater/win/ui/progress_wnd.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -341,4 +351,43 @@ } } +TEST_F(ProgressWndTest, LaunchCmdLine) { + using ::testing::AnyNumber; + EXPECT_CALL(*mock_progress_wnd_events_, DoExit()).Times(AnyNumber()); + EXPECT_CALL(*mock_progress_wnd_events_, DoClose()).Times(AnyNumber()); + + // Create a shared event to be waited for in this process and signaled in the + // test process. If the test is running elevated with UAC on, the test will + // also confirm that the test process is launched at medium integrity, by + // creating an event with a security descriptor that allows the medium + // integrity process to signal it. + test::EventHolder event_holder(IsElevatedWithUACOn() + ? CreateEveryoneWaitableEventForTest() + : test::CreateWaitableEventForTest()); + ASSERT_NE(event_holder.event.handle(), nullptr); + + base::CommandLine test_process_cmd_line = + GetTestProcessCommandLine(GetTestScope(), test::GetTestName()); + test_process_cmd_line.AppendSwitchNative( + IsElevatedWithUACOn() ? kTestEventToSignalIfMediumIntegrity + : kTestEventToSignal, + event_holder.name); + WTL::CMessageLoop ui_message_loop; + std::unique_ptr<ProgressWnd> progress_wnd = + MakeProgressWindow(&ui_message_loop); + AppCompletionInfo app_completion_info; + app_completion_info.completion_code = + CompletionCodes::COMPLETION_CODE_EXIT_SILENTLY_ON_LAUNCH_COMMAND; + app_completion_info.post_install_launch_command_line = + base::WideToUTF8(test_process_cmd_line.GetCommandLineString()); + ObserverCompletionInfo observer_completion_info; + observer_completion_info.completion_text = u"text"; + observer_completion_info.apps_info.push_back(app_completion_info); + progress_wnd->OnComplete(observer_completion_info); + + EXPECT_TRUE(event_holder.event.TimedWait(TestTimeouts::action_max_timeout())); + EXPECT_TRUE(test::WaitFor( + [] { return test::FindProcesses(kTestProcessExecutableName).empty(); })); +} + } // namespace updater::ui
diff --git a/chromeos/ash/components/mojo_service_manager/OWNERS b/chromeos/ash/components/mojo_service_manager/OWNERS index 7bd7ce6c3..1b233df9 100644 --- a/chromeos/ash/components/mojo_service_manager/OWNERS +++ b/chromeos/ash/components/mojo_service_manager/OWNERS
@@ -1,2 +1,2 @@ -chungsheng@chromium.org +chungsheng@google.com hashimoto@chromium.org
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index a0e30555..5287d2b 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -186,6 +186,11 @@ "RoundedWindows", base::FEATURE_DISABLED_BY_DEFAULT); +// Enables a content cache for FileSystemProvider extensions. +BASE_FEATURE(kFileSystemProviderContentCache, + "FileSystemProviderContentCache", + base::FEATURE_DISABLED_BY_DEFAULT); + const char kRoundedWindowsRadius[] = "window_radius"; bool IsAppInstallServiceUriEnabled() {
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index ebe6669..0d33e0ed 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -78,6 +78,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kRoundedWindows); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kMicrosoftOneDriveIntegrationForEnterprise); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +BASE_DECLARE_FEATURE(kFileSystemProviderContentCache); // Keep alphabetized.
diff --git a/clank b/clank index 93f4094..e1d0bc7 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 93f409484e269c3df9017ba14dc28a6ccd84bf2d +Subproject commit e1d0bc7ff99b302fe11d5a7563481e3fb42c14e2
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index e247c05..5cf6a830 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -424,7 +424,9 @@ if (!queryable_forms.empty() && client().GetCrowdsourcingManager()) { NotifyObservers(&Observer::OnBeforeLoadedServerPredictions); if (!client().GetCrowdsourcingManager()->StartQueryRequest( - queryable_forms, driver().IsolationInfo(), GetWeakPtr())) { + queryable_forms, driver().IsolationInfo(), + base::BindOnce(&AutofillManager::OnLoadedServerPredictions, + GetWeakPtr()))) { NotifyObservers(&Observer::OnAfterLoadedServerPredictions); } }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 7523aaa..948a455 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -61,8 +61,7 @@ // // It is owned by the AutofillDriver. class AutofillManager - : public AutofillCrowdsourcingManager::Observer, - public translate::TranslateDriver::LanguageDetectionObserver { + : public translate::TranslateDriver::LanguageDetectionObserver { public: // Observer of AutofillManager events. // @@ -499,10 +498,10 @@ private: friend class AutofillManagerTestApi; - // AutofillCrowdsourcingManager::Observer: + // Invoked by `AutofillCrowdsourcingManager`. void OnLoadedServerPredictions( std::string response, - const std::vector<FormSignature>& queried_form_signatures) override; + const std::vector<FormSignature>& queried_form_signatures); // Invoked when forms from OnFormsSeen() have been parsed to // |form_structures|.
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 8e488679..c3176ff 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -2066,7 +2066,7 @@ non_empty_types, was_autofilled, /*login_form_signature=*/{}, observed_submission), submitted_form->submission_source(), submitted_form->active_field_count(), - client().GetPrefs(), GetWeakPtr()); + client().GetPrefs()); } const gfx::Image& BrowserAutofillManager::GetCardImage(
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 2cde89d8..1ad542b 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -10619,7 +10619,7 @@ BrowserAutofillManagerTest::SetUp(); // All uploads should be expected explicitly. - EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest(_, _, _, _, _)) + EXPECT_CALL(*crowdsourcing_manager(), StartUploadRequest(_, _, _, _)) .Times(0); form_.name = u"MyForm"; @@ -10657,7 +10657,7 @@ FieldType::CREDIT_CARD_NAME_FIRST}), FieldAutofillTypeIs({FieldType::EMPTY_TYPE})), ObservedSubmissionIs(true))), - _, _, _, _)); + _, _, _)); FormSubmitted(form_); } @@ -10690,7 +10690,7 @@ FieldType::CREDIT_CARD_NAME_LAST, FieldType::NAME_LAST_SECOND})), ObservedSubmissionIs(false))), - _, _, _, _)); + _, _, _)); browser_autofill_manager_->OnFocusNoLongerOnForm(true); // 5. Grow the form by one field, which changes the form signature. @@ -10714,7 +10714,7 @@ FieldType::NAME_LAST_SECOND}), FieldAutofillTypeIs({FieldType::EMPTY_TYPE})), ObservedSubmissionIs(true))), - _, _, _, _)); + _, _, _)); FormSubmitted(form_); } @@ -10732,7 +10732,7 @@ FieldType::CREDIT_CARD_NAME_FIRST}), FieldAutofillTypeIs({FieldType::EMPTY_TYPE})), ObservedSubmissionIs(false))), - _, _, _, _)); + _, _, _)); browser_autofill_manager_->OnFocusNoLongerOnForm(true); // Simulate a navigation. This is when the vote is sent. @@ -10756,7 +10756,7 @@ FieldType::CREDIT_CARD_NAME_FIRST}), FieldAutofillTypeIs({FieldType::EMPTY_TYPE})), ObservedSubmissionIs(true))), - _, _, _, _)); + _, _, _)); FormSubmitted(form_); }
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc index cadb8c93..e48bfae 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.cc
@@ -121,6 +121,11 @@ "max-attempts", 5); +enum class RequestType { + kRequestQuery, + kRequestUpload, +}; + // Returns the base URL for the autofill server. GURL GetAutofillServerURL() { // If a valid autofill server URL is specified on the command line, then the @@ -172,15 +177,12 @@ }); } -std::string GetMetricName( - AutofillCrowdsourcingManager::RequestType request_type, - std::string_view suffix) { - auto TypeToName = - [](AutofillCrowdsourcingManager::RequestType type) -> std::string_view { +std::string GetMetricName(RequestType request_type, std::string_view suffix) { + auto TypeToName = [](RequestType type) -> std::string_view { switch (type) { - case AutofillCrowdsourcingManager::REQUEST_QUERY: + case RequestType::kRequestQuery: return "Query"; - case AutofillCrowdsourcingManager::REQUEST_UPLOAD: + case RequestType::kRequestUpload: return "Upload"; } NOTREACHED_NORETURN(); @@ -189,9 +191,10 @@ } net::NetworkTrafficAnnotationTag GetNetworkTrafficAnnotation( - const AutofillCrowdsourcingManager::RequestType& request_type) { - if (request_type == AutofillCrowdsourcingManager::REQUEST_QUERY) { - return net::DefineNetworkTrafficAnnotation("autofill_query", R"( + RequestType request_type) { + switch (request_type) { + case RequestType::kRequestQuery: + return net::DefineNetworkTrafficAnnotation("autofill_query", R"( semantics { sender: "Autofill" description: @@ -241,10 +244,8 @@ } } })"); - } - - DCHECK_EQ(request_type, AutofillCrowdsourcingManager::REQUEST_UPLOAD); - return net::DefineNetworkTrafficAnnotation("autofill_upload", R"( + case RequestType::kRequestUpload: + return net::DefineNetworkTrafficAnnotation("autofill_upload", R"( semantics { sender: "Autofill" description: @@ -290,6 +291,8 @@ } } })"); + } + NOTREACHED_NORETURN(); } size_t CountActiveFieldsInForms(const std::vector<FormStructure*>& forms) { @@ -470,17 +473,20 @@ // Gets an API method URL given its type (query or upload), an optional // resource ID, and the HTTP method to be used. // Example usage: -// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "GET") will return "/v1/pages/1234". -// * GetAPIMethodUrl(REQUEST_QUERY, "1234", "POST") will return "/v1/pages:get". -// * GetAPIMethodUrl(REQUEST_UPLOAD, "", "POST") will return "/v1/forms:vote". -std::string GetAPIMethodUrl(AutofillCrowdsourcingManager::RequestType type, +// * GetAPIMethodUrl(RequestType::kRequestQuery, "1234", "GET") will return +// "/v1/pages/1234". +// * GetAPIMethodUrl(RequestType::kRequestQuery, "1234", "POST") will return +// "/v1/pages:get". +// * GetAPIMethodUrl(RequestType::kRequestUpload, "", "POST") will return +// "/v1/forms:vote". +std::string GetAPIMethodUrl(RequestType type, std::string_view resource_id, std::string_view method) { const char* api_method_url = [&] { switch (type) { - case AutofillCrowdsourcingManager::REQUEST_QUERY: + case RequestType::kRequestQuery: return method == "POST" ? "/v1/pages:get" : "/v1/pages"; - case AutofillCrowdsourcingManager::REQUEST_UPLOAD: + case RequestType::kRequestUpload: return "/v1/forms:vote"; } NOTREACHED_NORETURN(); @@ -492,11 +498,10 @@ } // Gets HTTP body payload for API POST request. -std::optional<std::string> GetAPIBodyPayload( - std::string payload, - AutofillCrowdsourcingManager::RequestType type) { +std::optional<std::string> GetAPIBodyPayload(std::string payload, + RequestType type) { // Don't do anything for payloads not related to Query. - if (type != AutofillCrowdsourcingManager::REQUEST_QUERY) { + if (type != RequestType::kRequestQuery) { return std::move(payload); } // Wrap query payload in a request proto to interface with API Query method. @@ -573,7 +578,7 @@ } // namespace struct AutofillCrowdsourcingManager::FormRequestData { - base::WeakPtr<Observer> observer; + std::optional<QueryRequestCompleteCallback> callback = std::nullopt; std::vector<FormSignature> form_signatures; RequestType request_type; std::optional<net::IsolationInfo> isolation_info; @@ -618,7 +623,7 @@ bool AutofillCrowdsourcingManager::StartQueryRequest( const std::vector<FormStructure*>& forms, net::IsolationInfo isolation_info, - base::WeakPtr<Observer> observer) { + QueryRequestCompleteCallback callback) { if (!IsEnabled()) return false; @@ -654,9 +659,9 @@ } FormRequestData request_data = { - .observer = observer, + .callback = std::move(callback), .form_signatures = std::move(queried_form_signatures), - .request_type = AutofillCrowdsourcingManager::REQUEST_QUERY, + .request_type = RequestType::kRequestQuery, .isolation_info = std::move(isolation_info), .payload = std::move(payload).value(), }; @@ -666,9 +671,9 @@ if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) { LOG_AF(log_manager_) << LoggingScope::kAutofillServer << LogMessage::kCachedAutofillQuery << Br{} << query; - if (request_data.observer) { - request_data.observer->OnLoadedServerPredictions( - std::move(query_data), request_data.form_signatures); + if (request_data.callback && *request_data.callback) { + std::move(*request_data.callback) + .Run(std::move(query_data), request_data.form_signatures); } return true; } @@ -683,8 +688,7 @@ std::vector<AutofillUploadContents> upload_contents, mojom::SubmissionSource form_submission_source, int form_active_field_count, - PrefService* prefs, - base::WeakPtr<Observer> observer) { + PrefService* prefs) { if (!IsEnabled()) { return false; } @@ -727,9 +731,8 @@ } FormRequestData request_data = { - .observer = observer, .form_signatures = {form_signature}, - .request_type = AutofillCrowdsourcingManager::REQUEST_UPLOAD, + .request_type = RequestType::kRequestUpload, .isolation_info = std::nullopt, .payload = std::move(payload).value(), }; @@ -772,7 +775,7 @@ std::string resource_id; std::string method = "POST"; - if (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_QUERY) { + if (request_data.request_type == RequestType::kRequestQuery) { if (GetPayloadLength(request_data.payload) <= kMaxQueryGetSize) { resource_id = request_data.payload; method = "GET"; @@ -795,22 +798,21 @@ } bool AutofillCrowdsourcingManager::StartRequest(FormRequestData request_data) { - // REQUEST_UPLOADs take no IsolationInfo because Password Manager uploads when + // kRequestUploads take no IsolationInfo because Password Manager uploads when // RenderFrameHostImpl::DidCommitNavigation() is called, in which case // AutofillDriver::IsolationInfo() may crash because there is no committing // NavigationRequest. Not setting an IsolationInfo is safe because no // information about the response is passed to the renderer, or is otherwise // visible to a page. See crbug/1176635#c22. - DCHECK( - (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_UPLOAD) == - !request_data.isolation_info); + DCHECK((request_data.request_type == RequestType::kRequestUpload) == + !request_data.isolation_info); // Get the URL and method to use for this request. auto [request_url, method] = GetRequestURLAndMethod(request_data); // Track the URL length for GET queries because the URL length can be in the // thousands when rich metadata is enabled. - if (request_data.request_type == AutofillCrowdsourcingManager::REQUEST_QUERY && + if (request_data.request_type == RequestType::kRequestQuery && method == "GET") { base::UmaHistogramCounts100000(kUmaGetUrlLength, request_url.spec().length()); @@ -991,15 +993,15 @@ return; } - if (request_data.request_type != REQUEST_QUERY) { + if (request_data.request_type != RequestType::kRequestQuery) { return; } CacheQueryRequest(request_data.form_signatures, *response_body); base::UmaHistogramBoolean(kUmaWasInCache, simple_loader->LoadedFromCache()); - if (request_data.observer) { - request_data.observer->OnLoadedServerPredictions( - std::move(*response_body), request_data.form_signatures); + if (request_data.callback && *request_data.callback) { + std::move(*request_data.callback) + .Run(std::move(*response_body), request_data.form_signatures); } }
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h index 5296ea2..6180911 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager.h
@@ -45,11 +45,6 @@ // Obtains Autofill server predictions and upload votes for generating them. class AutofillCrowdsourcingManager { public: - enum RequestType { - REQUEST_QUERY, - REQUEST_UPLOAD, - }; - // Names of UMA metrics recorded in this class. static constexpr char kUmaApiUrlIsTooLong[] = "Autofill.Query.ApiUrlIsTooLong"; @@ -57,20 +52,6 @@ static constexpr char kUmaMethod[] = "Autofill.Query.Method"; static constexpr char kUmaWasInCache[] = "Autofill.Query.WasInCache"; - // An interface used to notify clients of AutofillCrowdsourcingManager. - class Observer { - public: - // Called when field type predictions are successfully received from the - // server. |response| contains the server response for the forms - // represented by |queried_form_signatures|. - virtual void OnLoadedServerPredictions( - std::string response, - const std::vector<FormSignature>& queried_form_signatures) = 0; - - protected: - virtual ~Observer() = default; - }; - // `client` owns (and hence survives) this AutofillCrowdsourcingManager. // `channel` determines the value for the the Google-API-key HTTP header and // whether raw metadata uploading is enabled. @@ -80,12 +61,18 @@ virtual ~AutofillCrowdsourcingManager(); + // The callback executed on successful completion of a query request. The + // first parameter contains the server response and the second parameter the + // queried form signatures. + using QueryRequestCompleteCallback = + base::OnceCallback<void(std::string, const std::vector<FormSignature>&)>; + // Starts a query request to Autofill servers. The observer is called with the // list of the fields of all requested forms. - // |forms| - array of forms aggregated in this request. + // `forms` - array of forms aggregated in this request. virtual bool StartQueryRequest(const std::vector<FormStructure*>& forms, net::IsolationInfo isolation_info, - base::WeakPtr<Observer> observer); + QueryRequestCompleteCallback callback); // Starts an upload request for `upload_contents`. If `upload_contents` has // more than one element, then `upload_contents[0]` is expected to correspond @@ -97,8 +84,7 @@ std::vector<AutofillUploadContents> upload_contents, mojom::SubmissionSource form_submission_source, int form_active_field_count, - PrefService* prefs, - base::WeakPtr<Observer> observer); + PrefService* prefs); // Returns true if the autofill server communication is enabled. bool IsEnabled() const;
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc index d6aad23..dcce417 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
@@ -198,9 +198,7 @@ // go over the wire, but allow calling back HTTP responses directly. // The responses in test are out of order and verify: successful query request, // successful upload request, failed upload request. -class AutofillCrowdsourcingManagerTest - : public AutofillCrowdsourcingManager::Observer, - public ::testing::Test { +class AutofillCrowdsourcingManagerTest : public ::testing::Test { public: enum class ResponseType { kQuerySuccessful, @@ -232,13 +230,14 @@ const std::vector<std::unique_ptr<FormStructure>>& form_structures) { return crowdsourcing_manager().StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - weak_ptr_factory_.GetWeakPtr()); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + weak_ptr_factory_.GetWeakPtr())); } - // AutofillCrowdsourcingManager::Observer implementation. void OnLoadedServerPredictions( std::string response_xml, - const std::vector<FormSignature>& form_signatures) override { + const std::vector<FormSignature>& form_signatures) { ResponseData response; response.response = std::move(response_xml); response.type_of_response = ResponseType::kQuerySuccessful; @@ -305,7 +304,9 @@ base::HistogramTester histogram; EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - GetWeakPtr())); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + GetWeakPtr()))); histogram.ExpectUniqueSample("Autofill.ServerQueryResponse", AutofillMetrics::QUERY_SENT, 1); histogram.ExpectUniqueSample(AutofillCrowdsourcingManager::kUmaMethod, @@ -325,7 +326,7 @@ std::string(), true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_1), form_structures[0]->submission_source(), - form_structures[0]->active_field_count(), &pref_service(), GetWeakPtr())); + form_structures[0]->active_field_count(), &pref_service())); // Request with id 2. std::vector<AutofillUploadContents> upload_contents_2 = @@ -333,7 +334,7 @@ std::string(), true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_2), form_structures[1]->submission_source(), - form_structures[1]->active_field_count(), &pref_service(), GetWeakPtr())); + form_structures[1]->active_field_count(), &pref_service())); // Request with id 3. Upload request with a non-empty additional password form // signature. std::vector<AutofillUploadContents> upload_contents_3 = @@ -341,7 +342,7 @@ true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_3), form_structures[1]->submission_source(), - form_structures[1]->active_field_count(), &pref_service(), GetWeakPtr())); + form_structures[1]->active_field_count(), &pref_service())); // Server responseses - returned out of sequence. const char* response_contents[] = { @@ -397,7 +398,9 @@ // Request with id 4, not successful. EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - GetWeakPtr())); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + GetWeakPtr()))); request = url_loader_factory().GetPendingRequest(4); histogram.ExpectUniqueSample("Autofill.ServerQueryResponse", AutofillMetrics::QUERY_SENT, 2); @@ -412,7 +415,9 @@ // Request with id 5. Let's pretend we hit the cache. EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - GetWeakPtr())); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + GetWeakPtr()))); histogram.ExpectBucketCount("Autofill.ServerQueryResponse", AutofillMetrics::QUERY_SENT, 3); histogram.ExpectBucketCount(AutofillCrowdsourcingManager::kUmaMethod, @@ -447,7 +452,9 @@ base::HistogramTester histogram; EXPECT_TRUE(crowdsourcing_manager->StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - GetWeakPtr())); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + GetWeakPtr()))); // Verify if histograms are right. histogram.ExpectUniqueSample("Autofill.ServerQueryResponse", @@ -538,7 +545,9 @@ base::HistogramTester histogram; EXPECT_TRUE(crowdsourcing_manager.StartQueryRequest( ToRawPointerVector(form_structures), driver().IsolationInfo(), - GetWeakPtr())); + base::BindOnce( + &AutofillCrowdsourcingManagerTest::OnLoadedServerPredictions, + GetWeakPtr()))); // Verify request. // Verify if histograms are right. @@ -643,7 +652,7 @@ true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), - form_structure.active_field_count(), pref_service.get(), GetWeakPtr())); + form_structure.active_field_count(), pref_service.get())); // Inspect the request that the test URL loader sent. network::TestURLLoaderFactory::PendingRequest* request = @@ -738,7 +747,7 @@ true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), - form_structure.active_field_count(), &pref_service(), GetWeakPtr())); + form_structure.active_field_count(), &pref_service())); auto* request = url_loader_factory().GetPendingRequest(0); @@ -764,7 +773,7 @@ true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents_2), form_structure.submission_source(), - form_structure.active_field_count(), &pref_service(), GetWeakPtr())); + form_structure.active_field_count(), &pref_service())); request = url_loader_factory().GetPendingRequest(2); url_loader_factory().SimulateResponseWithoutRemovingFromPendingList( @@ -839,7 +848,7 @@ true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), - form_structure.active_field_count(), &pref_service(), GetWeakPtr())); + form_structure.active_field_count(), &pref_service())); constexpr auto kTimeDeltaMargin = base::Milliseconds(100); const int max_attempts = crowdsourcing_manager().GetMaxServerAttempts(); @@ -1046,8 +1055,7 @@ }; class AutofillServerCommunicationTest - : public AutofillCrowdsourcingManager::Observer, - public testing::TestWithParam<ServerCommunicationMode> { + : public testing::TestWithParam<ServerCommunicationMode> { protected: void SetUp() override { testing::TestWithParam<ServerCommunicationMode>::SetUp(); @@ -1113,7 +1121,7 @@ // AutofillCrowdsourcingManager::Observer implementation. void OnLoadedServerPredictions( std::string /* response_xml */, - const std::vector<FormSignature>& /*form_signatures */) override { + const std::vector<FormSignature>& /*form_signatures */) { ASSERT_TRUE(run_loop_); run_loop_->QuitWhenIdle(); } @@ -1179,7 +1187,9 @@ &client(), version_info::Channel::UNKNOWN, nullptr); bool succeeded = crowdsourcing_manager.StartQueryRequest( ToRawPointerVector(form_structures), driver_.IsolationInfo(), - weak_ptr_factory_.GetWeakPtr()); + base::BindOnce( + &AutofillServerCommunicationTest::OnLoadedServerPredictions, + weak_ptr_factory_.GetWeakPtr())); if (succeeded) run_loop_->Run(); run_loop_.reset(); @@ -1203,8 +1213,7 @@ login_form_signature, observed_submission); bool succeeded = crowdsourcing_manager.StartUploadRequest( std::move(upload_contents), form.submission_source(), - form.active_field_count(), &pref_service(), - weak_ptr_factory_.GetWeakPtr()); + form.active_field_count(), &pref_service()); if (succeeded) run_loop_->Run(); run_loop_.reset();
diff --git a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h index 77b576d2..57acdb4 100644 --- a/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h +++ b/components/autofill/core/browser/crowdsourcing/mock_autofill_crowdsourcing_manager.h
@@ -29,7 +29,7 @@ StartQueryRequest, (const std::vector<FormStructure*>&, net::IsolationInfo, - base::WeakPtr<Observer>), + QueryRequestCompleteCallback), (override)); MOCK_METHOD(bool, @@ -37,8 +37,7 @@ (std::vector<AutofillUploadContents>, mojom::SubmissionSource, int, - PrefService*, - base::WeakPtr<Observer>), + PrefService*), (override)); };
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index ebd95ae1..7260091a 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -158,26 +158,6 @@ return MAX_VALID_FIELD_TYPE; } -// Encode password attributes and length into |upload|. -void EncodePasswordAttributesVote( - const std::pair<PasswordAttribute, bool>& password_attributes_vote, - const size_t password_length_vote, - const int password_symbol_vote, - AutofillUploadContents* upload) { - switch (password_attributes_vote.first) { - case PasswordAttribute::kHasLetter: - upload->set_password_has_letter(password_attributes_vote.second); - break; - case PasswordAttribute::kHasSpecialSymbol: - upload->set_password_has_special_symbol(password_attributes_vote.second); - if (password_attributes_vote.second) - upload->set_password_special_symbol(password_symbol_vote); - break; - case PasswordAttribute::kPasswordAttributesCount: - NOTREACHED(); - } - upload->set_password_length(password_length_vote); -} void EncodeRandomizedValue(const RandomizedEncoder& encoder, FormSignature form_signature, @@ -561,7 +541,6 @@ upload.set_form_signature(form_signature().value()); upload.set_autofill_used(form_was_autofilled); upload.set_data_present(data_present); - upload.set_passwords_revealed(passwords_were_revealed_); upload.set_has_form_tag(is_form_tag_); if (!current_page_language_->empty() && randomized_encoder_ != nullptr) { upload.set_language(current_page_language_.value()); @@ -594,12 +573,6 @@ static_cast<AutofillUploadContents_SubmissionIndicatorEvent>( triggering_event)); - if (password_attributes_vote_) { - EncodePasswordAttributesVote(*password_attributes_vote_, - password_length_vote_, password_symbol_vote_, - &upload); - } - if (!login_form_signature.empty()) { uint64_t login_sig; if (base::StringToUint64(login_form_signature, &login_sig))
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index 9b563fd..da959af 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -372,49 +372,6 @@ // Returns the possible form types. DenseSet<FormType> GetFormTypes() const; - bool passwords_were_revealed() const { return passwords_were_revealed_; } - void set_passwords_were_revealed(bool passwords_were_revealed) { - passwords_were_revealed_ = passwords_were_revealed; - } - - void set_password_attributes_vote( - const std::pair<PasswordAttribute, bool>& vote) { - password_attributes_vote_ = vote; - } - - std::optional<std::pair<PasswordAttribute, bool>> - get_password_attributes_vote() const { - return password_attributes_vote_; - } - - void set_password_length_vote(const size_t noisified_password_length) { - DCHECK(password_attributes_vote_.has_value()) - << "|password_length_vote_| doesn't make sense if " - "|password_attributes_vote_| has no value."; - password_length_vote_ = noisified_password_length; - } - - size_t get_password_length_vote() const { - DCHECK(password_attributes_vote_.has_value()) - << "|password_length_vote_| doesn't make sense if " - "|password_attributes_vote_| has no value."; - return password_length_vote_; - } - - void set_password_symbol_vote(int noisified_symbol) { - DCHECK(password_attributes_vote_.has_value()) - << "password_symbol_vote_| doesn't make sense if " - "|password_attributes_vote_| has no value."; - password_symbol_vote_ = noisified_symbol; - } - - int get_password_symbol_vote() const { - DCHECK(password_attributes_vote_.has_value()) - << "|password_symbol_vote_| doesn't make sense if " - "|password_attributes_vote_| has no value"; - return password_symbol_vote_; - } - mojom::SubmissionSource submission_source() const { return submission_source_; } @@ -631,24 +588,6 @@ // If phone number rationalization has been performed for a given section. std::set<Section> phone_rationalized_; - // True iff the form is a password form and the user has seen the password - // value before accepting the prompt to save. Used for crowdsourcing. - bool passwords_were_revealed_ = false; - - // The vote about password attributes (e.g. whether the password has a numeric - // character). - std::optional<std::pair<PasswordAttribute, bool>> password_attributes_vote_; - - // If |password_attribute_vote_| contains (kHasSpecialSymbol, true), this - // field contains noisified information about a special symbol in a - // user-created password stored as ASCII code. The default value of 0 - // indicates that no symbol was set. - int password_symbol_vote_ = 0; - - // Noisified password length for crowdsourcing. If |password_attributes_vote_| - // has no value, |password_length_vote_| should be ignored. - size_t password_length_vote_; - // Used to record whether developer has used autocomplete markup or // UPI-VPA hints, This is a bitmask of DeveloperEngagementMetric and set in // DetermineHeuristicTypes().
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index efe868e..aa2ca46 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -2536,9 +2536,6 @@ form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); for (auto& fs_field : *form_structure) fs_field->host_form_signature = form_structure->form_signature(); @@ -2568,9 +2565,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("1442000308"); - upload.set_passwords_revealed(false); - upload.set_password_has_letter(true); - upload.set_password_length(10u); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -2611,9 +2605,6 @@ } form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); for (auto& fs_field : *form_structure) fs_field->host_form_signature = form_structure->form_signature(); @@ -2708,9 +2699,6 @@ form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); for (auto& fs_field : *form_structure) fs_field->host_form_signature = form_structure->form_signature(); @@ -2740,9 +2728,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("1442000308"); - upload.set_passwords_revealed(false); - upload.set_password_has_letter(true); - upload.set_password_length(10u); test::FillUploadField(upload.add_field(), 3763331450U, 3U, 0); test::FillUploadField(upload.add_field(), 3494530716U, 5U, 0); @@ -2827,9 +2812,6 @@ form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); for (auto& fs_field : *form_structure) fs_field->host_form_signature = form_structure->form_signature(); @@ -2859,9 +2841,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("1442000308"); - upload.set_passwords_revealed(false); - upload.set_password_has_letter(true); - upload.set_password_length(10u); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -2941,9 +2920,6 @@ form.fields.push_back(checkable_field); form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); form_structure->set_submission_event( SubmissionIndicatorEvent::HTML_FORM_SUBMISSION); for (auto& fs_field : *form_structure) @@ -2976,9 +2952,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("1442000308"); - upload.set_passwords_revealed(false); - upload.set_password_has_letter(true); - upload.set_password_length(10u); upload.set_has_form_tag(true); test::FillUploadField(upload.add_field(), 3763331450U, 3U); @@ -3009,9 +2982,6 @@ } form_structure = std::make_unique<FormStructure>(form); - form_structure->set_password_attributes_vote( - std::make_pair(PasswordAttribute::kHasLetter, true)); - form_structure->set_password_length_vote(10u); form_structure->set_submission_event( SubmissionIndicatorEvent::HTML_FORM_SUBMISSION); ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); @@ -3143,7 +3113,6 @@ upload.set_autofill_used(true); upload.set_data_present("1440000000000000000802"); upload.set_login_form_signature(42); - upload.set_passwords_revealed(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -3244,7 +3213,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(true); upload.set_data_present("1440"); - upload.set_passwords_revealed(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -3326,7 +3294,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(true); upload.set_data_present("1440"); - upload.set_passwords_revealed(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -3397,7 +3364,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(true); upload.set_data_present("1440"); - upload.set_passwords_revealed(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_NONE); upload.set_has_form_tag(true); @@ -3499,7 +3465,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("0000000000001850"); - upload.set_passwords_revealed(false); upload.set_has_form_tag(true); test::FillUploadField(upload.add_field(), 3340391946, 51); test::FillUploadField(upload.add_field(), 1415886167, 52); @@ -3605,7 +3570,6 @@ upload.set_form_signature(form_structure.form_signature().value()); upload.set_autofill_used(false); upload.set_data_present(""); - upload.set_passwords_revealed(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_HTML_FORM_SUBMISSION); upload.set_has_form_tag(true); @@ -3863,7 +3827,6 @@ upload.set_form_signature(form_structure->form_signature().value()); upload.set_autofill_used(false); upload.set_data_present("1440000360000008"); - upload.set_passwords_revealed(false); upload.set_has_form_tag(false); upload.set_submission_event( AutofillUploadContents_SubmissionIndicatorEvent_XHR_SUCCEEDED); @@ -3949,7 +3912,6 @@ form.fields.push_back(field); FormStructure form_structure(form); - form_structure.set_passwords_were_revealed(true); for (auto& fs_field : form_structure) fs_field->host_form_signature = form_structure.form_signature(); @@ -3959,7 +3921,6 @@ std::string() /* login_form_signature */, true /* observed_submission */); ASSERT_EQ(1u, uploads.size()); - EXPECT_EQ(true, uploads.front().passwords_revealed()); } TEST_F(FormStructureTestImpl, EncodeUploadRequest_IsFormTag) { @@ -3978,7 +3939,6 @@ FormStructure form_structure(form); for (auto& fs_field : form_structure) fs_field->host_form_signature = form_structure.form_signature(); - form_structure.set_passwords_were_revealed(true); std::vector<AutofillUploadContents> uploads = form_structure.EncodeUploadRequest( {{}} /* available_field_types */, false /* form_was_autofilled */,
diff --git a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h index 7a2aa65..a745bf70 100644 --- a/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h +++ b/components/autofill/core/browser/test_utils/vote_uploads_test_matchers.h
@@ -99,6 +99,22 @@ signature.value()); } +inline ::testing::Matcher<AutofillUploadContents> PasswordLengthIsPositive() { + return ::testing::Property("password_length", + &AutofillUploadContents::password_length, + ::testing::Gt(0u)); +} + +inline ::testing::Matcher<AutofillUploadContents> HasPasswordAttribute() { + return ::testing::AnyOf( + ::testing::Property("has_password_has_letter", + &AutofillUploadContents::has_password_has_letter, + true), + ::testing::Property( + "has_password_has_special_symbol", + &AutofillUploadContents::has_password_has_special_symbol, true)); +} + } // namespace upload_contents_matchers } // namespace autofill
diff --git a/components/exo/wayland/wl_data_device_manager.cc b/components/exo/wayland/wl_data_device_manager.cc index 167b96c1..bb05f5d8 100644 --- a/components/exo/wayland/wl_data_device_manager.cc +++ b/components/exo/wayland/wl_data_device_manager.cc
@@ -319,7 +319,7 @@ if (serial_tracker_->GetPointerDownSerial() != serial) { LOG(ERROR) << "The serial passed to StartDrag for pointer does not match its " - "expected types. serial=" + "expected types. tracker_id=" << serial << ", " << serial_tracker_->ToString(); source->Cancelled(); return; @@ -331,7 +331,7 @@ if (serial_tracker_->GetTouchDownSerial() != serial) { LOG(ERROR) << "The serial passed to StartDrag for touch does not match its " - "expected types. serial=" + "expected types. tracker_id=" << serial << ", " << serial_tracker_->ToString(); source->Cancelled(); return; @@ -341,7 +341,7 @@ ui::mojom::DragEventSource::kTouch); } else { LOG(ERROR) << "Invalid event type for StartDrag:" << (int)*event_type - << ", serial=" << serial << ", " + << ", tracker_id=" << serial << ", " << serial_tracker_->ToString(); source->Cancelled(); return;
diff --git a/components/eye_dropper/eye_dropper_view_aura.cc b/components/eye_dropper/eye_dropper_view_aura.cc index 39036ab..2e79acb 100644 --- a/components/eye_dropper/eye_dropper_view_aura.cc +++ b/components/eye_dropper/eye_dropper_view_aura.cc
@@ -127,11 +127,24 @@ void EyeDropperView::PreEventDispatchHandler::OnTouchEvent( ui::TouchEvent* event) { if (event->type() == ui::ET_TOUCH_PRESSED) { + // For touch-move, we don't move the center of the EyeDropper to be at the + // touch point, but rather maintain the offset from the first press. touch_offset_ = event->root_location() - view_->GetWidget()->GetWindowBoundsInScreen().CenterPoint(); } if (event->type() == ui::ET_TOUCH_MOVED) { - view_->UpdatePosition(event->root_location() - touch_offset_); + // Keep EyeDropper always inside a display, but adjust offset if it is + // pushing up against the bounds. + gfx::Point position = event->root_location() - touch_offset_; + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestPoint(position); + if (display.bounds().Contains(position)) { + view_->UpdatePosition(std::move(position)); + } else { + touch_offset_ = + event->root_location() - + view_->GetWidget()->GetWindowBoundsInScreen().CenterPoint(); + } } }
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn index e200835..31a8008 100644 --- a/components/optimization_guide/core/BUILD.gn +++ b/components/optimization_guide/core/BUILD.gn
@@ -263,6 +263,8 @@ "model_execution/on_device_model_service_controller.h", "model_execution/optimization_guide_model_execution_error.cc", "model_execution/optimization_guide_model_execution_error.h", + "model_execution/redactor.cc", + "model_execution/redactor.h", "model_execution/session_impl.cc", "model_execution/session_impl.h", "model_execution/settings_enabled_observer.cc", @@ -336,6 +338,7 @@ deps += [ ":on_device_model_execution_proto_generator", "//components/version_info", + "//third_party/re2", ] } @@ -501,6 +504,7 @@ "model_execution/on_device_model_execution_proto_value_utils_unittest.cc", "model_execution/on_device_model_service_controller_unittest.cc", "model_execution/optimization_guide_model_execution_error_unittest.cc", + "model_execution/redactor_unittest.cc", "model_execution/test_on_device_model_component.cc", "model_execution/test_on_device_model_component.h", ]
diff --git a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc index 05c1d45..e5cbebb 100644 --- a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc +++ b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.cc
@@ -13,6 +13,7 @@ #include "base/task/thread_pool.h" #include "components/optimization_guide/core/model_execution/on_device_model_execution_proto_descriptors.h" #include "components/optimization_guide/core/model_execution/on_device_model_execution_proto_value_utils.h" +#include "components/optimization_guide/core/model_execution/redactor.h" #include "components/optimization_guide/core/optimization_guide_constants.h" namespace optimization_guide { @@ -39,6 +40,23 @@ return std::make_unique<proto::OnDeviceModelExecutionConfig>(config); } +std::vector<Rule> ExtractRedactRules(const proto::RedactRules& proto_rules) { + std::vector<Rule> rules; + if (proto_rules.rules_size()) { + for (const auto& rule : proto_rules.rules()) { + if (rule.has_regex() && rule.has_behavior()) { + rules.push_back(Rule()); + rules.back().regex = rule.regex(); + rules.back().behavior = rule.behavior(); + if (rule.has_replacement_string()) { + rules.back().replacement_string = rule.replacement_string(); + } + } + } + } + return rules; +} + std::string StringPrintfVector(const std::string& string_template, std::vector<std::string> args) { CHECK(args.size() <= kMaxArgs); @@ -129,7 +147,56 @@ proto::ModelExecutionFeature feature) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return base::Contains(feature_configs_, feature); + return base::Contains(feature_to_data_, feature); +} + +std::string +OnDeviceModelExecutionConfigInterpreter::GetStringToCheckForRedacting( + proto::ModelExecutionFeature feature, + const google::protobuf::MessageLite& message) const { + auto feature_iter = feature_to_data_.find(feature); + if (feature_iter == feature_to_data_.end() || + !feature_iter->second->redactor) { + return std::string(); + } + const auto& feature_config = feature_iter->second->config; + for (const auto& proto_field : + feature_config.output_config().redact_rules().fields_to_check()) { + std::optional<proto::Value> value = GetProtoValue(message, proto_field); + if (value.has_value()) { + const std::string string_value = GetStringFromValue(*value); + if (!string_value.empty()) { + return string_value; + } + } + } + return std::string(); +} + +const Redactor* OnDeviceModelExecutionConfigInterpreter::GetRedactorForFeature( + proto::ModelExecutionFeature feature) const { + const auto feature_iter = feature_to_data_.find(feature); + return feature_iter != feature_to_data_.end() + ? feature_iter->second->redactor.get() + : nullptr; +} + +void OnDeviceModelExecutionConfigInterpreter::OverrideFeatureConfigForTesting( + const proto::OnDeviceModelExecutionFeatureConfig& config) { + RegisterFeature(config); +} + +void OnDeviceModelExecutionConfigInterpreter::RegisterFeature( + const proto::OnDeviceModelExecutionFeatureConfig& config) { + std::unique_ptr<FeatureData> feature_data = std::make_unique<FeatureData>(); + feature_data->config = config; + if (config.has_output_config() && config.output_config().has_redact_rules() && + config.output_config().redact_rules().fields_to_check_size() && + !config.output_config().redact_rules().rules().empty()) { + feature_data->redactor = std::make_unique<Redactor>( + ExtractRedactRules(config.output_config().redact_rules())); + } + feature_to_data_[config.feature()] = std::move(feature_data); } void OnDeviceModelExecutionConfigInterpreter::PopulateFeatureConfigs( @@ -141,14 +208,14 @@ } for (const auto& feature_config : config->feature_configs()) { - feature_configs_[feature_config.feature()] = feature_config; + RegisterFeature(feature_config); } } void OnDeviceModelExecutionConfigInterpreter::ClearState() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - feature_configs_.clear(); + feature_to_data_.clear(); } std::optional< @@ -160,10 +227,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Get the config to construct the input string. - if (!HasConfigForFeature(feature)) { + auto feature_iter = feature_to_data_.find(feature); + if (feature_iter == feature_to_data_.end()) { return std::nullopt; } - auto feature_config = feature_configs_.at(feature); + const auto& feature_config = feature_iter->second->config; if (!feature_config.has_input_config()) { return std::nullopt; } @@ -225,11 +293,11 @@ const std::string& output) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!HasConfigForFeature(feature)) { + auto iter = feature_to_data_.find(feature); + if (iter == feature_to_data_.end()) { return std::nullopt; } - - auto feature_config = feature_configs_.at(feature); + const auto& feature_config = iter->second->config; if (!feature_config.has_output_config()) { return std::nullopt; } @@ -239,4 +307,7 @@ output); } +OnDeviceModelExecutionConfigInterpreter::FeatureData::FeatureData() = default; +OnDeviceModelExecutionConfigInterpreter::FeatureData::~FeatureData() = default; + } // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h index f3cf437..0fbd12e7 100644 --- a/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h +++ b/components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h
@@ -18,6 +18,8 @@ namespace optimization_guide { +class Redactor; + class OnDeviceModelExecutionConfigInterpreter { public: OnDeviceModelExecutionConfigInterpreter(); @@ -54,13 +56,32 @@ proto::ModelExecutionFeature feature, const std::string& output) const; + // Returns the string that is used for checking redaction against. + std::string GetStringToCheckForRedacting( + proto::ModelExecutionFeature feature, + const google::protobuf::MessageLite& message) const; + + // Returns the Redactor for the specified feature. Return value is owned by + // this and may be null. + const Redactor* GetRedactorForFeature( + proto::ModelExecutionFeature feature) const; + void OverrideFeatureConfigForTesting( - const proto::OnDeviceModelExecutionFeatureConfig& config) { - feature_configs_[config.feature()] = config; - } + const proto::OnDeviceModelExecutionFeatureConfig& config); private: - // Populates `feature_configs_` based on `config`. + // Contains the state applicable to a feature. + struct FeatureData { + FeatureData(); + ~FeatureData(); + proto::OnDeviceModelExecutionFeatureConfig config; + std::unique_ptr<Redactor> redactor; + }; + + void RegisterFeature( + const proto::OnDeviceModelExecutionFeatureConfig& config); + + // Populates `feature_to_data_` based on `config`. void PopulateFeatureConfigs( std::unique_ptr<proto::OnDeviceModelExecutionConfig> config); @@ -71,10 +92,9 @@ // The task runner to process new config files on. scoped_refptr<base::SequencedTaskRunner> background_task_runner_; - // Map from feature to its model execution feature config. - base::flat_map<proto::ModelExecutionFeature, - proto::OnDeviceModelExecutionFeatureConfig> - feature_configs_; + // Map from feature to associated state. + base::flat_map<proto::ModelExecutionFeature, std::unique_ptr<FeatureData>> + feature_to_data_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller.h b/components/optimization_guide/core/model_execution/on_device_model_service_controller.h index 6f80b3f..c38b0245 100644 --- a/components/optimization_guide/core/model_execution/on_device_model_service_controller.h +++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller.h
@@ -105,6 +105,10 @@ // OnDeviceModelComponentStateManager::Observer. void StateChanged(const OnDeviceModelComponentState* state) override; + OnDeviceModelExecutionConfigInterpreter& ConfigInterpreterForTesting() { + return *config_interpreter_; + } + protected: ~OnDeviceModelServiceController() override;
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc index 927f98a..f574f79 100644 --- a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc +++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
@@ -44,6 +44,9 @@ on_device_model::mojom::ResponseStatus g_on_complete_response_type = on_device_model::mojom::ResponseStatus::kOk; +// If non-empty, used as the output from Execute(). +std::string g_model_execute_result; + } // namespace std::vector<std::string> ConcatResponses( @@ -97,7 +100,11 @@ for (const std::string& context : context_) { remote->OnResponse("Context: " + context + "\n"); } - remote->OnResponse("Input: " + input->text + "\n"); + remote->OnResponse("Input: " + + (g_model_execute_result.empty() + ? input->text + : g_model_execute_result) + + "\n"); remote->OnComplete(g_on_complete_response_type); } @@ -229,6 +236,7 @@ public: void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + g_model_execute_result.clear(); g_execute_delay = base::TimeDelta(); g_on_complete_response_type = on_device_model::mojom::ResponseStatus::kOk; feature_list_.InitAndEnableFeatureWithParameters( @@ -259,18 +267,8 @@ }); } - void RecreateServiceController() { - access_controller_ = nullptr; - test_controller_ = nullptr; - - auto access_controller = - std::make_unique<OnDeviceModelAccessController>(pref_service_); - access_controller_ = access_controller.get(); - test_controller_ = base::MakeRefCounted<FakeOnDeviceModelServiceController>( - std::move(access_controller), - on_device_component_state_manager_.get()->GetWeakPtr()); - - proto::OnDeviceModelExecutionFeatureConfig config; + void PopulateConfigForFeature( + proto::OnDeviceModelExecutionFeatureConfig& config) { config.set_feature(kFeature); auto& input_config = *config.mutable_input_config(); input_config.set_request_base_name(proto::ComposeRequest().GetTypeName()); @@ -304,13 +302,49 @@ output_config.mutable_proto_field() ->add_proto_descriptors() ->set_tag_number(1); + } + proto::RedactRule& PopulateConfigForFeatureWithRedactRule( + proto::OnDeviceModelExecutionFeatureConfig& config, + const std::string& regex, + proto::RedactBehavior behavior = + proto::RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT) { + PopulateConfigForFeature(config); + auto& output_config = *config.mutable_output_config(); + auto& redact_rules = *output_config.mutable_redact_rules(); + auto& field = *redact_rules.add_fields_to_check(); + field.add_proto_descriptors()->set_tag_number(7); + field.add_proto_descriptors()->set_tag_number(1); + auto& redact_rule = *redact_rules.add_rules(); + redact_rule.set_regex(regex); + redact_rule.set_behavior(behavior); + return redact_rule; + } + + void RecreateServiceController() { + access_controller_ = nullptr; + test_controller_ = nullptr; + + auto access_controller = + std::make_unique<OnDeviceModelAccessController>(pref_service_); + access_controller_ = access_controller.get(); + test_controller_ = base::MakeRefCounted<FakeOnDeviceModelServiceController>( + std::move(access_controller), + on_device_component_state_manager_.get()->GetWeakPtr()); + + proto::OnDeviceModelExecutionFeatureConfig config; + PopulateConfigForFeature(config); auto config_interpreter = std::make_unique<OnDeviceModelExecutionConfigInterpreter>(); - auto* config_interpreter_raw = config_interpreter.get(); test_controller_->Init(base::FilePath::FromASCII("/foo"), std::move(config_interpreter)); - config_interpreter_raw->OverrideFeatureConfigForTesting(config); + OverrideFeatureConfigForTesting(config); + } + + void OverrideFeatureConfigForTesting( + const proto::OnDeviceModelExecutionFeatureConfig& config) { + test_controller_->ConfigInterpreterForTesting() + .OverrideFeatureConfigForTesting(config); } void AddContext(OptimizationGuideModelExecutor::Session& session, @@ -320,6 +354,7 @@ session.AddContext(request); } + // Calls Execute() after setting `input` as the page-url. void ExecuteModel(OptimizationGuideModelExecutor::Session& session, std::string_view input) { proto::ComposeRequest request; @@ -330,6 +365,29 @@ base::Unretained(this))); } + // Calls Execute() after setting `input` as the user_input. + void ExecuteModelUsingInput(OptimizationGuideModelExecutor::Session& session, + std::string_view input) { + proto::ComposeRequest request; + request.mutable_generate_params()->set_user_input(std::string(input)); + session.ExecuteModel( + request, + base::BindRepeating(&OnDeviceModelServiceControllerTest::OnResponse, + base::Unretained(this))); + } + + void ExecuteModelWithRewrite( + OptimizationGuideModelExecutor::Session& session) { + proto::ComposeRequest request; + auto& rewrite_params = *request.mutable_rewrite_params(); + rewrite_params.set_previous_response("bar"); + rewrite_params.set_tone(proto::COMPOSE_FORMAL); + session.ExecuteModel( + request, + base::BindRepeating(&OnDeviceModelServiceControllerTest::OnResponse, + base::Unretained(this))); + } + base::FilePath temp_dir() const { return temp_dir_.GetPath(); } protected: @@ -909,10 +967,9 @@ config.set_feature(kFeature); auto config_interpreter = std::make_unique<OnDeviceModelExecutionConfigInterpreter>(); - auto* config_interpreter_raw = config_interpreter.get(); test_controller_->Init(base::FilePath::FromASCII("/foo"), std::move(config_interpreter)); - config_interpreter_raw->OverrideFeatureConfigForTesting(config); + OverrideFeatureConfigForTesting(config); auto session = test_controller_->CreateSession( kFeature, CreateExecuteRemoteFn(), &logger_); @@ -953,10 +1010,9 @@ config.set_feature(kFeature); auto config_interpreter = std::make_unique<OnDeviceModelExecutionConfigInterpreter>(); - auto* config_interpreter_raw = config_interpreter.get(); test_controller_->Init(base::FilePath::FromASCII("/foo"), std::move(config_interpreter)); - config_interpreter_raw->OverrideFeatureConfigForTesting(config); + OverrideFeatureConfigForTesting(config); auto session = test_controller_->CreateSession( kFeature, CreateExecuteRemoteFn(), &logger_); @@ -1120,4 +1176,106 @@ OptimizationGuideModelExecutionError::ModelExecutionError::kFiltered); } +TEST_F(OnDeviceModelServiceControllerTest, RedactedField) { + proto::OnDeviceModelExecutionFeatureConfig config; + PopulateConfigForFeatureWithRedactRule(config, "bar"); + OverrideFeatureConfigForTesting(config); + + // `foo` doesn't match the redaction, so should be returned. + auto session1 = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session1); + ExecuteModelUsingInput(*session1, "foo"); + task_environment_.RunUntilIdle(); + const std::string expected_response1 = "Input: execute:foo\n"; + EXPECT_EQ(*response_received_, expected_response1); + EXPECT_THAT(streamed_responses_, ElementsAre(expected_response1)); + + // Input and output contain text matching redact, so should not be redacted. + response_received_.reset(); + streamed_responses_.clear(); + auto session2 = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session2); + ExecuteModelUsingInput(*session2, "abarx"); + task_environment_.RunUntilIdle(); + const std::string expected_response2 = "Input: execute:abarx\n"; + EXPECT_EQ(*response_received_, expected_response2); + EXPECT_THAT(streamed_responses_, ElementsAre(expected_response2)); + + // Output contains redacted text (and input doesn't), so redact. + g_model_execute_result = "abarx"; + response_received_.reset(); + streamed_responses_.clear(); + auto session3 = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session3); + ExecuteModelUsingInput(*session3, "foo"); + task_environment_.RunUntilIdle(); + const std::string expected_response3 = "Input: a[###]x\n"; + EXPECT_EQ(*response_received_, expected_response3); + EXPECT_THAT(streamed_responses_, ElementsAre(expected_response3)); +} + +TEST_F(OnDeviceModelServiceControllerTest, RejectedField) { + proto::OnDeviceModelExecutionFeatureConfig config; + PopulateConfigForFeatureWithRedactRule(config, "bar", + proto::RedactBehavior::REJECT); + OverrideFeatureConfigForTesting(config); + + auto session1 = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session1); + ExecuteModelUsingInput(*session1, "bar"); + task_environment_.RunUntilIdle(); + EXPECT_FALSE(response_received_); + ASSERT_TRUE(response_error_); + EXPECT_EQ( + *response_error_, + OptimizationGuideModelExecutionError::ModelExecutionError::kFiltered); +} + +TEST_F(OnDeviceModelServiceControllerTest, UsePreviousResponseForRewrite) { + proto::OnDeviceModelExecutionFeatureConfig config; + PopulateConfigForFeatureWithRedactRule(config, "bar"); + // Add a rule that identifies `previous_response` of `rewrite_params`. + auto& output_config = *config.mutable_output_config(); + auto& redact_rules = *output_config.mutable_redact_rules(); + auto& field = *redact_rules.add_fields_to_check(); + field.add_proto_descriptors()->set_tag_number(8); + field.add_proto_descriptors()->set_tag_number(1); + OverrideFeatureConfigForTesting(config); + + // Force 'bar' to be returned from model. + g_model_execute_result = "bar"; + + auto session = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session); + ExecuteModelWithRewrite(*session); + task_environment_.RunUntilIdle(); + // `bar` shouldn't be rewritten as it's in the input. + const std::string expected_response = "Input: bar\n"; + EXPECT_EQ(*response_received_, expected_response); + EXPECT_THAT(streamed_responses_, ElementsAre(expected_response)); +} + +TEST_F(OnDeviceModelServiceControllerTest, ReplacementText) { + proto::OnDeviceModelExecutionFeatureConfig config; + PopulateConfigForFeatureWithRedactRule(config, "bar") + .set_replacement_string("[redacted]"); + OverrideFeatureConfigForTesting(config); + + // Output contains redacted text (and input doesn't), so redact. + g_model_execute_result = "abarx"; + auto session = + test_controller_->CreateSession(kFeature, base::DoNothing(), &logger_); + ASSERT_TRUE(session); + ExecuteModelUsingInput(*session, "foo"); + task_environment_.RunUntilIdle(); + const std::string expected_response = "Input: a[redacted]x\n"; + EXPECT_EQ(*response_received_, expected_response); + EXPECT_THAT(streamed_responses_, ElementsAre(expected_response)); +} + } // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/redactor.cc b/components/optimization_guide/core/model_execution/redactor.cc new file mode 100644 index 0000000..4347f61 --- /dev/null +++ b/components/optimization_guide/core/model_execution/redactor.cc
@@ -0,0 +1,103 @@ +// 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/optimization_guide/core/model_execution/redactor.h" + +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "third_party/re2/src/re2/re2.h" + +namespace optimization_guide { + +Rule::Rule() = default; +Rule::Rule(const Rule& r) = default; +Rule::~Rule() = default; + +Redactor::RuleImpl::RuleImpl() = default; + +Redactor::RuleImpl::~RuleImpl() = default; + +Redactor::Redactor(const std::vector<Rule>& rules) { + for (const auto& rule : rules) { + if (rule.behavior == proto::RedactBehavior::REDACT_BEHAVIOR_UNSPECIFIED) { + continue; + } + auto rule_impl = std::make_unique<RuleImpl>(); + rule_impl->re = std::make_unique<re2::RE2>(rule.regex); + rule_impl->behavior = rule.behavior; + rule_impl->replacement_string = rule.replacement_string; + rules_.push_back(std::move(rule_impl)); + } +} + +Redactor::~Redactor() = default; + +RedactResult Redactor::Redact(const std::string& input, + std::string& output) const { + for (auto& rule : rules_) { + if (ProcessRule(*rule, input, output) == RedactResult::kReject) { + return RedactResult::kReject; + } + } + return RedactResult::kContinue; +} + +RedactResult Redactor::ProcessRule(const RuleImpl& rule, + const std::string& input, + std::string& output) const { + // This is rather expensive, only enter the main loop if there is at least one + // match. + absl::string_view output_view(output); + absl::string_view match; + if (!rule.re->Match(output_view, 0, output_view.length(), + re2::RE2::UNANCHORED, &match, 1)) { + return RedactResult::kContinue; + } + + if (rule.behavior == proto::RedactBehavior::REJECT) { + return RedactResult::kReject; + } + + size_t last_match_start = 0; + std::string new_output; + size_t next_start_offset; + do { + next_start_offset = match.data() - output_view.data() + match.length(); + if (rule.behavior == proto::RedactBehavior::REDACT_ALWAYS || + input.find(match) == std::string::npos) { + const size_t match_start_offset_in_output = + match.data() - output_view.data(); + new_output += + base::StrCat({std::string_view(output).substr( + last_match_start, + match_start_offset_in_output - last_match_start), + GetReplacementString(rule, match)}); + last_match_start = match_start_offset_in_output + match.length(); + } + } while (next_start_offset < output_view.length() && + rule.re->Match(output_view, next_start_offset, output_view.length(), + re2::RE2::UNANCHORED, &match, 1)); + if (last_match_start == 0) { + // No replacement happened, nothing to do. + return RedactResult::kContinue; + } + if (last_match_start != output.length()) { + new_output += output.substr(last_match_start); + } + std::swap(output, new_output); + return RedactResult::kContinue; +} + +std::string Redactor::GetReplacementString(const RuleImpl& rule, + absl::string_view match) const { + if (rule.replacement_string.has_value()) { + return *rule.replacement_string; + } + std::string replacement(match.length() + 2, '#'); + replacement[0] = '['; + replacement.back() = ']'; + return replacement; +} + +} // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/redactor.h b/components/optimization_guide/core/model_execution/redactor.h new file mode 100644 index 0000000..3ddddf11 --- /dev/null +++ b/components/optimization_guide/core/model_execution/redactor.h
@@ -0,0 +1,72 @@ +// 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_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_ + +#include <memory> +#include <optional> +#include <string> +#include <vector> + +#include "components/optimization_guide/proto/model_execution.pb.h" + +namespace re2 { +class RE2; +} // namespace re2 + +namespace optimization_guide { + +struct Rule { + Rule(); + Rule(const Rule& r); + ~Rule(); + + std::string regex; + proto::RedactBehavior behavior; + // If supplied, replaces the matching string. + std::optional<std::string> replacement_string; +}; + +enum RedactResult { + // Used if there was at least one rule that matched with a behavior of reject. + kReject, + + // No rules with reject matched. + kContinue, +}; + +// Used to redact (or reject) text. +class Redactor { + public: + explicit Redactor(const std::vector<Rule>& rules); + ~Redactor(); + + // Redacts (or rejects) the applicable text in`output`. `input` is the string + // regexes of type REDACT_IF_ONLY_IN_OUTPUT checks. + RedactResult Redact(const std::string& input, std::string& output) const; + + private: + struct RuleImpl { + RuleImpl(); + ~RuleImpl(); + std::unique_ptr<re2::RE2> re; + proto::RedactBehavior behavior; + std::optional<std::string> replacement_string; + }; + + std::string GetReplacementString(const RuleImpl& rule, + std::string_view match) const; + + // Processes a single regex, applying any redactions to `output`. + RedactResult ProcessRule(const RuleImpl& rule, + const std::string& input, + std::string& output) const; + + std::vector<std::unique_ptr<RuleImpl>> rules_; +}; + +} // namespace optimization_guide + +#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_MODEL_EXECUTION_REDACTOR_H_
diff --git a/components/optimization_guide/core/model_execution/redactor_unittest.cc b/components/optimization_guide/core/model_execution/redactor_unittest.cc new file mode 100644 index 0000000..1235410 --- /dev/null +++ b/components/optimization_guide/core/model_execution/redactor_unittest.cc
@@ -0,0 +1,73 @@ +// 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/optimization_guide/core/model_execution/redactor.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace optimization_guide { + +using proto::RedactBehavior; + +Rule CreateRule( + const std::string& regex, + RedactBehavior behavior = RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT, + std::optional<std::string> replacement_string = std::nullopt) { + Rule rule; + rule.regex = regex; + rule.behavior = behavior; + rule.replacement_string = std::move(replacement_string); + return rule; +} + +TEST(RedactorTest, RedactMultipleHitsNotPresentInInput) { + Redactor redactor({CreateRule("ab")}); + std::string output("ab cab"); + EXPECT_EQ(RedactResult::kContinue, redactor.Redact(std::string(), output)); + EXPECT_EQ("[##] c[##]", output); +} + +TEST(RedactorTest, RedactMultipleHits) { + Redactor redactor({CreateRule("ab")}); + std::string output("ab cab"); + redactor.Redact("zabq", output); + EXPECT_EQ("ab cab", output); +} + +TEST(RedactorTest, RedactMultipleHitsMultipleRegex) { + Redactor redactor({CreateRule("ab"), CreateRule("z")}); + std::string output("ab zcab"); + redactor.Redact(std::string(), output); + EXPECT_EQ("[##] [#]c[##]", output); +} + +TEST(RedactorTest, RedactNotAtEnd) { + Redactor redactor({CreateRule("ab")}); + std::string output("abc"); + redactor.Redact(std::string(), output); + EXPECT_EQ("[##]c", output); +} + +TEST(RedactorTest, RedactAlways) { + Redactor redactor({CreateRule("ab", RedactBehavior::REDACT_ALWAYS)}); + std::string output("abc"); + redactor.Redact("ab", output); + EXPECT_EQ("[##]c", output); +} + +TEST(RedactorTest, Reject) { + Redactor redactor({CreateRule("ab", RedactBehavior::REJECT)}); + std::string output("abc"); + EXPECT_EQ(RedactResult::kReject, redactor.Redact(std::string(), output)); +} + +TEST(RedactorTest, RedactWithReplacmentText) { + Redactor redactor({CreateRule("ab", RedactBehavior::REDACT_IF_ONLY_IN_OUTPUT, + "|redacted)")}); + std::string output("ab cab"); + EXPECT_EQ(RedactResult::kContinue, redactor.Redact(std::string(), output)); + EXPECT_EQ("|redacted) c|redacted)", output); +} + +} // namespace optimization_guide
diff --git a/components/optimization_guide/core/model_execution/session_impl.cc b/components/optimization_guide/core/model_execution/session_impl.cc index e76c0295..d0d2e265 100644 --- a/components/optimization_guide/core/model_execution/session_impl.cc +++ b/components/optimization_guide/core/model_execution/session_impl.cc
@@ -10,6 +10,7 @@ #include "components/optimization_guide/core/model_execution/on_device_model_access_controller.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/redactor.h" #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_util.h" @@ -354,8 +355,28 @@ return; } + std::string current_response = on_device_state_->current_response; + if (auto* redactor = + on_device_state_->config_interpreter->GetRedactorForFeature( + feature_)) { + auto redact_string_input = + on_device_state_->config_interpreter->GetStringToCheckForRedacting( + feature_, *last_message_); + if (redactor->Redact(redact_string_input, current_response) == + RedactResult::kReject) { + if (on_device_state_->histogram_logger) { + on_device_state_->histogram_logger->set_result( + ExecuteModelResult::kContainedPII); + on_device_state_->histogram_logger.reset(); + } + CancelPendingResponse(ExecuteModelResult::kUsedOnDeviceOutputUnsafe, + ModelExecutionError::kFiltered); + return; + } + } + auto output = on_device_state_->config_interpreter->ConstructOutputMetadata( - feature_, on_device_state_->current_response); + feature_, current_response); if (!output) { if (on_device_state_->histogram_logger) { on_device_state_->histogram_logger->set_result(
diff --git a/components/optimization_guide/core/model_execution/session_impl.h b/components/optimization_guide/core/model_execution/session_impl.h index dd36209f..27876215 100644 --- a/components/optimization_guide/core/model_execution/session_impl.h +++ b/components/optimization_guide/core/model_execution/session_impl.h
@@ -74,7 +74,9 @@ // On-device was used, it completed successfully, but the output is // considered unsafe. kUsedOnDeviceOutputUnsafe = 9, - kMaxValue = kUsedOnDeviceOutputUnsafe, + // On-device was used, but the output was rejected (because contained PII). + kContainedPII = 10, + kMaxValue = kContainedPII, }; SessionImpl(StartSessionFn start_session_fn,
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal index 2e8649b..d6d170d 160000 --- a/components/optimization_guide/internal +++ b/components/optimization_guide/internal
@@ -1 +1 @@ -Subproject commit 2e8649b36bd3e4e0ae00efabffc0e5a512316a2c +Subproject commit d6d170dc380770ce81ad2f7ea55435c98fe4083a
diff --git a/components/optimization_guide/proto/model_execution.proto b/components/optimization_guide/proto/model_execution.proto index 2962e64..e3a50296 100644 --- a/components/optimization_guide/proto/model_execution.proto +++ b/components/optimization_guide/proto/model_execution.proto
@@ -67,6 +67,41 @@ repeated OnDeviceModelExecutionFeatureConfig feature_configs = 1; } +enum RedactBehavior { + // No redaction. + REDACT_BEHAVIOR_UNSPECIFIED = 0; + + // Results in rejecting the output entirely. + REJECT = 1; + + // Redacts the text if only in the output (not in the redact input string). + REDACT_IF_ONLY_IN_OUTPUT = 2; + + // Redacts regardless of whether it occurs in the input or not. + REDACT_ALWAYS = 3; +} + +message RedactRule { + optional RedactBehavior behavior = 1; + optional string regex = 2; + // If supplied, replaces the matching string. + optional string replacement_string = 3; + // TODO: add support for replacement character. +} + +// Applies a set of rules to a field. +message RedactRules { + // Identifies the field to be checked for redaction (see + // REDACT_IF_ONLY_IN_OUTPUT). The first ProtoField that identifies a + // non-empty string is used. + repeated ProtoField fields_to_check = 1; + + // The set of regular exrepssions to check. When checking the regular + // expressions all are checked, unless one matches with a behavior of REJECT, + // in which case no need to continue. + repeated RedactRule rules = 2; +} + message OnDeviceModelExecutionFeatureConfig { // The feature this configuration is for. optional ModelExecutionFeature feature = 1; @@ -201,4 +236,7 @@ // The proto field to populate the output string with. optional ProtoField proto_field = 2; + + // Rules that result in redacting the output. + optional RedactRules redact_rules = 3; }
diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h index df935aa5..e61981b 100644 --- a/components/page_info/page_info.h +++ b/components/page_info/page_info.h
@@ -447,7 +447,7 @@ // specific data (local stored objects like cookies), site-specific // permissions (location, pop-up, plugin, etc. permissions) and site-specific // information (identity, connection status, etc.). - raw_ptr<PageInfoUI, DanglingUntriaged> ui_ = nullptr; + raw_ptr<PageInfoUI> ui_ = nullptr; // A web contents getter used to retrieve the associated WebContents object. base::WeakPtr<content::WebContents> web_contents_;
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/components/password_manager/core/browser/browser_save_password_progress_logger.cc index b6faeba..81b4db2 100644 --- a/components/password_manager/core/browser/browser_save_password_progress_logger.cc +++ b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -4,6 +4,7 @@ #include "components/password_manager/core/browser/browser_save_password_progress_logger.h" +#include <optional> #include <sstream> #include <string> #include <utility> @@ -26,6 +27,7 @@ #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/password_manager/core/browser/password_manager.h" +#include "components/password_manager/core/browser/votes_uploader.h" using autofill::AutofillType; using autofill::AutofillUploadContents; @@ -216,7 +218,8 @@ void BrowserSavePasswordProgressLogger::LogFormStructure( StringID label, - const FormStructure& form_structure) { + const FormStructure& form_structure, + std::optional<PasswordAttributesMetadata> password_attributes) { std::string message = GetStringFromID(label) + ": {\n"; message += GetStringFromID(STRING_FORM_SIGNATURE) + ": " + FormSignatureToDebugString(form_structure.form_signature()) + "\n"; @@ -229,7 +232,7 @@ message += GetStringFromID(STRING_ACTION) + ": " + ScrubURL(form_structure.target_url()) + "\n"; message += FormStructureToFieldsLogString(form_structure); - message += FormStructurePasswordAttributesLogString(form_structure); + message += VotesPasswordAttributesLogString(password_attributes); message += "}"; SendLog(message); } @@ -247,16 +250,15 @@ SendLog(message); } -std::string -BrowserSavePasswordProgressLogger::FormStructurePasswordAttributesLogString( - const FormStructure& form) { - const std::optional<std::pair<PasswordAttribute, bool>> attribute_vote = - form.get_password_attributes_vote(); - if (!attribute_vote.has_value()) +std::string BrowserSavePasswordProgressLogger::VotesPasswordAttributesLogString( + std::optional<PasswordAttributesMetadata> password_attributes) { + if (!password_attributes.has_value()) { return std::string(); + } + const std::pair<PasswordAttribute, bool> attribute_vote = + password_attributes->password_attributes_vote; std::string message; - const PasswordAttribute attribute = std::get<0>(attribute_vote.value()); - const bool attribute_value = std::get<1>(attribute_vote.value()); + const auto [attribute, attribute_value] = attribute_vote; switch (attribute) { case PasswordAttribute::kHasLetter: @@ -270,7 +272,7 @@ attribute_value); if (attribute_value) { std::string voted_symbol( - 1, static_cast<char>(form.get_password_symbol_vote())); + 1, static_cast<char>(password_attributes->password_symbol_vote)); message += PasswordAttributeLogString( STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_SPECIFIC_SPECIAL_SYMBOL, voted_symbol); @@ -281,7 +283,7 @@ break; } std::string password_length = - base::NumberToString(form.get_password_length_vote()); + base::NumberToString(password_attributes->password_length_vote); message += PasswordAttributeLogString( STRING_PASSWORD_REQUIREMENTS_VOTE_FOR_PASSWORD_LENGTH, password_length);
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.h b/components/password_manager/core/browser/browser_save_password_progress_logger.h index b56e5d9..a5eecb8 100644 --- a/components/password_manager/core/browser/browser_save_password_progress_logger.h +++ b/components/password_manager/core/browser/browser_save_password_progress_logger.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_BROWSER_SAVE_PASSWORD_PROGRESS_LOGGER_H_ #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_BROWSER_SAVE_PASSWORD_PROGRESS_LOGGER_H_ +#include <optional> #include <string> #include "base/containers/flat_map.h" @@ -13,6 +14,7 @@ #include "components/autofill/core/browser/proto/password_requirements.pb.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" #include "components/autofill/core/common/save_password_progress_logger.h" +#include "components/password_manager/core/browser/votes_uploader.h" #include "url/gurl.h" namespace autofill { @@ -48,7 +50,10 @@ // Browser-specific addition to the base class' Log* methods. The input is // sanitized and passed to SendLog for display. - void LogFormStructure(StringID label, const autofill::FormStructure& form); + void LogFormStructure( + StringID label, + const autofill::FormStructure& form, + std::optional<PasswordAttributesMetadata> password_attributes); // Browser-specific addition to the base class' Log* methods. The input is // sanitized and passed to SendLog for display. @@ -88,10 +93,10 @@ static std::string FormStructureToFieldsLogString( const autofill::FormStructure& form); - // Returns the string representation of password attributes for - // `FormStructure`. - static std::string FormStructurePasswordAttributesLogString( - const autofill::FormStructure& form); + // Returns the string representation of votes related password attributes from + // the `password_attributes`. + static std::string VotesPasswordAttributesLogString( + std::optional<PasswordAttributesMetadata> password_attributes); // Returns the string representation of a password attribute. static std::string PasswordAttributeLogString(
diff --git a/components/password_manager/core/browser/credential_cache.cc b/components/password_manager/core/browser/credential_cache.cc index ffe7211..66628e8 100644 --- a/components/password_manager/core/browser/credential_cache.cc +++ b/components/password_manager/core/browser/credential_cache.cc
@@ -11,6 +11,7 @@ #include <vector> #include "components/autofill/core/common/autofill_features.h" +#include "components/password_manager/core/browser/features/password_features.h" #include "components/password_manager/core/browser/origin_credential_store.h" #include "components/password_manager/core/browser/password_form.h" #include "url/origin.h" @@ -49,7 +50,13 @@ for (const PasswordForm* form : best_matches) { if (form->type == PasswordForm::Type::kReceivedViaSharing && !form->sharing_notification_displayed) { - unnotified_shared_credentials.push_back(*form); + // The cache is only useful when the sharing notification UI is displayed + // since it is used to mark those credentials as notified after the user + // interacts with the UI. + if (base::FeatureList::IsEnabled( + password_manager::features::kSharedPasswordNotificationUI)) { + unnotified_shared_credentials.push_back(*form); + } } } GetOrCreateCredentialStore(origin).SaveUnnotifiedSharedCredentials(
diff --git a/components/password_manager/core/browser/credential_cache_unittest.cc b/components/password_manager/core/browser/credential_cache_unittest.cc index 023a0a7..7d5ebfc6 100644 --- a/components/password_manager/core/browser/credential_cache_unittest.cc +++ b/components/password_manager/core/browser/credential_cache_unittest.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "components/password_manager/core/browser/origin_credential_store.h" #include "components/password_manager/core/browser/password_form.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" @@ -118,6 +119,9 @@ } TEST_F(CredentialCacheTest, StoresUnnotifiedSharedCredentialsCredentials) { + base::test::ScopedFeatureList feature_list( + password_manager::features::kSharedPasswordNotificationUI); + Origin origin = Origin::Create(GURL(kExampleSite)); std::unique_ptr<PasswordForm> non_shared_credentials = @@ -146,6 +150,30 @@ testing::ElementsAre(*shared_unnotified_credentials)); } +TEST_F( + CredentialCacheTest, + DoesNotStoreUnnotifiedSharedCredentialsCredentialsWhenFeatureIsDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature( + password_manager::features::kSharedPasswordNotificationUI); + + Origin origin = Origin::Create(GURL(kExampleSite)); + + std::unique_ptr<PasswordForm> shared_unnotified_credentials = + CreateEntry("shared_unnotified", "pass", GURL(kExampleSite), + PasswordForm::MatchType::kExact); + shared_unnotified_credentials->type = PasswordForm::Type::kReceivedViaSharing; + shared_unnotified_credentials->sharing_notification_displayed = false; + + cache()->SaveCredentialsAndBlocklistedForOrigin( + {shared_unnotified_credentials.get()}, IsOriginBlocklisted(false), + origin); + + EXPECT_THAT( + cache()->GetCredentialStore(origin).GetUnnotifiedSharedCredentials(), + testing::IsEmpty()); +} + TEST_F(CredentialCacheTest, StoresCredentialsForIndependentOrigins) { Origin origin = Origin::Create(GURL(kExampleSite)); Origin origin2 = Origin::Create(GURL(kExampleSite2));
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index 619aa04..2f895a4 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -583,7 +583,7 @@ FieldSingleUsernameVoteTypeIs(vote_type), FieldIsMostRecentSingleUsernameCandidateIs(most_recent)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); } // Creates LRU cache simulating user modifying non-password field outside of @@ -1271,7 +1271,7 @@ UploadFieldIs(submitted_form.fields[0], FieldType::PASSWORD), UploadFieldIs(submitted_form.fields[1], expected_vote))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); if (expected_vote == autofill::NEW_PASSWORD) { // An unrelated |FIRST_USE| vote. EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest); @@ -1359,7 +1359,7 @@ FieldVoteTypeIs(Field::USERNAME_OVERWRITTEN)), UploadFieldIs(password_field, FieldType::ACCOUNT_CREATION_PASSWORD))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -1413,7 +1413,7 @@ saved_match_.form_data.fields[kPasswordFieldIndex])), FieldVoteTypeIs(Field::CREDENTIALS_REUSED)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Saved credentials from the signup form were used for the first time on a // submitted form. The vote applies to the new form being submitted. @@ -1426,7 +1426,7 @@ submitted_form_.fields[kPasswordFieldIndex])), FieldVoteTypeIs(Field::FIRST_USE)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -1470,7 +1470,7 @@ FieldType::PASSWORD, FieldGenerationTypeIs(Field::NO_GENERATION)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -1555,7 +1555,7 @@ submitted_form_.fields[kPasswordFieldIndex])), FieldGenerationTypeIs(Field::NO_GENERATION)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -1589,7 +1589,7 @@ auto upload_contents_matcher = IsPasswordUpload(FieldsContain(UploadFieldIs( submitted_form_.fields[kPasswordFieldIndex], FieldType::PASSWORD))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Check that the password which was chosen by the user is saved. MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get()); @@ -2294,10 +2294,10 @@ if (password_revealed) form_manager_->OnPasswordsRevealed(); - EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest( - IsPasswordUpload(PasswordsRevealedIs(password_revealed)), _, - _, _, _)); + EXPECT_CALL( + crowdsourcing_manager(), + StartUploadRequest( + IsPasswordUpload(PasswordsRevealedIs(password_revealed)), _, _, _)); form_manager_->Save(); Mock::VerifyAndClearExpectations(&crowdsourcing_manager()); } @@ -2323,7 +2323,7 @@ submitted_form_.fields[kPasswordFieldIndex])), FieldGenerationTypeIs(Field::IGNORED_GENERATION_POPUP)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)) + StartUploadRequest(upload_contents_matcher, _, _, _)) .Times(generation_popup_shown ? 1 : 0); form_manager_->OnNoInteraction(false /*is_update */); Mock::VerifyAndClearExpectations(&crowdsourcing_manager()); @@ -2350,7 +2350,7 @@ submitted_form_.fields[kPasswordFieldIndex])), FieldGenerationTypeIs(Field::IGNORED_GENERATION_POPUP)))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)) + StartUploadRequest(upload_contents_matcher, _, _, _)) .Times(generation_popup_shown ? 1 : 0); form_manager_->OnNeverClicked(); @@ -2736,7 +2736,7 @@ UploadFieldIs(submitted_form.fields[1], FieldType::UNKNOWN_TYPE), UploadFieldIs(submitted_form.fields[2], FieldType::PASSWORD))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -2790,7 +2790,7 @@ // Upload username first flow votes on the username form. if constexpr (!BUILDFLAG(IS_ANDROID)) { EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _)); + StartUploadRequest(IsSingleUsernameUpload(), _, _, _)); } // Upload username first flow votes on the password form. @@ -2809,13 +2809,13 @@ SingleUsernameDataIs( EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); if (is_password_update) { EXPECT_CALL( crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(SingleUsernameDataIs(IsEmpty())), - _, _, _, _)); + _, _, _)); } base::HistogramTester histogram_tester; @@ -2868,7 +2868,7 @@ // Upload username first flow vote on the single username form. if constexpr (!BUILDFLAG(IS_ANDROID)) { EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _)); + StartUploadRequest(IsSingleUsernameUpload(), _, _, _)); } // Upload username first flow vote on the sign-up form. @@ -2886,7 +2886,7 @@ SingleUsernameDataIs( EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Simulate showing the prompt and saving the suggested value. form_manager_->SaveSuggestedUsernameValueToVotesUploader(); @@ -2955,7 +2955,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form_))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3015,7 +3015,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form_))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3062,7 +3062,7 @@ crowdsourcing_manager(), StartUploadRequest( IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _, - _, _)) + _)) .Times(0); // Expect upload for the password form. This upload is unrelated to UFF: it @@ -3070,7 +3070,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form_))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3126,7 +3126,7 @@ // Upload username first flow vote on the single username form. if constexpr (!BUILDFLAG(IS_ANDROID)) { EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(IsSingleUsernameUpload(), _, _, _, _)); + StartUploadRequest(IsSingleUsernameUpload(), _, _, _)); } // Upload username first flow vote on the sign-up form. @@ -3144,7 +3144,7 @@ SingleUsernameDataIs( EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Simulate showing the prompt and saving the suggested value. form_manager_->SaveSuggestedUsernameValueToVotesUploader(); @@ -3246,7 +3246,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3369,7 +3369,7 @@ FieldsContain(AllOf(FieldSignatureIs(kUsernameFieldSignature), FieldAutofillTypeIs({FieldType::NOT_USERNAME})))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); } else { EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest).Times(0); } @@ -3389,7 +3389,7 @@ SingleUsernameDataIs( EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); base::HistogramTester histogram_tester; form_manager_->Save(); @@ -3438,7 +3438,7 @@ crowdsourcing_manager(), StartUploadRequest( IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _, - _, _)) + _)) .Times(0); // Upload single username data for the password form. @@ -3450,7 +3450,7 @@ SingleUsernameDataIs( EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); form_manager_->Save(); } @@ -3869,7 +3869,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3921,7 +3921,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -3967,7 +3967,7 @@ EXPECT_CALL( crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs(kOtherFormSignature)), - _, _, _, _)) + _, _, _)) .Times(0); // Expect upload for the password form. This upload is unrelated to FPF: it @@ -3975,7 +3975,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); } @@ -4028,7 +4028,7 @@ EXPECT_CALL( crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs(kOtherFormSignature)), - _, _, _, _)) + _, _, _)) .Times(0); // Expect upload for the password form. This upload is unrelated to FPF: it @@ -4036,7 +4036,7 @@ EXPECT_CALL(crowdsourcing_manager(), StartUploadRequest(IsPasswordUpload(FormSignatureIs( CalculateFormSignature(submitted_form))), - _, _, _, _)); + _, _, _)); form_manager_->Save(); }
diff --git a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc index 331fd8cb..2355fa2 100644 --- a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc +++ b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
@@ -990,7 +990,7 @@ auto upload_contents_matcher = IsPasswordUpload(FieldsContain( UploadFieldIs(submitted_form.fields[0], FieldType::PASSWORD))); EXPECT_CALL(*mock_autofill_crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Check that the password which was chosen by the user is saved. PasswordForm saved_form; @@ -1336,14 +1336,14 @@ auto upload_contents_matcher = IsPasswordUpload(FieldsContain(UploadFieldIs( submitted_form_.fields[kPasswordFieldIndex], FieldType::PASSWORD))); EXPECT_CALL(*mock_autofill_crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); // Check that a correction vote is sent for the earlier saved form. upload_contents_matcher = IsPasswordUpload(FieldsContain( UploadFieldIs(field1, FieldType::USERNAME), UploadFieldIs(field3, FieldType::ACCOUNT_CREATION_PASSWORD))); EXPECT_CALL(*mock_autofill_crowdsourcing_manager(), - StartUploadRequest(upload_contents_matcher, _, _, _, _)); + StartUploadRequest(upload_contents_matcher, _, _, _)); password_save_manager_impl()->Save(&observed_form_, parsed_submitted_form); }
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc index 3d12b33..9b874080 100644 --- a/components/password_manager/core/browser/votes_uploader.cc +++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -5,6 +5,7 @@ #include "components/password_manager/core/browser/votes_uploader.h" #include <iostream> +#include <optional> #include <string> #include <utility> @@ -306,6 +307,29 @@ }); } +// Encode password attributes and length into `upload`. +void EncodePasswordAttributesMetadata( + const PasswordAttributesMetadata& password_attributes, + AutofillUploadContents& upload) { + switch (password_attributes.password_attributes_vote.first) { + case autofill::PasswordAttribute::kHasLetter: + upload.set_password_has_letter( + password_attributes.password_attributes_vote.second); + break; + case autofill::PasswordAttribute::kHasSpecialSymbol: + upload.set_password_has_special_symbol( + password_attributes.password_attributes_vote.second); + if (password_attributes.password_attributes_vote.second) { + upload.set_password_special_symbol( + password_attributes.password_symbol_vote); + } + break; + case autofill::PasswordAttribute::kPasswordAttributesCount: + NOTREACHED(); + } + upload.set_password_length(password_attributes.password_length_vote); +} + } // namespace SingleUsernameVoteData::SingleUsernameVoteData() @@ -441,7 +465,9 @@ return false; } - if (!client_->GetAutofillCrowdsourcingManager()) { + AutofillCrowdsourcingManager* crowdsourcing_manager = + client_->GetAutofillCrowdsourcingManager(); + if (!crowdsourcing_manager) { return false; } @@ -451,6 +477,13 @@ FormStructure form_structure(form_to_upload.form_data); form_structure.set_submission_event(submitted_form.submission_event); + // Annotate the form with the source language of the page. + form_structure.set_current_page_language(client_->GetPageLanguage()); + + // Attach the Randomized Encoder. + form_structure.set_randomized_encoder( + RandomizedEncoder::Create(client_->GetPrefs())); + FieldTypeSet available_field_types; // A map from field names to field types. FieldTypeMap field_types; @@ -458,6 +491,8 @@ // names. bool field_name_collision = false; auto username_vote_type = AutofillUploadContents::Field::NO_INFORMATION; + bool should_set_passwords_were_revealed = false; + std::optional<PasswordAttributesMetadata> password_attributes; if (autofill_type != autofill::USERNAME) { if (has_autofill_vote) { bool is_update = autofill_type == autofill::NEW_PASSWORD || @@ -481,8 +516,7 @@ SetFieldType(submitted_form.confirmation_password_element_renderer_id, autofill::CONFIRMATION_PASSWORD, field_types, field_name_collision); - form_structure.set_passwords_were_revealed( - has_passwords_revealed_vote_); + should_set_passwords_were_revealed = true; } // If a user accepts a save or update prompt, send a single username vote. if (autofill_type == autofill::PASSWORD || @@ -522,10 +556,10 @@ // The password attributes should be uploaded only on the first save or an // update. DCHECK_EQ(form_to_upload.times_used_in_html_form, 0); - GeneratePasswordAttributesVote(autofill_type == autofill::PASSWORD - ? form_to_upload.password_value - : form_to_upload.new_password_value, - &form_structure); + password_attributes = GeneratePasswordAttributesMetadata( + autofill_type == autofill::PASSWORD + ? form_to_upload.password_value + : form_to_upload.new_password_value); } } else { // User overwrites username. SetFieldType(form_to_upload.username_element_renderer_id, @@ -542,13 +576,26 @@ if (password_manager_util::IsLoggingActive(client_)) { BrowserSavePasswordProgressLogger logger(client_->GetLogManager()); - logger.LogFormStructure(Logger::STRING_PASSWORD_FORM_VOTE, form_structure); + logger.LogFormStructure(Logger::STRING_PASSWORD_FORM_VOTE, form_structure, + password_attributes); } - // Annotate the form with the source language of the page. - form_structure.set_current_page_language(client_->GetPageLanguage()); - return StartUploadRequest(form_structure, available_field_types, - login_form_signature); + std::vector<AutofillUploadContents> upload_contents = + form_structure.EncodeUploadRequest( + available_field_types, /*form_was_autofilled=*/false, + login_form_signature, /*observed_submission=*/true); + CHECK(!upload_contents.empty()); + upload_contents[0].set_passwords_revealed( + should_set_passwords_were_revealed && has_passwords_revealed_vote_); + + if (password_attributes) { + EncodePasswordAttributesMetadata(*password_attributes, upload_contents[0]); + } + + return crowdsourcing_manager->StartUploadRequest( + std::move(upload_contents), form_structure.submission_source(), + form_structure.active_field_count(), /* prefs=*/nullptr, + /*observer=*/nullptr); } // TODO(crbug.com/840384): Share common code with UploadPasswordVote. @@ -596,7 +643,8 @@ if (password_manager_util::IsLoggingActive(client_)) { BrowserSavePasswordProgressLogger logger(client_->GetLogManager()); - logger.LogFormStructure(Logger::STRING_FIRSTUSE_FORM_VOTE, form_structure); + logger.LogFormStructure(Logger::STRING_FIRSTUSE_FORM_VOTE, form_structure, + std::nullopt); } StartUploadRequest(form_structure, available_field_types); @@ -821,13 +869,13 @@ return false; } -void VotesUploader::GeneratePasswordAttributesVote( - const std::u16string& password_value, - FormStructure* form_structure) { +std::optional<PasswordAttributesMetadata> +VotesUploader::GeneratePasswordAttributesMetadata( + const std::u16string& password_value) { if (password_value.empty()) { - NOTREACHED() << "GeneratePasswordAttributesVote cannot take an empty " - "password value."; - return; + NOTREACHED_NORETURN() + << "GeneratePasswordAttributesMetadata cannot take an empty " + "password value."; } // Don't crowdsource password attributes for non-ascii passwords. @@ -835,7 +883,7 @@ if (!(password_manager_util::IsLetter(e) || password_manager_util::IsNumeric(e) || password_manager_util::IsSpecialSymbol(e))) { - return; + return std::nullopt; } } @@ -858,23 +906,24 @@ bool randomized_value_for_character_class = respond_randomly ? base::RandGenerator(2) : base::ranges::any_of(password_value, predicate); - form_structure->set_password_attributes_vote(std::make_pair( - character_class_attribute, randomized_value_for_character_class)); + PasswordAttributesMetadata password_attributes; + password_attributes.password_attributes_vote = std::make_pair( + character_class_attribute, randomized_value_for_character_class); if (character_class_attribute == autofill::PasswordAttribute::kHasSpecialSymbol && randomized_value_for_character_class) { - form_structure->set_password_symbol_vote( + password_attributes.password_symbol_vote = respond_randomly ? GetRandomSpecialSymbol() - : GetRandomSpecialSymbolFromPassword(password_value)); + : GetRandomSpecialSymbolFromPassword(password_value); } size_t actual_length = password_value.size(); - size_t randomized_length = actual_length <= 1 || base::RandGenerator(5) == 0 - ? actual_length - : base::RandGenerator(actual_length - 1) + 1; - - form_structure->set_password_length_vote(randomized_length); + password_attributes.password_length_vote = + actual_length <= 1 || base::RandGenerator(5) == 0 + ? actual_length + : base::RandGenerator(actual_length - 1) + 1; + return password_attributes; } void VotesUploader::StoreInitialFieldValues( @@ -904,8 +953,7 @@ available_field_types, /*form_was_autofilled=*/false, login_form_signature, /*observed_submission=*/true), form_to_upload.submission_source(), form_to_upload.active_field_count(), - /*pref_service=*/nullptr, - /*observer=*/nullptr); + /*pref_service=*/nullptr); } bool VotesUploader::SetSingleUsernameVoteOnUsernameForm( @@ -1081,7 +1129,7 @@ if (password_manager_util::IsLoggingActive(client_)) { BrowserSavePasswordProgressLogger logger(client_->GetLogManager()); logger.LogFormStructure(Logger::STRING_USERNAME_FIRST_FLOW_VOTE, - *form_to_upload); + *form_to_upload, std::nullopt); } if (StartUploadRequest(*form_to_upload, available_field_types)) {
diff --git a/components/password_manager/core/browser/votes_uploader.h b/components/password_manager/core/browser/votes_uploader.h index 5b84432..8fe2545 100644 --- a/components/password_manager/core/browser/votes_uploader.h +++ b/components/password_manager/core/browser/votes_uploader.h
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "components/autofill/core/common/unique_ids.h" @@ -83,6 +84,21 @@ bool is_form_overrule; }; +struct PasswordAttributesMetadata { + // The vote about password attributes (e.g. whether the password has a + // numeric character). + std::pair<autofill::PasswordAttribute, bool> password_attributes_vote; + + // If `password_attribute_vote` contains (kHasSpecialSymbol, true), this + // field contains noisified information about a special symbol in a + // user-created password stored as ASCII code. The default value of 0 + // indicates that no symbol was set. + int password_symbol_vote = 0; + + // Noisified password length for crowdsourcing. + int password_length_vote = 0; +}; + // This class manages vote uploads for password forms. class VotesUploader { public: @@ -161,10 +177,10 @@ const std::u16string& username, const std::u16string& password); - // Generates a password attributes vote based on |password_value| and saves it - // to |form_structure|. Declared as public for testing. - void GeneratePasswordAttributesVote(const std::u16string& password_value, - autofill::FormStructure* form_structure); + // Returns a password attributes vote based on `password_value` . Declared as + // public for testing. + std::optional<PasswordAttributesMetadata> GeneratePasswordAttributesMetadata( + const std::u16string& password_value); // Stores the |unique_renderer_id| and |values| of the fields in // |observed_form| to |initial_field_values_|. @@ -222,6 +238,7 @@ username_change_state_ = username_change_state; } + bool passwords_revealed_vote() const { return has_passwords_revealed_vote_; } void set_has_passwords_revealed_vote(bool has_passwords_revealed_vote) { has_passwords_revealed_vote_ = has_passwords_revealed_vote; } @@ -371,10 +388,10 @@ UsernameChangeState username_change_state_ = UsernameChangeState::kUnchanged; // If the user typed username that doesn't match any saved credentials, but - // matches an entry from |all_alternative_usernames| of a saved credential, - // |username_correction_vote_| stores the credential with matched username. - // The matched credential is copied to |username_correction_vote_|, but - // |username_correction_vote_.username_element| is set to the name of the + // matches an entry from `all_alternative_usernames` of a saved credential, + // `username_correction_vote_` stores the credential with matched username. + // The matched credential is copied to `username_correction_vote_`, but + // `username_correction_vote_.username_element` is set to the name of the // field where the matched username was found. std::optional<PasswordForm> username_correction_vote_;
diff --git a/components/password_manager/core/browser/votes_uploader_unittest.cc b/components/password_manager/core/browser/votes_uploader_unittest.cc index f46631c..3bca2724 100644 --- a/components/password_manager/core/browser/votes_uploader_unittest.cc +++ b/components/password_manager/core/browser/votes_uploader_unittest.cc
@@ -52,7 +52,9 @@ using ::autofill::upload_contents_matchers::FieldsContain; using ::autofill::upload_contents_matchers::FieldSignatureIs; using ::autofill::upload_contents_matchers::FormSignatureIs; +using ::autofill::upload_contents_matchers::HasPasswordAttribute; using ::autofill::upload_contents_matchers::ObservedSubmissionIs; +using ::autofill::upload_contents_matchers::PasswordLengthIsPositive; using ::autofill::upload_contents_matchers::SubmissionIndicatorEventIs; using ::testing::_; using ::testing::AllOf; @@ -183,6 +185,7 @@ auto upload_contents_matcher = IsPasswordUpload( FormSignatureIs(CalculateFormSignature(form_to_upload_.form_data)), + PasswordLengthIsPositive(), HasPasswordAttribute(), SubmissionIndicatorEventIs( SubmissionIndicatorEvent::HTML_FORM_SUBMISSION), LoginFormSignatureIs(login_form_signature_), @@ -190,8 +193,7 @@ UploadField(11, FieldType::CONFIRMATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::NEW_PASSWORD, login_form_signature_)); @@ -210,6 +212,7 @@ auto upload_contents_matcher = IsPasswordUpload( FormSignatureIs(CalculateFormSignature(form_to_upload_.form_data)), + PasswordLengthIsPositive(), HasPasswordAttribute(), SubmissionIndicatorEventIs( SubmissionIndicatorEvent::HTML_FORM_SUBMISSION), LoginFormSignatureIs(login_form_signature_), @@ -217,8 +220,7 @@ UploadField(12, FieldType::CONFIRMATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::PASSWORD, login_form_signature_)); @@ -241,8 +243,7 @@ UploadField(5, FieldType::ACCOUNT_CREATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::USERNAME, login_form_signature_)); @@ -282,8 +283,7 @@ 6, FieldType::USERNAME, FieldVoteTypeIs(Field::USERNAME_OVERWRITTEN)))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())) + /*pref_service=*/IsNull())) .After(first_call); votes_uploader.SendVotesOnSave(form_to_upload_.form_data, submitted_form_, matches, &form_to_upload_); @@ -307,8 +307,7 @@ UploadField(5, FieldType::ACCOUNT_CREATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::ACCOUNT_CREATION_PASSWORD, login_form_signature_)); @@ -335,8 +334,7 @@ 6, FieldType::USERNAME, FieldVoteTypeIs(Field::CREDENTIALS_REUSED)))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.SendVoteOnCredentialsReuse(form_to_upload_.form_data, submitted_form_, &pending); } @@ -362,8 +360,7 @@ UploadField(5, FieldType::PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::PASSWORD, login_form_signature_)); @@ -394,8 +391,7 @@ UploadField(5, FieldType::PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.SendVotesOnSave(form_to_upload_.form_data, submitted_form_, {}, &form_to_upload_); } @@ -474,8 +470,7 @@ : Not(HasPasswordLength())); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, autofill_type, login_form_signature_)); @@ -484,8 +479,7 @@ } } -TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote) { - VotesUploader votes_uploader(&client_, true); +TEST_F(VotesUploaderTest, GeneratePasswordAttributesMetadata) { // Checks that randomization distorts information about present and missed // character classes, but a true value is still restorable with aggregation // of many distorted reports. @@ -501,8 +495,6 @@ if (password_value.empty()) continue; - FormData form; - FormStructure form_structure(form); int reported_false[kNumberOfPasswordAttributes] = {0, 0}; int reported_true[kNumberOfPasswordAttributes] = {0, 0}; @@ -512,16 +504,18 @@ int kNumberOfRuns = 1000; for (int i = 0; i < kNumberOfRuns; ++i) { - votes_uploader.GeneratePasswordAttributesVote(password_value, - &form_structure); - std::optional<std::pair<PasswordAttribute, bool>> vote = - form_structure.get_password_attributes_vote(); - int attribute_index = static_cast<int>(vote->first); - if (vote->second) + VotesUploader votes_uploader(&client_, true); + std::optional<PasswordAttributesMetadata> password_attributes = + votes_uploader.GeneratePasswordAttributesMetadata(password_value); + std::pair<PasswordAttribute, bool> vote = + password_attributes->password_attributes_vote; + int attribute_index = static_cast<int>(vote.first); + if (vote.second) { reported_true[attribute_index]++; - else + } else { reported_false[attribute_index]++; - size_t reported_length = form_structure.get_password_length_vote(); + } + size_t reported_length = password_attributes->password_length_vote; if (reported_length == password_value.size()) { reported_actual_length++; } else { @@ -553,38 +547,34 @@ } TEST_F(VotesUploaderTest, GeneratePasswordSpecialSymbolVote) { - VotesUploader votes_uploader(&client_, true); const std::u16string password_value = u"password-withsymbols!"; const int kNumberOfRuns = 2000; const int kSpecialSymbolsAttribute = static_cast<int>(PasswordAttribute::kHasSpecialSymbol); - FormData form; - int correct_symbol_reported = 0; int wrong_symbol_reported = 0; int number_of_symbol_votes = 0; for (int i = 0; i < kNumberOfRuns; ++i) { - FormStructure form_structure(form); - - votes_uploader.GeneratePasswordAttributesVote(password_value, - &form_structure); - std::optional<std::pair<PasswordAttribute, bool>> vote = - form_structure.get_password_attributes_vote(); + VotesUploader votes_uploader(&client_, true); + std::optional<PasswordAttributesMetadata> password_attributes = + votes_uploader.GeneratePasswordAttributesMetadata(password_value); + std::pair<PasswordAttribute, bool> vote = + password_attributes->password_attributes_vote; // Continue if the vote is not about special symbols or implies that no // special symbols are used. - if (static_cast<int>(vote->first) != kSpecialSymbolsAttribute || - !vote->second) { - EXPECT_EQ(form_structure.get_password_symbol_vote(), 0); + if (static_cast<int>(vote.first) != kSpecialSymbolsAttribute || + !vote.second) { + EXPECT_EQ(password_attributes->password_symbol_vote, 0); continue; } number_of_symbol_votes += 1; - int symbol = form_structure.get_password_symbol_vote(); + int symbol = password_attributes->password_symbol_vote; if (symbol == '-' || symbol == '!') correct_symbol_reported += 1; else @@ -594,48 +584,40 @@ EXPECT_LT(0.15 * number_of_symbol_votes, wrong_symbol_reported); } -TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_OneCharacterPassword) { - // |VotesUploader::GeneratePasswordAttributesVote| shouldn't crash if a +TEST_F(VotesUploaderTest, + GeneratePasswordAttributesMetadata_OneCharacterPassword) { + // `VotesUploader::GeneratePasswordAttributesMetadata` shouldn't crash if a // password has only one character. - FormData form; - FormStructure form_structure(form); VotesUploader votes_uploader(&client_, true); - votes_uploader.GeneratePasswordAttributesVote(u"1", &form_structure); - std::optional<std::pair<PasswordAttribute, bool>> vote = - form_structure.get_password_attributes_vote(); - EXPECT_TRUE(vote.has_value()); - size_t reported_length = form_structure.get_password_length_vote(); + std::optional<PasswordAttributesMetadata> password_attributes = + votes_uploader.GeneratePasswordAttributesMetadata(u"1"); + EXPECT_TRUE(password_attributes.has_value()); + + size_t reported_length = password_attributes->password_length_vote; EXPECT_EQ(1u, reported_length); } -TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_AllAsciiCharacters) { - FormData form; - FormStructure form_structure(form); +TEST_F(VotesUploaderTest, + GeneratePasswordAttributesMetadata_AllAsciiCharacters) { VotesUploader votes_uploader(&client_, true); - votes_uploader.GeneratePasswordAttributesVote( - u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr" - u"stuvwxyz!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - &form_structure); - std::optional<std::pair<PasswordAttribute, bool>> vote = - form_structure.get_password_attributes_vote(); - EXPECT_TRUE(vote.has_value()); + std::optional<PasswordAttributesMetadata> password_attributes = + votes_uploader.GeneratePasswordAttributesMetadata( + u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr" + u"stuvwxyz!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"); + EXPECT_TRUE(password_attributes.has_value()); } -TEST_F(VotesUploaderTest, GeneratePasswordAttributesVote_NonAsciiPassword) { +TEST_F(VotesUploaderTest, GeneratePasswordAttributesMetadata_NonAsciiPassword) { // Checks that password attributes vote is not generated if the password has // non-ascii characters. for (const auto* password : {u"пароль1", u"パスワード", u"münchen", u"סיסמה-A", u"Σ-12345", u"գաղտնաբառըTTT", u"Slaptažodis", u"密碼", u"كلمهالسر", u"mậtkhẩu!", u"ລະຫັດຜ່ານ-l", u"စကားဝှက်ကို3", u"პაროლი", u"पारण शब्द"}) { - FormData form; - FormStructure form_structure(form); VotesUploader votes_uploader(&client_, true); - votes_uploader.GeneratePasswordAttributesVote(password, &form_structure); - std::optional<std::pair<PasswordAttribute, bool>> vote = - form_structure.get_password_attributes_vote(); - - EXPECT_FALSE(vote.has_value()) << password; + std::optional<PasswordAttributesMetadata> password_attributes = + votes_uploader.GeneratePasswordAttributesMetadata(password); + EXPECT_FALSE(password_attributes.has_value()) << password; } } @@ -690,8 +672,7 @@ FieldType::SINGLE_USERNAME, Field::WEAK))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -732,8 +713,7 @@ FieldType::NOT_USERNAME, Field::STRONG))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -754,8 +734,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, FieldType::PASSWORD, std::string()); } @@ -787,8 +766,7 @@ FieldType::SINGLE_USERNAME, Field::WEAK))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -807,8 +785,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -841,8 +818,7 @@ FieldType::NOT_USERNAME, Field::WEAK))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -860,8 +836,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -895,8 +870,7 @@ FieldType::SINGLE_USERNAME, Field::STRONG))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -914,8 +888,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -947,8 +920,7 @@ FieldType::NOT_USERNAME, Field::STRONG))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); } else { EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest) .Times(0); @@ -966,8 +938,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -997,7 +968,7 @@ mock_autofill_crowdsourcing_manager_, StartUploadRequest( IsPasswordUpload(FormSignatureIs(kSingleUsernameFormSignature)), _, _, - _, _)) + _)) .Times(0); votes_uploader.MaybeSendSingleUsernameVotes(); @@ -1012,8 +983,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -1047,8 +1017,7 @@ EqualsSingleUsernameDataVector({expected_single_username_data}))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); votes_uploader.UploadPasswordVote(submitted_form_, submitted_form_, autofill::PASSWORD, std::string()); } @@ -1076,8 +1045,7 @@ UploadField(11, FieldType::CONFIRMATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); base::HistogramTester histogram_tester; EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::PASSWORD, @@ -1105,8 +1073,7 @@ UploadField(12, FieldType::CONFIRMATION_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); base::HistogramTester histogram_tester; EXPECT_TRUE(votes_uploader.UploadPasswordVote( form_to_upload_, submitted_form_, FieldType::PASSWORD, @@ -1136,8 +1103,7 @@ Field::WEAK_FORGOT_PASSWORD))); EXPECT_CALL(mock_autofill_crowdsourcing_manager_, StartUploadRequest(upload_contents_matcher, _, _, - /*pref_service=*/IsNull(), - /*observer=*/IsNull())); + /*pref_service=*/IsNull())); base::HistogramTester histogram_tester; votes_uploader.MaybeSendSingleUsernameVotes();
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java index 0752d42..bbc5f68a 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
@@ -201,18 +201,13 @@ } } - /** - * Records that the Payment Request was not shown to the user and for what reason. - * - * @param reason An int indicating why the payment request was not shown. - */ - public void setNotShown(int reason) { - assert reason < NotShownReason.MAX; + /** Records that the Payment Request was not shown to the user. */ + public void setNotShown() { assert !mHasRecorded; if (!mHasRecorded) { mHasRecorded = true; - JourneyLoggerJni.get().setNotShown(mJourneyLoggerAndroid, JourneyLogger.this, reason); + JourneyLoggerJni.get().setNotShown(mJourneyLoggerAndroid, JourneyLogger.this); } } @@ -292,7 +287,7 @@ void setAborted(long nativeJourneyLoggerAndroid, JourneyLogger caller, int reason); - void setNotShown(long nativeJourneyLoggerAndroid, JourneyLogger caller, int reason); + void setNotShown(long nativeJourneyLoggerAndroid, JourneyLogger caller); void setNoMatchingCredentialsShown(long nativeJourneyLoggerAndroid, JourneyLogger caller);
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java index e798e7b3..84970eeca 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentNotShownError.java
@@ -8,32 +8,23 @@ /** The error of payment UIs not being shown. */ public class PaymentNotShownError { - private final int mNotShownReason; private final String mErrorMessage; private final int mReason; /** * Creates an instance with the error details. - * @param notShownReason The reason of not showing UI, defined in {@link NotShownReason}. + * * @param errorMessage The error message for informing the web developer. * @param paymentErrorReason The reason of the payment error, defined in {@link - * PaymentErrorReason}. + * PaymentErrorReason}. */ - /* package */ PaymentNotShownError( - int notShownReason, String errorMessage, int paymentErrorReason) { - assert notShownReason <= NotShownReason.MAX; + /* package */ PaymentNotShownError(String errorMessage, int paymentErrorReason) { assert paymentErrorReason >= PaymentErrorReason.MIN_VALUE; assert paymentErrorReason <= PaymentErrorReason.MAX_VALUE; - mNotShownReason = notShownReason; mErrorMessage = errorMessage; mReason = paymentErrorReason; } - /** @return The reason of not showing UI, defined in {@link NotShownReason}. */ - public int getNotShownReason() { - return mNotShownReason; - } - /** @return The error message for informing the web developer. */ public String getErrorMessage() { return mErrorMessage;
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java index 3d66d40..73162b5 100644 --- a/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java +++ b/components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java
@@ -976,15 +976,13 @@ mBrowserPaymentRequest.showOrSkipAppSelector( mIsShowWaitingForUpdatedDetails, mSpec.getRawTotal(), shouldSkip); if (showError != null) { - return new PaymentNotShownError( - NotShownReason.OTHER, showError, PaymentErrorReason.NOT_SUPPORTED); + return new PaymentNotShownError(showError, PaymentErrorReason.NOT_SUPPORTED); } if (mIsShowWaitingForUpdatedDetails) return null; String error = onShowCalledAndAppsQueriedAndDetailsFinalized(); if (error != null) { - return new PaymentNotShownError( - NotShownReason.OTHER, error, PaymentErrorReason.NOT_SUPPORTED); + return new PaymentNotShownError(error, PaymentErrorReason.NOT_SUPPORTED); } return null; @@ -1079,18 +1077,16 @@ } private void onShowFailed(String error) { - onShowFailed(NotShownReason.OTHER, error, PaymentErrorReason.USER_CANCEL); + onShowFailed(error, PaymentErrorReason.USER_CANCEL); } private void onShowFailed(PaymentNotShownError error) { - onShowFailed( - error.getNotShownReason(), error.getErrorMessage(), error.getPaymentErrorReason()); + onShowFailed(error.getErrorMessage(), error.getPaymentErrorReason()); } - // notShowReason is defined in NotShownReason. // paymentErrorReason is defined in PaymentErrorReason. - private void onShowFailed(int notShowReason, String error, int paymentErrorReason) { - mJourneyLogger.setNotShown(notShowReason); + private void onShowFailed(String error, int paymentErrorReason) { + mJourneyLogger.setNotShown(); disconnectFromClientWithDebugMessage(error, paymentErrorReason); if (sObserverForTest != null) sObserverForTest.onPaymentRequestServiceShowFailed(); } @@ -1107,10 +1103,6 @@ // All factories have responded, but none of them have apps. It's possible to add credit // cards, but the merchant does not support them either. The payment request must be // rejected. - int notShowReason = - mCanMakePayment - ? NotShownReason.NO_MATCHING_PAYMENT_METHOD - : NotShownReason.NO_SUPPORTED_PAYMENT_METHOD; String debugMessage; int paymentErrorReason; if (mDelegate.isOffTheRecord()) { @@ -1135,7 +1127,7 @@ : " " + mRejectShowErrorMessage); paymentErrorReason = PaymentErrorReason.NOT_SUPPORTED; } - return new PaymentNotShownError(notShowReason, debugMessage, paymentErrorReason); + return new PaymentNotShownError(debugMessage, paymentErrorReason); } return null; } @@ -1321,7 +1313,6 @@ // one. Only the first one will be shown. This also prevents multiple tabs and windows // from showing PaymentRequest UI at the same time. onShowFailed( - NotShownReason.CONCURRENT_REQUESTS, ErrorStrings.ANOTHER_UI_SHOWING, PaymentErrorReason.ALREADY_SHOWING); return; @@ -1334,7 +1325,6 @@ // page. mRejectShowForUserActivation = true; onShowFailed( - NotShownReason.OTHER, ErrorStrings.CANNOT_SHOW_WITHOUT_USER_ACTIVATION, PaymentErrorReason.USER_ACTIVATION_REQUIRED); return;
diff --git a/components/payments/content/android/journey_logger_android.cc b/components/payments/content/android/journey_logger_android.cc index 025ff6c..ced68d6 100644 --- a/components/payments/content/android/journey_logger_android.cc +++ b/components/payments/content/android/journey_logger_android.cc
@@ -160,12 +160,8 @@ void JourneyLoggerAndroid::SetNotShown( JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller, - jint jreason) { - DCHECK_GE(jreason, 0); - DCHECK_LT(jreason, JourneyLogger::NotShownReason::NOT_SHOWN_REASON_MAX); - journey_logger_.SetNotShown( - static_cast<JourneyLogger::NotShownReason>(jreason)); + const base::android::JavaParamRef<jobject>& jcaller) { + journey_logger_.SetNotShown(); } void JourneyLoggerAndroid::SetNoMatchingCredentialsShown(
diff --git a/components/payments/content/android/journey_logger_android.h b/components/payments/content/android/journey_logger_android.h index bba1afa..850a492 100644 --- a/components/payments/content/android/journey_logger_android.h +++ b/components/payments/content/android/journey_logger_android.h
@@ -76,8 +76,7 @@ const base::android::JavaParamRef<jobject>& jcaller, jint jreason); void SetNotShown(JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller, - jint jreason); + const base::android::JavaParamRef<jobject>& jcaller); void SetNoMatchingCredentialsShown( JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller);
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index f21b47d7..7221e48b 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -294,8 +294,7 @@ log_.Error(errors::kAnotherUiShowing); DCHECK(!has_recorded_completion_); has_recorded_completion_ = true; - journey_logger_.SetNotShown( - JourneyLogger::NOT_SHOWN_REASON_CONCURRENT_REQUESTS); + journey_logger_.SetNotShown(); client_->OnError(mojom::PaymentErrorReason::ALREADY_SHOWING, errors::kAnotherUiShowing); ResetAndDeleteThis(); @@ -310,7 +309,7 @@ log_.Error(errors::kCannotShowWithoutUserActivation); DCHECK(!has_recorded_completion_); has_recorded_completion_ = true; - journey_logger_.SetNotShown(JourneyLogger::NOT_SHOWN_REASON_OTHER); + journey_logger_.SetNotShown(); client_->OnError(mojom::PaymentErrorReason::USER_ACTIVATION_REQUIRED, errors::kCannotShowWithoutUserActivation); ResetAndDeleteThis(); @@ -325,7 +324,7 @@ log_.Error(errors::kCannotShowInBackgroundTab); DCHECK(!has_recorded_completion_); has_recorded_completion_ = true; - journey_logger_.SetNotShown(JourneyLogger::NOT_SHOWN_REASON_OTHER); + journey_logger_.SetNotShown(); client_->OnError(mojom::PaymentErrorReason::USER_CANCEL, errors::kCannotShowInBackgroundTab); ResetAndDeleteThis(); @@ -684,8 +683,7 @@ << "): requested method not supported."; DCHECK(!has_recorded_completion_); has_recorded_completion_ = true; - journey_logger_.SetNotShown( - JourneyLogger::NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD); + journey_logger_.SetNotShown(); client_->OnError(mojom::PaymentErrorReason::NOT_SUPPORTED, GetNotSupportedErrorMessage( spec_ ? spec_->payment_method_identifiers_set()
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc index 8acf469..113ea9a 100644 --- a/components/payments/core/journey_logger.cc +++ b/components/payments/core/journey_logger.cc
@@ -290,7 +290,7 @@ RecordJourneyStatsHistograms(COMPLETION_STATUS_OTHER_ABORTED); } -void JourneyLogger::SetNotShown(NotShownReason reason) { +void JourneyLogger::SetNotShown() { DCHECK(!WasPaymentRequestTriggered()); RecordJourneyStatsHistograms(COMPLETION_STATUS_COULD_NOT_SHOW); }
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h index b89652c1..6055b46 100644 --- a/components/payments/core/journey_logger.h +++ b/components/payments/core/journey_logger.h
@@ -208,17 +208,6 @@ ABORT_REASON_MAX, }; - // The reason why the Payment Request was not shown to the user. - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.payments - // GENERATED_JAVA_CLASS_NAME_OVERRIDE: NotShownReason - enum NotShownReason { - NOT_SHOWN_REASON_NO_MATCHING_PAYMENT_METHOD = 0, - NOT_SHOWN_REASON_NO_SUPPORTED_PAYMENT_METHOD = 1, - NOT_SHOWN_REASON_CONCURRENT_REQUESTS = 2, - NOT_SHOWN_REASON_OTHER = 3, - NOT_SHOWN_REASON_MAX = 4, - }; - // The categories of the payment methods. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.payments // GENERATED_JAVA_CLASS_NAME_OVERRIDE: PaymentMethodCategory @@ -324,9 +313,8 @@ // starting the logging of all the journey metrics. void SetAborted(AbortReason reason); - // Records that the Payment Request was not shown to the user, along with the - // reason. - void SetNotShown(NotShownReason reason); + // Records that the Payment Request was not shown to the user. + void SetNotShown(); // Records that the SPC No Matching Credentials UX was shown to the user. void SetNoMatchingCredentialsShown();
diff --git a/components/permissions_strings.grdp b/components/permissions_strings.grdp index 54778c8..6a69b78 100644 --- a/components/permissions_strings.grdp +++ b/components/permissions_strings.grdp
@@ -343,7 +343,7 @@ </if> <if expr="is_chromeos"> <message name="IDS_SMART_CARD_PERMISSION_PROMPT" desc="Text on dialog that asks the user for permission to access a smart card reader device and the card inserted in it (or presented to it, if contactless)."> - Control <ph name="ReaderName">$1<ex>HID Omnikey</ex></ph> and gain access to the smart card accessible to it? + Control <ph name="ReaderName">$1<ex>HID Omnikey</ex></ph> and gain access to the smart card accessible to it. </message> <message name="IDS_SMART_CARD_PERMISSION_ALWAYS_ALLOW" desc="Label on button to always allow access to this smart card reader and any card inserted in (or presented to) it."> Always allow, with any card
diff --git a/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1 b/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1 index b504d85e..1456bb26 100644 --- a/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1 +++ b/components/permissions_strings_grdp/IDS_SMART_CARD_PERMISSION_PROMPT.png.sha1
@@ -1 +1 @@ -867df8149907fdd937ec80f6c78f9becec1071c5 \ No newline at end of file +c7a637c5aea552ca968ce1e2feacc875119585dd \ No newline at end of file
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.cc b/components/privacy_sandbox/tracking_protection_onboarding.cc index ac06659..ccf8c83 100644 --- a/components/privacy_sandbox/tracking_protection_onboarding.cc +++ b/components/privacy_sandbox/tracking_protection_onboarding.cc
@@ -310,7 +310,8 @@ static_cast<int>(ToInternalAckAction(action))); } -void MaybeSetStartAndEndSurveyTime(PrefService* pref_service) { +void MaybeSetStartAndEndSurveyTime(PrefService* pref_service, + bool is_silent_onboarding_enabled) { if (pref_service->HasPrefPath( prefs::kTrackingProtectionSentimentSurveyStartTime)) { return; @@ -319,15 +320,30 @@ auto group = GetSurveyGroup(pref_service); // Setting the start and end time when applicable. // First, start by determining the anchor time. Control should be the first - // time this function runs. Treatment should be when the notice was acked. - // If the anchor time isn't year ready, return early. + // time this function runs (unless silent onbaording is enabled, in which + // case, we'd wait for the profile to get silentl Onboarded). Treatment should + // be when the notice was acked. If the anchor time isn't year ready, return + // early. base::Time anchor_time; switch (group) { case SentimentSurveyGroup::kNotSet: return; case SentimentSurveyGroup::kControlImmediate: case SentimentSurveyGroup::kControlDelayed: - anchor_time = base::Time::Now(); + // If Silent Onboarding is enabled, we use the Onboarding time to + // determine when the survey anchor time (Used to calculate the survey + // start and end time). If it is not enabled, we use "Now" as the anchor + // time. + if (is_silent_onboarding_enabled) { + if (!pref_service->HasPrefPath( + prefs::kTrackingProtectionSilentOnboardedSince)) { + return; + } + anchor_time = pref_service->GetTime( + prefs::kTrackingProtectionSilentOnboardedSince); + } else { + anchor_time = base::Time::Now(); + } break; case SentimentSurveyGroup::kTreatmentImmediate: case SentimentSurveyGroup::kTreatmentDelayed: @@ -399,8 +415,11 @@ TrackingProtectionOnboarding::TrackingProtectionOnboarding( PrefService* pref_service, - version_info::Channel channel) - : pref_service_(pref_service), channel_(channel) { + version_info::Channel channel, + bool is_silent_onboarding_enabled) + : pref_service_(pref_service), + channel_(channel), + is_silent_onboarding_enabled_(is_silent_onboarding_enabled) { CHECK(pref_service_); pref_change_registrar_.Init(pref_service_); @@ -451,7 +470,7 @@ void TrackingProtectionOnboarding::OnOnboardingAckedChanged() const { // Maybe set the Hats start and end time now that the profile is onboarded. - MaybeSetStartAndEndSurveyTime(pref_service_); + MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_); for (auto& observer : observers_) { observer.OnShouldShowNoticeUpdated(); } @@ -569,7 +588,7 @@ pref_service_->SetInteger(prefs::kTrackingProtectionSentimentSurveyGroup, static_cast<int>(internal_group)); - MaybeSetStartAndEndSurveyTime(pref_service_); + MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_); } TrackingProtectionOnboarding::SentimentSurveyGroup @@ -683,6 +702,8 @@ static_cast<int>( TrackingProtectionOnboarding::OnboardingStatus::kOnboarded)); RecordSilentOnboardingDidNoticeShownOnboard(true); + + MaybeSetStartAndEndSurveyTime(pref_service_, is_silent_onboarding_enabled_); } void TrackingProtectionOnboarding::NoticeShown(NoticeType notice_type) {
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.h b/components/privacy_sandbox/tracking_protection_onboarding.h index db1d3501..3b5f77d 100644 --- a/components/privacy_sandbox/tracking_protection_onboarding.h +++ b/components/privacy_sandbox/tracking_protection_onboarding.h
@@ -145,7 +145,8 @@ }; TrackingProtectionOnboarding(PrefService* pref_service, - version_info::Channel channel); + version_info::Channel channel, + bool is_silent_onboarding_enabled = false); ~TrackingProtectionOnboarding() override; virtual void AddObserver(Observer* observer); @@ -242,6 +243,7 @@ raw_ptr<PrefService> pref_service_; PrefChangeRegistrar pref_change_registrar_; version_info::Channel channel_; + bool is_silent_onboarding_enabled_; }; } // namespace privacy_sandbox
diff --git a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc index 22c3474c..a6fe1680 100644 --- a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc +++ b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
@@ -713,6 +713,109 @@ 1); } +class TrackingProtectionSentimentTrackinWithSilentOnboarding + : public TrackingProtectionSentimentTracking { + public: + void SetUp() override { + tracking_protection_onboarding_service_ = + std::make_unique<TrackingProtectionOnboarding>( + prefs(), version_info::Channel::UNKNOWN, + /* is_silent_onboarding_enabled=*/true); + } +}; + +TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding, + RegistersControlBeforeOnboarding) { + // Setup + tracking_protection_onboarding()->MaybeMarkSilentEligible(); + + // Action: Register the group. + tracking_protection_onboarding()->RegisterSentimentSurveyGroup( + SentimentSurveyGroup::kControlImmediate); + + // Verification: Registration no longer required. + EXPECT_FALSE( + tracking_protection_onboarding()->RequiresSentimentSurveyGroup()); + + // Registered group not yet returned + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kNotSet); + + // Registered group Still not returned even after the survey start time, and + // before the survey end time. + task_env_.FastForwardBy(base::Minutes(3)); + + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kNotSet); +} + +TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding, + RegistersControlAfterSilentOnboarding) { + // Setup + tracking_protection_onboarding()->MaybeMarkSilentEligible(); + tracking_protection_onboarding()->SilentOnboardingNoticeShown(); + + // Needs registration + EXPECT_TRUE(tracking_protection_onboarding()->RequiresSentimentSurveyGroup()); + + // Action: Register the group. + tracking_protection_onboarding()->RegisterSentimentSurveyGroup( + SentimentSurveyGroup::kControlDelayed); + + histogram_tester_.ExpectBucketCount( + "PrivacySandbox.TrackingProtection.SentimentSurvey.Registered", + TrackingProtectionOnboarding::SentimentSurveyGroupMetrics:: + kControlDelayed, + 1); + + // Verification: Registration no longer required. + EXPECT_FALSE( + tracking_protection_onboarding()->RequiresSentimentSurveyGroup()); + + // Registered group not yet returned + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kNotSet); + + // Registered returned after the survey start time, and before the survey end + // time. + task_env_.FastForwardBy(base::Days(14)); + + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kControlDelayed); +} + +TEST_F(TrackingProtectionSentimentTrackinWithSilentOnboarding, + RegistersControlAndOnboardsLater) { + // Setup + tracking_protection_onboarding()->MaybeMarkSilentEligible(); + + // Action: Register the group. + tracking_protection_onboarding()->RegisterSentimentSurveyGroup( + SentimentSurveyGroup::kControlImmediate); + + // Verification: Registration no longer required. + EXPECT_FALSE( + tracking_protection_onboarding()->RequiresSentimentSurveyGroup()); + + // Action: Silently onboard. + tracking_protection_onboarding()->SilentOnboardingNoticeShown(); + + // Registered group still not returned after Acking the notice + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kNotSet); + + // Registered group returned after the survey start time, and before the + // survey end time. + task_env_.FastForwardBy(base::Minutes(3)); + EXPECT_EQ(tracking_protection_onboarding()->GetEligibleSurveyGroup(), + SentimentSurveyGroup::kControlImmediate); + histogram_tester_.ExpectBucketCount( + "PrivacySandbox.TrackingProtection.SentimentSurvey.Registered", + TrackingProtectionOnboarding::SentimentSurveyGroupMetrics:: + kControlImmediate, + 1); +} + class TrackingProtectionOffboardingTest : public TrackingProtectionOnboardingTest { public:
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn index e29550a..b1fc89b 100644 --- a/components/safe_browsing/content/browser/BUILD.gn +++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -26,24 +26,6 @@ ] } -source_set("client_report_util") { - sources = [ - "client_report_util.cc", - "client_report_util.h", - ] - - configs += [ "//build/config/compiler:wexit_time_destructors" ] - - deps = [ - "//base:base", - "//components/safe_browsing/core/common/proto:csd_proto", - "//components/security_interstitials/content:security_interstitial_page", - "//components/security_interstitials/core", - "//components/security_interstitials/core:unsafe_resource", - "//content/public/browser", - ] -} - # NOTE: This target is separated from :browser as # //components/safe_browsing/content/browser/triggers, which this depends on, depends # on :browser. @@ -66,7 +48,6 @@ deps = [ ":browser", - ":client_report_util", "//base", "//components/no_state_prefetch/browser", "//components/prefs", @@ -95,6 +76,8 @@ "base_ui_manager.h", "browser_url_loader_throttle.cc", "browser_url_loader_throttle.h", + "client_report_util.cc", + "client_report_util.h", "mojo_safe_browsing_impl.cc", "mojo_safe_browsing_impl.h", "safe_browsing_controller_client.cc", @@ -107,6 +90,8 @@ "threat_details_cache.h", "threat_details_history.cc", "threat_details_history.h", + "unsafe_resource_util.cc", + "unsafe_resource_util.h", "url_checker_on_sb.cc", "url_checker_on_sb.h", "web_api_handshake_checker.cc", @@ -118,7 +103,6 @@ configs += [ "//build/config/compiler:wexit_time_destructors" ] deps = [ - ":client_report_util", "//base", "//base:i18n", "//components/back_forward_cache", @@ -190,7 +174,6 @@ "//components/optimization_guide/proto:optimization_guide_proto", "//components/safe_browsing:buildflags", "//components/safe_browsing/content/browser:browser", - "//components/safe_browsing/content/browser:client_report_util", "//components/safe_browsing/core/browser:browser", "//components/safe_browsing/core/browser/db:test_database_manager", "//components/safe_browsing/core/common",
diff --git a/components/safe_browsing/content/browser/async_check_tracker.cc b/components/safe_browsing/content/browser/async_check_tracker.cc index c62bcb5..2b331f3 100644 --- a/components/safe_browsing/content/browser/async_check_tracker.cc +++ b/components/safe_browsing/content/browser/async_check_tracker.cc
@@ -5,6 +5,7 @@ #include "components/safe_browsing/content/browser/async_check_tracker.h" #include "components/safe_browsing/content/browser/base_ui_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/common/features.h" #include "content/public/browser/browser_thread.h" @@ -22,6 +23,14 @@ return AsyncCheckTracker::FromWebContents(web_contents); } +// static +bool AsyncCheckTracker::IsMainPageLoadPending( + const security_interstitials::UnsafeResource& resource) { + // TODO(crbug.com/1501194): Implement this function when + // async Safe Browsing check is enabled. + return resource.IsMainPageLoadPendingWithSyncCheck(); +} + AsyncCheckTracker::AsyncCheckTracker(content::WebContents* web_contents, scoped_refptr<BaseUIManager> ui_manager) : content::WebContentsUserData<AsyncCheckTracker>(*web_contents),
diff --git a/components/safe_browsing/content/browser/async_check_tracker.h b/components/safe_browsing/content/browser/async_check_tracker.h index 4900e3a..0d08e6c 100644 --- a/components/safe_browsing/content/browser/async_check_tracker.h +++ b/components/safe_browsing/content/browser/async_check_tracker.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "components/safe_browsing/content/browser/url_checker_on_sb.h" +#include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_user_data.h" @@ -35,6 +36,13 @@ content::WebContents* web_contents, scoped_refptr<BaseUIManager> ui_manager); + // Returns true if the main frame load is pending (i.e. the navigation has not + // yet committed). Note that a main frame hit may not be pending, eg. 1) + // client side detection happens after the load is committed, or 2) async Safe + // Browsing check is enabled. + static bool IsMainPageLoadPending( + const security_interstitials::UnsafeResource& resource); + AsyncCheckTracker(const AsyncCheckTracker&) = delete; AsyncCheckTracker& operator=(const AsyncCheckTracker&) = delete;
diff --git a/components/safe_browsing/content/browser/base_blocking_page.cc b/components/safe_browsing/content/browser/base_blocking_page.cc index eea47dd..d26e13b 100644 --- a/components/safe_browsing/content/browser/base_blocking_page.cc +++ b/components/safe_browsing/content/browser/base_blocking_page.cc
@@ -11,12 +11,13 @@ #include "base/lazy_instance.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" #include "components/safe_browsing/content/browser/safe_browsing_controller_client.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/safe_browsing_loud_error_ui.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -68,7 +69,7 @@ base::Time::NowFromSystemTime(), controller(), /* created_prior_to_navigation */ - IsMainPageLoadBlocked(unsafe_resources))) {} + IsMainPageLoadPending(unsafe_resources))) {} BaseBlockingPage::~BaseBlockingPage() {} @@ -77,7 +78,7 @@ BaseBlockingPage::CreateDefaultDisplayOptions( const UnsafeResourceList& unsafe_resources) { return BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( - IsMainPageLoadBlocked(unsafe_resources), + IsMainPageLoadPending(unsafe_resources), false, // kSafeBrowsingExtendedReportingOptInAllowed false, // is_off_the_record false, // is_extended_reporting @@ -92,12 +93,12 @@ } // static -bool BaseBlockingPage::IsMainPageLoadBlocked( +bool BaseBlockingPage::IsMainPageLoadPending( const UnsafeResourceList& unsafe_resources) { // If there is more than one unsafe resource, the main page load must not be - // blocked. Otherwise, check if the one resource is. + // pending. Otherwise, check if the one resource is. return unsafe_resources.size() == 1 && - unsafe_resources[0].IsMainPageLoadBlocked(); + AsyncCheckTracker::IsMainPageLoadPending(unsafe_resources[0]); } void BaseBlockingPage::SetThreatDetailsProceedDelayForTesting(int64_t delay) {
diff --git a/components/safe_browsing/content/browser/base_blocking_page.h b/components/safe_browsing/content/browser/base_blocking_page.h index 83328188..cdc88d4 100644 --- a/components/safe_browsing/content/browser/base_blocking_page.h +++ b/components/safe_browsing/content/browser/base_blocking_page.h
@@ -48,7 +48,7 @@ // Returns true if the passed |unsafe_resources| is blocking the load of // the main page. - static bool IsMainPageLoadBlocked(const UnsafeResourceList& unsafe_resources); + static bool IsMainPageLoadPending(const UnsafeResourceList& unsafe_resources); // SecurityInterstitialPage method: void CommandReceived(const std::string& command) override;
diff --git a/components/safe_browsing/content/browser/base_ui_manager.cc b/components/safe_browsing/content/browser/base_ui_manager.cc index 75751e04..5e0e9ee 100644 --- a/components/safe_browsing/content/browser/base_ui_manager.cc +++ b/components/safe_browsing/content/browser/base_ui_manager.cc
@@ -11,10 +11,11 @@ #include "base/functional/callback.h" #include "base/i18n/rtl.h" #include "base/memory/ptr_util.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" #include "components/safe_browsing/content/browser/base_blocking_page.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/common/features.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -157,11 +158,11 @@ bool BaseUIManager::IsAllowlisted(const UnsafeResource& resource) { NavigationEntry* entry = nullptr; if (resource.is_subresource) { - entry = GetNavigationEntryForResource(resource); + entry = unsafe_resource_util::GetNavigationEntryForResource(resource); } content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); // |web_contents| can be null after RenderFrameHost is destroyed. if (!web_contents) return false; @@ -252,7 +253,7 @@ // The tab might have been closed. If it was closed, just act as if "Don't // Proceed" had been chosen. content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); if (!web_contents) { OnBlockingPageDone(std::vector<UnsafeResource>{resource}, false /* proceed */, web_contents, @@ -288,16 +289,17 @@ // |entry| can be null if we are on a brand new tab, and a resource is added // via javascript without a navigation. - content::NavigationEntry* entry = GetNavigationEntryForResource(resource); + content::NavigationEntry* entry = + unsafe_resource_util::GetNavigationEntryForResource(resource); GURL unsafe_url = resource.url; - if (entry && !resource.IsMainPageLoadBlocked()) { + if (entry && !AsyncCheckTracker::IsMainPageLoadPending(resource)) { unsafe_url = entry->GetURL(); } - // In top-document navigation cases, we just mark the resource unsafe and - // cancel the load from here, the actual interstitial will be shown from the - // SafeBrowsingNavigationThrottle when the navigation fails. + // If the top-level navigation is still pending, we just mark the resource + // unsafe and cancel the load from here, the actual interstitial will be shown + // from the SafeBrowsingNavigationThrottle when the navigation fails. // // In other cases, the error interstitial is manually loaded here, after the // load is canceled: @@ -309,8 +311,11 @@ // - Delayed Warning Experiment: When enabled, this method is only called // after the navigation completes and a user action occurs so the throttle // cannot be used. + // - Async check: If the check is not able to complete before + // DidFinishNavigation, it won't hit the throttle. const bool load_post_commit_error_page = - !resource.IsMainPageLoadBlocked() || resource.is_delayed_warning; + !AsyncCheckTracker::IsMainPageLoadPending(resource) || + resource.is_delayed_warning; if (!load_post_commit_error_page) { AddUnsafeResource(unsafe_url, resource); } @@ -546,10 +551,11 @@ // static GURL BaseUIManager::GetMainFrameAllowlistUrlForResource( const security_interstitials::UnsafeResource& resource) { - return GetAllowlistUrl(resource.url, resource.is_subresource, - resource.is_subresource - ? GetNavigationEntryForResource(resource) - : nullptr); + return GetAllowlistUrl( + resource.url, resource.is_subresource, + resource.is_subresource + ? unsafe_resource_util::GetNavigationEntryForResource(resource) + : nullptr); } } // namespace safe_browsing
diff --git a/components/safe_browsing/content/browser/client_report_util.cc b/components/safe_browsing/content/browser/client_report_util.cc index 07626bf..c395376 100644 --- a/components/safe_browsing/content/browser/client_report_util.cc +++ b/components/safe_browsing/content/browser/client_report_util.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "components/safe_browsing/content/browser/client_report_util.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_entry.h" @@ -236,7 +236,7 @@ // |GetNavigationEntryForResource| can only be called from the UI thread. if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { content::NavigationEntry* nav_entry = - GetNavigationEntryForResource(resource); + unsafe_resource_util::GetNavigationEntryForResource(resource); if (nav_entry) { page_url = nav_entry->GetURL(); } @@ -253,7 +253,7 @@ // |GetNavigationEntryForResource| can only be called from the UI thread. if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { content::NavigationEntry* nav_entry = - GetNavigationEntryForResource(resource); + unsafe_resource_util::GetNavigationEntryForResource(resource); if (nav_entry) { referrer_url = nav_entry->GetReferrer().url; }
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc index 546e1497..5e23723 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -24,6 +24,7 @@ #include "components/safe_browsing/content/browser/client_side_detection_feature_cache.h" #include "components/safe_browsing/content/browser/client_side_detection_service.h" #include "components/safe_browsing/content/browser/client_side_phishing_model.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" #include "components/safe_browsing/content/common/safe_browsing.mojom.h" #include "components/safe_browsing/content/common/visual_utils.h" @@ -31,7 +32,7 @@ #include "components/safe_browsing/core/browser/db/database_manager.h" #include "components/safe_browsing/core/browser/sync/sync_utils.h" #include "components/safe_browsing/core/common/features.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/zoom/zoom_controller.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc index c686a02..d6bf88e2 100644 --- a/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc +++ b/components/safe_browsing/content/browser/safe_browsing_blocking_page.cc
@@ -17,6 +17,7 @@ #include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h" #include "components/safe_browsing/content/browser/threat_details.h" #include "components/safe_browsing/content/browser/triggers/trigger_manager.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/core/browser/safe_browsing_hats_delegate.h" #include "components/safe_browsing/core/browser/safe_browsing_metrics_collector.h" @@ -25,7 +26,6 @@ #include "components/safe_browsing/core/common/utils.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/controller_client.h" #include "components/security_interstitials/core/safe_browsing_loud_error_ui.h" #include "components/security_interstitials/core/unsafe_resource.h"
diff --git a/components/safe_browsing/content/browser/threat_details.cc b/components/safe_browsing/content/browser/threat_details.cc index b78bc27..40ae3ae 100644 --- a/components/safe_browsing/content/browser/threat_details.cc +++ b/components/safe_browsing/content/browser/threat_details.cc
@@ -27,17 +27,18 @@ #include "base/strings/stringprintf.h" #include "components/back_forward_cache/back_forward_cache_disable.h" #include "components/history/core/browser/history_service.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" #include "components/safe_browsing/content/browser/base_ui_manager.h" #include "components/safe_browsing/content/browser/client_report_util.h" #include "components/safe_browsing/content/browser/threat_details_cache.h" #include "components/safe_browsing/content/browser/threat_details_history.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/browser/db/hit_report.h" #include "components/safe_browsing/core/browser/referrer_chain_provider.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/proto/csd.pb.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -551,7 +552,7 @@ AddUrl(referrer_url, GURL(), std::string(), nullptr); } - if (!resource_.IsMainPageLoadBlocked()) { + if (!AsyncCheckTracker::IsMainPageLoadPending(resource_)) { // Get URLs of frames, scripts etc from the DOM. // OnReceivedThreatDOMDetails will be called when the renderer replies. // TODO(mattm): In theory, if the user proceeds through the warning DOM
diff --git a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc index 6deb657..c095429 100644 --- a/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/ad_sampler_trigger.cc
@@ -17,10 +17,10 @@ #include "components/safe_browsing/content/browser/triggers/trigger_manager.h" #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h" #include "components/safe_browsing/content/browser/triggers/trigger_util.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/core/browser/referrer_chain_provider.h" #include "components/safe_browsing/core/common/features.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h"
diff --git a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc index 548d8fd..8f5e6cb 100644 --- a/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc +++ b/components/safe_browsing/content/browser/triggers/suspicious_site_trigger.cc
@@ -13,9 +13,9 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/content/browser/triggers/trigger_manager.h" #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/content/browser/web_contents_key.h" #include "components/safe_browsing/core/browser/referrer_chain_provider.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h"
diff --git a/components/safe_browsing/content/browser/ui_manager.cc b/components/safe_browsing/content/browser/ui_manager.cc index 13fe444..5245a696 100644 --- a/components/safe_browsing/content/browser/ui_manager.cc +++ b/components/safe_browsing/content/browser/ui_manager.cc
@@ -12,15 +12,16 @@ #include "base/threading/thread_restrictions.h" #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" #include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" #include "components/safe_browsing/content/browser/client_report_util.h" #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h" #include "components/safe_browsing/content/browser/threat_details.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" #include "components/safe_browsing/core/browser/ping_manager.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" @@ -62,7 +63,7 @@ void SafeBrowsingUIManager::CreateAndSendHitReport( const UnsafeResource& resource) { WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); DCHECK(web_contents); std::unique_ptr<HitReport> hit_report = std::make_unique<HitReport>(); hit_report->malicious_url = resource.url; @@ -71,7 +72,8 @@ hit_report->threat_source = resource.threat_source; hit_report->population_id = resource.threat_metadata.population_id; - NavigationEntry* entry = GetNavigationEntryForResource(resource); + NavigationEntry* entry = + unsafe_resource_util::GetNavigationEntryForResource(resource); if (entry) { hit_report->page_url = entry->GetURL(); hit_report->referrer_url = entry->GetReferrer().url; @@ -105,7 +107,7 @@ void SafeBrowsingUIManager::CreateAndSendClientSafeBrowsingWarningShownReport( const UnsafeResource& resource) { WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); DCHECK(web_contents); std::unique_ptr<ClientSafeBrowsingReportRequest> report = std::make_unique<ClientSafeBrowsingReportRequest>(); @@ -139,7 +141,7 @@ void SafeBrowsingUIManager::StartDisplayingBlockingPage( const security_interstitials::UnsafeResource& resource) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); if (!web_contents) { // Tab is gone. @@ -215,13 +217,13 @@ return; } - // With committed interstitials, if this is a main frame load, we need to - // get the navigation URL and referrer URL from the navigation entry now, - // since they are required for threat reporting, and the entry will be - // destroyed once the request is failed. - if (resource.IsMainPageLoadBlocked()) { + // If the main frame load is still pending, we need to get the navigation URL + // and referrer URL from the navigation entry now, since they are required for + // threat reporting, and the entry will be destroyed once the request is + // failed. + if (AsyncCheckTracker::IsMainPageLoadPending(resource)) { content::NavigationEntry* entry = - security_interstitials::GetNavigationEntryForResource(resource); + unsafe_resource_util::GetNavigationEntryForResource(resource); if (entry) { security_interstitials::UnsafeResource resource_copy(resource); resource_copy.navigation_url = entry->GetURL(); @@ -238,7 +240,7 @@ base::OnceCallback<void(bool)> callback, scoped_refptr<base::SequencedTaskRunner> callback_task_runner) { content::WebContents* web_contents = - security_interstitials::GetWebContentsForResource(resource); + unsafe_resource_util::GetWebContentsForResource(resource); auto determine_if_is_prerender = [resource, web_contents]() { content::RenderFrameHost* rfh = nullptr; if (resource.render_frame_token) {
diff --git a/components/safe_browsing/content/browser/ui_manager_unittest.cc b/components/safe_browsing/content/browser/ui_manager_unittest.cc index b42d9941..7f478c0 100644 --- a/components/safe_browsing/content/browser/ui_manager_unittest.cc +++ b/components/safe_browsing/content/browser/ui_manager_unittest.cc
@@ -14,11 +14,11 @@ #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h" #include "components/safe_browsing/content/browser/safe_browsing_blocking_page_factory.h" #include "components/safe_browsing/content/browser/safe_browsing_controller_client.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" #include "components/safe_browsing/core/browser/db/util.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/content/settings_page_helper.h" -#include "components/security_interstitials/content/unsafe_resource_util.h" #include "components/security_interstitials/core/base_safe_browsing_error_ui.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -108,7 +108,7 @@ manager->default_safe_page(), /*settings_helper=*/nullptr), BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( - BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources), + BaseBlockingPage::IsMainPageLoadPending(unsafe_resources), false, // is_extended_reporting_opt_in_allowed false, // is_off_the_record false, // is_extended_reporting_enabled @@ -349,7 +349,7 @@ ASSERT_TRUE(entry); EXPECT_TRUE(ui_manager()->IsUrlAllowlistedOrPendingForWebContents( resource.url, resource.is_subresource, entry, - security_interstitials::GetWebContentsForResource(resource), true, + unsafe_resource_util::GetWebContentsForResource(resource), true, &threat_type)); EXPECT_EQ(resource.threat_type, threat_type); } @@ -695,7 +695,7 @@ content::GlobalRenderFrameHostId invalid_rfh_id; resource.render_process_id = invalid_rfh_id.child_id; resource.render_frame_token = base::UnguessableToken::Create(); - ASSERT_FALSE(security_interstitials::GetWebContentsForResource(resource)); + ASSERT_FALSE(unsafe_resource_util::GetWebContentsForResource(resource)); EXPECT_FALSE(IsAllowlisted(resource)); }
diff --git a/components/security_interstitials/content/unsafe_resource_util.cc b/components/safe_browsing/content/browser/unsafe_resource_util.cc similarity index 72% rename from components/security_interstitials/content/unsafe_resource_util.cc rename to components/safe_browsing/content/browser/unsafe_resource_util.cc index c7d613f..1d80ff5 100644 --- a/components/security_interstitials/content/unsafe_resource_util.cc +++ b/components/safe_browsing/content/browser/unsafe_resource_util.cc
@@ -2,23 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/security_interstitials/content/unsafe_resource_util.h" +#include "components/safe_browsing/content/browser/unsafe_resource_util.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" -namespace security_interstitials { +namespace safe_browsing::unsafe_resource_util { content::NavigationEntry* GetNavigationEntryForResource( - const UnsafeResource& resource) { - content::WebContents* web_contents = GetWebContentsForResource(resource); - if (!web_contents) + const security_interstitials::UnsafeResource& resource) { + content::WebContents* web_contents = unsafe_resource_util::GetWebContentsForResource(resource); + if (!web_contents) { return nullptr; + } // If a safebrowsing hit occurs during main frame navigation, the navigation // will not be committed, and the pending navigation entry refers to the hit. - if (resource.IsMainPageLoadBlocked()) + if (AsyncCheckTracker::IsMainPageLoadPending(resource)) { return web_contents->GetController().GetPendingEntry(); + } // If a safebrowsing hit occurs on a subresource load, or on a main frame // after the navigation is committed, the last committed navigation entry // refers to the page with the hit. Note that there may concurrently be an @@ -28,7 +31,7 @@ } content::WebContents* GetWebContentsForResource( - const UnsafeResource& resource) { + const security_interstitials::UnsafeResource& resource) { if (resource.render_frame_token) { content::RenderFrameHost* rfh = content::RenderFrameHost::FromFrameToken( content::GlobalRenderFrameHostToken( @@ -41,4 +44,4 @@ return content::WebContents::FromFrameTreeNodeId(resource.frame_tree_node_id); } -} // namespace security_interstitials +} // namespace safe_browsing::unsafe_resource_util
diff --git a/components/security_interstitials/content/unsafe_resource_util.h b/components/safe_browsing/content/browser/unsafe_resource_util.h similarity index 63% rename from components/security_interstitials/content/unsafe_resource_util.h rename to components/safe_browsing/content/browser/unsafe_resource_util.h index a37fed6..c5d9ec3 100644 --- a/components/security_interstitials/content/unsafe_resource_util.h +++ b/components/safe_browsing/content/browser/unsafe_resource_util.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 COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_ -#define COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_ +#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_ +#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_ #include "components/security_interstitials/core/unsafe_resource.h" @@ -12,27 +12,28 @@ class WebContents; } // namespace content -namespace security_interstitials { +namespace safe_browsing::unsafe_resource_util { // Returns the NavigationEntry for |resource| (for a main frame hit) or // for the page which contains this resource (for a subresource hit). // This method must only be called while the UnsafeResource is still // "valid". // I.e, -// For MainPageLoadBlocked resources, it must not be called if the load +// For MainPageLoadPending resources, it must not be called if the load // was aborted (going back or replaced with a different navigation), // or resumed (proceeded through warning or matched whitelist). -// For non-MainPageLoadBlocked resources, it must not be called if any +// For non-MainPageLoadPending resources, it must not be called if any // other navigation has committed (whether by going back or unrelated // navigations), though a pending navigation is okay. content::NavigationEntry* GetNavigationEntryForResource( - const UnsafeResource& resource); + const security_interstitials::UnsafeResource& resource); // Returns the WebContents associated with the given |resource| based on the // frame or document for which it was created. If that frame/document no longer // exists, this returns nullptr. -content::WebContents* GetWebContentsForResource(const UnsafeResource& resource); +content::WebContents* GetWebContentsForResource( + const security_interstitials::UnsafeResource& resource); -} // namespace security_interstitials +} // namespace safe_browsing::unsafe_resource_util -#endif // COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_UNSAFE_RESOURCE_UTIL_H_ +#endif // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_UNSAFE_RESOURCE_UTIL_H_
diff --git a/components/security_interstitials/content/BUILD.gn b/components/security_interstitials/content/BUILD.gn index bd15725..b85b0e12 100644 --- a/components/security_interstitials/content/BUILD.gn +++ b/components/security_interstitials/content/BUILD.gn
@@ -56,8 +56,6 @@ "ssl_error_navigation_throttle.h", "stateful_ssl_host_state_delegate.cc", "stateful_ssl_host_state_delegate.h", - "unsafe_resource_util.cc", - "unsafe_resource_util.h", "urls.cc", "urls.h", "utils.cc",
diff --git a/components/security_interstitials/core/unsafe_resource.cc b/components/security_interstitials/core/unsafe_resource.cc index 9bd40c8..4e78cbf 100644 --- a/components/security_interstitials/core/unsafe_resource.cc +++ b/components/security_interstitials/core/unsafe_resource.cc
@@ -22,7 +22,7 @@ UnsafeResource::~UnsafeResource() = default; -bool UnsafeResource::IsMainPageLoadBlocked() const { +bool UnsafeResource::IsMainPageLoadPendingWithSyncCheck() const { // Subresource hits cannot happen until after main page load is committed. if (is_subresource) return false;
diff --git a/components/security_interstitials/core/unsafe_resource.h b/components/security_interstitials/core/unsafe_resource.h index 1b0e375..6adbebfa3 100644 --- a/components/security_interstitials/core/unsafe_resource.h +++ b/components/security_interstitials/core/unsafe_resource.h
@@ -55,11 +55,12 @@ UnsafeResource(const UnsafeResource& other); ~UnsafeResource(); - // Returns true if this UnsafeResource is a main frame load that was blocked - // while the navigation is still pending. Note that a main frame hit may not - // be blocking, eg. client side detection happens after the load is - // committed. - bool IsMainPageLoadBlocked() const; + // Returns true if this UnsafeResource is a main frame load while the + // navigation is still pending. Note that a main frame hit may not be + // blocking, eg. client side detection happens after the load is committed. + // Note: If kSafeBrowsingAsyncRealTimeCheck is supported, please call + // AsyncCheckTracker::IsMainPageLoadPending instead. + bool IsMainPageLoadPendingWithSyncCheck() const; // Checks if |callback| is not null and posts it to |callback_sequence|. void DispatchCallback(const base::Location& from_here,
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java index f610e8a..5a04c150 100644 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
@@ -64,12 +64,15 @@ private MakeCredential_Response mMakeCredentialCallback; private GetAssertion_Response mGetAssertionCallback; - // A queue is used to store pending IsUserVerifyingPlatformAuthenticatorAvailable request - // callbacks when there are multiple requests pending on the result from GMSCore. Noted that - // the callbacks may not be invoked in the same order as the pending requests, which in this - // situation does not matter because all pending requests will return the same value. - private Queue<org.chromium.mojo.bindings.Callbacks.Callback1<Boolean>> + // A queue for pending isUserVerifyingPlatformAuthenticatorAvailable request callbacks when + // there are multiple requests pending on the result from GMSCore. Note that the callbacks may + // not be invoked in the same order the pending requests were enqueued, but this is OK because + // all pending requests end up returning the same value. + private Queue<IsUserVerifyingPlatformAuthenticatorAvailable_Response> mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue = new LinkedList<>(); + // Similar to the above, but for pending isConditionalMediationAvailable request callbacks. + private Queue<IsConditionalMediationAvailable_Response> + mIsConditionalMediationAvailableCallbackQueue = new LinkedList<>(); private Fido2CredentialRequest mPendingFido2CredentialRequest; private Set<Fido2CredentialRequest> mUnclosedFido2CredentialRequests = new HashSet<>(); @@ -279,12 +282,10 @@ // If the gmscore and chromium versions are out of sync for some reason, this method will // return true but chrome will ignore conditional requests. Android surfaces only platform // credentials on conditional requests, use IsUVPAA as a proxy for availability. - mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.add(callback); + mIsConditionalMediationAvailableCallbackQueue.add(callback); getFido2CredentialRequest() .handleIsUserVerifyingPlatformAuthenticatorAvailableRequest( - mContext, - isUvpaa -> - onIsUserVerifyingPlatformAuthenticatorAvailableResponse(isUvpaa)); + mContext, isUvpaa -> onIsConditionalMediationAvailableResponse(isUvpaa)); } @Override @@ -325,6 +326,11 @@ mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.poll().call(isUVPAA); } + public void onIsConditionalMediationAvailableResponse(boolean isUVPAA) { + assert !mIsConditionalMediationAvailableCallbackQueue.isEmpty(); + mIsConditionalMediationAvailableCallbackQueue.poll().call(isUVPAA); + } + public void onError(Integer status) { // In case mojo pipe is closed due to the page begin destroyed while waiting for response. if (!mIsOperationPending) return;
diff --git a/content/browser/media/audio_stream_monitor.cc b/content/browser/media/audio_stream_monitor.cc index 0f6a801..7e616e0 100644 --- a/content/browser/media/audio_stream_monitor.cc +++ b/content/browser/media/audio_stream_monitor.cc
@@ -17,38 +17,37 @@ namespace { -AudioStreamMonitor* GetMonitorForRenderFrame(int render_process_id, - int render_frame_id) { +AudioStreamMonitor* GetMonitorForRenderFrame( + GlobalRenderFrameHostId render_frame_host_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); WebContentsImpl* const web_contents = static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost( - RenderFrameHost::FromID(render_process_id, render_frame_id))); + RenderFrameHost::FromID(render_frame_host_id))); return web_contents ? web_contents->audio_stream_monitor() : nullptr; } } // namespace AudioStreamMonitor::AudibleClientRegistration::AudibleClientRegistration( - GlobalRenderFrameHostId host_id, + GlobalRenderFrameHostId render_frame_host_id, AudioStreamMonitor* audio_stream_monitor) - : host_id_(host_id), audio_stream_monitor_(audio_stream_monitor) { - audio_stream_monitor_->AddAudibleClient(host_id_); + : render_frame_host_id_(render_frame_host_id), + audio_stream_monitor_(audio_stream_monitor) { + audio_stream_monitor_->AddAudibleClient(render_frame_host_id_); } AudioStreamMonitor::AudibleClientRegistration::~AudibleClientRegistration() { - audio_stream_monitor_->RemoveAudibleClient(host_id_); + audio_stream_monitor_->RemoveAudibleClient(render_frame_host_id_); } bool AudioStreamMonitor::StreamID::operator<(const StreamID& other) const { - return std::tie(render_process_id, render_frame_id, stream_id) < - std::tie(other.render_process_id, other.render_frame_id, - other.stream_id); + return std::tie(render_frame_host_id, stream_id) < + std::tie(other.render_frame_host_id, other.stream_id); } bool AudioStreamMonitor::StreamID::operator==(const StreamID& other) const { - return std::tie(render_process_id, render_frame_id, stream_id) == - std::tie(other.render_process_id, other.render_frame_id, - other.stream_id); + return std::tie(render_frame_host_id, stream_id) == + std::tie(other.render_frame_host_id, other.stream_id); } AudioStreamMonitor::AudioStreamMonitor(WebContents* contents) @@ -81,31 +80,35 @@ // Streams must be removed locally before calling UpdateStreams() in order to // avoid removing streams from the process twice, since RenderProcessHost // removes the streams on its own when the renderer process is gone. - base::EraseIf(streams_, - [render_process_id](const std::pair<StreamID, bool>& entry) { - return entry.first.render_process_id == render_process_id; - }); + base::EraseIf( + streams_, [render_process_id](const std::pair<StreamID, bool>& entry) { + return entry.first.render_frame_host_id.child_id == render_process_id; + }); UpdateStreams(); } std::unique_ptr<AudioStreamMonitor::AudibleClientRegistration> -AudioStreamMonitor::RegisterAudibleClient(GlobalRenderFrameHostId host_id) { +AudioStreamMonitor::RegisterAudibleClient( + GlobalRenderFrameHostId render_frame_host_id) { DCHECK(thread_checker_.CalledOnValidThread()); - return std::make_unique<AudibleClientRegistration>(host_id, this); + return std::make_unique<AudibleClientRegistration>(render_frame_host_id, + this); } -void AudioStreamMonitor::AddAudibleClient(GlobalRenderFrameHostId host_id) { +void AudioStreamMonitor::AddAudibleClient( + GlobalRenderFrameHostId render_frame_host_id) { DCHECK(thread_checker_.CalledOnValidThread()); - audible_clients_[host_id]++; + audible_clients_[render_frame_host_id]++; UpdateStreams(); } -void AudioStreamMonitor::RemoveAudibleClient(GlobalRenderFrameHostId host_id) { +void AudioStreamMonitor::RemoveAudibleClient( + GlobalRenderFrameHostId render_frame_host_id) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!audible_clients_.empty()); - auto it = audible_clients_.find(host_id); + auto it = audible_clients_.find(render_frame_host_id); CHECK(it != audible_clients_.end()); CHECK_GT(it->second, 0u); it->second--; @@ -118,52 +121,52 @@ } // static -void AudioStreamMonitor::StartMonitoringStream(int render_process_id, - int render_frame_id, - int stream_id) { +void AudioStreamMonitor::StartMonitoringStream( + GlobalRenderFrameHostId render_frame_host_id, + int stream_id) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce( [](const StreamID& sid) { - if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame( - sid.render_process_id, sid.render_frame_id)) { + if (AudioStreamMonitor* monitor = + GetMonitorForRenderFrame(sid.render_frame_host_id)) { monitor->StartMonitoringStreamOnUIThread(sid); } }, - StreamID{render_process_id, render_frame_id, stream_id})); + StreamID{render_frame_host_id, stream_id})); } // static -void AudioStreamMonitor::StopMonitoringStream(int render_process_id, - int render_frame_id, - int stream_id) { +void AudioStreamMonitor::StopMonitoringStream( + GlobalRenderFrameHostId render_frame_host_id, + int stream_id) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce( [](const StreamID& sid) { - if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame( - sid.render_process_id, sid.render_frame_id)) { + if (AudioStreamMonitor* monitor = + GetMonitorForRenderFrame(sid.render_frame_host_id)) { monitor->StopMonitoringStreamOnUIThread(sid); } }, - StreamID{render_process_id, render_frame_id, stream_id})); + StreamID{render_frame_host_id, stream_id})); } // static -void AudioStreamMonitor::UpdateStreamAudibleState(int render_process_id, - int render_frame_id, - int stream_id, - bool is_audible) { +void AudioStreamMonitor::UpdateStreamAudibleState( + GlobalRenderFrameHostId render_frame_host_id, + int stream_id, + bool is_audible) { GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce( [](const StreamID& sid, bool is_audible) { - if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame( - sid.render_process_id, sid.render_frame_id)) { + if (AudioStreamMonitor* monitor = + GetMonitorForRenderFrame(sid.render_frame_host_id)) { monitor->UpdateStreamAudibleStateOnUIThread(sid, is_audible); } }, - StreamID{render_process_id, render_frame_id, stream_id}, is_audible)); + StreamID{render_frame_host_id, stream_id}, is_audible)); } void AudioStreamMonitor::StartMonitoringStreamOnUIThread(const StreamID& sid) { @@ -208,9 +211,7 @@ for (auto& kv : streams_) { const bool is_stream_audible = kv.second; is_audible_ |= is_stream_audible; - GlobalRenderFrameHostId host_id(kv.first.render_process_id, - kv.first.render_frame_id); - audible_frames[host_id] |= is_stream_audible; + audible_frames[kv.first.render_frame_host_id] |= is_stream_audible; } for (auto& kv : audible_clients_) { @@ -278,15 +279,11 @@ void AudioStreamMonitor::RenderFrameDeleted( RenderFrameHost* render_frame_host) { - int render_process_id = render_frame_host->GetProcess()->GetID(); - int render_frame_id = render_frame_host->GetRoutingID(); - // It is possible for a frame to be deleted before notifications about its // streams are received. Explicitly clear these streams. - base::EraseIf(streams_, [render_process_id, render_frame_id]( + base::EraseIf(streams_, [render_frame_host]( const std::pair<StreamID, bool>& entry) { - return entry.first.render_process_id == render_process_id && - entry.first.render_frame_id == render_frame_id; + return entry.first.render_frame_host_id == render_frame_host->GetGlobalId(); }); UpdateStreams(); }
diff --git a/content/browser/media/audio_stream_monitor.h b/content/browser/media/audio_stream_monitor.h index 8fe47fb..ad12769 100644 --- a/content/browser/media/audio_stream_monitor.h +++ b/content/browser/media/audio_stream_monitor.h
@@ -13,6 +13,7 @@ #include "base/timer/timer.h" #include "build/build_config.h" #include "content/common/content_export.h" +#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" namespace content { @@ -57,18 +58,17 @@ // Starts or stops monitoring respectively for the stream owned by the // specified renderer. Safe to call from any thread. - static void StartMonitoringStream(int render_process_id, - int render_frame_id, - int stream_id); - static void StopMonitoringStream(int render_process_id, - int render_frame_id, + static void StartMonitoringStream( + GlobalRenderFrameHostId render_frame_host_id, + int stream_id); + static void StopMonitoringStream(GlobalRenderFrameHostId render_frame_host_id, int stream_id); // Updates the audible state for the given stream. Safe to call from any // thread. - static void UpdateStreamAudibleState(int render_process_id, - int render_frame_id, - int stream_id, - bool is_audible); + static void UpdateStreamAudibleState( + GlobalRenderFrameHostId render_frame_host_id, + int stream_id, + bool is_audible); // WebContentsObserver implementation void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; @@ -85,19 +85,19 @@ // Class to help automatically remove audible client. class CONTENT_EXPORT AudibleClientRegistration { public: - AudibleClientRegistration(GlobalRenderFrameHostId host_id, + AudibleClientRegistration(GlobalRenderFrameHostId render_frame_host_id, AudioStreamMonitor* audio_stream_monitor); ~AudibleClientRegistration(); private: - GlobalRenderFrameHostId host_id_; + GlobalRenderFrameHostId render_frame_host_id_; raw_ptr<AudioStreamMonitor> audio_stream_monitor_; }; // Registers an audible client, which will be unregistered when the returned // AudibleClientRegistration is released. std::unique_ptr<AudibleClientRegistration> RegisterAudibleClient( - GlobalRenderFrameHostId host_id); + GlobalRenderFrameHostId render_frame_host_id); private: friend class AudioStreamMonitorTest; @@ -110,8 +110,7 @@ }; struct CONTENT_EXPORT StreamID { - int render_process_id; - int render_frame_id; + GlobalRenderFrameHostId render_frame_host_id; int stream_id; bool operator<(const StreamID& other) const; bool operator==(const StreamID& other) const; @@ -133,8 +132,8 @@ void UpdateStreams(); // Adds/Removes Audible clients. - void AddAudibleClient(GlobalRenderFrameHostId host_id); - void RemoveAudibleClient(GlobalRenderFrameHostId host_id); + void AddAudibleClient(GlobalRenderFrameHostId render_frame_host_id); + void RemoveAudibleClient(GlobalRenderFrameHostId render_frame_host_id); // The WebContents instance to receive indicator toggle notifications. This // pointer should be valid for the lifetime of AudioStreamMonitor.
diff --git a/content/browser/media/audio_stream_monitor_unittest.cc b/content/browser/media/audio_stream_monitor_unittest.cc index ceae3d0..71882d1 100644 --- a/content/browser/media/audio_stream_monitor_unittest.cc +++ b/content/browser/media/audio_stream_monitor_unittest.cc
@@ -32,12 +32,11 @@ namespace { -const int kRenderProcessId = 1; -const int kAnotherRenderProcessId = 2; -const int kStreamId = 3; -const int kAnotherStreamId = 6; -const int kRenderFrameId = 4; -const int kAnotherRenderFrameId = 8; +const GlobalRenderFrameHostId kRenderFrameHostId = {1, 2}; +const GlobalRenderFrameHostId kRenderFrameHostIdSameProcess = {1, 3}; +const GlobalRenderFrameHostId kRenderFrameHostIdOtherProcess = {4, 5}; +const int kStreamId = 6; +const int kAnotherStreamId = 7; // Used to confirm audio indicator state changes occur at the correct times. class MockWebContentsDelegate : public WebContentsDelegate { @@ -79,12 +78,10 @@ task_environment()->FastForwardBy(delta); } - void ExpectIsMonitoring(int render_process_id, - int render_frame_id, + void ExpectIsMonitoring(GlobalRenderFrameHostId render_frame_host_id, int stream_id, bool is_polling) { - const AudioStreamMonitor::StreamID key = {render_process_id, - render_frame_id, stream_id}; + const AudioStreamMonitor::StreamID key = {render_frame_host_id, stream_id}; EXPECT_EQ(is_polling, monitor_->streams_.find(key) != monitor_->streams_.end()); } @@ -139,27 +136,23 @@ return base::Milliseconds(AudioStreamMonitor::kHoldOnMilliseconds); } - void StartMonitoring(int render_process_id, - int render_frame_id, + void StartMonitoring(GlobalRenderFrameHostId render_frame_host_id, int stream_id) { - monitor_->StartMonitoringStreamOnUIThread(AudioStreamMonitor::StreamID{ - render_process_id, render_frame_id, stream_id}); + monitor_->StartMonitoringStreamOnUIThread( + AudioStreamMonitor::StreamID{render_frame_host_id, stream_id}); } - void StopMonitoring(int render_process_id, - int render_frame_id, + void StopMonitoring(GlobalRenderFrameHostId render_frame_host_id, int stream_id) { - monitor_->StopMonitoringStreamOnUIThread(AudioStreamMonitor::StreamID{ - render_process_id, render_frame_id, stream_id}); + monitor_->StopMonitoringStreamOnUIThread( + AudioStreamMonitor::StreamID{render_frame_host_id, stream_id}); } - void UpdateAudibleState(int render_process_id, - int render_frame_id, + void UpdateAudibleState(GlobalRenderFrameHostId render_frame_host_id, int stream_id, bool is_audible) { monitor_->UpdateStreamAudibleStateOnUIThread( - AudioStreamMonitor::StreamID{render_process_id, render_frame_id, - stream_id}, + AudioStreamMonitor::StreamID{render_frame_host_id, stream_id}, is_audible); } @@ -188,24 +181,24 @@ TEST_F(AudioStreamMonitorTest, MonitorsWhenProvidedAStream) { EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false); - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); + StartMonitoring(kRenderFrameHostId, kStreamId); EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true); - StopMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); + StopMonitoring(kRenderFrameHostId, kStreamId); EXPECT_FALSE(monitor_->WasRecentlyAudible()); ExpectNotCurrentlyAudible(); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false); } // Tests that AudioStreamMonitor keeps the indicator on for the holding period // even if there is silence during the holding period. // See comments in audio_stream_monitor.h for expected behavior. TEST_F(AudioStreamMonitorTest, IndicatorIsOnUntilHoldingPeriodHasPassed) { - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); + StartMonitoring(kRenderFrameHostId, kStreamId); // Expect WebContents will get one call form AudioStreamMonitor to toggle the // indicator upon the very first notification that the stream has become @@ -219,7 +212,7 @@ do { ExpectCurrentlyAudibleChangeNotification(true); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true); + UpdateAudibleState(kRenderFrameHostId, kStreamId, true); ExpectTabWasRecentlyAudible(true, last_became_silent_time); FastForwardBy(one_time_step()); @@ -227,7 +220,7 @@ // Notify that the stream has become silent and advance time repeatedly, // ensuring that the indicator is being held on during the holding period. - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false); + UpdateAudibleState(kRenderFrameHostId, kStreamId, false); last_became_silent_time = base::TimeTicks::Now(); ExpectTabWasRecentlyAudible(true, last_became_silent_time); for (int i = 0; i < num_silence_steps; ++i) { @@ -257,8 +250,8 @@ // Tests that the AudioStreamMonitor correctly processes updates from two // different streams in the same tab. TEST_F(AudioStreamMonitorTest, HandlesMultipleStreamUpdate) { - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); - StartMonitoring(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId); + StartMonitoring(kRenderFrameHostId, kStreamId); + StartMonitoring(kRenderFrameHostIdSameProcess, kAnotherStreamId); base::TimeTicks last_became_silent_time; ExpectTabWasRecentlyAudible(false, last_became_silent_time); @@ -269,26 +262,23 @@ ExpectRecentlyAudibleChangeNotification(true); ExpectCurrentlyAudibleChangeNotification(true); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true); - UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, - false); + UpdateAudibleState(kRenderFrameHostId, kStreamId, true); + UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false); ExpectTabWasRecentlyAudible(true, last_became_silent_time); ExpectIsCurrentlyAudible(); // Halfway through the holding period, the second stream joins in. The // indicator stays on. FastForwardBy(holding_period() / 2); - UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, - true); + UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, true); ExpectTabWasRecentlyAudible(true, last_became_silent_time); ExpectIsCurrentlyAudible(); // Now, both streams become silent. The tab becoms silent but the indicator // stays on. ExpectCurrentlyAudibleChangeNotification(false); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false); - UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, - false); + UpdateAudibleState(kRenderFrameHostId, kStreamId, false); + UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false); last_became_silent_time = base::TimeTicks::Now(); ExpectNotCurrentlyAudible(); ExpectTabWasRecentlyAudible(true, last_became_silent_time); @@ -301,7 +291,7 @@ // The first stream becomes audible again during the holding period. // The tab becomes audible and the indicator stays on. ExpectCurrentlyAudibleChangeNotification(true); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true); + UpdateAudibleState(kRenderFrameHostId, kStreamId, true); ExpectTabWasRecentlyAudible(true, last_became_silent_time); ExpectIsCurrentlyAudible(); @@ -314,7 +304,7 @@ // The first stream becomes silent again. The tab becomes silent and the // indicator is still on. ExpectCurrentlyAudibleChangeNotification(false); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false); + UpdateAudibleState(kRenderFrameHostId, kStreamId, false); last_became_silent_time = base::TimeTicks::Now(); ExpectTabWasRecentlyAudible(true, last_became_silent_time); ExpectNotCurrentlyAudible(); @@ -329,16 +319,14 @@ // The tab becomes audible again. ExpectRecentlyAudibleChangeNotification(true); ExpectCurrentlyAudibleChangeNotification(true); - UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, - true); + UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, true); ExpectTabWasRecentlyAudible(true, last_became_silent_time); ExpectIsCurrentlyAudible(); // From here onwards, both streams are silent. Halfway through the holding // period, the tab is no longer audible but stays as recently audible. ExpectCurrentlyAudibleChangeNotification(false); - UpdateAudibleState(kRenderProcessId, kAnotherRenderFrameId, kAnotherStreamId, - false); + UpdateAudibleState(kRenderFrameHostIdSameProcess, kAnotherStreamId, false); last_became_silent_time = base::TimeTicks::Now(); FastForwardBy(holding_period() / 2); ExpectTabWasRecentlyAudible(true, last_became_silent_time); @@ -362,39 +350,39 @@ } TEST_F(AudioStreamMonitorTest, MultipleRendererProcesses) { - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); - StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); - StopMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); + StartMonitoring(kRenderFrameHostId, kStreamId); + StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true); + StopMonitoring(kRenderFrameHostIdOtherProcess, kStreamId); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, false); } TEST_F(AudioStreamMonitorTest, RenderProcessGone) { - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); - StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, true); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); - monitor_->RenderProcessGone(kRenderProcessId); - ExpectIsMonitoring(kRenderProcessId, kRenderFrameId, kStreamId, false); - monitor_->RenderProcessGone(kAnotherRenderProcessId); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, false); + StartMonitoring(kRenderFrameHostId, kStreamId); + StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, true); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true); + monitor_->RenderProcessGone(kRenderFrameHostId.child_id); + ExpectIsMonitoring(kRenderFrameHostId, kStreamId, false); + monitor_->RenderProcessGone(kRenderFrameHostIdOtherProcess.child_id); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, false); } TEST_F(AudioStreamMonitorTest, RenderFrameGone) { RenderFrameHost* render_frame_host = web_contents()->GetPrimaryMainFrame(); - int render_process_id = render_frame_host->GetProcess()->GetID(); - int render_frame_id = render_frame_host->GetRoutingID(); + GlobalRenderFrameHostId render_frame_host_id = + render_frame_host->GetGlobalId(); - StartMonitoring(render_process_id, render_frame_id, kStreamId); - StartMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId); - ExpectIsMonitoring(render_process_id, render_frame_id, kStreamId, true); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); + StartMonitoring(render_frame_host_id, kStreamId); + StartMonitoring(kRenderFrameHostIdOtherProcess, kStreamId); + ExpectIsMonitoring(render_frame_host_id, kStreamId, true); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true); monitor_->RenderFrameDeleted(render_frame_host); - ExpectIsMonitoring(render_process_id, render_frame_id, kStreamId, false); - ExpectIsMonitoring(kAnotherRenderProcessId, kRenderFrameId, kStreamId, true); + ExpectIsMonitoring(render_frame_host_id, kStreamId, false); + ExpectIsMonitoring(kRenderFrameHostIdOtherProcess, kStreamId, true); } TEST_F(AudioStreamMonitorTest, OneAudibleClient) { @@ -480,7 +468,7 @@ } TEST_F(AudioStreamMonitorTest, AudibleClientAndStream) { - StartMonitoring(kRenderProcessId, kRenderFrameId, kStreamId); + StartMonitoring(kRenderFrameHostId, kStreamId); ExpectNotCurrentlyAudible(); auto* render_frame_host_impl = @@ -494,7 +482,7 @@ ExpectIsCurrentlyAudible(); // The stream becomes audible and the tab remains audible. - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, true); + UpdateAudibleState(kRenderFrameHostId, kStreamId, true); ExpectIsCurrentlyAudible(); // Remove the client and the tab remains audible. @@ -503,7 +491,7 @@ // The stream becomes not audible and the tab is not audible. ExpectCurrentlyAudibleChangeNotification(false); - UpdateAudibleState(kRenderProcessId, kRenderFrameId, kStreamId, false); + UpdateAudibleState(kRenderFrameHostId, kStreamId, false); ExpectNotCurrentlyAudible(); }
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.h b/content/browser/renderer_host/media/audio_input_device_manager.h index 810862505..06bc725 100644 --- a/content/browser/renderer_host/media/audio_input_device_manager.h +++ b/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -76,7 +76,7 @@ base::ObserverList<MediaStreamProviderListener>::Unchecked listeners_; blink::MediaStreamDevices devices_; - const raw_ptr<media::AudioSystem, DanglingUntriaged> audio_system_; + const raw_ptr<media::AudioSystem> audio_system_; }; } // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc b/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc index 84fca22..3fe40c6 100644 --- a/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc +++ b/content/browser/renderer_host/media/audio_output_stream_observer_impl.cc
@@ -13,8 +13,7 @@ int render_process_id, int render_frame_id, int stream_id) - : render_process_id_(render_process_id), - render_frame_id_(render_frame_id), + : render_frame_host_id_(render_process_id, render_frame_id), stream_id_(stream_id) {} AudioOutputStreamObserverImpl::~AudioOutputStreamObserverImpl() { @@ -26,20 +25,18 @@ void AudioOutputStreamObserverImpl::DidStartPlaying() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); did_start_playing_ = true; - AudioStreamMonitor::StartMonitoringStream(render_process_id_, - render_frame_id_, stream_id_); + AudioStreamMonitor::StartMonitoringStream(render_frame_host_id_, stream_id_); } void AudioOutputStreamObserverImpl::DidStopPlaying() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - AudioStreamMonitor::StopMonitoringStream(render_process_id_, render_frame_id_, - stream_id_); + AudioStreamMonitor::StopMonitoringStream(render_frame_host_id_, stream_id_); did_start_playing_ = false; } void AudioOutputStreamObserverImpl::DidChangeAudibleState(bool is_audible) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - AudioStreamMonitor::UpdateStreamAudibleState( - render_process_id_, render_frame_id_, stream_id_, is_audible); + AudioStreamMonitor::UpdateStreamAudibleState(render_frame_host_id_, + stream_id_, is_audible); } } // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_stream_observer_impl.h b/content/browser/renderer_host/media/audio_output_stream_observer_impl.h index 23f2be6c..7d5ba5e 100644 --- a/content/browser/renderer_host/media/audio_output_stream_observer_impl.h +++ b/content/browser/renderer_host/media/audio_output_stream_observer_impl.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_STREAM_OBSERVER_IMPL_H_ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_OUTPUT_STREAM_OBSERVER_IMPL_H_ +#include "content/public/browser/global_routing_id.h" #include "media/mojo/mojom/audio_output_stream.mojom.h" namespace content { @@ -28,8 +29,7 @@ void DidChangeAudibleState(bool is_audible) override; private: - const int render_process_id_; - const int render_frame_id_; + const GlobalRenderFrameHostId render_frame_host_id_; const int stream_id_; bool did_start_playing_ = false;
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc index 670c3ae..47ce896 100644 --- a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
@@ -520,6 +520,9 @@ render_frame_host_ = web_contents_->GetPrimaryMainFrame(); } + std::unique_ptr<media::AudioManager> audio_manager_; + std::unique_ptr<media::AudioSystem> audio_system_; + // The order of these members is important on teardown: // MediaDevicesDispatcherHost expects to be destroyed on the IO thread while // MediaStreamManager expects to be destroyed after the IO thread has been @@ -528,8 +531,6 @@ content::BrowserTaskEnvironment task_environment_; std::unique_ptr<MediaDevicesDispatcherHost> host_; - std::unique_ptr<media::AudioManager> audio_manager_; - std::unique_ptr<media::AudioSystem> audio_system_; raw_ptr<media::FakeVideoCaptureDeviceFactory> video_capture_device_factory_; MediaDeviceEnumeration physical_devices_; url::Origin origin_;
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index ea9df560..3cf2a25 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -566,9 +566,9 @@ base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<MockMediaStreamDispatcherHost> host_; std::unique_ptr<MediaStreamManager> media_stream_manager_; - BrowserTaskEnvironment task_environment_; std::unique_ptr<media::AudioManager> audio_manager_; std::unique_ptr<media::AudioSystem> audio_system_; + BrowserTaskEnvironment task_environment_; MediaDeviceSaltAndOrigin salt_and_origin_; media::AudioDeviceDescriptions audio_device_descriptions_; std::vector<std::string> stub_video_device_ids_;
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc index 6c43006..db1b35d 100644 --- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -704,6 +704,9 @@ return audio_device; } + std::unique_ptr<MockAudioManager> audio_manager_; + std::unique_ptr<media::AudioSystem> audio_system_; + // media_stream_manager_ needs to outlive task_environment_ because it is a // CurrentThread::DestructionObserver. audio_manager_ needs to outlive // task_environment_ because it uses the underlying message loop. @@ -715,8 +718,6 @@ chromeos::ScopedLacrosServiceTestHelper lacros_service_test_helper_; mojo::Receiver<crosapi::mojom::MultiCaptureService> receiver_; #endif // BUILDFLAG(IS_CHROMEOS_LACROS) - std::unique_ptr<MockAudioManager> audio_manager_; - std::unique_ptr<media::AudioSystem> audio_system_; raw_ptr<MockVideoCaptureProvider> video_capture_provider_; std::unique_ptr<MediaStreamProviderListenerMock> stream_provider_listener_; size_t screen_count_ = 0;
diff --git a/content/browser/renderer_host/media/video_capture_unittest.cc b/content/browser/renderer_host/media/video_capture_unittest.cc index 1182caf..52595eef 100644 --- a/content/browser/renderer_host/media/video_capture_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_unittest.cc
@@ -95,10 +95,6 @@ public: VideoCaptureTest() : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP), - audio_manager_(std::make_unique<media::MockAudioManager>( - std::make_unique<media::TestAudioThread>())), - audio_system_( - std::make_unique<media::AudioSystemImpl>(audio_manager_.get())), task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {} VideoCaptureTest(const VideoCaptureTest&) = delete; @@ -108,6 +104,10 @@ void SetUp() override { SetBrowserClientForTesting(&browser_client_); + audio_manager_ = std::make_unique<media::MockAudioManager>( + std::make_unique<media::TestAudioThread>()); + audio_system_ = + std::make_unique<media::AudioSystemImpl>(audio_manager_.get()); media_stream_manager_ = std::make_unique<MediaStreamManager>( audio_system_.get(), std::make_unique<FakeVideoCaptureProvider>()); @@ -351,12 +351,13 @@ std::move(quit_closure).Run(); } + std::unique_ptr<media::AudioManager> audio_manager_; + std::unique_ptr<media::AudioSystem> audio_system_; + // |media_stream_manager_| needs to outlive |task_environment_| because it is // a CurrentThread::DestructionObserver. std::unique_ptr<MediaStreamManager> media_stream_manager_; const content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<media::AudioManager> audio_manager_; - std::unique_ptr<media::AudioSystem> audio_system_; content::TestBrowserContext browser_context_; content::TestContentBrowserClient browser_client_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 385789fb..86c6ef03 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -2773,15 +2773,12 @@ break; frame = frame->GetParent(); } - if (!frame) + if (!frame) { return PageVisibilityState::kHidden; + } - PageVisibilityState visibility_state = GetRenderWidgetHost()->is_hidden() - ? PageVisibilityState::kHidden - : PageVisibilityState::kVisible; - GetContentClient()->browser()->OverridePageVisibilityState(this, - &visibility_state); - return visibility_state; + return GetRenderWidgetHost()->is_hidden() ? PageVisibilityState::kHidden + : PageVisibilityState::kVisible; } bool RenderFrameHostImpl::Send(IPC::Message* message) {
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 89b2604..ec15b9a6 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -145,39 +145,6 @@ namespace content { namespace { -// Implementation of ContentBrowserClient that overrides -// OverridePageVisibilityState() and allows consumers to set a value. -class PrerenderTestContentBrowserClient - : public ContentBrowserTestContentBrowserClient { - public: - PrerenderTestContentBrowserClient() - : override_enabled_(false), - visibility_override_(PageVisibilityState::kVisible) {} - - PrerenderTestContentBrowserClient(const PrerenderTestContentBrowserClient&) = - delete; - PrerenderTestContentBrowserClient& operator=( - const PrerenderTestContentBrowserClient&) = delete; - - ~PrerenderTestContentBrowserClient() override {} - - void EnableVisibilityOverride(PageVisibilityState visibility_override) { - override_enabled_ = true; - visibility_override_ = visibility_override; - } - - void OverridePageVisibilityState( - RenderFrameHost* render_frame_host, - PageVisibilityState* visibility_state) override { - if (override_enabled_) - *visibility_state = visibility_override_; - } - - private: - bool override_enabled_; - PageVisibilityState visibility_override_; -}; - const char kTrustMeUrl[] = "trustme://host/path/"; const char kTrustMeIfEmbeddingSecureUrl[] = "trustmeifembeddingsecure://host/path/"; @@ -484,22 +451,6 @@ web_contents()->GetPrimaryMainFrame()->GetVisibilityState()); } -// Test that a frame visibility can be overridden by the ContentBrowserClient. -IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, - GetVisibilityState_Override) { - EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,foo"))); - - PrerenderTestContentBrowserClient new_client; - - web_contents()->WasShown(); - EXPECT_EQ(PageVisibilityState::kVisible, - web_contents()->GetPrimaryMainFrame()->GetVisibilityState()); - - new_client.EnableVisibilityOverride(PageVisibilityState::kHiddenButPainting); - EXPECT_EQ(PageVisibilityState::kHiddenButPainting, - web_contents()->GetPrimaryMainFrame()->GetVisibilityState()); -} - // Check that the URLLoaderFactories created by RenderFrameHosts for renderers // are not trusted. IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 966f79ab..2549daa 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1445,12 +1445,6 @@ RenderProcessHost* render_process_host, mojo::GenericPendingReceiver receiver) {} - // Allows to override the visibility state of a RenderFrameHost. - // |visibility_state| should not be null. It will only be set if needed. - virtual void OverridePageVisibilityState( - RenderFrameHost* render_frame_host, - PageVisibilityState* visibility_state) {} - // Allows an embedder to provide its own ControllerPresentationServiceDelegate // implementation. Returns nullptr if unavailable. virtual ControllerPresentationServiceDelegate*
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn index 931b2b2d..b2a85244 100644 --- a/google_apis/BUILD.gn +++ b/google_apis/BUILD.gn
@@ -316,6 +316,7 @@ bundle_data("google_apis_unittest_bundle_data") { testonly = true sources = [ + "test/data/calendar/calendar_list.json", "test/data/calendar/event_self_response_statuses.json", "test/data/calendar/event_statuses.json", "test/data/calendar/event_with_invalid_conference_data_uri.json",
diff --git a/google_apis/calendar/calendar_api_requests.cc b/google_apis/calendar/calendar_api_requests.cc index 2bef026..74fb64e 100644 --- a/google_apis/calendar/calendar_api_requests.cc +++ b/google_apis/calendar/calendar_api_requests.cc
@@ -6,7 +6,14 @@ #include <stddef.h> +#include <memory> +#include <utility> + +#include "base/memory/weak_ptr.h" #include "base/values.h" +#include "google_apis/common/api_error_codes.h" +#include "google_apis/common/base_requests.h" +#include "google_apis/common/request_sender.h" #include "net/base/url_util.h" namespace google_apis { @@ -20,6 +27,11 @@ // should return the participant/requester only as an attendee. constexpr int kMaxAttendees = 1; +// Requested maximum number of calendars returned. The default value is 100. +// Although the events shown to the user will be limited to a fixed number +// of selected calendars, it is best to be thorough here and filter later. +constexpr int kMaxCalendars = 250; + // Requested number of events returned on one result page. // The default value on the Calendar API side is 250 events per page and some // users have >250 events per month. @@ -30,6 +42,7 @@ // response. constexpr int kMaxResults = 2500; +// Requested fields to be returned in the Event list result. constexpr char kCalendarEventListFields[] = "timeZone,etag,kind,items(id,kind,summary,colorId," "status,start(date),end(date),start(dateTime),end(dateTime),htmlLink," @@ -37,6 +50,10 @@ "conferenceData(conferenceId,entryPoints(entryPointType,uri))," "creator(self))"; +// Requested fields to be returned in the CalendarList result. +constexpr char kCalendarListFields[] = + "etag,kind,items(id,colorId,selected,primary)"; + CalendarApiGetRequest::CalendarApiGetRequest(RequestSender* sender, const std::string& fields) : UrlFetchRequestBase(sender, ProgressCallback(), ProgressCallback()), @@ -71,6 +88,66 @@ return IsSuccessfulCalendarApiErrorCode(error); } +CalendarApiCalendarListRequest::CalendarApiCalendarListRequest( + RequestSender* sender, + const CalendarApiUrlGenerator& url_generator, + CalendarListCallback callback) + : CalendarApiGetRequest(sender, kCalendarListFields), + callback_(std::move(callback)), + url_generator_(url_generator) { + CHECK(!callback_.is_null()); +} + +CalendarApiCalendarListRequest::~CalendarApiCalendarListRequest() = default; + +GURL CalendarApiCalendarListRequest::GetURLInternal() const { + return url_generator_.GetCalendarListUrl(/*max_results=*/kMaxCalendars); +} + +void CalendarApiCalendarListRequest::ProcessURLFetchResults( + const network::mojom::URLResponseHead* response_head, + base::FilePath response_file, + std::string response_body) { + ApiErrorCode error = GetErrorCode(); + switch (error) { + case HTTP_SUCCESS: + blocking_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&CalendarApiCalendarListRequest::Parse, + std::move(response_body)), + base::BindOnce(&CalendarApiCalendarListRequest::OnDataParsed, + weak_ptr_factory_.GetWeakPtr(), error)); + break; + default: + RunCallbackOnPrematureFailure(error); + OnProcessURLFetchResultsComplete(); + break; + } +} + +void CalendarApiCalendarListRequest::RunCallbackOnPrematureFailure( + ApiErrorCode error) { + std::move(callback_).Run(error, std::unique_ptr<CalendarList>()); +} + +// static +std::unique_ptr<CalendarList> CalendarApiCalendarListRequest::Parse( + std::string json) { + std::unique_ptr<base::Value> value = ParseJson(json); + + return value ? CalendarList::CreateFrom(*value) : nullptr; +} + +void CalendarApiCalendarListRequest::OnDataParsed( + ApiErrorCode error, + std::unique_ptr<CalendarList> calendars) { + if (!calendars) { + error = PARSE_ERROR; + } + std::move(callback_).Run(error, std::move(calendars)); + OnProcessURLFetchResultsComplete(); +} + CalendarApiEventsRequest::CalendarApiEventsRequest( RequestSender* sender, const CalendarApiUrlGenerator& url_generator, @@ -82,7 +159,7 @@ url_generator_(url_generator), start_time_(start_time), end_time_(end_time) { - DCHECK(!callback_.is_null()); + CHECK(!callback_.is_null()); } CalendarApiEventsRequest::~CalendarApiEventsRequest() = default; @@ -115,14 +192,6 @@ } } -void CalendarApiEventsRequest::OnDataParsed(ApiErrorCode error, - std::unique_ptr<EventList> events) { - if (!events) - error = PARSE_ERROR; - std::move(callback_).Run(error, std::move(events)); - OnProcessURLFetchResultsComplete(); -} - void CalendarApiEventsRequest::RunCallbackOnPrematureFailure( ApiErrorCode error) { std::move(callback_).Run(error, std::unique_ptr<EventList>()); @@ -135,5 +204,14 @@ return value ? EventList::CreateFrom(*value) : nullptr; } +void CalendarApiEventsRequest::OnDataParsed(ApiErrorCode error, + std::unique_ptr<EventList> events) { + if (!events) { + error = PARSE_ERROR; + } + std::move(callback_).Run(error, std::move(events)); + OnProcessURLFetchResultsComplete(); +} + } // namespace calendar } // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_requests.h b/google_apis/calendar/calendar_api_requests.h index 99e7c31..fff3793 100644 --- a/google_apis/calendar/calendar_api_requests.h +++ b/google_apis/calendar/calendar_api_requests.h
@@ -5,6 +5,9 @@ #ifndef GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_ #define GOOGLE_APIS_CALENDAR_CALENDAR_API_REQUESTS_H_ +#include <memory> + +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "google_apis/calendar/calendar_api_response_types.h" #include "google_apis/calendar/calendar_api_url_generator.h" @@ -15,6 +18,12 @@ namespace calendar { +// Callback used for requests that the server returns Calendar List +// data formatted into JSON value. +using CalendarListCallback = + base::OnceCallback<void(ApiErrorCode error, + std::unique_ptr<CalendarList> calendars)>; + // Callback used for requests that the server returns Events data // formatted into JSON value. using CalendarEventListCallback = @@ -49,6 +58,46 @@ std::string fields_; }; +// Request to fetch the list of the user's calendars. +class CalendarApiCalendarListRequest : public CalendarApiGetRequest { + public: + CalendarApiCalendarListRequest(RequestSender* sender, + const CalendarApiUrlGenerator& url_generator, + CalendarListCallback callback); + CalendarApiCalendarListRequest(const CalendarApiCalendarListRequest&) = + delete; + CalendarApiCalendarListRequest& operator=( + const CalendarApiCalendarListRequest&) = delete; + ~CalendarApiCalendarListRequest() override; + + protected: + // CalendarApiGetRequest: + GURL GetURLInternal() const override; + + // UrlFetchRequestBase: + void ProcessURLFetchResults( + const network::mojom::URLResponseHead* response_head, + base::FilePath response_file, + std::string response_body) override; + + void RunCallbackOnPrematureFailure(ApiErrorCode code) override; + + private: + // Parses the Calendar List result to a CalendarList. + static std::unique_ptr<CalendarList> Parse(std::string json); + + // Receives the parsed calendar list and invokes the callback. + void OnDataParsed(ApiErrorCode error, + std::unique_ptr<CalendarList> calendars); + + CalendarListCallback callback_; + const CalendarApiUrlGenerator url_generator_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<CalendarApiCalendarListRequest> weak_ptr_factory_{this}; +}; + // Request to fetch calendar events. class CalendarApiEventsRequest : public CalendarApiGetRequest { public: @@ -68,7 +117,7 @@ // UrlFetchRequestBase: void ProcessURLFetchResults( const network::mojom::URLResponseHead* response_head, - const base::FilePath response_file, + base::FilePath response_file, std::string response_body) override; void RunCallbackOnPrematureFailure(ApiErrorCode code) override;
diff --git a/google_apis/calendar/calendar_api_requests_unittest.cc b/google_apis/calendar/calendar_api_requests_unittest.cc index f803cea..c18918d8 100644 --- a/google_apis/calendar/calendar_api_requests_unittest.cc +++ b/google_apis/calendar/calendar_api_requests_unittest.cc
@@ -14,6 +14,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/request_handler_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/test/test_shared_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" @@ -64,19 +65,59 @@ test_shared_loader_factory_; net::test_server::HttpRequest http_request_; - // Returns the mock calendar event list. + // Returns a mock response based on the request URL. std::unique_ptr<net::test_server::HttpResponse> HandleDataFileRequest( const net::test_server::HttpRequest& request) { http_request_ = request; - // Return the response from the event json file. - return test_util::CreateHttpResponseFromFile( - test_util::GetTestFilePath("calendar/events.json")); + if (net::test_server::ShouldHandle( + http_request_, "/calendar/v3/calendars/primary/events")) { + return test_util::CreateHttpResponseFromFile( + test_util::GetTestFilePath("calendar/events.json")); + } + if (net::test_server::ShouldHandle(http_request_, + "/calendar/v3/users/me/calendarList")) { + return test_util::CreateHttpResponseFromFile( + test_util::GetTestFilePath("calendar/calendar_list.json")); + } + NOTREACHED_NORETURN(); } }; -// Tests the CalendarApiRequestsTest can generate the correct url and get the -// correct response. +// Checks that CalendarApiCalendarListRequest can generate the correct url +// and get a calendar list response. +TEST_F(CalendarApiRequestsTest, GetCalendarListRequest) { + ApiErrorCode error = OTHER_ERROR; + std::unique_ptr<CalendarList> calendars; + + { + base::RunLoop run_loop; + auto request = std::make_unique<CalendarApiCalendarListRequest>( + request_sender_.get(), *url_generator_, + test_util::CreateQuitCallback( + &run_loop, + test_util::CreateCopyResultCallback(&error, &calendars))); + + request_sender_->StartRequestWithAuthRetry(std::move(request)); + run_loop.Run(); + } + + EXPECT_EQ(HTTP_SUCCESS, error); + EXPECT_EQ(net::test_server::METHOD_GET, http_request_.method); + EXPECT_EQ( + "/calendar/v3/users/me/calendarList" + "?maxResults=250" + "&fields=etag%2Ckind%2Citems(id%2CcolorId%2Cselected%2Cprimary)", + http_request_.relative_url); + + ASSERT_TRUE(calendars.get()); + EXPECT_EQ("calendar#calendarList", calendars->kind()); + EXPECT_EQ(true, calendars->items()[0]->selected()); + EXPECT_EQ(true, calendars->items()[0]->primary()); +} + +// Tests that CalendarApiEventsRequest can generate the correct url and get the +// correct event list response. TEST_F(CalendarApiRequestsTest, GetEventListRequest) { ApiErrorCode error = OTHER_ERROR; std::unique_ptr<EventList> events;
diff --git a/google_apis/calendar/calendar_api_response_types.cc b/google_apis/calendar/calendar_api_response_types.cc index 786f58b..bff261a 100644 --- a/google_apis/calendar/calendar_api_response_types.cc +++ b/google_apis/calendar/calendar_api_response_types.cc
@@ -27,6 +27,14 @@ namespace calendar { namespace { +// CalendarList +constexpr char kCalendarListKind[] = "calendar#calendarList"; + +// SingleCalendar +constexpr char kCalendarColorId[] = "colorId"; +constexpr char kPrimary[] = "primary"; +constexpr char kSelected[] = "selected"; +constexpr char kSingleCalendarKind[] = "calendar#calendarListEntry"; // EventList constexpr char kCalendarEventListKind[] = "calendar#events"; @@ -221,6 +229,18 @@ return result; } +bool ConvertCalendarListResponseItems(const base::Value* value, + SingleCalendar* calendar) { + base::JSONValueConverter<SingleCalendar> converter; + + if (!IsResourceKindExpected(*value, kSingleCalendarKind) || + !converter.Convert(*value, calendar)) { + DVLOG(1) << "Unable to create: Invalid calendarListEntry JSON!"; + return false; + } + return true; +} + } // namespace DateTime::DateTime() = default; @@ -320,5 +340,65 @@ items_.push_back(std::move(item)); } +SingleCalendar::SingleCalendar() = default; + +SingleCalendar::~SingleCalendar() = default; + +SingleCalendar::SingleCalendar(const SingleCalendar&) = default; + +SingleCalendar& SingleCalendar::operator=(const SingleCalendar&) = default; + +// static +void SingleCalendar::RegisterJSONConverter( + base::JSONValueConverter<SingleCalendar>* converter) { + converter->RegisterStringField(kApiResponseIdKey, &SingleCalendar::id_); + converter->RegisterStringField(kCalendarColorId, &SingleCalendar::color_id_); + converter->RegisterBoolField(kPrimary, &SingleCalendar::primary_); + converter->RegisterBoolField(kSelected, &SingleCalendar::selected_); +} + +int SingleCalendar::GetApproximateSizeInBytes() const { + int total_bytes = 0; + + total_bytes += sizeof(SingleCalendar); + total_bytes += id_.length(); + total_bytes += color_id_.length(); + total_bytes += sizeof(primary_); + total_bytes += sizeof(selected_); + + return total_bytes; +} + +CalendarList::CalendarList() = default; + +CalendarList::~CalendarList() = default; + +// static +void CalendarList::RegisterJSONConverter( + base::JSONValueConverter<CalendarList>* converter) { + converter->RegisterStringField(kApiResponseETagKey, &CalendarList::etag_); + converter->RegisterStringField(kApiResponseKindKey, &CalendarList::kind_); + converter->RegisterRepeatedCustomValue<SingleCalendar>( + kApiResponseItemsKey, &CalendarList::items_, + &ConvertCalendarListResponseItems); +} + +// static +std::unique_ptr<CalendarList> CalendarList::CreateFrom( + const base::Value& value) { + auto calendars = std::make_unique<CalendarList>(); + base::JSONValueConverter<CalendarList> converter; + if (!IsResourceKindExpected(value, kCalendarListKind) || + !converter.Convert(value, calendars.get())) { + DVLOG(1) << "Unable to create: Invalid CalendarList JSON!"; + return nullptr; + } + return calendars; +} + +void CalendarList::InjectItemForTesting(std::unique_ptr<SingleCalendar> item) { + items_.push_back(std::move(item)); +} + } // namespace calendar } // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_response_types.h b/google_apis/calendar/calendar_api_response_types.h index dbe1f4b..bcde83a 100644 --- a/google_apis/calendar/calendar_api_response_types.h +++ b/google_apis/calendar/calendar_api_response_types.h
@@ -28,6 +28,87 @@ namespace calendar { +// Parses a calendar list item from the response. +class SingleCalendar { + public: + SingleCalendar(); + SingleCalendar(const SingleCalendar&); + SingleCalendar& operator=(const SingleCalendar&); + ~SingleCalendar(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<SingleCalendar>* converter); + + // The Calendar ID + const std::string& id() const { return id_; } + void set_id(const std::string& id) { id_ = id; } + + // The color ID of the calendar + const std::string& color_id() const { return color_id_; } + void set_color_id(const std::string& color_id) { color_id_ = color_id; } + + // Indicates whether or not the calendar is selected. + bool selected() const { return selected_; } + void set_selected(bool selected) { selected_ = selected; } + + // Indicates whether or not the calendar is the primary calendar. + bool primary() const { return primary_; } + void set_primary(bool primary) { primary_ = primary; } + + // Return the approximate size of this calendar list item in bytes. + int GetApproximateSizeInBytes() const; + + private: + std::string id_; + std::string color_id_; + bool selected_ = false; + bool primary_ = false; +}; + +// Parses a list of calendars. +class CalendarList { + public: + CalendarList(); + CalendarList(const CalendarList&) = delete; + CalendarList& operator=(const CalendarList&) = delete; + ~CalendarList(); + + // Registers the mapping between JSON field names and the members in this + // class. + static void RegisterJSONConverter( + base::JSONValueConverter<CalendarList>* converter); + + // Creates CalendarList from parsed JSON. + static std::unique_ptr<CalendarList> CreateFrom(const base::Value& value); + + // Returns ETag for this calendar list. + const std::string& etag() const { return etag_; } + + // Returns the kind. + const std::string& kind() const { return kind_; } + + void set_etag(const std::string& etag) { etag_ = etag; } + void set_kind(const std::string& kind) { kind_ = kind; } + + // Returns a set of calendars. + const std::vector<std::unique_ptr<SingleCalendar>>& items() const { + return items_; + } + std::vector<std::unique_ptr<SingleCalendar>>* mutable_items() { + return &items_; + } + + void InjectItemForTesting(std::unique_ptr<SingleCalendar> item); + + private: + std::string etag_; + std::string kind_; + + std::vector<std::unique_ptr<SingleCalendar>> items_; +}; + // Parses the time field in the calendar Events.list response. class DateTime { public:
diff --git a/google_apis/calendar/calendar_api_response_types_unittest.cc b/google_apis/calendar/calendar_api_response_types_unittest.cc index 7e6d934..0d04d82 100644 --- a/google_apis/calendar/calendar_api_response_types_unittest.cc +++ b/google_apis/calendar/calendar_api_response_types_unittest.cc
@@ -4,6 +4,8 @@ #include "google_apis/calendar/calendar_api_response_types.h" +#include <memory> + #include "base/time/time.h" #include "base/values.h" #include "google_apis/common/test_util.h" @@ -13,13 +15,73 @@ namespace calendar { +TEST(CalendarAPIResponseTypesTest, ParseCalendarList) { + std::unique_ptr<base::Value> calendars = + test_util::LoadJSONFile("calendar/calendar_list.json"); + ASSERT_TRUE(calendars.get()); + + ASSERT_EQ(base::Value::Type::DICT, calendars->type()); + std::unique_ptr<CalendarList> calendar_list = + CalendarList::CreateFrom(*calendars); + + EXPECT_EQ("\"p32gqbiyrr257ya1\"", calendar_list->etag()); + EXPECT_EQ("calendar#calendarList", calendar_list->kind()); + EXPECT_EQ(3U, calendar_list->items().size()); + + const SingleCalendar& calendar = *calendar_list->items()[0]; + EXPECT_EQ(calendar.id(), "test1@google.com"); + EXPECT_EQ(calendar.color_id(), "14"); + EXPECT_TRUE(calendar.selected()); + EXPECT_TRUE(calendar.primary()); +} + +// Checks that calendar list entries with a missing 'selected' parameter +// are parsed to have a selected member equal to false. +TEST(CalendarAPIResponseTypesTest, ParseCalendarListWithUnselectedEntry) { + std::unique_ptr<base::Value> calendars = + test_util::LoadJSONFile("calendar/calendar_list.json"); + ASSERT_TRUE(calendars.get()); + + ASSERT_EQ(base::Value::Type::DICT, calendars->type()); + std::unique_ptr<CalendarList> calendar_list = + CalendarList::CreateFrom(*calendars); + + EXPECT_EQ(3U, calendar_list->items().size()); + + const SingleCalendar& calendar = *calendar_list->items()[1]; + EXPECT_EQ(calendar.id(), + "google.com_zu35dc5syt5k0fddetqqfggb75test@" + "group.calendar.google.com"); + EXPECT_FALSE(calendar.selected()); +} + +// Checks that calendar list entries with a missing 'primary' parameter +// are parsed to have a primary member equal to false. +TEST(CalendarAPIResponseTypesTest, ParseCalendarListWithNonPrimaryEntry) { + std::unique_ptr<base::Value> calendars = + test_util::LoadJSONFile("calendar/calendar_list.json"); + ASSERT_TRUE(calendars.get()); + + ASSERT_EQ(base::Value::Type::DICT, calendars->type()); + std::unique_ptr<CalendarList> calendar_list = + CalendarList::CreateFrom(*calendars); + + EXPECT_EQ(3U, calendar_list->items().size()); + + const SingleCalendar& calendar = *calendar_list->items()[2]; + EXPECT_EQ(calendar.id(), + "google.com_3edk4wi2oio66fu9l9zh19zsw9test@" + "group.calendar.google.com"); + EXPECT_FALSE(calendar.primary()); +} + TEST(CalendarAPIResponseTypesTest, ParseEventList) { std::unique_ptr<base::Value> events = test_util::LoadJSONFile("calendar/events.json"); ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ("America/Los_Angeles", event_list->time_zone()); EXPECT_EQ("calendar#events", event_list->kind()); @@ -53,7 +115,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(3U, event_list->items().size()); @@ -67,7 +129,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(4U, event_list->items().size()); @@ -82,7 +144,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(1U, event_list->items().size()); @@ -95,7 +157,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(1U, event_list->items().size()); @@ -108,7 +170,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(4U, event_list->items().size()); @@ -129,7 +191,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); EXPECT_EQ(8U, event_list->items().size()); @@ -157,7 +219,7 @@ ASSERT_TRUE(events.get()); ASSERT_EQ(base::Value::Type::DICT, events->type()); - auto event_list = EventList::CreateFrom(*events); + std::unique_ptr<EventList> event_list = EventList::CreateFrom(*events); ASSERT_EQ(event_list, nullptr); } } // namespace calendar
diff --git a/google_apis/calendar/calendar_api_url_generator.cc b/google_apis/calendar/calendar_api_url_generator.cc index 20a78cb..3b09e772 100644 --- a/google_apis/calendar/calendar_api_url_generator.cc +++ b/google_apis/calendar/calendar_api_url_generator.cc
@@ -18,6 +18,8 @@ // Hard coded URLs for communication with a google calendar server. constexpr char kCalendarV3ColorUrl[] = "calendar/v3/colors"; constexpr char kCalendarV3EventsUrl[] = "calendar/v3/calendars/primary/events"; +constexpr char kCalendarV3CalendarListUrl[] = + "calendar/v3/users/me/calendarList"; constexpr char kMaxAttendeesParameterName[] = "maxAttendees"; constexpr char kMaxResultsParameterName[] = "maxResults"; constexpr char kSingleEventsParameterName[] = "singleEvents"; @@ -69,5 +71,16 @@ return url; } +GURL CalendarApiUrlGenerator::GetCalendarListUrl( + std::optional<int> max_results) const { + GURL url = base_url_.Resolve(kCalendarV3CalendarListUrl); + if (max_results.has_value()) { + url = net::AppendOrReplaceQueryParameter( + url, kMaxResultsParameterName, + base::NumberToString(max_results.value())); + } + return url; +} + } // namespace calendar } // namespace google_apis
diff --git a/google_apis/calendar/calendar_api_url_generator.h b/google_apis/calendar/calendar_api_url_generator.h index 70666f5..e30448e6 100644 --- a/google_apis/calendar/calendar_api_url_generator.h +++ b/google_apis/calendar/calendar_api_url_generator.h
@@ -46,6 +46,11 @@ // Returns a URL to fetch a map of calendar color id to color code. GURL GetCalendarColorListUrl() const; + // Returns a URL to fetch a list of calendars. + // max_results Maximum number of calendars returned on one result page. + // Optional. + GURL GetCalendarListUrl(std::optional<int> max_results) const; + // The base url can be set here. It defaults to the production base url. void SetBaseUrlForTesting(const std::string& url) { base_url_ = GURL(url); }
diff --git a/google_apis/calendar/calendar_api_url_generator_unittest.cc b/google_apis/calendar/calendar_api_url_generator_unittest.cc index 0e1f3d7..ae93efd 100644 --- a/google_apis/calendar/calendar_api_url_generator_unittest.cc +++ b/google_apis/calendar/calendar_api_url_generator_unittest.cc
@@ -4,6 +4,8 @@ #include "google_apis/calendar/calendar_api_url_generator.h" +#include <optional> + #include "base/time/time.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" @@ -57,5 +59,20 @@ .spec()); } +TEST(CalendarApiUrlGeneratorTest, GetCalendarListUrl) { + CalendarApiUrlGenerator url_generator_; + EXPECT_EQ( + "https://www.googleapis.com/calendar/v3/users/me/calendarList" + "?maxResults=50", + url_generator_.GetCalendarListUrl(/*max_results=*/50).spec()); +} + +TEST(CalendarApiUrlGeneratorTest, + GetCalendarListUrlWithDefaultOptionalParameters) { + CalendarApiUrlGenerator url_generator_; + EXPECT_EQ( + "https://www.googleapis.com/calendar/v3/users/me/calendarList", + url_generator_.GetCalendarListUrl(/*max_results=*/std::nullopt).spec()); +} } // namespace calendar } // namespace google_apis
diff --git a/google_apis/test/data/calendar/calendar_list.json b/google_apis/test/data/calendar/calendar_list.json new file mode 100644 index 0000000..82b9e4b8 --- /dev/null +++ b/google_apis/test/data/calendar/calendar_list.json
@@ -0,0 +1,63 @@ +{ + "kind": "calendar#calendarList", + "etag": "\"p32gqbiyrr257ya1\"", + "nextSyncToken": "vFjLRyv2e1bgx1fBEAzswbbyRrCMgpo2T6Baf47ISpP5", + "items": [ + { + "kind": "calendar#calendarListEntry", + "etag": "\"3428208519567381\"", + "id": "test1@google.com", + "summary": "test1@google.com", + "description": "Primary Calendar", + "timeZone": "America/New_York", + "colorId": "14", + "backgroundColor": "#9fe1e7", + "foregroundColor": "#000000", + "selected": true, + "accessRole": "reader", + "primary": true, + "defaultReminders": [], + "conferenceProperties": { + "allowedConferenceSolutionTypes": [ + "hangoutsMeet" + ] + } + }, + { + "kind": "calendar#calendarListEntry", + "etag": "\"9090908504717641\"", + "id": "google.com_zu35dc5syt5k0fddetqqfggb75test@group.calendar.google.com", + "summary": "Happy Hour Events", + "timeZone": "America/New_York", + "colorId": "17", + "backgroundColor": "#9a9cff", + "foregroundColor": "#000000", + "accessRole": "reader", + "defaultReminders": [], + "conferenceProperties": { + "allowedConferenceSolutionTypes": [ + "hangoutsMeet" + ] + } + }, + { + "kind": "calendar#calendarListEntry", + "etag": "\"7777398739068290\"", + "id": "google.com_3edk4wi2oio66fu9l9zh19zsw9test@group.calendar.google.com", + "summary": "Birthdays", + "description": "Displays birthdays, anniversaries, and other event dates.", + "timeZone": "America/New_York", + "colorId": "13", + "backgroundColor": "#92e1c0", + "foregroundColor": "#000000", + "selected": true, + "accessRole": "reader", + "defaultReminders": [], + "conferenceProperties": { + "allowedConferenceSolutionTypes": [ + "hangoutsMeet" + ] + } + } + ] +}
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc index ac7d364..1638100f 100644 --- a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc +++ b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
@@ -127,6 +127,8 @@ return shared_image_representation_factory_->ProduceGLTexture(mailbox); } + // Creates a SharedImage that can be used for reading and writing via the + // GLES2 interface (these tests do both). Mailbox CreateSharedImage(const viz::SharedImageFormat& format) { auto mailbox = Mailbox::GenerateForSharedImage(); backing_factory_->CreateSharedImage(
diff --git a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc index 171d496..b0014ed4 100644 --- a/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc +++ b/gpu/command_buffer/tests/shared_image_gl_backing_produce_dawn_unittest.cc
@@ -97,12 +97,11 @@ // Create the shared image SharedImageInterface* sii = gl_context_->GetSharedImageInterface(); Mailbox gl_mailbox = - sii->CreateSharedImage( - viz::SinglePlaneFormat::kRGBA_8888, {1, 1}, - gfx::ColorSpace::CreateSRGB(), kTopLeft_GrSurfaceOrigin, - kPremul_SkAlphaType, - SHARED_IMAGE_USAGE_GLES2_READ | SHARED_IMAGE_USAGE_GLES2_WRITE, - "TestLabel", kNullSurfaceHandle) + sii->CreateSharedImage(viz::SinglePlaneFormat::kRGBA_8888, {1, 1}, + gfx::ColorSpace::CreateSRGB(), + kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, + SHARED_IMAGE_USAGE_GLES2_WRITE, "TestLabel", + kNullSurfaceHandle) ->mailbox(); SyncToken mailbox_produced_token = sii->GenVerifiedSyncToken(); gl()->WaitSyncTokenCHROMIUM(mailbox_produced_token.GetConstData());
diff --git a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm index 49342f5..02093c1 100644 --- a/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm +++ b/ios/chrome/browser/safe_browsing/model/safe_browsing_blocking_page.mm
@@ -56,7 +56,7 @@ SECURITY_SENSITIVE_SAFE_BROWSING_INTERSTITIAL); } return BaseSafeBrowsingErrorUI::SBErrorDisplayOptions( - resource.IsMainPageLoadBlocked(), + resource.IsMainPageLoadPendingWithSyncCheck(), /*is_extended_reporting_opt_in_allowed=*/false, /*is_off_the_record=*/false, /*is_extended_reporting=*/false, @@ -89,7 +89,7 @@ : IOSSecurityInterstitialPage(resource.weak_web_state.get(), GetMainFrameUrl(resource), client), - is_main_page_load_blocked_(resource.IsMainPageLoadBlocked()), + is_main_page_load_blocked_(resource.IsMainPageLoadPendingWithSyncCheck()), error_ui_(std::make_unique<SafeBrowsingLoudErrorUI>( resource.url, GetMainFrameUrl(resource),
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.h b/ios/chrome/browser/sessions/legacy_session_restoration_service.h index 3184ebf..093d4e9 100644 --- a/ios/chrome/browser/sessions/legacy_session_restoration_service.h +++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.h
@@ -58,6 +58,7 @@ void InvokeClosureWhenBackgroundProcessingDone( base::OnceClosure closure) final; void PurgeUnassociatedData(base::OnceClosure closure) final; + bool PlaceholderTabsEnabled() const final; // SessionRestorationObserver implementation. void WillStartSessionRestoration(Browser* browser) final;
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm index c0f388e..4f71e03 100644 --- a/ios/chrome/browser/sessions/legacy_session_restoration_service.mm +++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
@@ -161,6 +161,11 @@ purgeUnassociatedDataWithCompletion:std::move(closure)]; } +bool LegacySessionRestorationService::PlaceholderTabsEnabled() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return false; +} + void LegacySessionRestorationService::WillStartSessionRestoration( Browser* browser) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm index 931336d..1633235 100644 --- a/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm +++ b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
@@ -1050,3 +1050,8 @@ ->RemoveBrowser(&browser); service()->Disconnect(&browser); } + +// Tests that PlaceholderTabsEnabled() can be called at any time. +TEST_F(LegacySessionRestorationServiceTest, PlaceholderTabsEnabled) { + EXPECT_FALSE(service()->PlaceholderTabsEnabled()); +}
diff --git a/ios/chrome/browser/sessions/session_restoration_service.h b/ios/chrome/browser/sessions/session_restoration_service.h index 508b96b..fc1f2bd 100644 --- a/ios/chrome/browser/sessions/session_restoration_service.h +++ b/ios/chrome/browser/sessions/session_restoration_service.h
@@ -91,6 +91,9 @@ // Removes any persisted data that is no longer needed and invokes // `closure` on the calling sequence when done. virtual void PurgeUnassociatedData(base::OnceClosure closure) = 0; + + // Returns whether placeholder tabs support is enabled. + virtual bool PlaceholderTabsEnabled() const = 0; }; #endif // IOS_CHROME_BROWSER_SESSIONS_SESSION_RESTORATION_SERVICE_H_
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.h b/ios/chrome/browser/sessions/session_restoration_service_impl.h index b1b6b5a0..5d3887492 100644 --- a/ios/chrome/browser/sessions/session_restoration_service_impl.h +++ b/ios/chrome/browser/sessions/session_restoration_service_impl.h
@@ -61,6 +61,7 @@ void InvokeClosureWhenBackgroundProcessingDone( base::OnceClosure closure) final; void PurgeUnassociatedData(base::OnceClosure closure) final; + bool PlaceholderTabsEnabled() const final; private: // Helper type used to record information about a single WebStateList.
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.mm b/ios/chrome/browser/sessions/session_restoration_service_impl.mm index effc4d1..c733740 100644 --- a/ios/chrome/browser/sessions/session_restoration_service_impl.mm +++ b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
@@ -497,6 +497,11 @@ std::move(closure)); } +bool SessionRestorationServiceImpl::PlaceholderTabsEnabled() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return true; +} + #pragma mark - Private void SessionRestorationServiceImpl::MarkWebStateListDirty(
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm index c5a6765..d80096ab 100644 --- a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm +++ b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
@@ -1044,3 +1044,8 @@ service()->Disconnect(&browser); } + +// Tests that PlaceholderTabsEnabled() can be called at any time. +TEST_F(SessionRestorationServiceImplTest, PlaceholderTabsEnabled) { + EXPECT_TRUE(service()->PlaceholderTabsEnabled()); +}
diff --git a/ios/chrome/browser/sessions/test_session_restoration_service.h b/ios/chrome/browser/sessions/test_session_restoration_service.h index e0d76fd0..2ebf241 100644 --- a/ios/chrome/browser/sessions/test_session_restoration_service.h +++ b/ios/chrome/browser/sessions/test_session_restoration_service.h
@@ -39,6 +39,7 @@ void InvokeClosureWhenBackgroundProcessingDone( base::OnceClosure closure) override; void PurgeUnassociatedData(base::OnceClosure closure) final; + bool PlaceholderTabsEnabled() const final; private: base::ObserverList<SessionRestorationObserver, true> observers_;
diff --git a/ios/chrome/browser/sessions/test_session_restoration_service.mm b/ios/chrome/browser/sessions/test_session_restoration_service.mm index 99bfb6c9c..674d7a29 100644 --- a/ios/chrome/browser/sessions/test_session_restoration_service.mm +++ b/ios/chrome/browser/sessions/test_session_restoration_service.mm
@@ -97,3 +97,7 @@ base::SequencedTaskRunner::GetCurrentDefault()->PostTask(FROM_HERE, std::move(closure)); } + +bool TestSessionRestorationService::PlaceholderTabsEnabled() const { + return false; +}
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn index 61a450ff..8045aff 100644 --- a/ios/chrome/browser/tabs/model/BUILD.gn +++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -164,10 +164,15 @@ "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/web_state_list", "//ios/chrome/browser/sync/model/glue", - "//ios/web/common:features", "//ios/web/public", "//ios/web/public:web_state_observer", "//ios/web/public/navigation", + + # TODO(crbug.com/1504753): Remove those deps when support for legacy + # session storage is removed. + "//ios/chrome/browser/sessions:session_restoration_service", + "//ios/chrome/browser/sessions:session_restoration_service_factory", + "//ios/chrome/browser/shared/model/browser_state", "//ios/web/public/session", ] }
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h index dc20395..02ec813 100644 --- a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h +++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.h
@@ -63,6 +63,9 @@ // The associated WebState. web::WebState* const web_state_; + // Whether placeholder tabs support is enabled. + const bool placeholder_tabs_support_enabled_; + // The session storage for the WebState. Used only when the support for // placeholder tabs is not enabled. Invalid to use otherwise. mutable CRWSessionStorage* session_storage_;
diff --git a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm index 365730f..27f6075 100644 --- a/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm +++ b/ios/chrome/browser/tabs/model/ios_chrome_synced_tab_delegate.mm
@@ -10,12 +10,17 @@ #import "components/sync_sessions/synced_window_delegates_getter.h" #import "ios/chrome/browser/complex_tasks/model/ios_task_tab_helper.h" #import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h" -#import "ios/web/common/features.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" +#import "ios/web/public/web_state.h" + +// TODO(crbug.com/1504753): Remove those imports and the corresponding deps +// when support for legacy session storage is removed. +#import "ios/chrome/browser/sessions/session_restoration_service.h" +#import "ios/chrome/browser/sessions/session_restoration_service_factory.h" +#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/web/public/session/crw_navigation_item_storage.h" #import "ios/web/public/session/crw_session_storage.h" -#import "ios/web/public/web_state.h" namespace { @@ -30,27 +35,26 @@ : web_state->GetNavigationManager()->GetItemAtIndex(index); } -// Returns whether placeholder tabs are supported. -bool ArePlaceholderTabsSupported() { - // The support for placeholder tabs requires the WebState session id to be - // stable across application restart. It is the case since M-114 which added - // the code to save and restore the identifier. However, it also requires - // that the stable identifier is communicated to sync with the detail about - // the corresponding session which will happen as the application is used. - // - // Yet, placeholder tabs support is required to enable session restoration - // optimisations. As this will be launched later, it is expected that by - // that point, all existing sessions will have been converted to use the - // stable session id and the session state uploaded to sync. Thus it is - // safe to enable the support of placeholder tabs behind the same feature - // controlling the other session restoration optimisations. - return web::features::UseSessionSerializationOptimizations(); +// Returns whether the session restoration service requires the support of +// placeholder tabs to be used. +bool PlaceholderTabsSupportEnabled(web::WebState* web_state) { + // Some unit tests create WebStates without a BrowserState. Don't crash. + web::BrowserState* browser_state = web_state->GetBrowserState(); + if (!browser_state) { + return false; + } + + return SessionRestorationServiceFactory::GetForBrowserState( + ChromeBrowserState::FromBrowserState(browser_state)) + ->PlaceholderTabsEnabled(); } } // namespace IOSChromeSyncedTabDelegate::IOSChromeSyncedTabDelegate(web::WebState* web_state) - : web_state_(web_state) { + : web_state_(web_state), + placeholder_tabs_support_enabled_( + PlaceholderTabsSupportEnabled(web_state_)) { DCHECK(web_state); } @@ -163,7 +167,7 @@ bool IOSChromeSyncedTabDelegate::IsPlaceholderTab() const { // Can't be a placeholder tab if the support for placeholder tabs is not // enabled. - if (!ArePlaceholderTabsSupported()) { + if (!placeholder_tabs_support_enabled_) { return false; } @@ -247,7 +251,7 @@ // Never use the session storage when placeholder tabs support is enabled. // In fact, using the session storage is a workaround to missing placeholder // tab support. - if (ArePlaceholderTabsSupported()) { + if (placeholder_tabs_support_enabled_) { return false; }
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm index a0e2c3c..79bcae28 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm
@@ -148,14 +148,12 @@ // Observes the frame property of the view of the `webState` using KVO. - (void)observeWebStateViewFrame:(web::WebState*)webState { - if (_installedObserver || !webState->GetView()) { + if (base::FeatureList::IsEnabled(kFullscreenImprovement) || + _installedObserver || !webState->GetView()) { return; } NSKeyValueObservingOptions options = 0; - if (!base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) { - options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; - } [webState->GetView() addObserver:self forKeyPath:@"frame" options:options @@ -168,19 +166,9 @@ ofObject:(id)object change:(NSDictionary*)change context:(void*)context { - if (![keyPath isEqualToString:@"frame"] || object != _webState->GetView()) + if (base::FeatureList::IsEnabled(kFullscreenImprovement) || + ![keyPath isEqualToString:@"frame"] || object != _webState->GetView()) { return; - - if (!base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) { - NSValue* oldValue = - base::apple::ObjCCast<NSValue>(change[NSKeyValueChangeOldKey]); - NSValue* newValue = - base::apple::ObjCCast<NSValue>(change[NSKeyValueChangeNewKey]); - // If the value is unchanged -- if the old and new values are equal -- - // then return without notifying observers. - if (oldValue && newValue && [newValue isEqualToValue:oldValue]) { - return; - } } [self updateForCurrentState];
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 c47a6871..34c626c 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
@@ -36,6 +36,7 @@ #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_view_controller_mutator.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.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" @@ -73,6 +74,7 @@ NSString* const kSuggestedActionsSectionIdentifier = @"SuggestedActionsSectionIdentifier"; NSString* const kCellIdentifier = @"GridCellIdentifier"; +NSString* const kGroupCellIdentifier = @"GroupGridCellIdentifier"; // Creates an NSIndexPath with `index` in section 0. NSIndexPath* CreateIndexPath(NSInteger index) { @@ -85,9 +87,17 @@ return [NSString stringWithFormat:@"%@%ld", kGridCellIdentifierPrefix, index]; } +// Returns the accessibility identifier to set on a GroupGridCell when +// positioned at the given index. +NSString* GroupGridCellAccessibilityIdentifier(NSUInteger index) { + return [NSString + stringWithFormat:@"%@%ld", kGroupGridCellIdentifierPrefix, index]; +} + } // namespace @interface BaseGridViewController () <GridCellDelegate, + GroupGridCellDelegate, SuggestedActionsViewControllerDelegate, UICollectionViewDragDelegate, UICollectionViewDropDelegate, @@ -99,6 +109,9 @@ // The cell registration for grid cells. @property(nonatomic, strong) UICollectionViewCellRegistration* gridCellRegistration; +// The cell registration for grid group cells. +@property(nonatomic, strong) + UICollectionViewCellRegistration* groupGridCellRegistration; // The cell registration for the Suggested Actions cell. @property(nonatomic, strong) UICollectionViewCellRegistration* suggestedActionsCellRegistration; @@ -218,6 +231,8 @@ // registered. [collectionView registerClass:[GridCell class] forCellWithReuseIdentifier:kCellIdentifier]; + [collectionView registerClass:[GroupGridCell class] + forCellWithReuseIdentifier:kGroupCellIdentifier]; collectionView.delegate = self; collectionView.backgroundView = [[UIView alloc] init]; @@ -433,8 +448,14 @@ if (path.section != tabSectionIndex) { continue; } - GridCell* cell = ObjCCastStrict<GridCell>( - [self.collectionView cellForItemAtIndexPath:path]); + UICollectionViewCell* collectionViewCell = + [self.collectionView cellForItemAtIndexPath:path]; + if (![collectionViewCell isKindOfClass:[GridCell class]]) { + // TODO(crbug.com/1513165): Remove once the transition annimation for the + // group cells is available. + continue; + } + GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell); UICollectionViewLayoutAttributes* attributes = [self.collectionView layoutAttributesForItemAtIndexPath:path]; // Normalize frame to window coordinates. The attributes class applies this @@ -477,9 +498,14 @@ containsObject:selectedItemIndexPath]) { return nil; } - - GridCell* cell = ObjCCastStrict<GridCell>( - [self.collectionView cellForItemAtIndexPath:selectedItemIndexPath]); + UICollectionViewCell* collectionViewCell = + [self.collectionView cellForItemAtIndexPath:selectedItemIndexPath]; + if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) { + // TODO(crbug.com/1501837): Handle once the annimations are available for + // group cells. + return nil; + } + GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell); UICollectionViewLayoutAttributes* attributes = [self.collectionView layoutAttributesForItemAtIndexPath:selectedItemIndexPath]; @@ -603,6 +629,11 @@ // another – correct – layout shortly after the incorrect one. // Keep `items`' bounds valid. if (self.items.count == 0 || itemIndex >= self.items.count) { + if (base::FeatureList::IsEnabled(kTabGroupsInGrid)) { + return [self.collectionView + dequeueReusableCellWithReuseIdentifier:kGroupCellIdentifier + forIndexPath:indexPath]; + } // Dequeue using the reuse identifier, not the registration, as there is // no valid `item` that could be passed in for the configuration. return [self.collectionView @@ -610,6 +641,14 @@ forIndexPath:indexPath]; } TabSwitcherItem* item = self.items[itemIndex]; + if (base::FeatureList::IsEnabled(kTabGroupsInGrid)) { + UICollectionViewCellRegistration* groupCellRegistration = + self.groupGridCellRegistration; + return [self.collectionView + dequeueConfiguredReusableCellWithRegistration:groupCellRegistration + forIndexPath:indexPath + item:item]; + } UICollectionViewCellRegistration* registration = self.gridCellRegistration; return [self.collectionView @@ -679,8 +718,14 @@ return nil; } - GridCell* cell = ObjCCastStrict<GridCell>( - [self.collectionView cellForItemAtIndexPath:indexPath]); + UICollectionViewCell* collectionViewCell = + [self.collectionView cellForItemAtIndexPath:indexPath]; + if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) { + // TODO(crbug.com/1501837): Handle the context menu for group cells, and + // remove this check. + return nil; + } + GridCell* cell = ObjCCastStrict<GridCell>(collectionViewCell); MenuScenarioHistogram scenario; if (_mode == TabGridModeSearch) { @@ -874,8 +919,14 @@ return nil; } - GridCell* gridCell = ObjCCastStrict<GridCell>( - [self.collectionView cellForItemAtIndexPath:indexPath]); + UICollectionViewCell* collectionViewCell = + [self.collectionView cellForItemAtIndexPath:indexPath]; + if ([collectionViewCell isKindOfClass:[GroupGridCell class]]) { + // TODO(crbug.com/1513165): Remove once the annimations for group cells are + // available. + return nil; + } + GridCell* gridCell = ObjCCastStrict<GridCell>(collectionViewCell); return gridCell.dragPreviewParameters; } @@ -1025,6 +1076,13 @@ } } +#pragma mark - GroupGridCellDelegate + +- (void)closeButtonTappedForGroupCell:(GroupGridCell*)cell { + [self.delegate gridViewController:self + didCloseItemWithID:cell.itemIdentifier]; +} + #pragma mark - SuggestedActionsViewControllerDelegate - (void)suggestedActionsViewController: @@ -1451,6 +1509,14 @@ - (void)createRegistrations { __weak __typeof(self) weakSelf = self; + auto configureGroupGridCell = + ^(GroupGridCell* cell, NSIndexPath* indexPath, TabSwitcherItem* item) { + [weakSelf configureGroupCell:cell withItem:item atIndex:indexPath.item]; + }; + self.groupGridCellRegistration = [UICollectionViewCellRegistration + registrationWithCellClass:[GroupGridCell class] + configurationHandler:configureGroupGridCell]; + // Register GridCell. auto configureGridCell = ^(GridCell* cell, NSIndexPath* indexPath, TabSwitcherItem* item) { @@ -1600,6 +1666,64 @@ return [self.items indexOfObjectPassingTest:selectedTest]; } +// Configures `groupCell`'s identifier and title synchronously, and pass the +// list of `GroupTabInfo`asynchronously with information from `item`. Updates +// the `cell`'s theme to this view controller's theme. This view controller +// becomes the delegate for the cell. +- (void)configureGroupCell:(GroupGridCell*)cell + withItem:(TabSwitcherItem*)item + atIndex:(NSUInteger)index { + CHECK(cell); + CHECK(item); + cell.delegate = self; + cell.theme = self.theme; + cell.itemIdentifier = item.identifier; + cell.title = item.title; + cell.titleHidden = item.hidesTitle; + cell.accessibilityIdentifier = GroupGridCellAccessibilityIdentifier(index); + if (self.mode == TabGridModeSelection) { + if ([self.gridProvider isItemSelected:item.identifier]) { + cell.state = GridCellStateEditingSelected; + } else { + cell.state = GridCellStateEditingUnselected; + } + } else { + cell.state = GridCellStateNotEditing; + } + [item fetchFavicon:^(TabSwitcherItem* innerItem, UIImage* icon) { + // Only update the icon if the cell is not already reused for another item. + if (cell.itemIdentifier == innerItem.identifier) { + // TODO(crbug.com/1501837): Remove once the group color is available + // throught the group model. Keep for now for testing purposes. + cell.icon = icon; + } + }]; + + [item fetchSnapshot:^(TabSwitcherItem* innerItem, UIImage* snapshot) { + // Only update the icon if the cell is not already reused for another item. + if (cell.itemIdentifier == innerItem.identifier) { + GroupTabInfo* snapshotFavicon = [[GroupTabInfo alloc] init]; + snapshotFavicon.snapshot = snapshot; + snapshotFavicon.favicon = snapshot; + // The `snapshotFavicon` is for demo purposes only, it will be replaced + // when the group tab model is available, the objects in `groupTabInfos` + // can be updated manually to view the different group tab configurations. + NSArray<GroupTabInfo*>* groupTabInfos = @[ + snapshotFavicon, snapshotFavicon, snapshotFavicon, snapshotFavicon, + snapshotFavicon, snapshotFavicon + ]; + [cell configureWithGroupTabInfos:groupTabInfos]; + } + }]; + + cell.opacity = 1.0f; + if (item.showsActivity) { + [cell showActivityIndicator]; + } else { + [cell hideActivityIndicator]; + } +} + // Configures `cell`'s identifier and title synchronously, and favicon and // snapshot asynchronously with information from `item`. Updates the `cell`'s // theme to this view controller's theme. This view controller becomes the
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h index 06d2993..c0afdd3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.h
@@ -8,6 +8,7 @@ #import <UIKit/UIKit.h> #import "ios/chrome/browser/ui/commerce/price_card/price_card_view.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_theme.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_cell.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_grid_to_tab_transition_view.h" @@ -19,13 +20,6 @@ - (void)closeButtonTappedForCell:(GridCell*)cell; @end -// Values describing the editing state of the cell. -typedef NS_ENUM(NSUInteger, GridCellState) { - GridCellStateNotEditing = 1, - GridCellStateEditingUnselected, - GridCellStateEditingSelected, -}; - // A square-ish cell in a grid. Contains an icon, title, snapshot, and close // button. @interface GridCell : TabCell
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm index c2c828a..08f7e09 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
@@ -14,7 +14,6 @@ #import "ios/chrome/browser/shared/ui/elements/top_aligned_image_view.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" -#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" #import "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h index 9bdedcb..d76ef71 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h
@@ -14,6 +14,12 @@ // index]. extern NSString* const kGridCellIdentifierPrefix; +// Accessibility identifier prefix of a group grid cell. To reference a specific +// cell, concatenate `kGroupGridCellIdentifierPrefix` with the index of the +// cell. For example, [NSString stringWithFormat:@"%@%d", +// kGroupGridCellIdentifierPrefix, index]. +extern NSString* const kGroupGridCellIdentifierPrefix; + // Accessibility identifier for the close button in a grid cell. extern NSString* const kGridCellCloseButtonIdentifier; @@ -99,4 +105,10 @@ extern const CGFloat kGridCellPriceDropLeadingSpacing; extern const CGFloat kGridCellPriceDropTrailingSpacing; +typedef NS_ENUM(NSUInteger, GridCellState) { + GridCellStateNotEditing = 1, + GridCellStateEditingUnselected, + GridCellStateEditingSelected, +}; + #endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm index bef4b06..b360ea2 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.mm
@@ -7,6 +7,10 @@ // Accessibility identifier prefix of a grid cell. NSString* const kGridCellIdentifierPrefix = @"GridCellIdentifierPrefix"; +// Accessibility identifier prefix of a grid cell. +NSString* const kGroupGridCellIdentifierPrefix = + @"GroupGridCellIdentifierPrefix"; + // Accessibility identifier for the close button in a grid cell. NSString* const kGridCellCloseButtonIdentifier = @"GridCellCloseButtonIdentifier";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h index f63c407..b3771024 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_theme.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_info.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_cell.h" @@ -18,13 +19,6 @@ - (void)closeButtonTappedForGroupCell:(GroupGridCell*)cell; @end -// Values describing the editing state of the cell. -typedef NS_ENUM(NSUInteger, GroupGridCellState) { - GroupGridCellStateNotEditing = 1, - GroupGridCellStateEditingUnselected, - GroupGridCellStateEditingSelected, -}; - // A square-ish cell in a grid. Contains the group's favicon, its title and // close button. @interface GroupGridCell : TabCell @@ -39,7 +33,7 @@ // Sets to update and keep cell alpha in sync. @property(nonatomic, assign) CGFloat opacity; // The current state which the cell should display. -@property(nonatomic, assign) GroupGridCellState state; +@property(nonatomic, assign) GridCellState state; // Configures every tab of the group with a given snapshot/favicon pairs. - (void)configureWithGroupTabInfos:(NSArray<GroupTabInfo*>*)groupTabInfos;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm index c0fcac1..6471153 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
@@ -84,7 +84,7 @@ - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - _state = GroupGridCellStateNotEditing; + _state = GridCellStateNotEditing; // The background color must be set to avoid the corners behind the rounded // layer from showing when dragging and dropping. Unfortunately, using @@ -567,7 +567,7 @@ } - (UIImage*)selectIconImageForCurrentState { - if (_state == GroupGridCellStateEditingUnselected) { + if (_state == GridCellStateEditingUnselected) { return DefaultSymbolTemplateWithPointSize(kCircleSymbol, kIconSymbolPointSize); } @@ -609,10 +609,10 @@ } - (BOOL)isInSelectionMode { - return self.state != GroupGridCellStateNotEditing; + return self.state != GridCellStateNotEditing; } -- (void)setState:(GroupGridCellState)state { +- (void)setState:(GridCellState)state { if (state == _state) { return; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm index 14d3084f..214ce98 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
@@ -21,6 +21,9 @@ // Size of the decoration corner when the cell is selected. const CGFloat kCornerSize = 16; +// Threshold width for collapsing the cell and hiding the close button. +const CGFloat kCollapsedWidthThreshold = 150; + // Content view constants. const CGFloat kFaviconLeadingMargin = 16; const CGFloat kCloseButtonMargin = 10; @@ -52,6 +55,10 @@ // Circular spinner that shows the loading state of the tab. MDCActivityIndicator* _activityIndicator; + + // Title label's trailing constraints. + NSLayoutConstraint* _titleLabelCollapsedTrailingConstraint; + NSLayoutConstraint* _titleLabelTrailingConstraint; } - (instancetype)initWithFrame:(CGRect)frame { @@ -147,6 +154,15 @@ _rightTailView.hidden = !selected; _topLeftCornerView.hidden = !selected; _topRightCornerView.hidden = !selected; + + [self updateCollapsedState]; +} + +- (void)applyLayoutAttributes: + (UICollectionViewLayoutAttributes*)layoutAttributes { + [super applyLayoutAttributes:layoutAttributes]; + + [self updateCollapsedState]; } #pragma mark - UICollectionViewCell @@ -199,6 +215,30 @@ _decorationLayersUpdated = YES; } +/// Hides the close button view if the cell is collapsed. +- (void)updateCollapsedState { + BOOL collapsed = NO; + if (self.frame.size.width < kCollapsedWidthThreshold) { + // Don't hide the close button if the cell is selected. + collapsed = !self.selected; + } + + if (collapsed == _closeButton.hidden) { + return; + } + + _closeButton.hidden = collapsed; + + // To avoid breaking the layout, always disable the active constraint first. + if (collapsed) { + _titleLabelTrailingConstraint.active = NO; + _titleLabelCollapsedTrailingConstraint.active = YES; + } else { + _titleLabelCollapsedTrailingConstraint.active = NO; + _titleLabelTrailingConstraint.active = YES; + } +} + // Sets the cell constraints. - (void)setupConstraints { UILayoutGuide* leadingImageGuide = [[UILayoutGuide alloc] init]; @@ -220,11 +260,8 @@ AddSameConstraints(leadingImageGuide, _faviconView); AddSameConstraints(leadingImageGuide, _activityIndicator); - /// `_closeButton` image constraints. + /// `_closeButton` constraints. [NSLayoutConstraint activateConstraints:@[ - [_closeButton.leadingAnchor - constraintEqualToAnchor:_titleLabel.trailingAnchor - constant:kCloseButtonMargin], [_closeButton.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor constant:-kCloseButtonMargin], @@ -235,13 +272,16 @@ ]]; /// `_titleLabel` constraints. + _titleLabelTrailingConstraint = [_titleLabel.trailingAnchor + constraintEqualToAnchor:_closeButton.leadingAnchor + constant:-kTitleInset]; + _titleLabelCollapsedTrailingConstraint = [_titleLabel.trailingAnchor + constraintEqualToAnchor:contentView.trailingAnchor + constant:-kTitleInset]; [NSLayoutConstraint activateConstraints:@[ [_titleLabel.leadingAnchor constraintEqualToAnchor:leadingImageGuide.trailingAnchor constant:kTitleInset], - [_titleLabel.trailingAnchor - constraintLessThanOrEqualToAnchor:contentView.trailingAnchor - constant:-kTitleInset], [_titleLabel.centerYAnchor constraintEqualToAnchor:contentView.centerYAnchor], ]];
diff --git a/ios/chrome/browser/ui/unit_conversion/BUILD.gn b/ios/chrome/browser/ui/unit_conversion/BUILD.gn index 56137ea..ab3b951 100644 --- a/ios/chrome/browser/ui/unit_conversion/BUILD.gn +++ b/ios/chrome/browser/ui/unit_conversion/BUILD.gn
@@ -44,6 +44,7 @@ ] deps = [ ":constants", + "//components/crash/core/common", "//components/prefs", "//ios/chrome/app/strings", "//ios/chrome/browser/shared/ui/symbols",
diff --git a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm index 52d18d0..62be56d 100644 --- a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm +++ b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
@@ -7,7 +7,10 @@ #import <vector> #import "base/check.h" +#import "base/debug/dump_without_crashing.h" #import "base/notreached.h" +#import "base/strings/sys_string_conversions.h" +#import "components/crash/core/common/crash_key.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/ui/unit_conversion/unit_conversion_constants.h" #import "ios/chrome/browser/ui/unit_conversion/unit_conversion_mutator.h" @@ -467,6 +470,43 @@ } } +- (void)generateDumpReport { + // There has been evidence that unitMenuButtonTitle may be nil (see + // crbug/1512445) but this could not be reproduced. To prevent further + // crash, set the title to a valid string and log more info so this can + // be debugged. + // TODO(crbug.com/1513168): remove when the issue is fixed. + NSString* debugSourceUnit = _formattedSourceUnit; + if (!debugSourceUnit) { + debugSourceUnit = [_sourceUnit description]; + } + if (!debugSourceUnit) { + debugSourceUnit = @""; + } + if ([debugSourceUnit length] > 31) { + debugSourceUnit = [debugSourceUnit substringToIndex:31]; + } + NSString* debugTargetUnit = _formattedTargetUnit; + if (!debugTargetUnit) { + debugTargetUnit = [_targetUnit description]; + } + if (!debugTargetUnit) { + debugTargetUnit = @""; + } + if ([debugTargetUnit length] > 31) { + debugTargetUnit = [debugTargetUnit substringToIndex:31]; + } + static crash_reporter::CrashKeyString<32> sourceKey("source_unit"); + crash_reporter::ScopedCrashKeyString crashSourceKey( + &sourceKey, base::SysNSStringToUTF8(debugSourceUnit)); + + static crash_reporter::CrashKeyString<32> targetKey("target_unit"); + crash_reporter::ScopedCrashKeyString crashTargetKey( + &targetKey, base::SysNSStringToUTF8(debugTargetUnit)); + + base::debug::DumpWithoutCrashing(); +} + #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { @@ -501,6 +541,11 @@ } else { NOTREACHED_NORETURN(); } + + if (!unitMenuButtonTitle) { + unitMenuButtonTitle = @""; + [self generateDumpReport]; + } UIButtonConfiguration* unitMenuButtonConfiguration = cell.unitMenuButton.configuration; unitMenuButtonConfiguration.attributedTitle = [self
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 5370effe..f896ed6 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -55a056904656de72e797a23b6a39b3c66bee3a0a \ No newline at end of file +d993b76ada9c5f5522d770d7ef3e676e38d34be3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 3f08bea6..5bed726 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -2e130d8faaa86d745e6a8d37d33688bd8082d48c \ No newline at end of file +6b3a919faf4176124aa8d3e031c1bcacf2258eef \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index c405e9e..391485d2 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -fafa9a291ec1e036ead78e4758c2450491830be8 \ No newline at end of file +73e9840224064639a3e94e0e4574d455f0e65cfc \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index d8f4caa..d2e0cec 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -a3ce27dd82e16caf6eecb16ff43274d99e36e987 \ No newline at end of file +64f39ba3b9c8b8d957e1ce1e3cb3405c14a2b979 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 32f84e9..36edc26f 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -c69d827812c640c5939cad173867737c6ba5e833 \ No newline at end of file +e867aa6bbdf80ea7eab1814ca0f6e9546f822d51 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 89a711e..99d70158 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -d8217234f3502146d8623f95ad760b0e00d91c0f \ No newline at end of file +5123007a328f2100bb08e81108972835b3922b54 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index e364c136..0993858c 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -d5b76e4e5dee70358814fbe60efa70cee7e2ecee \ No newline at end of file +78652ed2f1573874826b3a0b03cd51d76a513bd7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 01e3cb8..0282d39 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -a5fa1f969c43c034a1eef3d3903e40dc2d7e6ca4 \ No newline at end of file +622fa3d70bc9d5b666f3d322d889a43d93242476 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 00bbdba59..33be0e3 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -c60230963f286e6e8c712f15d43132e7a4d89d09 \ No newline at end of file +8d340b1c37e30ea4ad26e2854bb138f99b2e828e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 88009b31..bb6ff17 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -b74e5edc85b3b83bd5b48b35d0db8b54a65d67f0 \ No newline at end of file +1a7df88d2ce8e86546975daa8c84196d4ecc23de \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index b84924c7..d125338 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -1c0690d9572073a7872140e70375d0f8bef66672 \ No newline at end of file +bef2afa2ae40d627c9793fec7de2e42eb20e5c62 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 84d3220..c57a893 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -a291bb6a88e0212fa4c8300e364bf4b5f30a0048 \ No newline at end of file +50b48dd625d63050824df681e6501e225024ce97 \ No newline at end of file
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index 0b8d5f6e..edf01d97 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -136,8 +136,6 @@ "src/components/Chips/src/MDCChipView.h", "src/components/Chips/src/MDCChipViewAccessoryView.h", "src/components/Chips/src/MDCChipViewDeleteButton.h", - "src/components/Chips/src/MDCLegacyChipField.h", - "src/components/Chips/src/MDCLegacyChipFieldDelegate.h", "src/components/Chips/src/MaterialChips.h", "src/components/Chips/src/PerformantShadowMigration/MDCChipView+ShadowsPrivate.h", "src/components/Chips/src/Theming/MDCChipView+MaterialTheming.h", @@ -924,9 +922,6 @@ "src/components/Chips/src/MDCChipViewAccessoryView.m", "src/components/Chips/src/MDCChipViewDeleteButton.h", "src/components/Chips/src/MDCChipViewDeleteButton.m", - "src/components/Chips/src/MDCLegacyChipField.h", - "src/components/Chips/src/MDCLegacyChipField.m", - "src/components/Chips/src/MDCLegacyChipFieldDelegate.h", "src/components/Chips/src/MaterialChips.h", "src/components/Chips/src/PerformantShadowMigration/MDCChipView+ShadowsPrivate.h", "src/components/Chips/src/Theming/MDCChipView+MaterialTheming.h",
diff --git a/ios/third_party/material_components_ios/src b/ios/third_party/material_components_ios/src index c4c73b5..00fac7e 160000 --- a/ios/third_party/material_components_ios/src +++ b/ios/third_party/material_components_ios/src
@@ -1 +1 @@ -Subproject commit c4c73b5452c7efca23db99cde8746d36e0ed107a +Subproject commit 00fac7e67918c03a47eb79b5e65d7a5aa6cbf70f
diff --git a/ios_internal b/ios_internal index 6ab4b39..ac06513 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 6ab4b39499215991e1d58a879aec026c6f54a925 +Subproject commit ac06513c41078df3c7e5c292bbfdd2423dc61741
diff --git a/media/cdm/cdm_module.cc b/media/cdm/cdm_module.cc index 83bd26b..65fef0d 100644 --- a/media/cdm/cdm_module.cc +++ b/media/cdm/cdm_module.cc
@@ -172,6 +172,7 @@ void CdmModule::InitializeCdmModule() { DCHECK(initialized_); DCHECK(initialize_cdm_module_func_); + TRACE_EVENT0("media", "CdmModule::InitializeCdmModule"); initialize_cdm_module_func_(); }
diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn index 2c445208..9e2cf61 100644 --- a/mojo/public/java/BUILD.gn +++ b/mojo/public/java/BUILD.gn
@@ -29,7 +29,6 @@ "bindings/src/org/chromium/mojo/bindings/AssociatedInterfaceRequestNotSupported.java", "bindings/src/org/chromium/mojo/bindings/AutoCloseableRouter.java", "bindings/src/org/chromium/mojo/bindings/BindingsHelper.java", - "bindings/src/org/chromium/mojo/bindings/Callbacks.java", "bindings/src/org/chromium/mojo/bindings/ConnectionErrorHandler.java", "bindings/src/org/chromium/mojo/bindings/Connector.java", "bindings/src/org/chromium/mojo/bindings/DataHeader.java",
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java deleted file mode 100644 index 0ee59d9..0000000 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Callbacks.java +++ /dev/null
@@ -1,250 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file was generated using -// mojo/tools/generate_java_callback_interfaces.py - -package org.chromium.mojo.bindings; - -/** Contains a generic interface for callbacks. */ -public interface Callbacks { - - /** A generic callback. */ - interface Callback0 { - /** Call the callback. */ - public void call(); - } - - /** - * A generic 1-argument callback. - * - * @param <T1> the type of argument 1. - */ - interface Callback1<T1> { - /** Call the callback. */ - public void call(T1 arg1); - } - - /** - * A generic 2-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - */ - interface Callback2<T1, T2> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2); - } - - /** - * A generic 3-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - */ - interface Callback3<T1, T2, T3> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2, T3 arg3); - } - - /** - * A generic 4-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - */ - interface Callback4<T1, T2, T3, T4> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4); - } - - /** - * A generic 5-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - */ - interface Callback5<T1, T2, T3, T4, T5> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); - } - - /** - * A generic 6-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - * @param <T6> the type of argument 6. - */ - interface Callback6<T1, T2, T3, T4, T5, T6> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); - } - - /** - * A generic 7-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - * @param <T6> the type of argument 6. - * @param <T7> the type of argument 7. - */ - interface Callback7<T1, T2, T3, T4, T5, T6, T7> { - /** Call the callback. */ - public void call(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); - } - - /** - * A generic 11-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - * @param <T6> the type of argument 6. - * @param <T7> the type of argument 7. - * @param <T8> the type of argument 8. - * @param <T9> the type of argument 9. - * @param <T10> the type of argument 10. - * @param <T11> the type of argument 11. - */ - interface Callback11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> { - /** Call the callback. */ - public void call( - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11); - } - - /** - * A generic 13-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - * @param <T6> the type of argument 6. - * @param <T7> the type of argument 7. - * @param <T8> the type of argument 8. - * @param <T9> the type of argument 9. - * @param <T10> the type of argument 10. - * @param <T11> the type of argument 11. - * @param <T12> the type of argument 12. - * @param <T13> the type of argument 13. - */ - interface Callback13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> { - /** Call the callback. */ - public void call( - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13); - } - - /** - * A generic 22-argument callback. - * - * @param <T1> the type of argument 1. - * @param <T2> the type of argument 2. - * @param <T3> the type of argument 3. - * @param <T4> the type of argument 4. - * @param <T5> the type of argument 5. - * @param <T6> the type of argument 6. - * @param <T7> the type of argument 7. - * @param <T8> the type of argument 8. - * @param <T9> the type of argument 9. - * @param <T10> the type of argument 10. - * @param <T11> the type of argument 11. - * @param <T12> the type of argument 12. - * @param <T13> the type of argument 13. - * @param <T14> the type of argument 14. - * @param <T15> the type of argument 15. - * @param <T16> the type of argument 16. - * @param <T17> the type of argument 17. - * @param <T18> the type of argument 18. - * @param <T19> the type of argument 19. - * @param <T20> the type of argument 20. - * @param <T21> the type of argument 21. - * @param <T22> the type of argument 22. - */ - interface Callback22< - T1, - T2, - T3, - T4, - T5, - T6, - T7, - T8, - T9, - T10, - T11, - T12, - T13, - T14, - T15, - T16, - T17, - T18, - T19, - T20, - T21, - T22> { - /** Call the callback. */ - public void call( - T1 arg1, - T2 arg2, - T3 arg3, - T4 arg4, - T5 arg5, - T6 arg6, - T7 arg7, - T8 arg8, - T9 arg9, - T10 arg10, - T11 arg11, - T12 arg12, - T13 arg13, - T14 arg14, - T15 arg15, - T16 arg16, - T17 arg17, - T18 arg18, - T19 arg19, - T20 arg20, - T21 arg21, - T22 arg22); - } -}
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java index db07462..51ab799 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
@@ -4,7 +4,6 @@ package org.chromium.mojo.bindings; -import org.chromium.mojo.bindings.Callbacks.Callback1; import org.chromium.mojo.bindings.Interface.AbstractProxy.HandlerImpl; import org.chromium.mojo.bindings.interfacecontrol.QueryVersion; import org.chromium.mojo.bindings.interfacecontrol.RequireVersion; @@ -53,12 +52,17 @@ /** Returns the version number of the interface that the remote side supports. */ public int getVersion(); + /** Callback interface for the async response to {@link Proxy#queryVersion}. */ + interface QueryVersionCallback { + public void call(int version); + } + /** * Queries the max version that the remote side supports. On completion, the result will * be returned as the input of |callback|. The version number of this interface pointer * will also be updated. */ - public void queryVersion(Callback1<Integer> callback); + public void queryVersion(QueryVersionCallback callback); /** * If the remote side doesn't support the specified version, it will close its end of @@ -167,7 +171,7 @@ * @see Handler#queryVersion(org.chromium.mojo.bindings.Callbacks.Callback1) */ @Override - public void queryVersion(final Callback1<Integer> callback) { + public void queryVersion(QueryVersionCallback callback) { RunMessageParams message = new RunMessageParams(); message.input = new RunInput(); message.input.setQueryVersion(new QueryVersion()); @@ -176,7 +180,7 @@ getCore(), mMessageReceiver, message, - new Callback1<RunResponseMessageParams>() { + new InterfaceControlMessagesHelper.SendRunMessageCallback() { @Override public void call(RunResponseMessageParams response) { if (response.output != null
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java index 253e639..33882dd 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java
@@ -4,7 +4,6 @@ package org.chromium.mojo.bindings; -import org.chromium.mojo.bindings.Callbacks.Callback1; import org.chromium.mojo.bindings.Interface.Manager; import org.chromium.mojo.bindings.Interface.Proxy; import org.chromium.mojo.bindings.interfacecontrol.InterfaceControlMessagesConstants; @@ -23,14 +22,22 @@ */ public class InterfaceControlMessagesHelper { /** + * Callback interface for the async response to {@link + * InterfaceControlMessagesHelper#sendRunMessage}. + */ + interface SendRunMessageCallback { + public void call(RunResponseMessageParams params); + } + + /** * MessageReceiver that forwards a message containing a {@link RunResponseMessageParams} to a * callback. */ private static class RunResponseForwardToCallback extends SideEffectFreeCloseable implements MessageReceiver { - private final Callback1<RunResponseMessageParams> mCallback; + private final SendRunMessageCallback mCallback; - RunResponseForwardToCallback(Callback1<RunResponseMessageParams> callback) { + RunResponseForwardToCallback(SendRunMessageCallback callback) { mCallback = callback; } @@ -51,7 +58,7 @@ Core core, MessageReceiverWithResponder receiver, RunMessageParams params, - Callback1<RunResponseMessageParams> callback) { + SendRunMessageCallback callback) { Message message = params.serializeWithHeader( core,
diff --git a/mojo/public/java/system/BUILD.gn b/mojo/public/java/system/BUILD.gn index 4d6caf24..862f772 100644 --- a/mojo/public/java/system/BUILD.gn +++ b/mojo/public/java/system/BUILD.gn
@@ -106,7 +106,6 @@ "javatests/src/org/chromium/mojo/bindings/BindingsTest.java", "javatests/src/org/chromium/mojo/bindings/BindingsTestUtils.java", "javatests/src/org/chromium/mojo/bindings/BindingsVersioningTest.java", - "javatests/src/org/chromium/mojo/bindings/CallbacksTest.java", "javatests/src/org/chromium/mojo/bindings/ConnectorTest.java", "javatests/src/org/chromium/mojo/bindings/ExecutorFactoryTest.java", "javatests/src/org/chromium/mojo/bindings/InterfacesTest.java",
diff --git a/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java b/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java deleted file mode 100644 index c9f8e6b..0000000 --- a/mojo/public/java/system/javatests/src/org/chromium/mojo/bindings/CallbacksTest.java +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.mojo.bindings; - -import androidx.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.mojo.bindings.Callbacks.Callback1; -import org.chromium.mojo.bindings.Callbacks.Callback7; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** Testing generated callbacks */ -@RunWith(BaseJUnit4ClassRunner.class) -public class CallbacksTest { - /** Testing {@link Callback1}. */ - @Test - @SmallTest - public void testCallback1() { - final List<Integer> parameters = new ArrayList<Integer>(); - new Callback1<Integer>() { - @Override - public void call(Integer i1) { - parameters.add(i1); - } - }.call(1); - Assert.assertEquals(Arrays.asList(1), parameters); - } - - /** Testing {@link Callback7}. */ - @Test - @SmallTest - public void testCallback7() { - final List<Integer> parameters = new ArrayList<Integer>(); - new Callback7<Integer, Integer, Integer, Integer, Integer, Integer, Integer>() { - @Override - public void call( - Integer i1, - Integer i2, - Integer i3, - Integer i4, - Integer i5, - Integer i6, - Integer i7) { - parameters.add(i1); - parameters.add(i2); - parameters.add(i3); - parameters.add(i4); - parameters.add(i5); - parameters.add(i6); - parameters.add(i7); - } - }.call(1, 2, 3, 4, 5, 6, 7); - Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), parameters); - } -}
diff --git a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl index c8d1209..72a57f5 100644 --- a/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl
@@ -18,13 +18,14 @@ {% endmacro %} {%- macro declare_callback(method) -%} - -interface {{method|interface_response_name}} extends org.chromium.mojo.bindings.Callbacks.Callback{{method.response_parameters|length}}{% if method.response_parameters %}< -{%- for param in method.response_parameters -%} -{{param.kind|java_type(True)}} +interface {{method|interface_response_name}} { + public void call( +{%- for param in method.response_parameters %} + {{param.kind|java_type(True)}} {{param|name}} {%- if not loop.last %}, {% endif %} -{%- endfor -%} ->{% endif %} { } +{%- endfor -%} + ); +} {%- endmacro -%} {%- macro run_callback(variable, parameters) -%}
diff --git a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java index bddd5426d..85edafe 100644 --- a/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java +++ b/services/device/nfc/android/java/src/org/chromium/device/nfc/NfcImpl.java
@@ -29,7 +29,6 @@ import org.chromium.device.mojom.NdefWriteOptions; import org.chromium.device.mojom.Nfc; import org.chromium.device.mojom.NfcClient; -import org.chromium.mojo.bindings.Callbacks; import org.chromium.mojo.bindings.InterfaceRequest; import org.chromium.mojo.bindings.Router; import org.chromium.mojo.system.MojoException; @@ -202,7 +201,11 @@ */ @Override public void push(NdefMessage message, NdefWriteOptions options, Push_Response callback) { - if (!checkIfReady(callback)) return; + NdefError error = checkIfReady(); + if (error != null) { + callback.call(error); + return; + } if (mOperationsSuspended) { callback.call( @@ -247,7 +250,11 @@ */ @Override public void makeReadOnly(MakeReadOnly_Response callback) { - if (!checkIfReady(callback)) return; + NdefError error = checkIfReady(); + if (error != null) { + callback.call(error); + return; + } if (mOperationsSuspended) { callback.call( @@ -289,7 +296,12 @@ */ @Override public void watch(int id, Watch_Response callback) { - if (!checkIfReady(callback)) return; + NdefError error = checkIfReady(); + if (error != null) { + callback.call(error); + return; + } + // We received a duplicate |id| here that should never happen, in such a case we should // report a bad message to Mojo but unfortunately Mojo bindings for Java does not support // this feature yet. So, we just passes back a generic error instead. @@ -415,20 +427,6 @@ } /** - * Uses checkIfReady() method and if NFC cannot be used, calls mojo callback with NdefError. - * - * @param callback Generic callback that is provided to watch() and push() methods. - * @return boolean true if NFC functionality can be used, false otherwise. - */ - private boolean checkIfReady(Callbacks.Callback1<NdefError> callback) { - NdefError error = checkIfReady(); - if (error == null) return true; - - callback.call(error); - return false; - } - - /** * Implementation of android.nfc.NfcAdapter.ReaderCallback. Callback is called when NFC tag is * discovered, Tag object is delegated to mojo service implementation method * NfcImpl.onTagDiscovered(). @@ -611,7 +609,8 @@ pendingMakeReadOnlyOperationCompleted( createError( NdefErrorType.NOT_SUPPORTED, - "Failed to make read-only because the tag cannot be made read-only")); + "Failed to make read-only because the tag cannot be made" + + " read-only")); } } catch (TagLostException e) { Log.w(TAG, "Cannot make NFC tag read-only. Tag is lost: " + e.getMessage());
diff --git a/services/on_device_model/ml/chrome_ml.cc b/services/on_device_model/ml/chrome_ml.cc index 4a22e6ba..db3cd48 100644 --- a/services/on_device_model/ml/chrome_ml.cc +++ b/services/on_device_model/ml/chrome_ml.cc
@@ -134,6 +134,10 @@ DISABLE_CFI_DLSYM bool ChromeML::IsGpuBlocked() const { + if (allow_gpu_for_testing_) { + return false; + } + GpuConfig gpu_config; if (!api().GetGpuConfig(gpu_config)) { LogGpuBlocked(GpuBlockedReason::kGpuConfigError);
diff --git a/services/on_device_model/ml/chrome_ml.h b/services/on_device_model/ml/chrome_ml.h index b2432b2c..e8e77c5 100644 --- a/services/on_device_model/ml/chrome_ml.h +++ b/services/on_device_model/ml/chrome_ml.h
@@ -37,12 +37,17 @@ // Whether or not the GPU is blocklisted. bool IsGpuBlocked() const; + void SetAllowGpuForTesting(bool allow_gpu) { + allow_gpu_for_testing_ = allow_gpu; + } + private: static std::unique_ptr<ChromeML> Create( const std::optional<std::string>& library_name); const base::ScopedNativeLibrary library_; const raw_ptr<const ChromeMLAPI> api_; + bool allow_gpu_for_testing_ = false; }; } // namespace ml
diff --git a/services/webnn/dml/graph_impl_test.cc b/services/webnn/dml/graph_impl_test.cc index 96f5ea0..dcbd61b 100644 --- a/services/webnn/dml/graph_impl_test.cc +++ b/services/webnn/dml/graph_impl_test.cc
@@ -11,7 +11,9 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "components/ml/webnn/features.mojom-features.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/webnn/dml/adapter.h" #include "services/webnn/dml/command_queue.h" @@ -227,12 +229,17 @@ void SetUp() override; protected: + base::test::ScopedFeatureList scoped_feature_list_; base::test::TaskEnvironment task_environment_; scoped_refptr<Adapter> adapter_; }; void WebNNGraphDMLImplTest::SetUp() { SKIP_TEST_IF(!UseGPUInTests()); + + scoped_feature_list_.InitAndEnableFeature( + webnn::mojom::features::kWebMachineLearningNeuralNetwork); + ASSERT_TRUE(InitializeGLDisplay()); Adapter::EnableDebugLayerForTesting(); auto adapter_creation_result = Adapter::GetInstanceForTesting();
diff --git a/services/webnn/webnn_graph_impl_unittest.cc b/services/webnn/webnn_graph_impl_unittest.cc index 7d930f4..c07a3f3 100644 --- a/services/webnn/webnn_graph_impl_unittest.cc +++ b/services/webnn/webnn_graph_impl_unittest.cc
@@ -5001,8 +5001,9 @@ } TEST_F(WebNNGraphImplTest, ValidateInputsTest) { - base::test::ScopedFeatureList feature_list; - feature_list.InitFromCommandLine("WebMachineLearningNeuralNetwork", ""); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + webnn::mojom::features::kWebMachineLearningNeuralNetwork); const std::vector<uint32_t> dimensions = {3, 5}; // Build the graph with mojo type.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index b30a1ec..f80b4e3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -15098,66 +15098,6 @@ ] } ], - "RequestDesktopSiteDefaultsControlCohort": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RequestDesktopSiteDefaultsControlSynthetic" - ] - } - ] - } - ], - "RequestDesktopSiteDefaultsEnabledCohort": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RequestDesktopSiteDefaultsSynthetic" - ] - } - ] - } - ], - "RequestDesktopSiteOptInControlCohort": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RequestDesktopSiteOptInControlSynthetic" - ] - } - ] - } - ], - "RequestDesktopSiteOptInEnabledCohort": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "RequestDesktopSiteOptInSynthetic" - ] - } - ] - } - ], "ResponsiveToolbar": [ { "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore index 3674dd1..b3a5540 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -64,12 +64,6 @@ /google-truth/src/ /googlefonts_testdata/data /guava/lib/ -/gvr-android-sdk/common_library.aar -/gvr-android-sdk/libgvr_shim_static_*.a -/gvr-android-sdk/test-apks/daydream_home/*.apk -/gvr-android-sdk/test-apks/vr_keyboard/*.apk -/gvr-android-sdk/test-apks/vr_services/*.apk -/gvr-android-sdk/test-libraries/controller_test_api.aar /hamcrest/lib/ /icu4j/lib/ /instrumented_libraries/scripts/*.tgz
diff --git a/third_party/angle b/third_party/angle index e3600ab..82c95b3 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit e3600abb810666033b35b8e98043869fb1c10603 +Subproject commit 82c95b3012573f46a99f7f32d2a93c3671c0e8b9
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl index 5d3ab23..59969ef 100644 --- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl +++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
@@ -106,11 +106,6 @@ public: - // ComputedStyle sub-objects are heavily inlined, and on relatively hot - // codepaths. Disable pointer-compression. - template <typename T> - using DataMember = subtle::UncompressedMember<T>; - inline bool IndependentInheritedEqual(const ComputedStyleBase& o) const { return ( {{fieldwise_compare(computed_style, computed_style.all_fields @@ -262,7 +257,7 @@ // Storage. {% for subgroup in computed_style.subgroups %} - DataMember<{{subgroup.type_name}}> {{subgroup.member_name}}; + Member<{{subgroup.type_name}}> {{subgroup.member_name}}; {% endfor %} {# Members #} @@ -329,7 +324,7 @@ } template <typename T> - static T* Access(ComputedStyleBase::DataMember<T>& data, bool& access_flag) { + static T* Access(Member<T>& data, bool& access_flag) { if (!access_flag) { access_flag = true; data = data->Copy();
diff --git a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl index 5557ad8..cd164f8 100644 --- a/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl +++ b/third_party/blink/renderer/build/scripts/templates/fields/group.tmpl
@@ -60,7 +60,7 @@ bool operator!=(const {{group.type_name}}& other) const { return !(*this == other); } {% for subgroup in group.subgroups %} - DataMember<{{subgroup.type_name}}> {{subgroup.member_name}}; + Member<{{subgroup.type_name}}> {{subgroup.member_name}}; {% endfor %} {% for field in group.fields %} {{declare_storage(field)}}
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index 4d996fc..4977d03 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -5315,7 +5315,7 @@ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"], interpolable: true, layout_dependent: true, - field_group: "*", + field_group: "svg", field_template: "external", include_paths: ["third_party/blink/renderer/core/style/transform_origin.h"], default_value: "TransformOrigin(Length::Percent(50.0), Length::Percent(50.0), 0)",
diff --git a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc index 9103f5b..27c46438 100644 --- a/third_party/blink/renderer/core/editing/visible_units_paragraph.cc +++ b/third_party/blink/renderer/core/editing/visible_units_paragraph.cc
@@ -126,12 +126,12 @@ if (layout_object->IsText() && To<LayoutText>(layout_object)->ResolvedTextLength()) { if (style.ShouldPreserveBreaks()) { - auto* text = To<LayoutText>(layout_object); - int index = text->TextLength(); + const String& text = To<LayoutText>(layout_object)->GetText(); + int index = text.length(); if (previous_node_iterator == start_node && candidate_offset < index) index = max(0, candidate_offset); while (--index >= 0) { - if ((*text)[index] == '\n') { + if (text[index] == '\n') { return PositionTemplate<Strategy>(To<Text>(previous_node_iterator), index + 1); } @@ -239,21 +239,24 @@ // can't accept the caret. if (layout_object->IsText() && To<LayoutText>(layout_object)->ResolvedTextLength()) { - auto* const text = To<LayoutText>(layout_object); + auto* const layout_text = To<LayoutText>(layout_object); if (style.ShouldPreserveBreaks()) { - const int length = text->TextLength(); + const String& text = layout_text->GetText(); + const int length = text.length(); for (int i = (next_node_iterator == start_node ? candidate_offset : 0); i < length; ++i) { - if ((*text)[i] == '\n') { - return PositionTemplate<Strategy>(To<Text>(next_node_iterator), - i + text->TextStartOffset()); + if (text[i] == '\n') { + return PositionTemplate<Strategy>( + To<Text>(next_node_iterator), + i + layout_text->TextStartOffset()); } } } candidate_node = next_node_iterator; candidate_type = PositionAnchorType::kOffsetInAnchor; - candidate_offset = text->CaretMaxOffset() + text->TextStartOffset(); + candidate_offset = + layout_text->CaretMaxOffset() + layout_text->TextStartOffset(); next_node_iterator = nextNode(); } else if (EditingIgnoresContent(*next_node_iterator) || IsDisplayInsideTable(next_node_iterator)) {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 49e0954..500074c 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -1310,8 +1310,9 @@ else if (auto* option = DynamicTo<HTMLOptionElement>(element)) item_string = option->TextIndentedToRespectGroupLabel(); - if (GetLayoutObject() && GetLayoutObject()->Style()) - GetLayoutObject()->Style()->ApplyTextTransform(&item_string); + if (GetLayoutObject() && GetLayoutObject()->Style()) { + return GetLayoutObject()->Style()->ApplyTextTransform(item_string); + } return item_string; }
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index d851151..96fdba63 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -479,6 +479,7 @@ void HTMLDocumentParser::PrepareToStopParsing() { TRACE_EVENT1("blink", "HTMLDocumentParser::PrepareToStopParsing", "parser", (void*)this); + base::ElapsedTimer timer; DCHECK(!HasInsertionPoint()); // If we've already been detached, e.g. in @@ -523,6 +524,8 @@ GetDocument()->OnPrepareToStopParsing(); AttemptToRunDeferredScriptsAndEnd(); + + base::UmaHistogramTimes("Blink.PrepareToStopParsingTime", timer.Elapsed()); } bool HTMLDocumentParser::IsParsingFragment() const { @@ -652,6 +655,7 @@ "should_complete", should_run_until_completion, "bytes_queued", starting_bytes); } + base::ElapsedTimer pump_tokenizer_timer; // We tell the InspectorInstrumentation about every pump, even if we end up // pumping nothing. It can filter out empty pumps itself. @@ -760,6 +764,9 @@ } } + base::UmaHistogramTimes("Blink.PumpTokenizerTime", + pump_tokenizer_timer.Elapsed()); + if (is_tracing) { TRACE_EVENT_END2("blink", "HTMLDocumentParser::PumpTokenizer", "parsed_tokens", tokens_parsed, "parsed_bytes",
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc index d687b459..f27b248 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -874,6 +874,8 @@ LayoutUnit row_gap = grid->GridGap(kForRows); LayoutUnit column_gap = grid->GridGap(kForColumns); + // TODO(kschmi) - merge area names in `GridLineResolver` so that + // subgrid-inherited grid areas are included. for (const auto& item : grid->StyleRef().GridTemplateAreas()->named_areas) { const GridArea& area = item.value; const String& name = item.key; @@ -959,19 +961,13 @@ }; const NamedGridLinesMap& explicit_lines_map = - (direction == kForColumns) - ? grid_container_style.GridTemplateColumns().named_grid_lines - : grid_container_style.GridTemplateRows().named_grid_lines; + grid->CachedPlacementData().line_resolver.ExplicitNamedLinesMap( + direction); process_grid_lines_map(explicit_lines_map); - - if (const auto& grid_template_areas = - grid_container_style.GridTemplateAreas()) { - const NamedGridLinesMap& implicit_lines_map = - (direction == kForColumns) - ? grid_template_areas->implicit_named_grid_column_lines - : grid_template_areas->implicit_named_grid_row_lines; - process_grid_lines_map(implicit_lines_map); - } + const NamedGridLinesMap& implicit_lines_map = + grid->CachedPlacementData().line_resolver.ImplicitNamedLinesMap( + direction); + process_grid_lines_map(implicit_lines_map); return lines; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.h b/third_party/blink/renderer/core/inspector/inspector_highlight.h index c32f6ff..049c17e 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight.h +++ b/third_party/blink/renderer/core/inspector/inspector_highlight.h
@@ -283,10 +283,6 @@ ColorFormat color_format_; }; -std::unique_ptr<protocol::DictionaryValue> InspectorGridHighlight( - Node*, - const InspectorGridHighlightConfig& config); - std::unique_ptr<protocol::DictionaryValue> InspectorFlexContainerHighlight( Node* node, const InspectorFlexContainerHighlightConfig& config); @@ -305,6 +301,9 @@ // CORE_EXPORT is required to make these functions available for unit tests. std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT +InspectorGridHighlight(Node*, const InspectorGridHighlightConfig& config); + +std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT BuildSnapContainerInfo(Node* node); std::unique_ptr<protocol::DictionaryValue> CORE_EXPORT
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc index 06cb262..822fe1b8 100644 --- a/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc +++ b/third_party/blink/renderer/core/inspector/inspector_highlight_test.cc
@@ -353,4 +353,142 @@ Eq("lab(20 -10 -10)")); } +TEST_F(InspectorHighlightTest, GridLineNames) { + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #grid { + display: grid; + grid-template-columns: [a] 1fr [b] 1fr [c] 1fr; + grid-template-rows: [d] 1fr [e] 1fr [f] 1fr; + } + #subgrid { + display: grid; + grid-column: 1 / 4; + grid-row: 1 / 4; + grid-template-columns: subgrid [a_sub] [b_sub] [c_sub]; + grid-template-rows: subgrid [d_sub] [e_sub] [f_sub]; + } + </style> + <div id="grid"> + <div id="subgrid"> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + </div> + </div> + )HTML"); + GetDocument().View()->UpdateAllLifecyclePhasesForTest(); + Node* subgrid = GetDocument().getElementById(AtomicString("subgrid")); + EXPECT_TRUE(subgrid); + auto info = + InspectorGridHighlight(subgrid, InspectorHighlight::DefaultGridConfig()); + EXPECT_TRUE(info); + + auto CompareLineNames = [](protocol::ListValue* row_or_column_list, + WTF::Vector<WTF::String>& expected_names) -> void { + for (wtf_size_t i = 0; i < row_or_column_list->size(); ++i) { + protocol::DictionaryValue* current_value = + static_cast<protocol::DictionaryValue*>(row_or_column_list->at(i)); + + WTF::String string_value; + EXPECT_TRUE(current_value->getString("name", &string_value)); + + EXPECT_EQ(expected_names[i], string_value); + } + }; + + protocol::ListValue* row_info = info->getArray("rowLineNameOffsets"); + EXPECT_EQ(row_info->size(), 6u); + WTF::Vector<WTF::String> expected_row_names = {"d", "e_sub", "e", + "f", "d_sub", "f_sub"}; + CompareLineNames(row_info, expected_row_names); + + protocol::ListValue* column_info = info->getArray("columnLineNameOffsets"); + EXPECT_EQ(column_info->size(), 6u); + WTF::Vector<WTF::String> expected_column_names = {"b", "a_sub", "b_sub", + "c", "a", "c_sub"}; + CompareLineNames(column_info, expected_column_names); +} + +TEST_F(InspectorHighlightTest, GridAreaNames) { + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #grid { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr 1fr; + grid-template-areas: + "a a a" + "b b b" + "c c c"; + } + #subgrid { + display: grid; + grid-column: 1 / 4; + grid-row: 1 / 4; + grid-template-columns: subgrid; + grid-template-rows: subgrid; + grid-template-areas: + "d d d" + "e e e" + "f f f"; + } + </style> + <div id="grid"> + <div id="subgrid"> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + <div class="griditem"></div> + </div> + </div> + )HTML"); + GetDocument().View()->UpdateAllLifecyclePhasesForTest(); + + auto CompareAreaNames = [](protocol::DictionaryValue* area_names, + WTF::Vector<WTF::String>& expected_names) -> void { + for (WTF::String& name : expected_names) { + EXPECT_TRUE(area_names->get(name)); + } + }; + + Node* grid = GetDocument().getElementById(AtomicString("grid")); + EXPECT_TRUE(grid); + auto grid_info = + InspectorGridHighlight(grid, InspectorHighlight::DefaultGridConfig()); + EXPECT_TRUE(grid_info); + protocol::DictionaryValue* grid_area_names = + grid_info->getObject("areaNames"); + EXPECT_EQ(grid_area_names->size(), 3u); + + WTF::Vector<WTF::String> expected_grid_area_names = {"a", "b", "c"}; + CompareAreaNames(grid_area_names, expected_grid_area_names); + + Node* subgrid = GetDocument().getElementById(AtomicString("subgrid")); + EXPECT_TRUE(subgrid); + auto subgrid_info = + InspectorGridHighlight(subgrid, InspectorHighlight::DefaultGridConfig()); + EXPECT_TRUE(subgrid_info); + + protocol::DictionaryValue* subgrid_area_names = + subgrid_info->getObject("areaNames"); + EXPECT_EQ(subgrid_area_names->size(), 3u); + + // TODO(kschmi): This should include "a", "b", and "c", but it's not + // currently. See TODO in `BuildAreaNamePaths`. + WTF::Vector<WTF::String> expected_subgrid_area_names = {"d", "e", "f"}; + CompareAreaNames(subgrid_area_names, expected_subgrid_area_names); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/fragment_builder.cc b/third_party/blink/renderer/core/layout/fragment_builder.cc index d05b4e4..03253fe 100644 --- a/third_party/blink/renderer/core/layout/fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/fragment_builder.cc
@@ -250,8 +250,18 @@ PropagateSnapAreas(child); PropagateScrollStartTarget(child); + // Propagate info about OOF descendants if necessary. This part must be + // skipped when adding OOF children to fragmentainers, as propagation is + // special and performed manually from the OOF code in such cases, and cannot + // be done as part of adding child fragments. First of all, the parameters to + // PropagateOOFPositionedInfo() will be different from what we can provide + // here, and furthermore, OOFs in fragmentation are added by recreating + // fragmentainers, by adding old children and then appending new OOF + // children. This may take place in several passes (if there are nested OOFs + // that are discovered as part of laying out an outer OOF), and repropagating + // for OOFs that were laid out previously over and over again would be wrong. if (child.NeedsOOFPositionedInfoPropagation() && - !disable_oof_descendants_propagation_) { + (!IsFragmentainerBoxType() || !child.IsOutOfFlowPositioned())) { LayoutUnit adjustment_for_oof_propagation = BlockOffsetAdjustmentForFragmentainer();
diff --git a/third_party/blink/renderer/core/layout/fragment_builder.h b/third_party/blink/renderer/core/layout/fragment_builder.h index 53addfa..6e3a907 100644 --- a/third_party/blink/renderer/core/layout/fragment_builder.h +++ b/third_party/blink/renderer/core/layout/fragment_builder.h
@@ -299,10 +299,6 @@ LayoutUnit BlockOffsetAdjustmentForFragmentainer( LayoutUnit fragmentainer_consumed_block_size = LayoutUnit()) const; - void SetDisableOOFDescendantsPropagation() { - disable_oof_descendants_propagation_ = true; - } - bool HasOutOfFlowFragmentChild() const { return has_out_of_flow_fragment_child_; } @@ -635,7 +631,6 @@ bool should_add_break_tokens_manually_ = false; bool has_out_of_flow_fragment_child_ = false; bool has_out_of_flow_in_fragmentainer_subtree_ = false; - bool disable_oof_descendants_propagation_ = false; #if DCHECK_IS_ON() bool is_may_have_descendant_above_block_start_explicitly_set_ = false;
diff --git a/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h b/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h index 381e8aa..59bdd84 100644 --- a/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h +++ b/third_party/blink/renderer/core/layout/grid/grid_line_resolver.h
@@ -70,13 +70,13 @@ const ComputedStyle& grid_item_style, GridTrackSizingDirection track_direction) const; - private: const NamedGridLinesMap& ImplicitNamedLinesMap( GridTrackSizingDirection track_direction) const; const NamedGridLinesMap& ExplicitNamedLinesMap( GridTrackSizingDirection track_direction) const; + private: const NamedGridLinesMap& AutoRepeatLineNamesMap( GridTrackSizingDirection track_direction) const;
diff --git a/third_party/blink/renderer/core/layout/inline/inline_node.cc b/third_party/blink/renderer/core/layout/inline/inline_node.cc index b820488..7b41ed43 100644 --- a/third_party/blink/renderer/core/layout/inline/inline_node.cc +++ b/third_party/blink/renderer/core/layout/inline/inline_node.cc
@@ -943,8 +943,8 @@ FontCachePurgePreventer font_cache_purge_preventer; String new_text(std::move(new_text_in)); - layout_text->StyleRef().ApplyTextTransform(&new_text, - layout_text->PreviousCharacter()); + new_text = layout_text->StyleRef().ApplyTextTransform( + new_text, layout_text->PreviousCharacter()); layout_text->SetTextInternal(new_text); InlineNode node(editor.GetLayoutBlockFlow()); @@ -978,7 +978,6 @@ if (!data->offset_mapping) { DCHECK(!data->text_content.IsNull()); ComputeOffsetMapping(GetLayoutBlockFlow(), data); - DCHECK(data->offset_mapping); } return data->offset_mapping.Get(); @@ -1020,9 +1019,11 @@ // TODO(xiaochengh): This doesn't compute offset mapping correctly when // text-transform CSS property changes text length. OffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder(); - mapping_builder.SetDestinationString(data->text_content); - data->offset_mapping = mapping_builder.Build(); - DCHECK(data->offset_mapping); + data->offset_mapping = nullptr; + if (mapping_builder.SetDestinationString(data->text_content)) { + data->offset_mapping = mapping_builder.Build(); + DCHECK(data->offset_mapping); + } } const OffsetMapping* InlineNode::GetOffsetMapping( @@ -1104,7 +1105,7 @@ data.svg_node_data_ = svg_attr_builder.CreateSvgInlineNodeData(); // Compute DOM offsets of text chunks. - mapping_builder.SetDestinationString(ifc_text_content); + CHECK(mapping_builder.SetDestinationString(ifc_text_content)); OffsetMapping* mapping = mapping_builder.Build(); StringView ifc_text_view(ifc_text_content); for (wtf_size_t i = 0; i < data.svg_node_data_->character_data_list.size(); @@ -1530,24 +1531,24 @@ return; auto* first_line_items = MakeGarbageCollected<InlineItemsData>(); - first_line_items->text_content = data->text_content; + String text_content = data->text_content; bool needs_reshape = false; if (first_line_style->TextTransform() != block_style->TextTransform()) { // TODO(kojii): This logic assumes that text-transform is applied only to // ::first-line, and does not work when the base style has text-transform // and ::first-line has different text-transform. - first_line_style->ApplyTextTransform(&first_line_items->text_content); - if (first_line_items->text_content != data->text_content) { + text_content = first_line_style->ApplyTextTransform(text_content); + if (text_content != data->text_content) { // TODO(kojii): When text-transform changes the length, we need to adjust // offset in InlineItem, or re-collect inlines. Other classes such as // line breaker need to support the scenario too. For now, we force the // string to be the same length to prevent them from crashing. This may // result in a missing or a duplicate character if the length changes. - TruncateOrPadText(&first_line_items->text_content, - data->text_content.length()); + TruncateOrPadText(&text_content, data->text_content.length()); needs_reshape = true; } } + first_line_items->text_content = text_content; first_line_items->items.AppendVector(data->items); for (auto& item : first_line_items->items) {
diff --git a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc index b578cfb..21ef27e 100644 --- a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc +++ b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.cc
@@ -213,9 +213,17 @@ return; } -void OffsetMappingBuilder::SetDestinationString(String string) { +bool OffsetMappingBuilder::SetDestinationString(const String& string) { DCHECK_EQ(destination_length_, string.length()); + if (RuntimeEnabledFeatures::NoOffsetMappingForInconsistentTextEnabled() && + destination_length_ != string.length()) { + // If we continue building an OffsetMapping with the inconsistent IFC text + // content, it might cause out-of-bounds accesses. It happens only if we + // have a bug, and we should fail safely. + return false; + } destination_string_ = string; + return true; } OffsetMapping* OffsetMappingBuilder::Build() {
diff --git a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h index 81c6637..2015c60 100644 --- a/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h +++ b/third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h
@@ -119,7 +119,9 @@ unsigned offset); // Set the destination string of the offset mapping. - void SetDestinationString(String); + // Returns false if the specified string is inconsistent with + // `destination_length_`. We can't build an OffstMapping in such case. + bool SetDestinationString(const String&); // Finalize and return the offset mapping. // This method can only be called once, as it can invalidate the stored data.
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 36260f4..2ea90a1 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -328,8 +328,8 @@ float max_option_width = 0; if (!box.ShouldApplySizeContainment()) { for (auto* const option : select.GetOptionList()) { - String text = option->TextIndentedToRespectGroupLabel(); - style.ApplyTextTransform(&text); + String text = + style.ApplyTextTransform(option->TextIndentedToRespectGroupLabel()); // We apply SELECT's style, not OPTION's style because max_option_width is // used to determine intrinsic width of the menulist box. max_option_width =
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 2d83804..307fe766 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -715,16 +715,18 @@ bool LayoutText::IsAllCollapsibleWhitespace() const { NOT_DESTROYED(); unsigned length = TextLength(); - if (Is8Bit()) { + if (text_.Is8Bit()) { for (unsigned i = 0; i < length; ++i) { - if (!StyleRef().IsCollapsibleWhiteSpace(Characters8()[i])) + if (!StyleRef().IsCollapsibleWhiteSpace(text_.Characters8()[i])) { return false; + } } return true; } for (unsigned i = 0; i < length; ++i) { - if (!StyleRef().IsCollapsibleWhiteSpace(Characters16()[i])) + if (!StyleRef().IsCollapsibleWhiteSpace(text_.Characters16()[i])) { return false; + } } return true; } @@ -877,7 +879,7 @@ void LayoutText::ApplyTextTransform() { NOT_DESTROYED(); if (const ComputedStyle* style = Style()) { - style->ApplyTextTransform(&text_, PreviousCharacter()); + text_ = style->ApplyTextTransform(text_, PreviousCharacter()); // We use the same characters here as for list markers. // See CollectUACounterStyleRules() in ua_counter_style_map.cc.
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index f8a82e83..31c4bb0 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -130,29 +130,10 @@ PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override; - bool Is8Bit() const { - NOT_DESTROYED(); - return text_.Is8Bit(); - } - const LChar* Characters8() const { - NOT_DESTROYED(); - return text_.Characters8(); - } - const UChar* Characters16() const { - NOT_DESTROYED(); - return text_.Characters16(); - } bool HasEmptyText() const { NOT_DESTROYED(); return text_.empty(); } - UChar CharacterAt(unsigned) const; - UChar UncheckedCharacterAt(unsigned) const; - UChar operator[](unsigned i) const { - NOT_DESTROYED(); - return UncheckedCharacterAt(i); - } - UChar32 CodepointAt(unsigned) const; unsigned TextLength() const { NOT_DESTROYED(); return text_.length(); @@ -448,28 +429,6 @@ return first_fragment_item_index_; } -inline UChar LayoutText::UncheckedCharacterAt(unsigned i) const { - SECURITY_DCHECK(i < TextLength()); - return Is8Bit() ? Characters8()[i] : Characters16()[i]; -} - -inline UChar LayoutText::CharacterAt(unsigned i) const { - if (i >= TextLength()) - return 0; - - return UncheckedCharacterAt(i); -} - -inline UChar32 LayoutText::CodepointAt(unsigned i) const { - if (i >= TextLength()) - return 0; - if (Is8Bit()) - return Characters8()[i]; - UChar32 c; - U16_GET(Characters16(), 0, i, TextLength(), c); - return c; -} - inline void LayoutText::DetachAbstractInlineTextBoxesIfNeeded() { if (UNLIKELY(has_abstract_inline_text_box_)) DetachAbstractInlineTextBoxes();
diff --git a/third_party/blink/renderer/core/layout/logical_box_fragment.cc b/third_party/blink/renderer/core/layout/logical_box_fragment.cc index 2c20a74..6786198 100644 --- a/third_party/blink/renderer/core/layout/logical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/logical_box_fragment.cc
@@ -16,8 +16,14 @@ FontBaseline baseline_type) const { // For checkbox and radio controls, we always use the border edge instead of // the margin edge. - if (physical_fragment_.Style().IsCheckboxOrRadioPart()) - return FontHeight(margins.line_over + BlockSize(), margins.line_under); + if (physical_fragment_.Style().IsCheckboxOrRadioPart()) { + if (baseline_type == kAlphabeticBaseline) { + return FontHeight(margins.line_over + BlockSize(), margins.line_under); + } + // For a central baseline, center within the checkbox/radio part. + return FontHeight(margins.line_over + BlockSize() / 2, + BlockSize() - BlockSize() / 2 + margins.line_under); + } absl::optional<LayoutUnit> baseline; switch (physical_fragment_.Style().BaselineSource()) {
diff --git a/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc index 5e2a5c7..88e2d492 100644 --- a/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/simplified_layout_algorithm.cc
@@ -221,6 +221,10 @@ const LayoutResult* SimplifiedLayoutAlgorithm::CreateResultAfterManualChildLayout() { + if (container_builder_.HasOutOfFlowFragmentainerDescendants()) { + container_builder_.AddMulticolWithPendingOOFs(Node()); + } + const LayoutResult* result = container_builder_.ToBoxFragment(); if (result->GetPhysicalFragment().IsOutOfFlowPositioned()) { result->CopyMutableOutOfFlowData(previous_result_);
diff --git a/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc b/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc index 134f5eb0d..b8da069a 100644 --- a/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.cc
@@ -26,7 +26,6 @@ container_builder_.SetPageNameIfNeeded(previous_fragment.PageName()); container_builder_.SetFragmentBlockSize( params.space.FragmentainerBlockSize()); - container_builder_.SetDisableOOFDescendantsPropagation(); container_builder_.SetHasOutOfFlowFragmentChild(true); const BlockBreakToken* old_fragment_break_token =
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 4082b53..1d4c9467 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1303,6 +1303,7 @@ HistoryItem* previous_history_item, CommitReason commit_reason) { TRACE_EVENT("blink", "FrameLoader::CommitDocumentLoader"); + base::ElapsedTimer timer; document_loader_ = document_loader; CHECK(document_loader_); @@ -1341,6 +1342,8 @@ Client()->TransitionToCommittedForNewPage(); document_loader_->CommitNavigation(); + + base::UmaHistogramTimes("Blink.CommitDocumentLoaderTime", timer.Elapsed()); } void FrameLoader::RestoreScrollPositionAndViewState() {
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 5c061d8..ab78e1ee 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -110,14 +110,12 @@ struct SameSizeAsComputedStyleBase : public GarbageCollected<SameSizeAsComputedStyleBase> { SameSizeAsComputedStyleBase() { - base::debug::Alias(&data_refs); base::debug::Alias(&pointers); base::debug::Alias(&bitfields); } private: - void* data_refs[8]; - Member<void*> pointers[1]; + Member<void*> pointers[9]; unsigned bitfields[5]; }; @@ -1823,47 +1821,43 @@ namespace { -static void ApplyMathAutoTransform(String* text) { - if (text->length() != 1) { - return; +String ApplyMathAutoTransform(const String& text) { + if (text.length() != 1) { + return text; } - UChar character = (*text)[0]; - UChar32 transformed_char = ItalicMathVariant((*text)[0]); + UChar character = text[0]; + UChar32 transformed_char = ItalicMathVariant(text[0]); if (transformed_char == static_cast<UChar32>(character)) { - return; + return text; } Vector<UChar> transformed_text(U16_LENGTH(transformed_char)); int i = 0; U16_APPEND_UNSAFE(transformed_text, i, transformed_char); - *text = String(transformed_text); + return String(transformed_text); } } // namespace -void ComputedStyle::ApplyTextTransform(String* text, - UChar previous_character) const { +String ComputedStyle::ApplyTextTransform(const String& text, + UChar previous_character) const { switch (TextTransform()) { case ETextTransform::kNone: - return; + return text; case ETextTransform::kCapitalize: - *text = Capitalize(*text, previous_character); - return; + return Capitalize(text, previous_character); case ETextTransform::kUppercase: { const LayoutLocale* locale = GetFontDescription().Locale(); CaseMap case_map(locale ? locale->CaseMapLocale() : CaseMap::Locale()); - *text = DisableNewGeorgianCapitalLetters(case_map.ToUpper(*text)); - return; + return DisableNewGeorgianCapitalLetters(case_map.ToUpper(text)); } case ETextTransform::kLowercase: { const LayoutLocale* locale = GetFontDescription().Locale(); CaseMap case_map(locale ? locale->CaseMapLocale() : CaseMap::Locale()); - *text = case_map.ToLower(*text); - return; + return case_map.ToLower(text); } case ETextTransform::kMathAuto: - ApplyMathAutoTransform(text); - return; + return ApplyMathAutoTransform(text); } NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 925b9bc6..c2426d3 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -1144,7 +1144,8 @@ bool ShouldUseTextIndent(bool is_first_line) const; // text-transform utility functions. - void ApplyTextTransform(String*, UChar previous_character = ' ') const; + [[nodiscard]] String ApplyTextTransform(const String&, + UChar previous_character = ' ') const; // Line-height utility functions. const Length& SpecifiedLineHeight() const { return LineHeightInternal(); }
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc index e3ac18e0..c0901434 100644 --- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc +++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
@@ -51,6 +51,7 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/platform/graphics/video_frame_sink_bundle.h" +#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h" #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/p2p/empty_network_manager.h" @@ -443,8 +444,8 @@ context.GetBrowserInterfaceBroker().GetInterface( perf_recorder.InitWithNewPipeAndPassReceiver()); - webrtc_video_perf_reporter_.Initialize( - context.GetTaskRunner(TaskType::kInternalMedia), + webrtc_video_perf_reporter_ = MakeGarbageCollected<WebrtcVideoPerfReporter>( + context.GetTaskRunner(TaskType::kInternalMedia), &context, std::move(perf_recorder)); } @@ -626,7 +627,7 @@ base::FeatureList::IsEnabled(features::kWebRtcSendPacketBatch)); gpu_factories_ = gpu_factories; - // base::Unretained is safe below, because + // WrapCrossThreadWeakPersistent is safe below, because // PeerConnectionDependencyFactory (that holds `webrtc_video_perf_reporter_`) // outlives the encoders and decoders that are using the callback. The // lifetime of PeerConnectionDependencyFactory is tied to the ExecutionContext @@ -637,13 +638,15 @@ blink::CreateWebrtcVideoEncoderFactory( gpu_factories, std::move(video_encoder_metrics_provider_factory), base::BindRepeating(&WebrtcVideoPerfReporter::StoreWebrtcVideoStats, - base::Unretained(&webrtc_video_perf_reporter_))); + WrapCrossThreadWeakPersistent( + webrtc_video_perf_reporter_.Get()))); std::unique_ptr<webrtc::VideoDecoderFactory> webrtc_decoder_factory = blink::CreateWebrtcVideoDecoderFactory( gpu_factories, media_decoder_factory, std::move(media_task_runner), render_color_space, base::BindRepeating(&WebrtcVideoPerfReporter::StoreWebrtcVideoStats, - base::Unretained(&webrtc_video_perf_reporter_))); + WrapCrossThreadWeakPersistent( + webrtc_video_perf_reporter_.Get()))); // Enable Multiplex codec in SDP optionally. if (base::FeatureList::IsEnabled(blink::features::kWebRtcMultiplexCodec)) { @@ -903,7 +906,6 @@ void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DVLOG(1) << "PeerConnectionDependencyFactory::CleanupPeerConnectionFactory()"; - webrtc_video_perf_reporter_.Shutdown(); socket_factory_ = nullptr; // Not obtaining `signaling_thread` using GetWebRtcSignalingTaskRunner() // because that method triggers EnsureInitialized() and we're trying to @@ -1013,5 +1015,7 @@ Supplement<ExecutionContext>::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); visitor->Trace(p2p_socket_dispatcher_); + visitor->Trace(webrtc_video_perf_reporter_); } + } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h index a4200ef4..e17bf1b6 100644 --- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h +++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
@@ -20,7 +20,6 @@ #include "third_party/blink/renderer/platform/heap/prefinalizer.h" #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h" #include "third_party/blink/renderer/platform/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/gc_plugin.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/webrtc/api/async_dns_resolver.h" @@ -198,6 +197,8 @@ std::unique_ptr<IpcNetworkManager> network_manager_; std::unique_ptr<IpcPacketSocketFactory> socket_factory_; + Member<WebrtcVideoPerfReporter> webrtc_video_perf_reporter_; + rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_; // Dispatches all P2P sockets. @@ -208,9 +209,6 @@ raw_ptr<media::GpuVideoAcceleratorFactories, ExperimentalRenderer> gpu_factories_; - GC_PLUGIN_IGNORE("https://crbug.com/1381979") - WebrtcVideoPerfReporter webrtc_video_perf_reporter_; - THREAD_CHECKER(thread_checker_); };
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc index 6f5445b..cee2a22 100644 --- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc +++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.cc
@@ -10,28 +10,15 @@ namespace blink { -WebrtcVideoPerfReporter::WebrtcVideoPerfReporter() { - weak_this_ = weak_factory_.GetWeakPtr(); -} - -WebrtcVideoPerfReporter::~WebrtcVideoPerfReporter() { - // `task_runner_` may not be set in some unit tests of other features. - DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence()); -} - -void WebrtcVideoPerfReporter::Shutdown() { - // `task_runner_` may not be set in some unit tests of other features. - DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence()); - weak_factory_.InvalidateWeakPtrs(); -} - -void WebrtcVideoPerfReporter::Initialize( +WebrtcVideoPerfReporter::WebrtcVideoPerfReporter( scoped_refptr<base::SingleThreadTaskRunner> task_runner, + ContextLifecycleNotifier* notifier, mojo::PendingRemote<media::mojom::blink::WebrtcVideoPerfRecorder> - perf_recorder) { + perf_recorder) + : perf_recorder_(notifier) { task_runner_ = task_runner; DCHECK(task_runner_->RunsTasksInCurrentSequence()); - perf_recorder_.Bind(std::move(perf_recorder)); + perf_recorder_.Bind(std::move(perf_recorder), task_runner_); } void WebrtcVideoPerfReporter::StoreWebrtcVideoStats( @@ -42,7 +29,7 @@ FROM_HERE, base::BindOnce( &WebrtcVideoPerfReporter::StoreWebrtcVideoStatsOnTaskRunner, - weak_this_, stats_key, video_stats)); + WrapWeakPersistent(this), stats_key, video_stats)); } void WebrtcVideoPerfReporter::StoreWebrtcVideoStatsOnTaskRunner( @@ -51,6 +38,10 @@ DCHECK(task_runner_); DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (!perf_recorder_.is_bound()) { + return; + } + auto mojo_features = media::mojom::blink::WebrtcPredictionFeatures::New( stats_key.is_decode, static_cast<media::mojom::blink::VideoCodecProfile>(
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h index 2bbbb188..784b934 100644 --- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h +++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter.h
@@ -8,41 +8,41 @@ #include "base/task/single_thread_task_runner.h" #include "media/base/video_codecs.h" #include "media/mojo/mojom/webrtc_video_perf.mojom-blink.h" -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/peerconnection/stats_collector.h" namespace blink { +class ContextLifecycleNotifier; + // This class is used for WebRTC video performance stats data collection. Its // sole purpose is to pass data collected in the render process to the browser // process where the data is stored to a local database. The data is later used // for smoothness predictions when the MediaCapabilities API receives a query // for a particular video configuration. -class MODULES_EXPORT WebrtcVideoPerfReporter { +class MODULES_EXPORT WebrtcVideoPerfReporter + : public GarbageCollected<WebrtcVideoPerfReporter> { public: - WebrtcVideoPerfReporter(); - ~WebrtcVideoPerfReporter(); - - void Initialize( + WebrtcVideoPerfReporter( scoped_refptr<base::SingleThreadTaskRunner> task_runner, + ContextLifecycleNotifier* notifier, mojo::PendingRemote<media::mojom::blink::WebrtcVideoPerfRecorder> perf_recorder); void StoreWebrtcVideoStats(const StatsCollector::StatsKey& stats_key, const StatsCollector::VideoStats& video_stats); - void Shutdown(); + void Trace(Visitor* visitor) const { visitor->Trace(perf_recorder_); } private: void StoreWebrtcVideoStatsOnTaskRunner( const StatsCollector::StatsKey& stats_key, const StatsCollector::VideoStats& video_stats); - base::WeakPtr<WebrtcVideoPerfReporter> weak_this_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - mojo::Remote<media::mojom::blink::WebrtcVideoPerfRecorder> perf_recorder_; - base::WeakPtrFactory<WebrtcVideoPerfReporter> weak_factory_{this}; + HeapMojoRemote<media::mojom::blink::WebrtcVideoPerfRecorder> perf_recorder_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc index b54127f9..48d4a66 100644 --- a/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/webrtc_video_perf_reporter_test.cc
@@ -46,15 +46,15 @@ public: WebrtcVideoPerfReporterTest() { mock_recorder_ = std::make_unique<MockWebrtcVideoPerfRecorder>(); - reporter_.Initialize( + reporter_ = MakeGarbageCollected<WebrtcVideoPerfReporter>( blink::scheduler::GetSingleThreadTaskRunnerForTesting(), - mock_recorder_->CreatePendingRemote()); + /* notifier */ nullptr, mock_recorder_->CreatePendingRemote()); } protected: test::TaskEnvironment task_environment_; std::unique_ptr<MockWebrtcVideoPerfRecorder> mock_recorder_; - WebrtcVideoPerfReporter reporter_; + Persistent<WebrtcVideoPerfReporter> reporter_; }; TEST_F(WebrtcVideoPerfReporterTest, StoreWebrtcVideoStats) { @@ -78,7 +78,7 @@ EXPECT_EQ(kExpectedFeaturesA, *features); EXPECT_EQ(kExpectedVideoStats, *video_stats); }); - reporter_.StoreWebrtcVideoStats(kStatsKeyA, kVideoStats); + reporter_->StoreWebrtcVideoStats(kStatsKeyA, kVideoStats); base::RunLoop().RunUntilIdle(); // Toggle the booleans. @@ -97,7 +97,7 @@ EXPECT_EQ(kExpectedFeaturesB, *features); EXPECT_EQ(kExpectedVideoStats, *video_stats); }); - reporter_.StoreWebrtcVideoStats(kStatsKeyB, kVideoStats); + reporter_->StoreWebrtcVideoStats(kStatsKeyB, kVideoStats); base::RunLoop().RunUntilIdle(); }
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc index 4950372..5dadc933 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -579,7 +579,7 @@ return "2d"; case WGPUTextureDimension_3D: return "3d"; - case WGPUTextureDimension_Force32: + default: NOTREACHED(); } return "";
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index a2d10ed5..ad0a62b 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -36,6 +36,10 @@ *out = {}; out->view = in->view()->GetHandle(); + out->depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; + if (in->hasDepthSlice()) { + out->depthSlice = in->depthSlice(); + } if (in->hasResolveTarget()) { out->resolveTarget = in->resolveTarget()->GetHandle(); } @@ -52,6 +56,30 @@ namespace { // Dawn represents `undefined` as the special uint32_t value +// WGPU_DEPTH_SLICE_UNDEFINED (0xFFFF'FFFF). Blink must make sure that an +// actual value of 0xFFFF'FFFF coming in from JS is not treated as +// WGPU_DEPTH_SLICE_UNDEFINED, so it injects an error in that case. +std::string ValidateColorAttachmentsDepthSlice( + const HeapVector<Member<GPURenderPassColorAttachment>>& in) { + for (wtf_size_t i = 0; i < in.size(); ++i) { + if (!in[i]) { + continue; + } + + const GPURenderPassColorAttachment* attachment = in[i].Get(); + if (attachment->hasDepthSlice() && + attachment->depthSlice() == WGPU_DEPTH_SLICE_UNDEFINED) { + std::ostringstream error; + error << "depthSlice (" << attachment->depthSlice() + << ") in colorAttachments[" << i << "] is too large"; + return error.str(); + } + } + + return std::string(); +} + +// Dawn represents `undefined` as the special uint32_t value // WGPU_QUERY_SET_INDEX_UNDEFINED (0xFFFF'FFFF). Blink must make sure that an // actual value of 0xFFFF'FFFF coming in from JS is not treated as // WGPU_QUERY_SET_INDEX_UNDEFINED, so it injects an error in that case. @@ -195,6 +223,13 @@ std::unique_ptr<WGPURenderPassColorAttachment[]> color_attachments; dawn_desc.colorAttachmentCount = descriptor->colorAttachments().size(); if (dawn_desc.colorAttachmentCount > 0) { + std::string error = + ValidateColorAttachmentsDepthSlice(descriptor->colorAttachments()); + if (!error.empty()) { + GetProcs().commandEncoderInjectValidationError(GetHandle(), + error.c_str()); + } + if (!ConvertToDawn(descriptor->colorAttachments(), &color_attachments, exception_state)) { return nullptr;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl index 638e1f18..08a7c8c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl
@@ -6,6 +6,7 @@ dictionary GPURenderPassColorAttachment { required GPUTextureView view; + GPUSize32 depthSlice; GPUTextureView resolveTarget; GPUColor clearValue;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 9ba3fc49..ccf5dd6 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2581,6 +2581,10 @@ name: "NonStandardAppearanceValuesLowUsage", }, { + name: "NoOffsetMappingForInconsistentText", + status: "stable", + }, + { name: "NotificationConstructor", // Android won't be able to reliably support non-persistent notifications, the // intended behavior for which is in flux by itself.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index d7a60ab0..c3e4b9f9 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1512,19 +1512,6 @@ # Bug in <select multiple> tap behavior: crbug.com/1045672 fast/forms/select/listbox-tap.html [ Failure ] -# ========== Unload deprecation pending - -# unload-deprecate is a large virtual test suite. Rather than adding -# the tests one-by-one (which requires a VirtualTestSuites-owner -# review for each CL), they have been added as "Skip". They will be -# removed from this section as we address each one as part of -# https://crbug.com/1488371. -# See https://docs.google.com/document/d/1FH0iG8G8mEebjMpVA_zvSfHBWUhWqC92jRFctaGcxrc/edit#heading=h.pacsgp238vkn - -crbug.com/1488371 virtual/deprecate-unload/http/tests/navigation/image-load-in-unload-handler.html [ Failure Skip Timeout ] - -# ========== End of Unload deprecation pending - ######## Unload Deprecation # This is for tests in the "deprecate-unload" virtual suite that # cannot be fixed and require a timeout expecation. @@ -2663,10 +2650,6 @@ crbug.com/626703 external/wpt/screen-orientation/lock-unlock-check.html [ Timeout ] crbug.com/626703 [ Win10.20h2 ] external/wpt/fledge/tentative/direct-from-seller-signals.https.window.html?6-10 [ Skip Timeout ] crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-095.html [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html [ Failure ] -crbug.com/626703 external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html [ Failure ] crbug.com/626703 external/wpt/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html [ Failure ] crbug.com/626703 external/wpt/svg/color-inherit-link-visited.svg [ Failure ] crbug.com/626703 external/wpt/html/semantics/forms/the-input-element/input-type-checkbox-switch.tentative.window.html [ Failure ] @@ -5144,6 +5127,7 @@ crbug.com/1509336 http/tests/devtools/har-importer.js [ Failure Pass ] crbug.com/1509336 http/tests/devtools/network/json-preview.js [ Failure Pass ] crbug.com/1509336 http/tests/devtools/network/network-choose-preview-view.js [ Failure Pass ] +crbug.com/1509336 http/tests/devtools/network/network-xhr-binary-content.js [ Failure Pass ] # Possible Interop PE 2024 investigation crbug.com/1495467 external/wpt/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=LEFT&button=0&buttons=1 [ Failure ] @@ -5209,9 +5193,6 @@ crbug.com/1299948 [ Mac12 ] external/wpt/css/css-tables/crashtests/textarea-intrinsic-size-crash.html [ Pass Timeout ] crbug.com/1299972 [ Linux ] screen_orientation/screenorientation-unsupported-no-crash.html [ Failure Pass Timeout ] -# Disabled temporarily to land https://crrev.com/c/5134807 -crbug.com/1509340 http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js [ Failure Pass ] - # Disable flaky test for further investigation crbug.com/1229801 http/tests/devtools/elements/css-rule-hover-highlights-selectors.js [ Failure Pass ] @@ -6270,7 +6251,6 @@ [ Debug Mac13 ] jquery/traversing.html [ Skip Timeout ] [ Debug Mac13 ] external/wpt/html/interaction/focus/chrome-object-tab-focus-bug.html [ Failure ] [ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/sandbox-attribute.https.html [ Failure ] -[ Debug Mac13 ] accessibility/selection-change-notification-on-selection-removed.html [ Failure ] [ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.worker.html [ Failure ] [ Debug Mac13 ] external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ] [ Debug Mac13 ] http/tests/devtools/sources/debugger-breakpoints/breakpoint-manager-listeners-count.js [ Failure ] @@ -6880,3 +6860,6 @@ # TODO(crbug.com/1496375): Re-enable these tests. crbug.com/1496375 [ Linux ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ] crbug.com/1496375 [ Mac ] http/tests/loading/image-picture-download-after-shrink.html [ Failure Pass ] + +# Gardener 2023-12-20 +[ Mac ] accessibility/selection-change-notification-on-selection-removed.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 29e9eac..dade4ad 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2508,7 +2508,6 @@ "http/tests/inspector-protocol/permissions-policy.js", "http/tests/navigation/history-back-across-form-submission-to-fragment.html", "http/tests/navigation/image-css-load-in-subframe-unload-handler.html", - "http/tests/navigation/image-load-in-unload-handler.html", "http/tests/navigation/redirect-on-back-updates-history-item.html", "http/tests/navigation/redirect-on-reload-updates-history-item.html", "http/tests/navigation/targeted-navigation-in-unload-handler.html",
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html new file mode 100644 index 0000000..6b9427d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/relayout-fixedpos-in-abspos-in-relpos-in-nested-multicol.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1501713"> +<div style="columns:2; column-fill:auto; height:100px; will-change:transform;"> + <div style="columns:2; column-fill:auto;"> + <div style="position:relative;"> + <div style="position:absolute; height:150px;"> + <div id="trouble" style="position:fixed; height:50px;"></div> + </div> + </div> + </div> +</div> +<script> + document.body.offsetHeight; + trouble.style.width = "2px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html index c3f61075..a43403c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional-ref.html
@@ -14,8 +14,16 @@ } </style> -<p>The checkbox should be center-aligned with the label text.</p> +<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p> <div style="writing-mode: vertical-lr"> <input type="checkbox" id="checkbox" checked> <label for="checkbox">こんにちわ</label> </div> + +<br> + +<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-lr; text-orientation: sideways;"> + <input type="checkbox" id="checkbox" checked> + <label for="checkbox">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html index b19de13..377a8e8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-lr-baseline.optional.html
@@ -14,8 +14,16 @@ } </style> -<p>The checkbox should be center-aligned with the label text.</p> +<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p> <div style="writing-mode: vertical-lr"> <input type="checkbox" id="checkbox" checked> <label for="checkbox">こんにちわ</label> </div> + +<br> + +<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-lr; text-orientation: sideways;"> + <input type="checkbox" id="checkbox" checked> + <label for="checkbox">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html index a253a71d..7fe6db340 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional-ref.html
@@ -14,8 +14,16 @@ } </style> -<p>The checkbox should be center-aligned with the label text.</p> +<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p> <div style="writing-mode: vertical-rl"> <input type="checkbox" id="checkbox" checked> <label for="checkbox">こんにちわ</label> </div> + +<br> + +<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-rl; text-orientation: sideways;"> + <input type="checkbox" id="checkbox" checked> + <label for="checkbox">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html index 3efb211..630a83c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/checkbox-appearance-native-vertical-rl-baseline.optional.html
@@ -14,8 +14,16 @@ } </style> -<p>The checkbox should be center-aligned with the label text.</p> +<p>The checkbox should be center-aligned with the label it since text is non-alphabetic.</p> <div style="writing-mode: vertical-rl"> <input type="checkbox" id="checkbox" checked> <label for="checkbox">こんにちわ</label> </div> + +<br> + +<p>The checkbox should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-rl; text-orientation: sideways;"> + <input type="checkbox" id="checkbox" checked> + <label for="checkbox">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html index 9b09537c9..6fca0762 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional-ref.html
@@ -14,8 +14,16 @@ } </style> -<p>The radio button should be center-aligned with the label text.</p> +<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p> <div style="writing-mode: vertical-lr"> <input type="radio" id="radio" checked> <label for="radio">こんにちわ</label> </div> + +<br> + +<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-lr; text-orientation: sideways;"> + <input type="radio" id="radio" checked> + <label for="radio">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html index 8d5bf75f..c7810034 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-lr-baseline.optional.html
@@ -14,8 +14,16 @@ } </style> -<p>The radio button should be center-aligned with the label text.</p> +<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p> <div style="writing-mode: vertical-lr"> <input type="radio" id="radio" checked> <label for="radio">こんにちわ</label> </div> + +<br> + +<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-lr; text-orientation: sideways;"> + <input type="radio" id="radio" checked> + <label for="radio">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html index 95871a51..9e5dda82 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional-ref.html
@@ -14,8 +14,16 @@ } </style> -<p>The radio button should be center-aligned with the label text.</p> +<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p> <div style="writing-mode: vertical-rl"> <input type="radio" id="radio" checked> <label for="radio">こんにちわ</label> </div> + +<br> + +<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-rl; text-orientation: sideways;"> + <input type="radio" id="radio" checked> + <label for="radio">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html index 4c5a59a0..6f7eed7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html +++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/forms/radio-appearance-native-vertical-rl-baseline.optional.html
@@ -14,8 +14,16 @@ } </style> -<p>The radio button should be center-aligned with the label text.</p> +<p>The radio button should be center-aligned with the label text since it is non-alphabetic.</p> <div style="writing-mode: vertical-rl"> <input type="radio" id="radio" checked> <label for="radio">こんにちわ</label> </div> + +<br> + +<p>The radio button should be left-aligned with the label text since it has text-orientation sideways.</p> +<div style="writing-mode: vertical-rl; text-orientation: sideways;"> + <input type="radio" id="radio" checked> + <label for="radio">Baseline</label> +</div>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt index 18cf94d..6695740 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods-expected.txt
@@ -2,29 +2,29 @@ Expression `document.querySelector('div').x = "foo"` has side effect: true, expected: true Expression `$('div')` -has side effect: false, expected: false +has side effect: true, expected: true Expression `$$('div')` -has side effect: false, expected: false +has side effect: true, expected: true Expression `$x('//div')` -has side effect: false, expected: false +has side effect: true, expected: true Expression `getEventListeners(document)` -has side effect: false, expected: false +has side effect: true, expected: true Expression `$.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `$$.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `$x.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `getEventListeners.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `monitorEvents()` has side effect: true, expected: true Expression `unmonitorEvents()` has side effect: true, expected: true Expression `monitorEvents.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `unmonitorEvents.toString()` -has side effect: false, expected: false +has side effect: true, expected: true Expression `document.getElementsByTagName('div')` has side effect: false, expected: false Expression `document.getElementsByTagNameNS(namespace, 'div')`
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js index 3333f3a..28a112d8 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/side-effects/evaluate-embedder-side-effect-free-methods.js
@@ -37,20 +37,20 @@ await checkHasSideEffect(`document.querySelector('div').x = "foo"`); // Command Line API - await checkHasNoSideEffect(`$('div')`); - await checkHasNoSideEffect(`$$('div')`); - await checkHasNoSideEffect(`$x('//div')`); - await checkHasNoSideEffect(`getEventListeners(document)`); - await checkHasNoSideEffect(`$.toString()`); - await checkHasNoSideEffect(`$$.toString()`); - await checkHasNoSideEffect(`$x.toString()`); - await checkHasNoSideEffect(`getEventListeners.toString()`); + await checkHasSideEffect(`$('div')`); + await checkHasSideEffect(`$$('div')`); + await checkHasSideEffect(`$x('//div')`); + await checkHasSideEffect(`getEventListeners(document)`); + await checkHasSideEffect(`$.toString()`); + await checkHasSideEffect(`$$.toString()`); + await checkHasSideEffect(`$x.toString()`); + await checkHasSideEffect(`getEventListeners.toString()`); // Unsafe Command Line API await checkHasSideEffect(`monitorEvents()`); await checkHasSideEffect(`unmonitorEvents()`); - await checkHasNoSideEffect(`monitorEvents.toString()`); - await checkHasNoSideEffect(`unmonitorEvents.toString()`); + await checkHasSideEffect(`monitorEvents.toString()`); + await checkHasSideEffect(`unmonitorEvents.toString()`); // Document await checkHasNoSideEffect(`document.getElementsByTagName('div')`);
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt new file mode 100644 index 0000000..71c4b3e --- /dev/null +++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler-expected.txt
@@ -0,0 +1,3 @@ +Ping sent successfully +HTTP_REFERER: http://127.0.0.1:8000/navigation/image-load-in-pagehide-handler.html +REQUEST_METHOD: GET
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html similarity index 67% rename from third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html rename to third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html index d872a82..aa60cbc6 100644 --- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler.html +++ b/third_party/blink/web_tests/http/tests/navigation/image-load-in-pagehide-handler.html
@@ -2,7 +2,7 @@ <html> <head> - <title>Image load in unload handler</title> + <title>Image load in pagehide handler</title> <script> // We need to ensure that other instances of this test running in parallel // (e.g. in a virtual suite) do not interfere. @@ -15,32 +15,32 @@ async function test() { - const response = await fetch(`resources/delete-ping.php?test=unload-image-${key}`); + const response = await fetch(`resources/delete-ping.php?test=pagehide-image-${key}`); if (response.ok) { // We can't go to check-ping.php directly, since that doesn't start sending - // a response until the ping data is detected, but unload handlers (where + // a response until the ping data is detected, but pagehide handlers (where // we send the ping) are only run once we've begun receiving data from the // page being navigated to. Instead, we go through a dummy redirect page, - // to make sure that the onunload handler has run before we get to + // to make sure that the onpagehide handler has run before we get to // check-ping.php. - location.assign(`resources/ping-redirect.html?test=unload-image-${key}`); + location.assign(`resources/ping-redirect.html?test=pagehide-image-${key}`); } } function ping() { var img = new Image(1, 1); - img.src = `resources/save-Ping.php?test=unload-image-${key}` + img.src = `resources/save-Ping.php?test=pagehide-image-${key}` } </script> </head> -<body onload="test();" onunload="ping();"> +<body onload="test();" onpagehide="ping();"> Test case for https://bugs.webkit.org/show_bug.cgi?id=30457. Previously, if an image<br> - load was trigger from an unload handler, we would kill it almost immediately due to the<br> + load was trigger from an pagehide handler, we would kill it almost immediately due to the<br> navigation stopping all loaders. These loads now happen entirely in the background and detached<br> from the DOM, so they're invisible to the normal resource load callback infrastructure. We generate a<br> - timestamp, then in the unload handler, we load an 'image' (actually a php script) that takes the<br> + timestamp, then in the pagehide handler, we load an 'image' (actually a php script) that takes the<br> timestamp as a parameter and saves it to a file. The destination page is a php script that checks for<br> the existence of that file and passes the test if the file contains the expected timestamp.<br> </body>
diff --git a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt b/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt deleted file mode 100644 index 05f1e2a..0000000 --- a/third_party/blink/web_tests/http/tests/navigation/image-load-in-unload-handler-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -Ping sent successfully -HTTP_REFERER: http://127.0.0.1:8000/navigation/image-load-in-unload-handler.html -REQUEST_METHOD: GET
diff --git a/third_party/dawn b/third_party/dawn index 667f56e..4d6794a 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 667f56eab3feb5ed6aa40dd9b2319b3fb784f1f6 +Subproject commit 4d6794a7625867209adaaf3839b6969578acea2f
diff --git a/third_party/depot_tools b/third_party/depot_tools index 3900055..007dd45 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 390005586bde14be9b55fde71ca4ae2107021ac9 +Subproject commit 007dd45a94b8fe400fb69113f7999fed185cb5c1
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 7a46eb1..c415910 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 7a46eb1458616c7271b7aa5787a8ae89c800bc34 +Subproject commit c41591023f94b09a395d82d1c8bf571ead6895b2
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 5fad45b..d757184 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 5fad45b99a7ca290b0e36ca81f0074589ee2ef9b +Subproject commit d7571848c16a0ff89d4964c838dc44e0ce915049
diff --git a/third_party/gvr-android-sdk/BUILD.gn b/third_party/gvr-android-sdk/BUILD.gn deleted file mode 100644 index 2a6ded8..0000000 --- a/third_party/gvr-android-sdk/BUILD.gn +++ /dev/null
@@ -1,74 +0,0 @@ -# Copyright 2016 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/android/rules.gni") -import("//build/config/c++/c++.gni") -import("//device/vr/buildflags/buildflags.gni") - -assert(enable_vr) - -android_aar_prebuilt("controller_test_api_java") { - testonly = true - aar_path = "test-libraries/controller_test_api.aar" - proguard_configs = [ "test-libraries/proguard.txt" ] - - # Jar includes conflicting copies of Desugar-runtime.jar classes. - # Includes conflicting copy from j2objc/annotations. - # Errorprone annotations conflicts with doubledown!material_design. - jar_excluded_patterns = [ - "*ThrowableExtension*.class", - "*j2objc/annotations*", - "com/google/errorprone/annotations*", - ] - - deps = [ - ":gvr_common_java", - "//third_party/android_deps:guava_android_java", - ] -} - -android_aar_prebuilt("gvr_common_java") { - aar_path = "src/libraries/sdk-common-1.130.0.aar" - proguard_configs = [ - "src/proguard-gvr.txt", - "proguard-gvr-chromium.txt", - ] - ignore_native_libraries = true - deps = [ "//third_party/android_protobuf:protobuf_nano_javalib" ] -} - -android_aar_prebuilt("gvr_controller_java") { - aar_path = "src/libraries/sdk-controller-1.130.0.aar" - deps = [ ":gvr_common_java" ] -} - -config("libgvr_config") { - include_dirs = [ "src/libraries/headers/" ] -} - -component("gvr_shim") { - libs = [ - "android", - "log", - ] - if (enable_chrome_android_internal && !is_official_build) { - deps = [ "//clank/third_party/gvr_shim" ] - } else { - if (use_relative_vtables_abi) { - _vtables = "_vtables" - } else { - _vtables = "" - } - library = "//third_party/gvr-android-sdk/libgvr_shim_static_${current_cpu}${_vtables}.a" - libs += [ library ] - - if (libcxx_is_shared) { - ldflags = [ - "-Wl,--whole-archive", - rebase_path(library, root_build_dir), - "-Wl,--no-whole-archive", - ] - } - } -}
diff --git a/third_party/gvr-android-sdk/DEPS b/third_party/gvr-android-sdk/DEPS deleted file mode 100644 index 978e204..0000000 --- a/third_party/gvr-android-sdk/DEPS +++ /dev/null
@@ -1,5 +0,0 @@ -include_rules = [ - '+base/android/jni_android.h', - '+third_party/jni_zero/jni_int_wrapper.h', - '+third_party/jni_zero/jni_zero_helper.h', -]
diff --git a/third_party/gvr-android-sdk/DIR_METADATA b/third_party/gvr-android-sdk/DIR_METADATA deleted file mode 100644 index 4aece69..0000000 --- a/third_party/gvr-android-sdk/DIR_METADATA +++ /dev/null
@@ -1,5 +0,0 @@ -monorail { - component: "Internals>XR>VR" -} -team_email: "xr-dev@chromium.org" -os: ANDROID
diff --git a/third_party/gvr-android-sdk/LICENSE b/third_party/gvr-android-sdk/LICENSE deleted file mode 100644 index a2945f2..0000000 --- a/third_party/gvr-android-sdk/LICENSE +++ /dev/null
@@ -1,7943 +0,0 @@ - Copyright (c) 2015, Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - -==================== -Open Source Licenses -==================== - -This software may use portions of the following libraries subject to the accompanying licenses: - -**************************** -chromium_audio -**************************** -// Copyright 2014 The Chromium Authors -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -curl -**************************** -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1996 - 2014, Daniel Stenberg, <daniel@haxx.se>. - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - - -**************************** -dynamic_annotations -**************************** -Copyright (c) 2008-2009, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -eigen3 -**************************** -Eigen is primarily MPL2 licensed. See COPYING.MPL2 and these links: - http://www.mozilla.org/MPL/2.0/ - http://www.mozilla.org/MPL/2.0/FAQ.html - -Some files contain third-party code under BSD or LGPL licenses, whence -the other COPYING.* files here. - -All the LGPL code is either LGPL 2.1-only, or LGPL 2.1-or-later. -For this reason, the COPYING.LGPL file contains the LGPL 2.1 text. - -If you want to guarantee that the Eigen code that you are #including -is licensed under the MPL2 and possibly more permissive licenses (like -BSD), #define this preprocessor symbol: EIGEN_MPL2_ONLY -For example, with most compilers, you could add this to your project - CXXFLAGS: -DEIGEN_MPL2_ONLY -This will cause a compilation error to be generated if you #include -any code that is LGPL licensed. - ----------------------------------------------------------------------- -Following applies to: -./test/mapstaticmethods.cpp -./test/schur_real.cpp -./test/prec_inverse_4x4.cpp -./test/smallvectors.cpp -./test/redux.cpp -./test/special_numbers.cpp -./test/adjoint.cpp -./test/resize.cpp -./test/mixingtypes.cpp -./test/product_trmv.cpp -./test/sparse_solvers.cpp -./test/cholesky.cpp -./test/geo_quaternion.cpp -./test/miscmatrices.cpp -./test/stddeque.cpp -./test/integer_types.cpp -./test/product_large.cpp -./test/eigensolver_generic.cpp -./test/householder.cpp -./test/geo_orthomethods.cpp -./test/array_for_matrix.cpp -./test/sparseLM.cpp -./test/upperbidiagonalization.cpp -./test/nomalloc.cpp -./test/packetmath.cpp -./test/jacobisvd.cpp -./test/geo_transformations.cpp -./test/swap.cpp -./test/eigensolver_selfadjoint.cpp -./test/inverse.cpp -./test/product_selfadjoint.cpp -./test/product_trsolve.cpp -./test/product_extra.cpp -./test/sparse_solver.h -./test/mapstride.cpp -./test/mapped_matrix.cpp -./test/geo_eulerangles.cpp -./test/eigen2support.cpp -./test/denseLM.cpp -./test/stdvector.cpp -./test/nesting_ops.cpp -./test/sparse_permutations.cpp -./test/zerosized.cpp -./test/exceptions.cpp -./test/vectorwiseop.cpp -./test/cwiseop.cpp -./test/basicstuff.cpp -./test/product_trmm.cpp -./test/linearstructure.cpp -./test/sparse_product.cpp -./test/stdvector_overload.cpp -./test/stable_norm.cpp -./test/umeyama.cpp -./test/unalignedcount.cpp -./test/triangular.cpp -./test/product_mmtr.cpp -./test/sparse_basic.cpp -./test/sparse_vector.cpp -./test/meta.cpp -./test/real_qz.cpp -./test/ref.cpp -./test/eigensolver_complex.cpp -./test/cholmod_support.cpp -./test/conjugate_gradient.cpp -./test/sparse.h -./test/simplicial_cholesky.cpp -./test/bicgstab.cpp -./test/dynalloc.cpp -./test/product_notemporary.cpp -./test/geo_hyperplane.cpp -./test/lu.cpp -./test/qr.cpp -./test/hessenberg.cpp -./test/sizeof.cpp -./test/main.h -./test/selfadjoint.cpp -./test/permutationmatrices.cpp -./test/superlu_support.cpp -./test/qtvector.cpp -./test/geo_homogeneous.cpp -./test/determinant.cpp -./test/array_reverse.cpp -./test/unalignedassert.cpp -./test/stdlist.cpp -./test/product_symm.cpp -./test/corners.cpp -./test/dontalign.cpp -./test/visitor.cpp -./test/geo_alignedbox.cpp -./test/diagonalmatrices.cpp -./test/product_small.cpp -./test/eigensolver_generalized_real.cpp -./test/umfpack_support.cpp -./test/first_aligned.cpp -./test/qr_fullpivoting.cpp -./test/array_replicate.cpp -./test/geo_parametrizedline.cpp -./test/eigen2/eigen2_unalignedassert.cpp -./test/eigen2/eigen2_prec_inverse_4x4.cpp -./test/eigen2/eigen2_alignedbox.cpp -./test/eigen2/eigen2_sparse_product.cpp -./test/eigen2/eigen2_meta.cpp -./test/eigen2/eigen2_nomalloc.cpp -./test/eigen2/eigen2_visitor.cpp -./test/eigen2/eigen2_packetmath.cpp -./test/eigen2/eigen2_svd.cpp -./test/eigen2/eigen2_mixingtypes.cpp -./test/eigen2/eigen2_qr.cpp -./test/eigen2/eigen2_cwiseop.cpp -./test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp -./test/eigen2/eigen2_smallvectors.cpp -./test/eigen2/eigen2_commainitializer.cpp -./test/eigen2/eigen2_sparse_solvers.cpp -./test/eigen2/eigen2_hyperplane.cpp -./test/eigen2/eigen2_eigensolver.cpp -./test/eigen2/eigen2_linearstructure.cpp -./test/eigen2/eigen2_sizeof.cpp -./test/eigen2/eigen2_parametrizedline.cpp -./test/eigen2/eigen2_lu.cpp -./test/eigen2/eigen2_adjoint.cpp -./test/eigen2/eigen2_geometry.cpp -./test/eigen2/eigen2_stdvector.cpp -./test/eigen2/eigen2_newstdvector.cpp -./test/eigen2/eigen2_submatrices.cpp -./test/eigen2/sparse.h -./test/eigen2/eigen2_swap.cpp -./test/eigen2/eigen2_triangular.cpp -./test/eigen2/eigen2_basicstuff.cpp -./test/eigen2/gsl_helper.h -./test/eigen2/eigen2_dynalloc.cpp -./test/eigen2/eigen2_array.cpp -./test/eigen2/eigen2_map.cpp -./test/eigen2/main.h -./test/eigen2/eigen2_miscmatrices.cpp -./test/eigen2/eigen2_product_large.cpp -./test/eigen2/eigen2_first_aligned.cpp -./test/eigen2/eigen2_cholesky.cpp -./test/eigen2/eigen2_determinant.cpp -./test/eigen2/eigen2_sum.cpp -./test/eigen2/eigen2_inverse.cpp -./test/eigen2/eigen2_regression.cpp -./test/eigen2/eigen2_product_small.cpp -./test/eigen2/eigen2_qtvector.cpp -./test/eigen2/eigen2_sparse_vector.cpp -./test/eigen2/product.h -./test/eigen2/eigen2_sparse_basic.cpp -./test/eigen2/eigen2_bug_132.cpp -./test/array.cpp -./test/product_syrk.cpp -./test/commainitializer.cpp -./test/conservative_resize.cpp -./test/qr_colpivoting.cpp -./test/nullary.cpp -./test/bandmatrix.cpp -./test/pastix_support.cpp -./test/product.h -./test/block.cpp -./test/vectorization_logic.cpp -./test/jacobi.cpp -./test/diagonal.cpp -./test/schur_complex.cpp -./test/sizeoverflow.cpp -./bench/BenchTimer.h -./bench/benchFFT.cpp -./bench/eig33.cpp -./bench/spbench/spbenchsolver.h -./bench/spbench/spbenchstyle.h -./lapack/complex_double.cpp -./lapack/cholesky.cpp -./lapack/lapack_common.h -./lapack/eigenvalues.cpp -./lapack/single.cpp -./lapack/lu.cpp -./lapack/complex_single.cpp -./lapack/double.cpp -./demos/mix_eigen_and_c/binary_library.cpp -./demos/mix_eigen_and_c/binary_library.h -./demos/mix_eigen_and_c/example.c -./demos/mandelbrot/mandelbrot.cpp -./demos/mandelbrot/mandelbrot.h -./demos/opengl/icosphere.cpp -./demos/opengl/icosphere.h -./demos/opengl/camera.cpp -./demos/opengl/quaternion_demo.h -./demos/opengl/camera.h -./demos/opengl/trackball.h -./demos/opengl/gpuhelper.h -./demos/opengl/trackball.cpp -./demos/opengl/gpuhelper.cpp -./demos/opengl/quaternion_demo.cpp -./debug/gdb/printers.py -./unsupported/test/minres.cpp -./unsupported/test/openglsupport.cpp -./unsupported/test/jacobisvd.cpp -./unsupported/test/dgmres.cpp -./unsupported/test/matrix_square_root.cpp -./unsupported/test/bdcsvd.cpp -./unsupported/test/matrix_exponential.cpp -./unsupported/test/forward_adolc.cpp -./unsupported/test/polynomialsolver.cpp -./unsupported/test/matrix_function.cpp -./unsupported/test/sparse_extra.cpp -./unsupported/test/matrix_functions.h -./unsupported/test/svd_common.h -./unsupported/test/FFTW.cpp -./unsupported/test/alignedvector3.cpp -./unsupported/test/autodiff.cpp -./unsupported/test/gmres.cpp -./unsupported/test/BVH.cpp -./unsupported/test/levenberg_marquardt.cpp -./unsupported/test/matrix_power.cpp -./unsupported/test/kronecker_product.cpp -./unsupported/test/splines.cpp -./unsupported/test/polynomialutils.cpp -./unsupported/bench/bench_svd.cpp -./unsupported/Eigen/IterativeSolvers -./unsupported/Eigen/src/IterativeSolvers/DGMRES.h -./unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h -./unsupported/Eigen/src/IterativeSolvers/GMRES.h -./unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h -./unsupported/Eigen/src/IterativeSolvers/Scaling.h -./unsupported/Eigen/src/IterativeSolvers/MINRES.h -./unsupported/Eigen/src/SparseExtra/RandomSetter.h -./unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h -./unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h -./unsupported/Eigen/src/SparseExtra/MarketIO.h -./unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h -./unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h -./unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h -./unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h -./unsupported/Eigen/src/BVH/BVAlgorithms.h -./unsupported/Eigen/src/BVH/KdBVH.h -./unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h -./unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h -./unsupported/Eigen/src/AutoDiff/AutoDiffVector.h -./unsupported/Eigen/src/Splines/Spline.h -./unsupported/Eigen/src/Splines/SplineFitting.h -./unsupported/Eigen/src/Splines/SplineFwd.h -./unsupported/Eigen/src/SVD/JacobiSVD.h -./unsupported/Eigen/src/SVD/BDCSVD.h -./unsupported/Eigen/src/SVD/SVDBase.h -./unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h -./unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h -./unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h -./unsupported/Eigen/src/MatrixFunctions/StemFunction.h -./unsupported/Eigen/src/MatrixFunctions/MatrixPower.h -./unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h -./unsupported/Eigen/src/MatrixFunctions/MatrixFunctionAtomic.h -./unsupported/Eigen/src/MoreVectorization/MathFunctions.h -./unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h -./unsupported/Eigen/src/FFT/ei_fftw_impl.h -./unsupported/Eigen/src/FFT/ei_kissfft_impl.h -./unsupported/Eigen/src/Polynomials/PolynomialSolver.h -./unsupported/Eigen/src/Polynomials/Companion.h -./unsupported/Eigen/src/Polynomials/PolynomialUtils.h -./unsupported/Eigen/src/NumericalDiff/NumericalDiff.h -./unsupported/Eigen/src/Skyline/SkylineProduct.h -./unsupported/Eigen/src/Skyline/SkylineMatrixBase.h -./unsupported/Eigen/src/Skyline/SkylineStorage.h -./unsupported/Eigen/src/Skyline/SkylineUtil.h -./unsupported/Eigen/src/Skyline/SkylineInplaceLU.h -./unsupported/Eigen/src/Skyline/SkylineMatrix.h -./unsupported/Eigen/SparseExtra -./unsupported/Eigen/AdolcForward -./unsupported/Eigen/KroneckerProduct -./unsupported/Eigen/NonLinearOptimization -./unsupported/Eigen/BVH -./unsupported/Eigen/OpenGLSupport -./unsupported/Eigen/ArpackSupport -./unsupported/Eigen/AutoDiff -./unsupported/Eigen/Splines -./unsupported/Eigen/MPRealSupport -./unsupported/Eigen/MatrixFunctions -./unsupported/Eigen/MoreVectorization -./unsupported/Eigen/LevenbergMarquardt -./unsupported/Eigen/AlignedVector3 -./unsupported/Eigen/FFT -./unsupported/Eigen/Polynomials -./unsupported/Eigen/NumericalDiff -./unsupported/Eigen/Skyline -./COPYING.README -./COPYING.README -./LICENSE -./LICENSE -./LICENSE -./Eigen/Eigen2Support -./Eigen/src/Eigen2Support/VectorBlock.h -./Eigen/src/Eigen2Support/Cwise.h -./Eigen/src/Eigen2Support/Minor.h -./Eigen/src/Eigen2Support/Lazy.h -./Eigen/src/Eigen2Support/Memory.h -./Eigen/src/Eigen2Support/MathFunctions.h -./Eigen/src/Eigen2Support/Geometry/AlignedBox.h -./Eigen/src/Eigen2Support/Geometry/Hyperplane.h -./Eigen/src/Eigen2Support/Geometry/Quaternion.h -./Eigen/src/Eigen2Support/Geometry/Rotation2D.h -./Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h -./Eigen/src/Eigen2Support/Geometry/RotationBase.h -./Eigen/src/Eigen2Support/Geometry/Translation.h -./Eigen/src/Eigen2Support/Geometry/Scaling.h -./Eigen/src/Eigen2Support/Geometry/AngleAxis.h -./Eigen/src/Eigen2Support/Geometry/Transform.h -./Eigen/src/Eigen2Support/TriangularSolver.h -./Eigen/src/Eigen2Support/LU.h -./Eigen/src/Eigen2Support/QR.h -./Eigen/src/Eigen2Support/SVD.h -./Eigen/src/Eigen2Support/Meta.h -./Eigen/src/Eigen2Support/Block.h -./Eigen/src/Eigen2Support/Macros.h -./Eigen/src/Eigen2Support/LeastSquares.h -./Eigen/src/Eigen2Support/CwiseOperators.h -./Eigen/src/Jacobi/Jacobi.h -./Eigen/src/misc/Kernel.h -./Eigen/src/misc/SparseSolve.h -./Eigen/src/misc/Solve.h -./Eigen/src/misc/Image.h -./Eigen/src/SparseCore/SparseColEtree.h -./Eigen/src/SparseCore/SparseTranspose.h -./Eigen/src/SparseCore/SparseUtil.h -./Eigen/src/SparseCore/SparseCwiseBinaryOp.h -./Eigen/src/SparseCore/SparseDiagonalProduct.h -./Eigen/src/SparseCore/SparseProduct.h -./Eigen/src/SparseCore/SparseDot.h -./Eigen/src/SparseCore/SparseCwiseUnaryOp.h -./Eigen/src/SparseCore/SparseSparseProductWithPruning.h -./Eigen/src/SparseCore/SparseBlock.h -./Eigen/src/SparseCore/SparseDenseProduct.h -./Eigen/src/SparseCore/CompressedStorage.h -./Eigen/src/SparseCore/SparseMatrixBase.h -./Eigen/src/SparseCore/MappedSparseMatrix.h -./Eigen/src/SparseCore/SparseTriangularView.h -./Eigen/src/SparseCore/SparseView.h -./Eigen/src/SparseCore/SparseFuzzy.h -./Eigen/src/SparseCore/TriangularSolver.h -./Eigen/src/SparseCore/SparseSelfAdjointView.h -./Eigen/src/SparseCore/SparseMatrix.h -./Eigen/src/SparseCore/SparseVector.h -./Eigen/src/SparseCore/AmbiVector.h -./Eigen/src/SparseCore/ConservativeSparseSparseProduct.h -./Eigen/src/SparseCore/SparseRedux.h -./Eigen/src/SparseCore/SparsePermutation.h -./Eigen/src/Eigenvalues/RealSchur.h -./Eigen/src/Eigenvalues/ComplexEigenSolver.h -./Eigen/src/Eigenvalues/GeneralizedEigenSolver.h -./Eigen/src/Eigenvalues/ComplexSchur.h -./Eigen/src/Eigenvalues/RealQZ.h -./Eigen/src/Eigenvalues/EigenSolver.h -./Eigen/src/Eigenvalues/HessenbergDecomposition.h -./Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h -./Eigen/src/Eigenvalues/Tridiagonalization.h -./Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h -./Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h -./Eigen/src/SuperLUSupport/SuperLUSupport.h -./Eigen/src/StlSupport/StdDeque.h -./Eigen/src/StlSupport/StdVector.h -./Eigen/src/StlSupport/StdList.h -./Eigen/src/StlSupport/details.h -./Eigen/src/SparseQR/SparseQR.h -./Eigen/src/LU/Inverse.h -./Eigen/src/LU/arch/Inverse_SSE.h -./Eigen/src/LU/Determinant.h -./Eigen/src/LU/PartialPivLU.h -./Eigen/src/LU/FullPivLU.h -./Eigen/src/UmfPackSupport/UmfPackSupport.h -./Eigen/src/OrderingMethods/Ordering.h -./Eigen/src/OrderingMethods/Eigen_Colamd.h -./Eigen/src/QR/HouseholderQR.h -./Eigen/src/QR/ColPivHouseholderQR.h -./Eigen/src/QR/FullPivHouseholderQR.h -./Eigen/src/SVD/JacobiSVD.h -./Eigen/src/SVD/UpperBidiagonalization.h -./Eigen/src/Geometry/OrthoMethods.h -./Eigen/src/Geometry/AlignedBox.h -./Eigen/src/Geometry/Hyperplane.h -./Eigen/src/Geometry/Quaternion.h -./Eigen/src/Geometry/EulerAngles.h -./Eigen/src/Geometry/Rotation2D.h -./Eigen/src/Geometry/ParametrizedLine.h -./Eigen/src/Geometry/RotationBase.h -./Eigen/src/Geometry/arch/Geometry_SSE.h -./Eigen/src/Geometry/Umeyama.h -./Eigen/src/Geometry/Homogeneous.h -./Eigen/src/Geometry/Translation.h -./Eigen/src/Geometry/Scaling.h -./Eigen/src/Geometry/AngleAxis.h -./Eigen/src/Geometry/Transform.h -./Eigen/src/plugins/BlockMethods.h -./Eigen/src/plugins/CommonCwiseUnaryOps.h -./Eigen/src/plugins/CommonCwiseBinaryOps.h -./Eigen/src/plugins/MatrixCwiseUnaryOps.h -./Eigen/src/plugins/MatrixCwiseBinaryOps.h -./Eigen/src/Householder/Householder.h -./Eigen/src/Householder/HouseholderSequence.h -./Eigen/src/Householder/BlockHouseholder.h -./Eigen/src/Core/VectorBlock.h -./Eigen/src/Core/Matrix.h -./Eigen/src/Core/Ref.h -./Eigen/src/Core/SelfAdjointView.h -./Eigen/src/Core/MathFunctions.h -./Eigen/src/Core/GlobalFunctions.h -./Eigen/src/Core/MapBase.h -./Eigen/src/Core/EigenBase.h -./Eigen/src/Core/GenericPacketMath.h -./Eigen/src/Core/NestByValue.h -./Eigen/src/Core/CwiseUnaryOp.h -./Eigen/src/Core/SolveTriangular.h -./Eigen/src/Core/Fuzzy.h -./Eigen/src/Core/Visitor.h -./Eigen/src/Core/Map.h -./Eigen/src/Core/NoAlias.h -./Eigen/src/Core/Diagonal.h -./Eigen/src/Core/StableNorm.h -./Eigen/src/Core/CoreIterators.h -./Eigen/src/Core/products/Parallelizer.h -./Eigen/src/Core/products/SelfadjointMatrixVector.h -./Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h -./Eigen/src/Core/products/TriangularSolverMatrix.h -./Eigen/src/Core/products/GeneralMatrixMatrix.h -./Eigen/src/Core/products/SelfadjointProduct.h -./Eigen/src/Core/products/CoeffBasedProduct.h -./Eigen/src/Core/products/TriangularMatrixVector.h -./Eigen/src/Core/products/SelfadjointMatrixMatrix.h -./Eigen/src/Core/products/TriangularSolverVector.h -./Eigen/src/Core/products/SelfadjointRank2Update.h -./Eigen/src/Core/products/GeneralBlockPanelKernel.h -./Eigen/src/Core/products/GeneralMatrixVector.h -./Eigen/src/Core/products/TriangularMatrixMatrix.h -./Eigen/src/Core/Reverse.h -./Eigen/src/Core/BooleanRedux.h -./Eigen/src/Core/Replicate.h -./Eigen/src/Core/arch/AltiVec/PacketMath.h -./Eigen/src/Core/arch/AltiVec/Complex.h -./Eigen/src/Core/arch/SSE/PacketMath.h -./Eigen/src/Core/arch/SSE/Complex.h -./Eigen/src/Core/arch/SSE/MathFunctions.h -./Eigen/src/Core/arch/NEON/PacketMath.h -./Eigen/src/Core/arch/NEON/Complex.h -./Eigen/src/Core/arch/Default/Settings.h -./Eigen/src/Core/CwiseUnaryView.h -./Eigen/src/Core/Array.h -./Eigen/src/Core/ArrayWrapper.h -./Eigen/src/Core/Swap.h -./Eigen/src/Core/Transpositions.h -./Eigen/src/Core/Random.h -./Eigen/src/Core/IO.h -./Eigen/src/Core/SelfCwiseBinaryOp.h -./Eigen/src/Core/VectorwiseOp.h -./Eigen/src/Core/Select.h -./Eigen/src/Core/ArrayBase.h -./Eigen/src/Core/DenseCoeffsBase.h -./Eigen/src/Core/DiagonalProduct.h -./Eigen/src/Core/Assign.h -./Eigen/src/Core/Redux.h -./Eigen/src/Core/ForceAlignedAccess.h -./Eigen/src/Core/BandMatrix.h -./Eigen/src/Core/PlainObjectBase.h -./Eigen/src/Core/DenseBase.h -./Eigen/src/Core/Flagged.h -./Eigen/src/Core/CwiseBinaryOp.h -./Eigen/src/Core/ProductBase.h -./Eigen/src/Core/TriangularMatrix.h -./Eigen/src/Core/Transpose.h -./Eigen/src/Core/DiagonalMatrix.h -./Eigen/src/Core/Dot.h -./Eigen/src/Core/Functors.h -./Eigen/src/Core/PermutationMatrix.h -./Eigen/src/Core/NumTraits.h -./Eigen/src/Core/MatrixBase.h -./Eigen/src/Core/DenseStorage.h -./Eigen/src/Core/util/Memory.h -./Eigen/src/Core/util/StaticAssert.h -./Eigen/src/Core/util/BlasUtil.h -./Eigen/src/Core/util/MatrixMapper.h -./Eigen/src/Core/util/XprHelper.h -./Eigen/src/Core/util/ForwardDeclarations.h -./Eigen/src/Core/util/Meta.h -./Eigen/src/Core/util/Macros.h -./Eigen/src/Core/util/Constants.h -./Eigen/src/Core/CwiseNullaryOp.h -./Eigen/src/Core/Block.h -./Eigen/src/Core/GeneralProduct.h -./Eigen/src/Core/CommaInitializer.h -./Eigen/src/Core/ReturnByValue.h -./Eigen/src/Core/Stride.h -./Eigen/src/SPQRSupport/SuiteSparseQRSupport.h -./Eigen/src/SparseLU/SparseLU_column_dfs.h -./Eigen/src/SparseLU/SparseLU_panel_dfs.h -./Eigen/src/SparseLU/SparseLU_relax_snode.h -./Eigen/src/SparseLU/SparseLU_panel_bmod.h -./Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h -./Eigen/src/SparseLU/SparseLU_Utils.h -./Eigen/src/SparseLU/SparseLU_gemm_kernel.h -./Eigen/src/SparseLU/SparseLU_kernel_bmod.h -./Eigen/src/SparseLU/SparseLU_pivotL.h -./Eigen/src/SparseLU/SparseLU_Memory.h -./Eigen/src/SparseLU/SparseLU_heap_relax_snode.h -./Eigen/src/SparseLU/SparseLUImpl.h -./Eigen/src/SparseLU/SparseLU_copy_to_ucol.h -./Eigen/src/SparseLU/SparseLU_Structs.h -./Eigen/src/SparseLU/SparseLU.h -./Eigen/src/SparseLU/SparseLU_column_bmod.h -./Eigen/src/SparseLU/SparseLU_pruneL.h -./Eigen/src/IterativeLinearSolvers/IncompleteLUT.h -./Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h -./Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h -./Eigen/src/IterativeLinearSolvers/ConjugateGradient.h -./Eigen/src/IterativeLinearSolvers/BiCGSTAB.h -./Eigen/src/SparseCholesky/SimplicialCholesky.h -./Eigen/src/Cholesky/LDLT.h -./Eigen/src/Cholesky/LLT.h -./Eigen/src/CholmodSupport/CholmodSupport.h -./Eigen/src/PaStiXSupport/PaStiXSupport.h -./Eigen/src/MetisSupport/MetisSupport.h -./Eigen/StdVector -./Eigen/Core -./Eigen/SparseLU -./Eigen/StdList -./Eigen/StdDeque -./Eigen/SparseCholesky -./scripts/relicense.py -./scripts/relicense.py -./blas/BandTriangularSolver.h -./blas/PackedTriangularMatrixVector.h -./blas/complex_double.cpp -./blas/level2_real_impl.h -./blas/level1_cplx_impl.h -./blas/level1_impl.h -./blas/level1_real_impl.h -./blas/level3_impl.h -./blas/single.cpp -./blas/level2_cplx_impl.h -./blas/PackedSelfadjointProduct.h -./blas/Rank2Update.h -./blas/complex_single.cpp -./blas/PackedTriangularSolverVector.h -./blas/double.cpp -./blas/common.h -./blas/level2_impl.h -./blas/GeneralRank1Update.h - -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. - ----------------------------------------------------------------------- -Following applies to: -./doc/UsingIntelMKL.dox -./doc/UsingIntelMKL.dox -./Eigen/src/Eigenvalues/ComplexSchur_MKL.h -./Eigen/src/Eigenvalues/ComplexSchur_MKL.h -./Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h -./Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h -./Eigen/src/Eigenvalues/RealSchur_MKL.h -./Eigen/src/Eigenvalues/RealSchur_MKL.h -./Eigen/src/LU/arch/Inverse_SSE.h -./Eigen/src/LU/arch/Inverse_SSE.h -./Eigen/src/LU/PartialPivLU_MKL.h -./Eigen/src/LU/PartialPivLU_MKL.h -./Eigen/src/QR/HouseholderQR_MKL.h -./Eigen/src/QR/HouseholderQR_MKL.h -./Eigen/src/QR/ColPivHouseholderQR_MKL.h -./Eigen/src/QR/ColPivHouseholderQR_MKL.h -./Eigen/src/SVD/JacobiSVD_MKL.h -./Eigen/src/SVD/JacobiSVD_MKL.h -./Eigen/src/PardisoSupport/PardisoSupport.h -./Eigen/src/PardisoSupport/PardisoSupport.h -./Eigen/src/Core/Assign_MKL.h -./Eigen/src/Core/Assign_MKL.h -./Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h -./Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h -./Eigen/src/Core/products/GeneralMatrixVector_MKL.h -./Eigen/src/Core/products/GeneralMatrixVector_MKL.h -./Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h -./Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h -./Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h -./Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h -./Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h -./Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h -./Eigen/src/Core/products/TriangularMatrixVector_MKL.h -./Eigen/src/Core/products/TriangularMatrixVector_MKL.h -./Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h -./Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h -./Eigen/src/Core/products/TriangularSolverMatrix_MKL.h -./Eigen/src/Core/products/TriangularSolverMatrix_MKL.h -./Eigen/src/Core/util/MKL_support.h -./Eigen/src/Core/util/MKL_support.h -./Eigen/src/Cholesky/LLT_MKL.h -./Eigen/src/Cholesky/LLT_MKL.h - -/* - Copyright (c) 2011, Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. * Neither the name of Intel Corporation nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - ----------------------------------------------------------------------- -Following applies to: - everything under ./bench/btl - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds -of works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, -family, or household purposes, or (2) anything designed or sold for -incorporation into a dwelling. In determining whether a product is a -consumer product, doubtful cases shall be resolved in favor of -coverage. For a particular product received by a particular user, -"normally used" refers to a typical or common use of that class of -product, regardless of the status of the particular user or of the way -in which the particular user actually uses, or expects or is expected -to use, the product. A product is a consumer product regardless of -whether the product has substantial commercial, industrial or -non-consumer uses, unless such uses represent the only significant -mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to -install and execute modified versions of a covered work in that User -Product from a modified version of its Corresponding Source. The -information must suffice to ensure that the continued functioning of -the modified object code is in no case prevented or interfered with -solely because modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include -a requirement to continue to provide support service, warranty, or -updates for a work that has been modified or installed by the -recipient, or for the User Product in which it has been modified or -installed. Access to a network may be denied when the modification -itself materially and adversely affects the operation of the network -or violates the rules and protocols for communication across the -network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material -you add to a covered work, you may (if authorized by the copyright -holders of that material) supplement the terms of this License with -terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions - of it) with contractual assumptions of liability to the recipient, - for any liability that these contractual assumptions directly - impose on those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement -or otherwise) that contradict the conditions of this License, they do -not excuse you from the conditions of this License. If you cannot -convey a covered work so as to satisfy simultaneously your obligations -under this License and any other pertinent obligations, then as a -consequence you may not convey it at all. For example, if you agree -to terms that obligate you to collect a royalty for further conveying -from those to whom you convey the Program, the only way you could -satisfy both those terms and this License would be to refrain entirely -from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES -AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM -(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF -THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER -OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it - does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> This program comes - with ABSOLUTELY NO WARRANTY; for details type `show w'. This is - free software, and you are welcome to redistribute it under - certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, your -program's commands might be different; for a GUI interface, you would -use an "about box". - - You should also get your employer (if you work as a programmer) or -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. For more information on this, and how to apply and follow -the GNU GPL, see <http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your -program into proprietary programs. If your program is a subroutine -library, you may consider it more useful to permit linking proprietary -applications with the library. If this is what you want to do, use -the GNU Lesser General Public License instead of this License. But -first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>. - - ----------------------------------------------------------------------- -Following applies to: -./test/metis_support.cpp -./test/sparselu.cpp -./unsupported/test/mpreal/mpreal.h -./unsupported/Eigen/src/IterativeSolvers/IterationController.h -./unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h -./unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h -./Eigen/src/OrderingMethods/Amd.h -./Eigen/src/SparseCholesky/SimplicialCholesky_impl.h - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the -GNU General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this - license document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this - license document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of - this License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. - - ----------------------------------------------------------------------- -Following applies to: -./unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h -./unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h -./unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h -./unsupported/Eigen/src/LevenbergMarquardt/LMpar.h -./unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h - -Minpack Copyright Notice (1999) University of Chicago. All rights -reserved - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the -following conditions are met: - -1. Redistributions of source code must retain the above -copyright notice, this list of conditions and the following -disclaimer. - -2. Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials -provided with the distribution. - -3. The end-user documentation included with the -redistribution, if any, must include the following -acknowledgment: - - "This product includes software developed by the - University of Chicago, as Operator of Argonne National - Laboratory. - -Alternately, this acknowledgment may appear in the software -itself, if and wherever such third-party acknowledgments -normally appear. - -4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" -WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE -UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE -OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY -OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR -USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF -THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) -DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL -BE CORRECTED. - -5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT -HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, -INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF -ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF -PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER -SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT -(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, -EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE -POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -**************************** -freetype2 -**************************** -FreeType - -Quoth http://freetype.sourceforge.net/license.html: - -FreeType comes with two licenses from which you can choose the one -which fits your needs best. - - * The FreeType License is the most commonly used one. - It is a BSD-style license with a credit clause (and thus not - compatible with the GPL). - - * The GNU General Public License (GPL). - For all projects which use the GPL also or which need a license - compatible to the GPL. - -FTL.TXT: ---- - - The FreeType Project LICENSE - ---------------------------- - - 2006-Jan-27 - - Copyright 1996-2002, 2006 by - David Turner, Robert Wilhelm, and Werner Lemberg - - - -Introduction -============ - - The FreeType Project is distributed in several archive packages; - some of them may contain, in addition to the FreeType font engine, - various tools and contributions which rely on, or relate to, the - FreeType Project. - - This license applies to all files found in such packages, and - which do not fall under their own explicit license. The license - affects thus the FreeType font engine, the test programs, - documentation and makefiles, at the very least. - - This license was inspired by the BSD, Artistic, and IJG - (Independent JPEG Group) licenses, which all encourage inclusion - and use of free software in commercial and freeware products - alike. As a consequence, its main points are that: - - o We don't promise that this software works. However, we will be - interested in any kind of bug reports. (`as is' distribution) - - o You can use this software for whatever you want, in parts or - full form, without having to pay us. (`royalty-free' usage) - - o You may not pretend that you wrote this software. If you use - it, or only parts of it, in a program, you must acknowledge - somewhere in your documentation that you have used the - FreeType code. (`credits') - - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering The FreeType Project and - assume no liability related to The FreeType Project. - - - Finally, many people asked us for a preferred form for a - credit/disclaimer to use in compliance with this license. We thus - encourage you to use the following text: - - """ - Portions of this software are copyright (C) <year> The FreeType - Project (www.freetype.org). All rights reserved. - """ - - Please replace <year> with the value from the FreeType version you - actually use. - - -Legal Terms -=========== - -0. Definitions --------------- - - Throughout this license, the terms `package', `FreeType Project', - and `FreeType archive' refer to the set of files originally - distributed by the authors (David Turner, Robert Wilhelm, and - Werner Lemberg) as the `FreeType Project', be they named as alpha, - beta or final release. - - `You' refers to the licensee, or person using the project, where - `using' is a generic term including compiling the project's source - code as well as linking it to form a `program' or `executable'. - This program is referred to as `a program using the FreeType - engine'. - - This license applies to all files distributed in the original - FreeType Project, including all source code, binaries and - documentation, unless otherwise stated in the file in its - original, unmodified form as distributed in the original archive. - If you are unsure whether or not a particular file is covered by - this license, you must contact us to verify this. - - The FreeType Project is copyright (C) 1996-2000 by David Turner, - Robert Wilhelm, and Werner Lemberg. All rights reserved except as - specified below. - -1. No Warranty --------------- - - THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO - USE, OF THE FREETYPE PROJECT. - -2. Redistribution ------------------ - - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the FreeType Project (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: - - o Redistribution of source code must retain this license file - (`FTL.TXT') unaltered; any additions, deletions or changes to - the original files must be clearly indicated in accompanying - documentation. The copyright notices of the unaltered, - original files must be preserved in all copies of source - files. - - o Redistribution in binary form must provide a disclaimer that - states that the software is based in part of the work of the - FreeType Team, in the distribution documentation. We also - encourage you to put an URL to the FreeType web page in your - documentation, though this isn't mandatory. - - These conditions apply to any software derived from or based on - the FreeType Project, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. - -3. Advertising --------------- - - Neither the FreeType authors and contributors nor you shall use - the name of the other for commercial, advertising, or promotional - purposes without specific prior written permission. - - We suggest, but do not require, that you use one or more of the - following phrases to refer to this software in your documentation - or advertising materials: `FreeType Project', `FreeType Engine', - `FreeType library', or `FreeType Distribution'. - - As you have not signed this license, you are not required to - accept it. However, as the FreeType Project is copyrighted - material, only this license, or another one contracted with the - authors, grants you the right to use, distribute, and modify it. - Therefore, by using, distributing, or modifying the FreeType - Project, you indicate that you understand and accept all the terms - of this license. - -4. Contacts ------------ - - There are two mailing lists related to FreeType: - - o freetype@nongnu.org - - Discusses general use and applications of FreeType, as well as - future and wanted additions to the library and distribution. - If you are looking for support, start in this list if you - haven't found anything to help you in the documentation. - - o freetype-devel@nongnu.org - - Discusses bugs, as well as engine internals, design issues, - specific licenses, porting, etc. - - Our home page can be found at - - http://www.freetype.org - - ---- end of FTL.TXT --- - - -**************************** -GL -**************************** -Mesa Component Licenses - -Component Location Primary Author License ----------------------------------------------------------------------------- -Main Mesa code src/mesa/ Brian Paul Mesa (MIT) - -Device drivers src/mesa/drivers/* See drivers See drivers - -Ext headers include/GL/glext.h SGI SGI Free B - include/GL/glxext.h - -GLUT src/glut/ Mark Kilgard Mark's copyright - -GLEW src/glew-1.13.0 Nigel Stewart Modified BSD - -Mesa GLU library src/glu/mesa/ Brian Paul GNU-LGPL - -SGI GLU library src/glu/sgi/ SGI SGI Free B - -demo programs progs/demos/ various see source files - -X demos progs/xdemos/ Brian Paul see source files - -SGI demos progs/samples/ SGI SGI copyright - -RedBook demos progs/redbook/ SGI SGI copyright - ---------------------- -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------- - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of Alan Hourihane not be used in -advertising or publicity pertaining to distribution of the software without -specific, written prior permission. Alan Hourihane makes no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ----------------------------------------------------------------------- - - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - ---------------------- - -The OpenGL Extension Wrangler Library -Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org> -Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org> -Copyright (C) 2002, Lev Povalahev -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* The name of the author may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -gradle -**************************** - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ------------------------------------------------------------------------------- -License for the slf4j package ------------------------------------------------------------------------------- -SLF4J License - -Copyright (c) 2004-2007 QOS.ch -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -These terms are identical to those of the MIT License, also called the X License or the X11 License, -which is a simple, permissive non-copyleft free software license. It is deemed compatible with virtually -all types of licenses, commercial or otherwise. In particular, the Free Software Foundation has declared it -compatible with GNU GPL. It is also known to be approved by the Apache Software Foundation as compatible -with Apache Software License. - - ------------------------------------------------------------------------------- -License for the JUnit package ------------------------------------------------------------------------------- -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM -CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - -a) in the case of the initial Contributor, the initial code and -documentation distributed under this Agreement, and - -b) in the case of each subsequent Contributor: - -i) changes to the Program, and - -ii) additions to the Program; - -where such changes and/or additions to the Program originate from and are -distributed by that particular Contributor. A Contribution 'originates' from a -Contributor if it was added to the Program by such Contributor itself or anyone -acting on such Contributor's behalf. Contributions do not include additions to -the Program which: (i) are separate modules of software distributed in -conjunction with the Program under their own license agreement, and (ii) are not -derivative works of the Program. - -"Contributor" means any person or entity that distributes the Program. - -"Licensed Patents " mean patent claims licensable by a Contributor which are -necessarily infringed by the use or sale of its Contribution alone or when -combined with the Program. - -"Program" means the Contributions distributed in accordance with this Agreement. - -"Recipient" means anyone who receives the Program under this Agreement, -including all Contributors. - -2. GRANT OF RIGHTS - -a) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free copyright license to -reproduce, prepare derivative works of, publicly display, publicly perform, -distribute and sublicense the Contribution of such Contributor, if any, and such -derivative works, in source code and object code form. - -b) Subject to the terms of this Agreement, each Contributor hereby grants -Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed -Patents to make, use, sell, offer to sell, import and otherwise transfer the -Contribution of such Contributor, if any, in source code and object code form. -This patent license shall apply to the combination of the Contribution and the -Program if, at the time the Contribution is added by the Contributor, such -addition of the Contribution causes such combination to be covered by the -Licensed Patents. The patent license shall not apply to any other combinations -which include the Contribution. No hardware per se is licensed hereunder. - -c) Recipient understands that although each Contributor grants the licenses -to its Contributions set forth herein, no assurances are provided by any -Contributor that the Program does not infringe the patent or other intellectual -property rights of any other entity. Each Contributor disclaims any liability to -Recipient for claims brought by any other entity based on infringement of -intellectual property rights or otherwise. As a condition to exercising the -rights and licenses granted hereunder, each Recipient hereby assumes sole -responsibility to secure any other intellectual property rights needed, if any. -For example, if a third party patent license is required to allow Recipient to -distribute the Program, it is Recipient's responsibility to acquire that license -before distributing the Program. - -d) Each Contributor represents that to its knowledge it has sufficient -copyright rights in its Contribution, if any, to grant the copyright license set -forth in this Agreement. - -3. REQUIREMENTS - -A Contributor may choose to distribute the Program in object code form under its -own license agreement, provided that: - -a) it complies with the terms and conditions of this Agreement; and - -b) its license agreement: - -i) effectively disclaims on behalf of all Contributors all warranties and -conditions, express and implied, including warranties or conditions of title and -non-infringement, and implied warranties or conditions of merchantability and -fitness for a particular purpose; - -ii) effectively excludes on behalf of all Contributors all liability for -damages, including direct, indirect, special, incidental and consequential -damages, such as lost profits; - -iii) states that any provisions which differ from this Agreement are offered -by that Contributor alone and not by any other party; and - -iv) states that source code for the Program is available from such -Contributor, and informs licensees how to obtain it in a reasonable manner on or -through a medium customarily used for software exchange. - -When the Program is made available in source code form: - -a) it must be made available under this Agreement; and - -b) a copy of this Agreement must be included with each copy of the Program. - -Contributors may not remove or alter any copyright notices contained within the -Program. - -Each Contributor must identify itself as the originator of its Contribution, if -any, in a manner that reasonably allows subsequent Recipients to identify the -originator of the Contribution. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities with -respect to end users, business partners and the like. While this license is -intended to facilitate the commercial use of the Program, the Contributor who -includes the Program in a commercial product offering should do so in a manner -which does not create potential liability for other Contributors. Therefore, if -a Contributor includes the Program in a commercial product offering, such -Contributor ("Commercial Contributor") hereby agrees to defend and indemnify -every other Contributor ("Indemnified Contributor") against any losses, damages -and costs (collectively "Losses") arising from claims, lawsuits and other legal -actions brought by a third party against the Indemnified Contributor to the -extent caused by the acts or omissions of such Commercial Contributor in -connection with its distribution of the Program in a commercial product -offering. The obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. In order -to qualify, an Indemnified Contributor must: a) promptly notify the Commercial -Contributor in writing of such claim, and b) allow the Commercial Contributor to -control, and cooperate with the Commercial Contributor in, the defense and any -related settlement negotiations. The Indemnified Contributor may participate in -any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial product -offering, Product X. That Contributor is then a Commercial Contributor. If that -Commercial Contributor then makes performance claims, or offers warranties -related to Product X, those performance claims and warranties are such -Commercial Contributor's responsibility alone. Under this section, the -Commercial Contributor would have to defend claims against the other -Contributors related to those performance claims and warranties, and if a court -requires any other Contributor to pay any damages as a result, the Commercial -Contributor must pay those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, -NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each -Recipient is solely responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its exercise of -rights under this Agreement, including but not limited to the risks and costs of -program errors, compliance with applicable laws, damage to or loss of data, -programs or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY -CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS -GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under applicable -law, it shall not affect the validity or enforceability of the remainder of the -terms of this Agreement, and without further action by the parties hereto, such -provision shall be reformed to the minimum extent necessary to make such -provision valid and enforceable. - -If Recipient institutes patent litigation against a Contributor with respect to -a patent applicable to software (including a cross-claim or counterclaim in a -lawsuit), then any patent licenses granted by that Contributor to such Recipient -under this Agreement shall terminate as of the date such litigation is filed. In -addition, if Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the Program -itself (excluding combinations of the Program with other software or hardware) -infringes such Recipient's patent(s), then such Recipient's rights granted under -Section 2(b) shall terminate as of the date such litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it fails to -comply with any of the material terms or conditions of this Agreement and does -not cure such failure in a reasonable period of time after becoming aware of -such noncompliance. If all Recipient's rights under this Agreement terminate, -Recipient agrees to cease use and distribution of the Program as soon as -reasonably practicable. However, Recipient's obligations under this Agreement -and any licenses granted by Recipient relating to the Program shall continue and -survive. - -Everyone is permitted to copy and distribute copies of this Agreement, but in -order to avoid inconsistency the Agreement is copyrighted and may only be -modified in the following manner. The Agreement Steward reserves the right to -publish new versions (including revisions) of this Agreement from time to time. -No one other than the Agreement Steward has the right to modify this Agreement. -IBM is the initial Agreement Steward. IBM may assign the responsibility to serve -as the Agreement Steward to a suitable separate entity. Each new version of the -Agreement will be given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the Agreement -under which it was received. In addition, after a new version of the Agreement -is published, Contributor may elect to distribute the Program (including its -Contributions) under the new version. Except as expressly stated in Sections -2(a) and 2(b) above, Recipient receives no rights or licenses to the -intellectual property of any Contributor under this Agreement, whether -expressly, by implication, estoppel or otherwise. All rights in the Program not -expressly granted under this Agreement are reserved. - -This Agreement is governed by the laws of the State of New York and the -intellectual property laws of the United States of America. No party to this -Agreement will bring a legal action under this Agreement more than one year -after the cause of action arose. Each party waives its rights to a jury trial in -any resulting litigation. - ------------------------------------------------------------------------------- -License for the JCIFS package ------------------------------------------------------------------------------- -JCIFS License - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - - -**************************** -icu -**************************** -ICU - -There are two licenses here: -- ICU license -- Unicode Terms of Use ------------------------------------------------------------------------------- -ICU License - ICU 1.8.1 and later -From http://source.icu-project.org/repos/icu/icu/trunk/license.html -X License (old version). For license pedigree see the -ICU FAQ at http://icu-project.org/userguide/icufaq.html - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1995-2006 International Business Machines Corporation and others - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -provided that the above copyright notice(s) and this permission notice appear -in all copies of the Software and that both the above copyright notice(s) and -this permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE -LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - -All trademarks and registered trademarks mentioned herein are the property of their respective owners. - ------------------------------------------------------------------------------- -Unicode Terms of Use, from http://www.unicode.org/copyright.html - - For the general privacy policy governing access to this site, see the -Unicode Privacy Policy. For trademark usage, see the Unicode Consortium -Trademarks and Logo Policy. - Notice to End User: Terms of Use - Carefully read the following legal agreement ("Agreement"). Use or copying -of the software and/or codes provided with this agreement (The "Software") -constitutes your acceptance of these terms - - 1. Unicode Copyright. - 1. Copyright 1991-2007 Unicode, Inc. All rights reserved. - 2. Certain documents and files on this website contain a legend -indicating that "Modification is permitted." Any person is hereby authorized, -without fee, to modify such documents and files to create derivative works -conforming to the Unicode Standard, subject to Terms and Conditions herein. - 3. Any person is hereby authorized, without fee, to view, use, -reproduce, and distribute all documents and files solely for informational -purposes in the creation of products supporting the Unicode Standard, subject -to the Terms and Conditions herein. - 4. Further specifications of rights and restrictions pertaining -to the use of the particular set of data files known as the "Unicode Character -Database" can be found in Exhibit 1. - 5. Each version of the Unicode Standard has further specifications -of rights and restrictions of use. For the book editions, these are found on -the back of the title page. For the online edition, certain files (such as the -PDF files for book chapters and code charts) carry specific restrictions. All -other files are covered under these general Terms of Use. To request a -permission to reproduce any part of the Unicode Standard, please contact the -Unicode Consortium. - 6. No license is granted to "mirror" the Unicode website where a -fee is charged for access to the "mirror" site. - 7. Modification is not permitted with respect to this document. -All copies of this document must be verbatim. - 2. Restricted Rights Legend. Any technical data or software which is -licensed to the United States of America, its agencies and/or instrumentalities -under this Agreement is commercial technical data or commercial computer -software developed exclusively at private expense as defined in FAR 2.101, or -DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, -duplication, or disclosure by the Government is subject to restrictions as set -forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) -and this Agreement. For Software, in accordance with FAR 12-212 or -DFARS 227-7202, as applicable, use, duplication or disclosure by the Government -is subject to the restrictions set forth in this Agreement. - 3. Warranties and Disclaimers. - 1. This publication and/or website may include technical or -typographical errors or other inaccuracies . Changes are periodically added to -the information herein; these changes will be incorporated in new editions of -the publication and/or website. Unicode may make improvements and/or changes -in the product(s) and/or program(s) described in this publication and/or -website at any time. - 2. If this file has been purchased on magnetic or optical media -from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange -of the defective media within ninety (90) days of original purchase. - 3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR -SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, -IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. -UNICODE AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN -THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR -LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. - 4. Waiver of Damages. In no event shall Unicode or its licensors be -liable for any special, incidental, indirect or consequential damages of any -kind, or any damages whatsoever, whether or not Unicode was advised of the -possibility of the damage, including, without limitation, those resulting from -the following: loss of use, data or profits, in connection with the use, -modification or distribution of this information or its derivatives. - 5. Trademarks. - 1. Unicode and the Unicode logo are registered trademarks of -Unicode, Inc. - 2. This site contains product names and corporate names of other -companies. All product names and company names and logos mentioned herein are -the trademarks or registered trademarks of their respective owners. Other -products and corporate names mentioned herein which are trademarks of a third -party are used only for explanation and for the owners' benefit and with no -intent to infringe. - 3. Use of third party products or information referred to herein -is at the user\x{2019}s risk. - 6. Miscellaneous. - 1. Jurisdiction and Venue. This server is operated from a location -in the State of California, United States of America. Unicode makes no -representation that the materials are appropriate for use in other locations. -If you access this server from other locations, you are responsible for -compliance with local laws. This Agreement, all use of this site and any -claims and damages resulting from use of this site are governed solely by the -laws of the State of California without regard to any principles which would -apply the laws of a different jurisdiction. The user agrees that any disputes -regarding this site shall be resolved solely in the courts located in Santa -Clara County, California. The user agrees said courts have personal -jurisdiction and agree to waive any right to transfer the dispute to any other -forum. - 2. Modification by Unicode Unicode shall have the right to modify -this Agreement at any time by posting it to this site. The user may not assign -any part of this Agreement without Unicode\x{2019}s prior written consent. - 3. Taxes. The user agrees to pay any taxes arising from access to -this website or use of the information herein, except for those based on -Unicode\x{2019}s net income. - 4. Severability. If any provision of this Agreement is declared -invalid or unenforceable, the remaining provisions of this Agreement shall -remain in effect. - 5. Entire Agreement. This Agreement constitutes the entire -agreement between the parties. - -EXHIBIT 1 -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - - Unicode Data Files include all data files under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/ . Unicode Software includes any source code -published in the Unicode Standard or under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/. - - NOTICE TO USER: Carefully read the following legal agreement. BY -DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES -("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND -AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF -YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA -FILES OR SOFTWARE. - - COPYRIGHT AND PERMISSION NOTICE - - Copyright 1991-2007 Unicode, Inc. All rights reserved. Distributed under -the Terms of Use in http://www.unicode.org/copyright.html. - - Permission is hereby granted, free of charge, to any person obtaining a -copy of the Unicode data files and any associated documentation (the "Data -Files") or Unicode software and any associated documentation (the "Software") -to deal in the Data Files or Software without restriction, including without -limitation the rights to use, copy, modify, merge, publish, distribute, and/or -sell copies of the Data Files or Software, and to permit persons to whom the -Data Files or Software are furnished to do so, provided that (a) the above -copyright notice(s) and this permission notice appear with all copies of the -Data Files or Software, (b) both the above copyright notice(s) and this -permission notice appear in associated documentation, and (c) there is clear -notice in each modified Data File or in the Software as well as in the -documentation associated with the Data File(s) or Software that the data or -software has been modified. - - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD -PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN -THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR -SOFTWARE. - - Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or other -dealings in these Data Files or Software without prior written authorization -of the copyright holder. - - Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be -registered in some jurisdictions. All other trademarks and registered -trademarks mentioned herein are the property of their respective owners. - - -**************************** -icu -**************************** -ICU - -There are two licenses here: -- ICU license -- Unicode Terms of Use ------------------------------------------------------------------------------- -ICU License - ICU 1.8.1 and later -From http://source.icu-project.org/repos/icu/icu/trunk/license.html -X License (old version). For license pedigree see the -ICU FAQ at http://icu-project.org/userguide/icufaq.html - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1995-2006 International Business Machines Corporation and others - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -provided that the above copyright notice(s) and this permission notice appear -in all copies of the Software and that both the above copyright notice(s) and -this permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE -LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - -All trademarks and registered trademarks mentioned herein are the property of their respective owners. - ------------------------------------------------------------------------------- -Unicode Terms of Use, from http://www.unicode.org/copyright.html - - For the general privacy policy governing access to this site, see the -Unicode Privacy Policy. For trademark usage, see the Unicode Consortium -Trademarks and Logo Policy. - Notice to End User: Terms of Use - Carefully read the following legal agreement ("Agreement"). Use or copying -of the software and/or codes provided with this agreement (The "Software") -constitutes your acceptance of these terms - - 1. Unicode Copyright. - 1. Copyright 1991-2007 Unicode, Inc. All rights reserved. - 2. Certain documents and files on this website contain a legend -indicating that "Modification is permitted." Any person is hereby authorized, -without fee, to modify such documents and files to create derivative works -conforming to the Unicode Standard, subject to Terms and Conditions herein. - 3. Any person is hereby authorized, without fee, to view, use, -reproduce, and distribute all documents and files solely for informational -purposes in the creation of products supporting the Unicode Standard, subject -to the Terms and Conditions herein. - 4. Further specifications of rights and restrictions pertaining -to the use of the particular set of data files known as the "Unicode Character -Database" can be found in Exhibit 1. - 5. Each version of the Unicode Standard has further specifications -of rights and restrictions of use. For the book editions, these are found on -the back of the title page. For the online edition, certain files (such as the -PDF files for book chapters and code charts) carry specific restrictions. All -other files are covered under these general Terms of Use. To request a -permission to reproduce any part of the Unicode Standard, please contact the -Unicode Consortium. - 6. No license is granted to "mirror" the Unicode website where a -fee is charged for access to the "mirror" site. - 7. Modification is not permitted with respect to this document. -All copies of this document must be verbatim. - 2. Restricted Rights Legend. Any technical data or software which is -licensed to the United States of America, its agencies and/or instrumentalities -under this Agreement is commercial technical data or commercial computer -software developed exclusively at private expense as defined in FAR 2.101, or -DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, -duplication, or disclosure by the Government is subject to restrictions as set -forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) -and this Agreement. For Software, in accordance with FAR 12-212 or -DFARS 227-7202, as applicable, use, duplication or disclosure by the Government -is subject to the restrictions set forth in this Agreement. - 3. Warranties and Disclaimers. - 1. This publication and/or website may include technical or -typographical errors or other inaccuracies . Changes are periodically added to -the information herein; these changes will be incorporated in new editions of -the publication and/or website. Unicode may make improvements and/or changes -in the product(s) and/or program(s) described in this publication and/or -website at any time. - 2. If this file has been purchased on magnetic or optical media -from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange -of the defective media within ninety (90) days of original purchase. - 3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR -SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, -IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. -UNICODE AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN -THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR -LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. - 4. Waiver of Damages. In no event shall Unicode or its licensors be -liable for any special, incidental, indirect or consequential damages of any -kind, or any damages whatsoever, whether or not Unicode was advised of the -possibility of the damage, including, without limitation, those resulting from -the following: loss of use, data or profits, in connection with the use, -modification or distribution of this information or its derivatives. - 5. Trademarks. - 1. Unicode and the Unicode logo are registered trademarks of -Unicode, Inc. - 2. This site contains product names and corporate names of other -companies. All product names and company names and logos mentioned herein are -the trademarks or registered trademarks of their respective owners. Other -products and corporate names mentioned herein which are trademarks of a third -party are used only for explanation and for the owners' benefit and with no -intent to infringe. - 3. Use of third party products or information referred to herein -is at the user\x{2019}s risk. - 6. Miscellaneous. - 1. Jurisdiction and Venue. This server is operated from a location -in the State of California, United States of America. Unicode makes no -representation that the materials are appropriate for use in other locations. -If you access this server from other locations, you are responsible for -compliance with local laws. This Agreement, all use of this site and any -claims and damages resulting from use of this site are governed solely by the -laws of the State of California without regard to any principles which would -apply the laws of a different jurisdiction. The user agrees that any disputes -regarding this site shall be resolved solely in the courts located in Santa -Clara County, California. The user agrees said courts have personal -jurisdiction and agree to waive any right to transfer the dispute to any other -forum. - 2. Modification by Unicode Unicode shall have the right to modify -this Agreement at any time by posting it to this site. The user may not assign -any part of this Agreement without Unicode\x{2019}s prior written consent. - 3. Taxes. The user agrees to pay any taxes arising from access to -this website or use of the information herein, except for those based on -Unicode\x{2019}s net income. - 4. Severability. If any provision of this Agreement is declared -invalid or unenforceable, the remaining provisions of this Agreement shall -remain in effect. - 5. Entire Agreement. This Agreement constitutes the entire -agreement between the parties. - -EXHIBIT 1 -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - - Unicode Data Files include all data files under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/ . Unicode Software includes any source code -published in the Unicode Standard or under the directories -http://www.unicode.org/Public/, http://www.unicode.org/reports/, and -http://www.unicode.org/cldr/data/. - - NOTICE TO USER: Carefully read the following legal agreement. BY -DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES -("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND -AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF -YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA -FILES OR SOFTWARE. - - COPYRIGHT AND PERMISSION NOTICE - - Copyright 1991-2007 Unicode, Inc. All rights reserved. Distributed under -the Terms of Use in http://www.unicode.org/copyright.html. - - Permission is hereby granted, free of charge, to any person obtaining a -copy of the Unicode data files and any associated documentation (the "Data -Files") or Unicode software and any associated documentation (the "Software") -to deal in the Data Files or Software without restriction, including without -limitation the rights to use, copy, modify, merge, publish, distribute, and/or -sell copies of the Data Files or Software, and to permit persons to whom the -Data Files or Software are furnished to do so, provided that (a) the above -copyright notice(s) and this permission notice appear with all copies of the -Data Files or Software, (b) both the above copyright notice(s) and this -permission notice appear in associated documentation, and (c) there is clear -notice in each modified Data File or in the Software as well as in the -documentation associated with the Data File(s) or Software that the data or -software has been modified. - - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD -PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN -THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR -SOFTWARE. - - Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or other -dealings in these Data Files or Software without prior written authorization -of the copyright holder. - - Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be -registered in some jurisdictions. All other trademarks and registered -trademarks mentioned herein are the property of their respective owners. - - -**************************** -java/android_libs/exoplayer -**************************** - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -**************************** -java/android_libs/protobuf_nano -**************************** -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Code generated by the Protocol Buffer compiler is owned by the owner -of the input file used when generating it. This code is not -standalone and requires a support library to be linked with it. This -support library is itself covered by the above license. - - -**************************** -javascript/jquery_ui -**************************** -The MIT License (MIT) - -Copyright (c) 2015 jQuery Foundation and other contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -**************************** -javascript/jquery/v2_0_1 -**************************** -Copyright 2013 jQuery Foundation and other contributors -http://jquery.com/ - -https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt -https://github.com/jquery/sizzle/blob/master/LICENSE - -jQuery and Sizzle are released under MIT Licence. - -The text is provided below. - -MIT License ----- - -Copyright 2013 jQuery Foundation and other contributors -http://jquery.com/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -**************************** -javascript/tracing_framework -**************************** -Copyright 2012, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -java_src/android_libs/exoplayer -**************************** - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -**************************** -java_src/android_libs/protobuf_nano/v2 -**************************** -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Code generated by the Protocol Buffer compiler is owned by the owner -of the input file used when generating it. This code is not -standalone and requires a support library to be linked with it. This -support library is itself covered by the above license. - - -**************************** -jpeg -**************************** -(extracted from src/README) - -LEGAL ISSUES -============ - -In plain English: - -1. We don't promise that this software works. (But if you find any bugs, - please let us know!) -2. You can use this software for whatever you want. You don't have to pay us. -3. You may not pretend that you wrote this software. If you use it in a - program, you must acknowledge somewhere in your documentation that - you've used the IJG code. - -In legalese: - -The authors make NO WARRANTY or representation, either express or implied, -with respect to this software, its quality, accuracy, merchantability, or -fitness for a particular purpose. This software is provided "AS IS", and you, -its user, assume the entire risk as to its quality and accuracy. - -This software is copyright (C) 1991-1998, Thomas G. Lane. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this -software (or portions thereof) for any purpose, without fee, subject to these -conditions: -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice -unaltered; and any additions, deletions, or changes to the original files -must be clearly indicated in accompanying documentation. -(2) If only executable code is distributed, then the accompanying -documentation must state that "this software is based in part on the work of -the Independent JPEG Group". -(3) Permission for use of this software is granted only if the user accepts -full responsibility for any undesirable consequences; the authors accept -NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, -not just to the unmodified library. If you use our work, you ought to -acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name -in advertising or publicity relating to this software or products derived from -it. This software may be referred to only as "the Independent JPEG Group's -software". - -We specifically permit and encourage the use of this software as the basis of -commercial products, provided that all warranty or liability claims are -assumed by the product vendor. - - -ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, -sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. -ansi2knr.c is NOT covered by the above copyright and conditions, but instead -by the usual distribution terms of the Free Software Foundation; principally, -that you must include source code if you redistribute it. (See the file -ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part -of any program generated from the IJG code, this does not limit you more than -the foregoing paragraphs do. - -The Unix configuration script "configure" was produced with GNU Autoconf. -It is copyright by the Free Software Foundation but is freely distributable. -The same holds for its supporting scripts (config.guess, config.sub, -ltconfig, ltmain.sh). Another support script, install-sh, is copyright -by M.I.T. but is also freely distributable. - -It appears that the arithmetic coding option of the JPEG spec is covered by -patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot -legally be used without obtaining one or more licenses. For this reason, -support for arithmetic coding has been removed from the free JPEG software. -(Since arithmetic coding provides only a marginal gain over the unpatented -Huffman mode, it is unlikely that very many implementations will support it.) -So far as we are aware, there are no patent restrictions on the remaining -code. - -The IJG distribution formerly included code to read and write GIF files. -To avoid entanglement with the Unisys LZW patent, GIF reading support has -been removed altogether, and the GIF writer has been simplified to produce -"uncompressed GIFs". This technique does not use the LZW algorithm; the -resulting GIF files are larger than usual, but are readable by all standard -GIF decoders. - -We are required to state that - "The Graphics Interchange Format(c) is the Copyright property of - CompuServe Incorporated. GIF(sm) is a Service Mark property of - CompuServe Incorporated." - - -**************************** -libogg -**************************** -Copyright (c) 2002, Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -**************************** -libunwind -**************************** -Copyright (c) 2002 Hewlett-Packard Co. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -**************************** -libvorbis -**************************** -Copyright (c) 2002-2008 Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -libxcb -**************************** -Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett. -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall -be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the names of the authors -or their institutions shall not be used in advertising or -otherwise to promote the sale, use or other dealings in this -Software without prior written authorization from the -authors. - - -**************************** -libxml -**************************** -Libxml2, an XML C Parser - -Except where otherwise noted in the source code (e.g. the files hash.c, -list.c and the trio files, which are covered by a similar licence but -with different Copyright notices) all the files are: - - Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is fur- -nished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- -NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - --------------------------------------------------------------------- - -Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -Author: breese@users.sourceforge.net - -(taken from hash.c) - --------------------------------------------------------------------- - - Copyright (C) 2000 Gary Pennington and Daniel Veillard. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -Author: Gary.Pennington@uk.sun.com - -(taken from list.c) - --------------------------------------------------------------------- - -Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -(taken from trio.h and trio.c) - --------------------------------------------------------------------- - -Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -(taken from triodef.h, trionan.h, and trionan.c) - --------------------------------------------------------------------- - -Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -(taken from triop.h) - --------------------------------------------------------------------- - -Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND -CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - -(taken from triostr.h and triostr.c) - -************************************************************************* - -http://ctrio.sourceforge.net/ - -************************************************************************* - - -**************************** -lodepng -**************************** -LodePNG - -Copyright (c) 2005-2013 Lode Vandevenne - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - - -**************************** -minizip -**************************** -zlib - -(extracted from README, except for match.S) - -Copyright notice: - - (C) 1995-2004 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - -(extracted from match.S, for match.S only) - - Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -**************************** -mongoose -**************************** -Copyright (c) 2004-2013 Sergey Lyubka - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -**************************** -objective_c/gtm_session_fetcher -**************************** - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -**************************** -openctm -**************************** -Copyright (c) 2009-2010 Marcus Geelnard - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - - -**************************** -OpenCV -**************************** -IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. - -By downloading, copying, installing or using the software you agree to this license. -If you do not agree to this license, do not download, install, -copy or use the software. - - - Intel License Agreement - For Open Source Computer Vision Library - -Copyright (C) 2000, 2001, Intel Corporation, all rights reserved. -Copyright (C) 2013, OpenCV Foundation, all rights reserved. -Third party copyrights are property of their respective owners. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistribution's of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistribution's in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * The name of Intel Corporation may not be used to endorse or promote products - derived from this software without specific prior written permission. - -This software is provided by the copyright holders and contributors "as is" and -any express or implied warranties, including, but not limited to, the implied -warranties of merchantability and fitness for a particular purpose are disclaimed. -In no event shall the Intel Corporation or contributors be liable for any direct, -indirect, incidental, special, exemplary, or consequential damages -(including, but not limited to, procurement of substitute goods or services; -loss of use, data, or profits; or business interruption) however caused -and on any theory of liability, whether in contract, strict liability, -or tort (including negligence or otherwise) arising in any way out of -the use of this software, even if advised of the possibility of such damage. - -**************************** -openssl -**************************** -BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL -licensing. Files that are completely new have a Google copyright and an ISC -license. This license is reproduced at the bottom of this file. - -Contributors to BoringSSL are required to follow the CLA rules for Chromium: -https://cla.developers.google.com/clas - -Some files from Intel are under yet another license, which is also included -underneath. - -The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the -OpenSSL License and the original SSLeay license apply to the toolkit. See below -for the actual license texts. Actually both licenses are BSD-style Open Source -licenses. In case of any license issues related to OpenSSL please contact -openssl-core@openssl.org. - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - - -ISC license used for completely new code in BoringSSL: - -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - - -Some files from Intel carry the following license: - -# Copyright (c) 2012, Intel Corporation -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the -# distribution. -# -# * Neither the name of the Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# -# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -openssl/boringssl -**************************** -BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL -licensing. Files that are completely new have a Google copyright and an ISC -license. This license is reproduced at the bottom of this file. - -Contributors to BoringSSL are required to follow the CLA rules for Chromium: -https://cla.developers.google.com/clas - -Some files from Intel are under yet another license, which is also included -underneath. - -The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the -OpenSSL License and the original SSLeay license apply to the toolkit. See below -for the actual license texts. Actually both licenses are BSD-style Open Source -licenses. In case of any license issues related to OpenSSL please contact -openssl-core@openssl.org. - - OpenSSL License - --------------- - -/* ==================================================================== - * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - - -ISC license used for completely new code in BoringSSL: - -/* Copyright (c) 2015, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - - -Some files from Intel carry the following license: - -# Copyright (c) 2012, Intel Corporation -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the -# distribution. -# -# * Neither the name of the Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# -# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -pcre -**************************** -PCRE LICENCE ------------- - -PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - -Release 8 of PCRE is distributed under the terms of the "BSD" licence, as -specified below. The documentation for PCRE, supplied in the "doc" -directory, is distributed under the same terms as the software itself. The data -in the testdata directory is not copyrighted and is in the public domain. - -The basic library functions are written in C and are freestanding. Also -included in the distribution is a set of C++ wrapper functions, and a -just-in-time compiler that can be used to optimize pattern matching. These -are both optional features that can be omitted when the library is built. - - -THE BASIC LIBRARY FUNCTIONS ---------------------------- - -Written by: Philip Hazel -Email local part: ph10 -Email domain: cam.ac.uk - -University of Cambridge Computing Service, -Cambridge, England. - -Copyright (c) 1997-2015 University of Cambridge -All rights reserved. - - -PCRE JUST-IN-TIME COMPILATION SUPPORT -------------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2010-2015 Zoltan Herczeg -All rights reserved. - - -STACK-LESS JUST-IN-TIME COMPILER --------------------------------- - -Written by: Zoltan Herczeg -Email local part: hzmester -Emain domain: freemail.hu - -Copyright(c) 2009-2015 Zoltan Herczeg -All rights reserved. - - -THE C++ WRAPPER FUNCTIONS -------------------------- - -Contributed by: Google Inc. - -Copyright (c) 2007-2012, Google Inc. -All rights reserved. - - -THE "BSD" LICENCE ------------------ - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the name of Google - Inc. nor the names of their contributors may be used to endorse or - promote products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -End - - -**************************** -pffft -**************************** -Copyright (c) 2013 Julien Pommier ( pommier@modartt.com ) - -Based on original fortran 77 code from FFTPACKv4 from NETLIB, -authored by Dr Paul Swarztrauber of NCAR, in 1985. - -As confirmed by the NCAR fftpack software curators, the following -FFTPACKv5 license applies to FFTPACKv4 sources. My changes are -released under the same terms. - -FFTPACK license: - -http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html - -Copyright (c) 2004 the University Corporation for Atmospheric -Research ("UCAR"). All rights reserved. Developed by NCAR's -Computational and Information Systems Laboratory, UCAR, -www.cisl.ucar.edu. - -Redistribution and use of the Software in source and binary forms, -with or without modification, is permitted provided that the -following conditions are met: - -- Neither the names of NCAR's Computational and Information Systems -Laboratory, the University Corporation for Atmospheric Research, -nor the names of its sponsors or contributors may be used to -endorse or promote products derived from this Software without -specific prior written permission. - -- Redistributions of source code must retain the above copyright -notices, this list of conditions, and the disclaimer below. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions, and the disclaimer below in the -documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - - -**************************** -png -**************************** -libpng - -This copy of the libpng notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail. - -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: - -If you modify libpng you may insert additional notices immediately following -this sentence. - -libpng versions 1.2.6, August 15, 2004, through 1.2.27, April 29, 2008, are -Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.2.5 -with the following individual added to the list of Contributing Authors - - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are -Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6 -with the following individuals added to the list of Contributing Authors - - Simon-Pierre Cadieux - Eric S. Raymond - Gilles Vollant - -and with the following additions to the disclaimer: - - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. - -libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-0.96, -with the following individuals added to the list of Contributing Authors: - - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik - -libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88, -with the following individuals added to the list of Contributing Authors: - - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner - -libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. - -For the purposes of this copyright and license, "Contributing Authors" -is defined as the following set of individuals: - - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. - -Permission is hereby granted to use, copy, modify, and distribute this -source code, or portions hereof, for any purpose, without fee, subject -to the following restrictions: - -1. The origin of this source code must not be misrepresented. - -2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. - -3. This Copyright notice may not be removed or altered from any - source or altered source distribution. - -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. - - -A "png_get_copyright" function is available, for convenient use in "about" -boxes and the like: - - printf("%s",png_get_copyright(NULL)); - -Also, the PNG logo (in PNG format, of course) is supplied in the -files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a -certification mark of the Open Source Initiative. - -Glenn Randers-Pehrson -glennrp at users.sourceforge.net -April 29, 2008 - - -**************************** -protobuf -**************************** -Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Code generated by the Protocol Buffer compiler is owned by the owner -of the input file used when generating it. This code is not -standalone and requires a support library to be linked with it. This -support library is itself covered by the above license. - - -**************************** -re2 -**************************** -// Copyright (c) 2009 The RE2 Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -**************************** -stblib -**************************** - License for STBLIB - A collection of public-domain single-file C/C++ - libraries, primarily aimed at game developers. - -The compilation and test files are licensed under the MIT license, but the -single-file libraries themselves are in the public domain (free for use and -modification for any purpose without legal friction). - -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - -**************************** -stl -**************************** -SGI STL - -The STL portion of GNU libstdc++ that is used with gcc3 and gcc4 is licensed -under the GPL, with the following exception: - -# As a special exception, you may use this file as part of a free software -# library without restriction. Specifically, if other files instantiate -# templates or use macros or inline functions from this file, or you compile -# this file and link it with other files to produce an executable, this -# file does not by itself cause the resulting executable to be covered by -# the GNU General Public License. This exception does not however -# invalidate any other reasons why the executable file might be covered by -# the GNU General Public License. - - - -**************************** -tinyxml -**************************** -TinyXml is released under the zlib license: - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - - - -**************************** -tz -**************************** -With a few exceptions, all files in the tz code and data (including -this one) are in the public domain. The exceptions are tzcode's -date.c, newstrftime.3, and strftime.c, which contain material derived -from BSD and which use the BSD 3-clause license. - - -**************************** -utf -**************************** -UTF-8 Library - -The authors of this software are Rob Pike and Ken Thompson. - Copyright (c) 1998-2002 by Lucent Technologies. -Permission to use, copy, modify, and distribute this software for any -purpose without fee is hereby granted, provided that this entire notice -is included in all copies of any software which is or includes a copy -or modification of this software and in all copies of the supporting -documentation for such software. -THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED -WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY -REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY -OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - - -**************************** -xmpmeta -**************************** -xmpmeta. A fast XMP metadata parsing and writing library. -Copyright 2016 Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -* Neither the name of Google Inc. nor the names of its contributors may be - used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -**************************** -Xorg -**************************** -The following is the 'standard copyright' agreed upon by most contributors, -and is currently the canonical license preferred by the X.Org Foundation. -This is a slight variant of the common MIT license form published by the -Open Source Initiative at http://www.opensource.org/licenses/mit-license.php - -Copyright holders of new code should use this license statement where -possible, and insert their name to this list. Please sort by surname -for people, and by the full name for other entities (e.g. Juliusz -Chroboczek sorts before Intel Corporation sorts before Daniel Stone). - -See each individual source file or directory for the license that applies -to that file. - -Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett -Copyright © 2009 Red Hat, Inc. -Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates. -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ---------------------------------------------------------------------- - -The following licenses are 'legacy' - usually MIT/X11 licenses with the name -of the copyright holder(s) in the license statement: - -Copyright 1984-1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -X Window System is a trademark of The Open Group. - - ---------------------------------------- - -Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 X Consortium -Copyright 2000 The XFree86 Project, Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the X Consortium. - -Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by -Digital Equipment Corporation - -Portions Copyright 1990, 1991 by Tektronix, Inc. - -Permission to use, copy, modify and distribute this documentation for -any purpose and without fee is hereby granted, provided that the above -copyright notice appears in all copies and that both that copyright notice -and this permission notice appear in all copies, and that the names of -Digital and Tektronix not be used in in advertising or publicity pertaining -to this documentation without specific, written prior permission. -Digital and Tektronix makes no representations about the suitability -of this documentation for any purpose. -It is provided ``as is'' without express or implied warranty. - - ---------------------------------------- - -Copyright (c) 1999-2000 Free Software Foundation, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -FREE SOFTWARE FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the Free Software Foundation -shall not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization from the -Free Software Foundation. - - ---------------------------------------- - -Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - All Rights Reserved - -This file is a component of an X Window System-specific implementation -of Xcms based on the TekColor Color Management System. TekColor is a -trademark of Tektronix, Inc. The term "TekHVC" designates a particular -color space that is the subject of U.S. Patent No. 4,985,853 (equivalent -foreign patents pending). Permission is hereby granted to use, copy, -modify, sell, and otherwise distribute this software and its -documentation for any purpose and without fee, provided that: - -1. This copyright, permission, and disclaimer notice is reproduced in - all copies of this software and any modification thereof and in - supporting documentation; -2. Any color-handling application which displays TekHVC color - cooordinates identifies these as TekHVC color coordinates in any - interface that displays these coordinates and in any associated - documentation; -3. The term "TekHVC" is always used, and is only used, in association - with the mathematical derivations of the TekHVC Color Space, - including those provided in this file and any equivalent pathways and - mathematical derivations, regardless of digital (e.g., floating point - or integer) representation. - -Tektronix makes no representation about the suitability of this software -for any purpose. It is provided "as is" and with all faults. - -TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, -INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY -SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF -CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -(c) Copyright 1995 FUJITSU LIMITED -This is source code modified by FUJITSU LIMITED under the Joint -Development Agreement for the CDE/Motif PST. - - ---------------------------------------- - -Copyright 1992 by Oki Technosystems Laboratory, Inc. -Copyright 1992 by Fuji Xerox Co., Ltd. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Oki Technosystems -Laboratory and Fuji Xerox not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. -Oki Technosystems Laboratory and Fuji Xerox make no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS -LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1990, 1991, 1992, 1993, 1994 by FUJITSU LIMITED - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of FUJITSU LIMITED -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -FUJITSU LIMITED makes no representations about the suitability of -this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - - -Copyright (c) 1995 David E. Wexelblat. All rights reserved - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL DAVID E. WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of David E. Wexelblat shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from David E. Wexelblat. - - ---------------------------------------- - -Copyright 1990, 1991 by OMRON Corporation - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name OMRON not be used in -advertising or publicity pertaining to distribution of the software without -specific, written prior permission. OMRON makes no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by -Digital Equipment Corporation - -Portions Copyright 1990, 1991 by Tektronix, Inc - -Rewritten for X.org by Chris Lee <clee@freedesktop.org> - -Permission to use, copy, modify, distribute, and sell this documentation -for any purpose and without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. -Chris Lee makes no representations about the suitability for any purpose -of the information in this document. It is provided \`\`as-is'' without -express or implied warranty. - - ---------------------------------------- - -Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts, -Copyright 1994 by FUJITSU LIMITED -Copyright 1994 by Sony Corporation - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital, FUJITSU -LIMITED and Sony Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. - -DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED -AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - - -Copyright 1991 by the Open Software Foundation - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of Open Software Foundation -not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. Open Software -Foundation makes no representations about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - -OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN BE -LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1990, 1991, 1992,1993, 1994 by FUJITSU LIMITED -Copyright 1993, 1994 by Sony Corporation - -Permission to use, copy, modify, distribute, and sell this software and -its documentation for any purpose is hereby granted without fee, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of FUJITSU LIMITED and Sony Corporation -not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. FUJITSU LIMITED and -Sony Corporation makes no representations about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - -FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD -TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL FUJITSU LIMITED OR SONY CORPORATION BE LIABLE -FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright (c) 1993, 1995 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1991, 1992, 1993, 1994 by FUJITSU LIMITED -Copyright 1993 by Digital Equipment Corporation - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of FUJITSU LIMITED and -Digital Equipment Corporation not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. FUJITSU LIMITED and Digital Equipment Corporation -makes no representations about the suitability of this software for -any purpose. It is provided "as is" without express or implied -warranty. - -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1992, 1993 by FUJITSU LIMITED -Copyright 1993 by Fujitsu Open Systems Solutions, Inc. -Copyright 1994 by Sony Corporation - -Permission to use, copy, modify, distribute and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of FUJITSU LIMITED, -Fujitsu Open Systems Solutions, Inc. and Sony Corporation not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. -FUJITSU LIMITED, Fujitsu Open Systems Solutions, Inc. and -Sony Corporation make no representations about the suitability of -this software for any purpose. It is provided "as is" without -express or implied warranty. - -FUJITSU LIMITED, FUJITSU OPEN SYSTEMS SOLUTIONS, INC. AND SONY -CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, -IN NO EVENT SHALL FUJITSU OPEN SYSTEMS SOLUTIONS, INC., FUJITSU LIMITED -AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1987, 1988, 1990, 1993 by Digital Equipment Corporation, -Maynard, Massachusetts, - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - - ---------------------------------------- - -Copyright 1993 by SunSoft, Inc. -Copyright 1999-2000 by Bruno Haible - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the names of SunSoft, Inc. and -Bruno Haible not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. SunSoft, Inc. and Bruno Haible make no representations -about the suitability of this software for any purpose. It is -provided "as is" without express or implied warranty. - -SunSoft Inc. AND Bruno Haible DISCLAIM ALL WARRANTIES WITH REGARD -TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS, IN NO EVENT SHALL SunSoft, Inc. OR Bruno Haible BE LIABLE -FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1991 by the Open Software Foundation -Copyright 1993 by the TOSHIBA Corp. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of Open Software Foundation and TOSHIBA -not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. Open Software -Foundation and TOSHIBA make no representations about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - -OPEN SOFTWARE FOUNDATION AND TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN OR TOSHIBA BE -LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1988 by Wyse Technology, Inc., San Jose, Ca., - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name Wyse not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -WYSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - - ---------------------------------------- - - -Copyright 1991 by the Open Software Foundation -Copyright 1993, 1994 by the Sony Corporation - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of Open Software Foundation and -Sony Corporation not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior permission. -Open Software Foundation and Sony Corporation make no -representations about the suitability of this software for any purpose. -It is provided "as is" without express or implied warranty. - -OPEN SOFTWARE FOUNDATION AND SONY CORPORATION DISCLAIM ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OPEN -SOFTWARE FOUNDATIONN OR SONY CORPORATION BE LIABLE FOR ANY SPECIAL, -INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1992, 1993 by FUJITSU LIMITED -Copyright 1993 by Fujitsu Open Systems Solutions, Inc. - -Permission to use, copy, modify, distribute and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of FUJITSU LIMITED and -Fujitsu Open Systems Solutions, Inc. not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. -FUJITSU LIMITED and Fujitsu Open Systems Solutions, Inc. makes no -representations about the suitability of this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJITSU LIMITED AND FUJITSU OPEN SYSTEMS SOLUTIONS, INC. DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU OPEN SYSTEMS -SOLUTIONS, INC. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT -OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1993, 1994 by Sony Corporation - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Sony Corporation -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. -Sony Corporation makes no representations about the suitability of -this software for any purpose. It is provided "as is" without -express or implied warranty. - -SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1986, 1998 The Open Group -Copyright (c) 2000 The XFree86 Project, Inc. - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -Except as contained in this notice, the name of the X Consortium or of the -XFree86 Project shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization from the X Consortium and the XFree86 Project. - - ---------------------------------------- - -Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, - and Nippon Telegraph and Telephone Corporation -Copyright 1991 by the Open Software Foundation -Copyright 1993 by the FUJITSU LIMITED - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of OMRON, NTT Software, NTT, and -Open Software Foundation not be used in advertising or publicity -pertaining to distribution of the software without specific, -written prior permission. OMRON, NTT Software, NTT, and Open Software -Foundation make no representations about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - -OMRON, NTT SOFTWARE, NTT, AND OPEN SOFTWARE FOUNDATION -DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT -SHALL OMRON, NTT SOFTWARE, NTT, OR OPEN SOFTWARE FOUNDATION BE -LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 1988 by Wyse Technology, Inc., San Jose, Ca, -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - - -Copyright 1991, 1992 by Fuji Xerox Co., Ltd. -Copyright 1992, 1993, 1994 by FUJITSU LIMITED - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Fuji Xerox, -FUJITSU LIMITED not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. Fuji Xerox, FUJITSU LIMITED make no representations -about the suitability of this software for any purpose. -It is provided "as is" without express or implied warranty. - -FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX, -FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA -OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 2006 Josh Triplett - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - - ---------------------------------------- - -(c) Copyright 1996 by Sebastien Marineau and Holger Veit - <marineau@genie.uottawa.ca> - <Holger.Veit@gmd.de> - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF -OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -Except as contained in this notice, the name of Sebastien Marineau or Holger Veit -shall not be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization from Holger Veit or -Sebastien Marineau. - - ---------------------------------------- - -Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, - and Nippon Telegraph and Telephone Corporation -Copyright 1991 by the Open Software Foundation -Copyright 1993 by the TOSHIBA Corp. -Copyright 1993, 1994 by Sony Corporation -Copyright 1993, 1994 by the FUJITSU LIMITED - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of OMRON, NTT Software, NTT, Open -Software Foundation, and Sony Corporation not be used in advertising -or publicity pertaining to distribution of the software without specific, -written prior permission. OMRON, NTT Software, NTT, Open Software -Foundation, and Sony Corporation make no representations about the -suitability of this software for any purpose. It is provided "as is" -without express or implied warranty. - -OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, AND SONY -CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT -SHALL OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, OR SONY -CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright 2000 by Bruno Haible - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Bruno Haible not -be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. Bruno Haible -makes no representations about the suitability of this software for -any purpose. It is provided "as is" without express or implied -warranty. - -Bruno Haible DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -NO EVENT SHALL Bruno Haible BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright © 2003 Keith Packard - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of Keith Packard not be used in -advertising or publicity pertaining to distribution of the software without -specific, written prior permission. Keith Packard makes no -representations about the suitability of this software for any purpose. It -is provided "as is" without express or implied warranty. - -KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - ---------------------------------------- - -Copyright (c) 2007-2009, Troy D. Hanson -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------- - -Copyright 1992, 1993 by TOSHIBA Corp. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of TOSHIBA not be used in advertising -or publicity pertaining to distribution of the software without specific, -written prior permission. TOSHIBA make no representations about the -suitability of this software for any purpose. It is provided "as is" -without express or implied warranty. - -TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - - - ---------------------------------------- - -Copyright IBM Corporation 1993 - -All Rights Reserved - -License to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of IBM not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND -NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL -IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - - ---------------------------------------- - -Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, - and Nippon Telegraph and Telephone Corporation - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the names of OMRON, NTT Software, and NTT -not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. OMRON, NTT Software, -and NTT make no representations about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - -OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD -TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, BE -LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - -**************************** -zlib -**************************** -(extracted from README, except for match.S) - -Copyright notice: - - (C) 1995-2013 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. - -(extracted from match.S, for match.S only) - -Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com> - -This software is provided 'as-is', without any express or implied -warranty. In no event will the author be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. - - -**************************** -googleurl -**************************** -Copyright 2007, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -------------------------------------------------------------------------------- - -The file url_parse.cc is based on nsURLParsers.cc from Mozilla. This file is -licensed separately as follows: - -The contents of this file are subject to the Mozilla Public License Version -1.1 (the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at -http://www.mozilla.org/MPL/ - -Software distributed under the License is distributed on an "AS IS" basis, -WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -for the specific language governing rights and limitations under the -License. - -The Original Code is mozilla.org code. - -The Initial Developer of the Original Code is -Netscape Communications Corporation. -Portions created by the Initial Developer are Copyright (C) 1998 -the Initial Developer. All Rights Reserved. - -Contributor(s): - Darin Fisher (original author) - -Alternatively, the contents of this file may be used under the terms of -either the GNU General Public License Version 2 or later (the "GPL"), or -the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -in which case the provisions of the GPL or the LGPL are applicable instead -of those above. If you wish to allow use of your version of this file only -under the terms of either the GPL or the LGPL, and not to allow others to -use your version of this file under the terms of the MPL, indicate your -decision by deleting the provisions above and replace them with the notice -and other provisions required by the GPL or the LGPL. If you do not delete -the provisions above, a recipient may use your version of this file under -the terms of any one of the MPL, the GPL or the LGPL. - -------------------------------------------------------------------------------- - -The file icu_utf.cc is from IBM. This file is licensed separately as follows: - -ICU License - ICU 1.8.1 and later - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1995-2009 International Business Machines Corporation and others - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, and/or sell copies of the Software, and to permit persons -to whom the Software is furnished to do so, provided that the above -copyright notice(s) and this permission notice appear in all copies of -the Software and that both the above copyright notice(s) and this -permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY -SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, use -or other dealings in this Software without prior written authorization -of the copyright holder. - - -**************************** - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -**************************** -jsoncpp -**************************** -The JsonCpp library's source code, including accompanying documentation, -tests and demonstration applications, are licensed under the following -conditions... - -The author (Baptiste Lepilleur) explicitly disclaims copyright in all -jurisdictions which recognize such a disclaimer. In such jurisdictions, -this software is released into the Public Domain. - -In jurisdictions which do not recognize Public Domain property (e.g. Germany as of -2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is -released under the terms of the MIT License (see below). - -In jurisdictions which recognize Public Domain property, the user of this -software may choose to accept it either as 1) Public Domain, 2) under the -conditions of the MIT License (see below), or 3) under the terms of dual -Public Domain/MIT License conditions described here, as they choose. - -The MIT License is about as close to Public Domain as a license can get, and is -described in clear, concise terms at: - - http://en.wikipedia.org/wiki/MIT_License - -The full text of the MIT License follows: - -======================================================================== -Copyright (c) 2007-2010 Baptiste Lepilleur - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -======================================================================== -(END LICENSE TEXT) - -The MIT license is compatible with both the GPL and commercial -software, affording one all of the rights of Public Domain with the -minor nuisance of being required to keep the above copyright notice -and license text in the source code. Note also that by accepting the -Public Domain "license" you can re-license your copy using whatever -license you like. - - -**************************** -libwebp -**************************** -Copyright (c) 2010, Google Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * Neither the name of Google nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/gvr-android-sdk/OWNERS b/third_party/gvr-android-sdk/OWNERS deleted file mode 100644 index e9a59ed0..0000000 --- a/third_party/gvr-android-sdk/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -file://components/webxr/OWNERS -mthiesse@chromium.org -vollick@chromium.org - -per-file *.sha1=file://build/OWNERS
diff --git a/third_party/gvr-android-sdk/README.chromium b/third_party/gvr-android-sdk/README.chromium deleted file mode 100644 index 331f14c2..0000000 --- a/third_party/gvr-android-sdk/README.chromium +++ /dev/null
@@ -1,46 +0,0 @@ -Name: GVR Android SDK -Short Name: gvr -URL: https://github.com/googlevr/gvr-android-sdk -Version: 1.130.0 -Date: 1 March 2018 -Revision: 233e7fe922a543e0bc55382d64cacd047307d0e7 -License: Apache 2.0 -License File: LICENSE -Security Critical: yes -Shipped: yes - -Description: -The GVR Android SDK supports both Daydream and Cardboard, including a simple API -used for creating apps inserted into Cardboard viewers, and the more complex API -for supporting Daydream-ready phones and the Daydream controller. - -Local Modifications: -- Due to binary size concern, we have decided to use a static shim library -instead of the shared library that comes with this checkout. The static -libraries are downloaded from a public storage through gclient sync. - -- For Version 1.10.0, we have two date: 6 Dec 2016 and 10 Feb 2017. The latter -version cherrypick a CL that fix a crash on K and L. - -- All JNI calls in the static library also needs to be manually registered. So -we have 3 jni related files. These files were generated by -base/android/jni_generator/jni_generator.py from Java files. Modifications to -these generated files are documented in the files. - - - The files generated by jni_generator.py use base::size which is not available - from third_party; std::extent<decltype> was used instead, which is standard C++ - and available. - -- In order to run automated end-to-end tests on VR features, VR Services -(com.google.vr.vrcore) and in some cases Daydream Home -(com.google.android.vr.home) need to be installed before running tests. These -are downloaded into test-apks/vr_services and test-apks/daydream_home, -respectively. The downloaded APKs are the release APKs that are or were -publicly available via the Play Store. - -- In order to run automated end-to-end tests that involve a Daydream controller, -controller_test_api.aar needs to be present. This allows us to send controller -events using broadcasts like a real controller sends them over Bluetooth. The -library is open-sourced similar to the other .aars, but since it's only useful -for Chromium at the moment, it is uploaded to storage instead of to GitHub like -the GVR SDK.
diff --git a/third_party/gvr-android-sdk/controller_test_api_java.info b/third_party/gvr-android-sdk/controller_test_api_java.info deleted file mode 100644 index 02a8986..0000000 --- a/third_party/gvr-android-sdk/controller_test_api_java.info +++ /dev/null
@@ -1,14 +0,0 @@ -# Generated by //build/android/gyp/aar.py -# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". - -aidl = [] -assets = [] -has_classes_jar = true -has_native_libraries = false -has_proguard_flags = false -has_r_text_file = false -is_manifest_empty = true -manifest_package = "com.google.vr.testframework.controller" -resources = [] -subjar_tuples = [] -subjars = []
diff --git a/third_party/gvr-android-sdk/display_synchronizer_jni.h b/third_party/gvr-android-sdk/display_synchronizer_jni.h deleted file mode 100644 index 0a76439..0000000 --- a/third_party/gvr-android-sdk/display_synchronizer_jni.h +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is of the same format as file that generated by -// third_party/jni_zero/jni_zero.py -// For -// com/google/vr/cardboard/DisplaySynchronizer - -// Local modification includes: -// 1. Remove all implementation, only keep definition. -// 2. Use absolute path instead of relative path. -// 3. Removed all helper functions such as: Create. -// 4. Added function RegisterDisplaySynchronizerNatives at the end of this file. -// 5. Added "vr" as an argument to base::android::LazyGetClass. - -#ifndef com_google_vr_cardboard_DisplaySynchronizer_JNI -#define com_google_vr_cardboard_DisplaySynchronizer_JNI - -#include "base/android/jni_android.h" -// ---------------------------------------------------------------------------- -// Native JNI methods -// ---------------------------------------------------------------------------- -#include <jni.h> -#include <atomic> -#include <type_traits> - -#include "third_party/jni_zero/jni_int_wrapper.h" -#include "third_party/jni_zero/jni_zero_helper.h" - -// Step 1: forward declarations. -namespace { - -const char kDisplaySynchronizerClassPath[] = - "com/google/vr/cardboard/DisplaySynchronizer"; -// Leaking this jclass as we cannot use LazyInstance from some threads. -std::atomic<jclass> g_DisplaySynchronizer_clazz __attribute__((unused)) - (nullptr); -#define DisplaySynchronizer_clazz(env) \ - base::android::LazyGetClass(env, kDisplaySynchronizerClassPath, "vr", \ - &g_DisplaySynchronizer_clazz) - -} // namespace - -namespace DisplaySynchronizer { - -extern "C" __attribute__((visibility("default"))) jlong -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate( - JNIEnv* env, - jobject jcaller, - jclass classLoader, - jobject appContext); - -// Step 2: method stubs. -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer); - -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer, - jlong expectedInterval, - jlong vsyncOffset); - -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate( - JNIEnv* env, - jobject jcaller, - jlong nativeDisplaySynchronizer, - jlong syncTime, - jint currentRotation); - -extern "C" __attribute__((visibility("default"))) void -Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged( - JNIEnv* env, - jobject obj, - jlong native_object); - -// Step 3: RegisterNatives. - -static const JNINativeMethod kMethodsDisplaySynchronizer[] = { - {"nativeCreate", - "(" - "Ljava/lang/ClassLoader;" - "Landroid/content/Context;" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeCreate)}, - {"nativeDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeDestroy)}, - {"nativeReset", - "(" - "J" - "J" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeReset)}, - {"nativeUpdate", - "(" - "J" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate)}, - {"nativeOnMetricsChanged", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged)}, -}; - -static bool RegisterNativesImpl(JNIEnv* env) { - const int kMethodsDisplaySynchronizerSize = - std::extent<decltype(kMethodsDisplaySynchronizer)>(); - - if (env->RegisterNatives(DisplaySynchronizer_clazz(env), - kMethodsDisplaySynchronizer, - kMethodsDisplaySynchronizerSize) < 0) { - jni_generator::HandleRegistrationError(env, DisplaySynchronizer_clazz(env), - __FILE__); - return false; - } - - return true; -} - -static bool RegisterDisplaySynchronizerNatives(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace DisplaySynchronizer - -#endif // com_google_vr_cardboard_DisplaySynchronizer_JNI
diff --git a/third_party/gvr-android-sdk/gvr_api_jni.h b/third_party/gvr-android-sdk/gvr_api_jni.h deleted file mode 100644 index b4cde5ed..0000000 --- a/third_party/gvr-android-sdk/gvr_api_jni.h +++ /dev/null
@@ -1,1745 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is of the same format as file that generated by -// base/android/jni_generator/jni_generator.py -// For -// com/google/vr/ndk/base/GvrApi - -// Local modification includes: -// 1. Remove all implementation, only keep definition. -// 2. Use absolute path instead of relative path. -// 3. Removed all helper functions such as: Create. -// 4. Removed external functions that don't have implementation in shim file. -// 5. Changed RectF, Point, and PoseTracker to correct package name. -// 6. Added function RegisterGvrApiNatives at the end of this file. -// 7. Added "vr" as an argument to base::android::LazyGetClass. - -#ifndef com_google_vr_ndk_base_GvrApi_JNI -#define com_google_vr_ndk_base_GvrApi_JNI - -#include "base/android/jni_android.h" -// ---------------------------------------------------------------------------- -// Native JNI methods -// ---------------------------------------------------------------------------- -#include <jni.h> -#include <atomic> -#include <type_traits> - -#include "third_party/jni_zero/jni_int_wrapper.h" -#include "third_party/jni_zero/jni_zero_helper.h" - -// Step 1: forward declarations. -namespace { -const char kGvrApiClassPath[] = "com/google/vr/ndk/base/GvrApi"; -// Leaking this jclass as we cannot use LazyInstance from some threads. -std::atomic<jclass> g_GvrApi_clazz __attribute__((unused)) (nullptr); -#define GvrApi_clazz(env) \ - base::android::LazyGetClass(env, kGvrApiClassPath, "vr", &g_GvrApi_clazz) - -} // namespace - -namespace GvrApi { -// Step 2: method stubs. - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListCreate( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListDestroy( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewportList); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetSize( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewportList); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetItem( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewportList, - jint index, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListSetItem( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewportList, - jint index, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportCreate( - JNIEnv* env, - jclass jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportDestroy( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceUv( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jobject out); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceUv( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jfloat left, - jfloat top, - jfloat right, - jfloat bottom); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceFov( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jobject out); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceFov( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jfloat left, - jfloat top, - jfloat right, - jfloat bottom); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTransform( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jfloatArray matrix); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTransform( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jfloatArray matrix); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportEqual(JNIEnv* env, - jclass jcaller, - jlong nativeA, - jlong nativeB); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTargetEye( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTargetEye( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jint eye); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceBufferIndex( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceBufferIndex( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jint index); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetExternalSurfaceId( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurfaceId( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jint id); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurface( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jlong nativeExternalSurface); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetReprojection( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetReprojection( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jint reprojection); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceLayer( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferViewport, - jint layerIndex); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecCreate( - JNIEnv* env, - jclass jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecDestroy( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSize( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jobject size); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSize( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jint width, - jint height); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetColorFormat( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jint format); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetDepthStencilFormat( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jint format); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetMultiviewLayers( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jint numLayers); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSamples( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSamples( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec, - jint samples); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceCreateWithListeners( - JNIEnv* env, - jclass jcaller, - jlong nativeGvrContext, - jobject surfaceListener, - jobject frameListener, - jobject handler); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceDestroy( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetId( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec); - -JNI_BOUNDARY_EXPORT jobject -Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetSurface( - JNIEnv* env, - jclass jcaller, - jlong nativeBufferSpec); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainCreate(JNIEnv* env, - jclass jcaller, - jlong nativeContext, - jlongArray specs); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainDestroy(JNIEnv* env, - jclass jcaller, - jlong nativeContext); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferCount( - JNIEnv* env, - jclass jcaller, - jlong nativeSwapChain); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferSize( - JNIEnv* env, - jclass jcaller, - jlong nativeSwapChain, - jint bufferIndex, - jobject size); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainResizeBuffer( - JNIEnv* env, - jclass jcaller, - jlong nativeSwapChain, - jint bufferIndex, - jint width, - jint height); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainAcquireFrame( - JNIEnv* env, - jclass jcaller, - jlong nativeSwapChain); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeFrameBindBuffer(JNIEnv* env, - jclass jcaller, - jlong nativeFrame, - jint bufferIndex); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeFrameUnbind( - JNIEnv* env, - jclass jcaller, - jlong nativeFrame); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetFramebufferObject( - JNIEnv* env, - jclass jcaller, - jlong nativeFrame, - jint bufferIndex); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetBufferSize(JNIEnv* env, - jclass jcaller, - jlong nativeFrame, - jint bufferIndex, - jobject size); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeFrameSubmit( - JNIEnv* env, - jclass jcaller, - jlong nativeFrame, - jlong nativeBufferViewportList, - jfloatArray headSpaceFromStartSpace); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeUsingDynamicLibrary(JNIEnv* env, - jclass jcaller); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeUsingShimLibrary(JNIEnv* env, - jclass jcaller); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetApplicationState(JNIEnv* env, - jclass jcaller, - jclass classLoader, - jobject context); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetDynamicLibraryLoadingEnabled( - JNIEnv* env, - jclass jcaller, - jboolean enabled); - -JNI_BOUNDARY_EXPORT jlong Java_com_google_vr_ndk_base_GvrApi_nativeCreate( - JNIEnv* env, - jobject jcaller, - jclass classLoader, - jobject context, - jlong synchronizer, - jint widthPixels, - jint heightPixels, - jfloat xDpi, - jfloat yDpi, - jobject optionalPoseTrackingForTesting); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeRequestContextSharing( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jobject eglListener); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeGetError(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeClearError(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jstring -Java_com_google_vr_ndk_base_GvrApi_nativeGetErrorString(JNIEnv* env, - jclass jcaller, - jint errorCode); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeGetUserPrefs(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeUserPrefsGetControllerHandedness( - JNIEnv* env, - jclass jcaller, - jlong nativeUserPrefs); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativePause( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeResume( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeReleaseGvrContext( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeInitializeGl( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceCreatedReprojectionThread( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceChangedReprojectionThread( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetRecommendedBufferViewports( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jlong nativeBufferViewportList); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenBufferViewports( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jlong nativeBufferViewportList); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetMaximumEffectiveRenderTargetSize( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jobject size); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenTargetSize( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jobject size); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeDistortToScreen( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint textureId, - jlong nativeBufferViewportList, - jfloatArray headSpaceFromStartSpace, - jlong timeNs); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultFramebufferActive( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jobject -Java_com_google_vr_ndk_base_GvrApi_nativeRenderReprojectionThread( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeOnPauseReprojectionThread( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceRotation( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jfloatArray outRotation, - jlong timeNs); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceTransform( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jfloatArray outTransform, - jlong timeNs); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetIgnoreManualPauseResumeTracker( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jboolean shouldIgnore); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativePauseTracking( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jbyteArray -Java_com_google_vr_ndk_base_GvrApi_nativePauseTrackingGetState( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeResumeTracking(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeResumeTrackingSetState( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jbyteArray trackerStateBytes); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeResetTracking( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeRecenterTracking( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetEyeFromHeadMatrix( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint eye, - jfloatArray out); - -JNI_BOUNDARY_EXPORT jintArray -Java_com_google_vr_ndk_base_GvrApi_nativeGetWindowBounds( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jfloatArray -Java_com_google_vr_ndk_base_GvrApi_nativeComputeDistortedPoint( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint eyeType, - jfloatArray uvIn); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultViewerProfile( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jstring viewerProfileUri); - -JNI_BOUNDARY_EXPORT jstring -Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerVendor( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jstring -Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerModel(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerType(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeSetAsyncReprojectionEnabled( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jboolean enabled); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeGetAsyncReprojectionEnabled( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeIsFeatureSupported( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint feature); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeReconnectSensors( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetIdleListener(JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jobject idleListener); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeSetViewerParams( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jbyteArray serializedViewerParams); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetDisplayMetrics( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint widthPixels, - jint heightPixels, - jfloat xDpi, - jfloat yDpi); - -JNI_BOUNDARY_EXPORT jfloat -Java_com_google_vr_ndk_base_GvrApi_nativeGetBorderSizeMeters( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeSetSurfaceSize( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jint surfaceWidthPixels, - jint surfaceHeightPixels); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeSetLensOffset( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext, - jfloat x, - jfloat y, - jfloat rotation); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDumpDebugData( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeUsingVrDisplayService( - JNIEnv* env, - jobject jcaller, - jlong nativeGvrContext); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeCreateEvent(JNIEnv* env, jclass clazz); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeCreateValue(JNIEnv* env, jclass clazz); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDestroyEvent( - JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeDestroyValue( - JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeGetCurrentProperties( - JNIEnv* env, - jobject object, - jlong native_object); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeGetEventFlags(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeGetEventTimestamp(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeGetEventType(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativeGetProperty(JNIEnv* env, - jclass clazz, - jlong native_properties, - jint property_key, - jlong native_value); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventFlags( - JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform( - JNIEnv* env, - jclass clazz, - jlong native_object, - jfloatArray rotation_out_array); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventType( - JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jboolean -Java_com_google_vr_ndk_base_GvrApi_nativePollEvent(JNIEnv* env, - jobject object, - jlong native_object, - jlong event_out); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFlags(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jfloat -Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFloat(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT jint -Java_com_google_vr_ndk_base_GvrApi_nativeValueAsInt(JNIEnv* env, - jclass clazz, - jlong native_object); - -JNI_BOUNDARY_EXPORT void Java_com_google_vr_ndk_base_GvrApi_nativeValueAsMat4f( - JNIEnv* env, - jclass clazz, - jlong native_object, - jfloatArray mat4_out_array); - -JNI_BOUNDARY_EXPORT jlong -Java_com_google_vr_ndk_base_GvrApi_nativeValueGetFlags(JNIEnv* env, - jclass clazz, - jlong native_object); - -// Step 3: RegisterNatives. - -static const JNINativeMethod kMethodsGvrApi[] = { - {"nativeBufferViewportListCreate", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListCreate)}, - {"nativeBufferViewportListDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListDestroy)}, - {"nativeBufferViewportListGetSize", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetSize)}, - {"nativeBufferViewportListGetItem", - "(" - "J" - "I" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListGetItem)}, - {"nativeBufferViewportListSetItem", - "(" - "J" - "I" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportListSetItem)}, - {"nativeBufferViewportCreate", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportCreate)}, - {"nativeBufferViewportDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportDestroy)}, - {"nativeBufferViewportGetSourceUv", - "(" - "J" - "Landroid/graphics/RectF;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceUv)}, - {"nativeBufferViewportSetSourceUv", - "(" - "J" - "F" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceUv)}, - {"nativeBufferViewportGetSourceFov", - "(" - "J" - "Landroid/graphics/RectF;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceFov)}, - {"nativeBufferViewportSetSourceFov", - "(" - "J" - "F" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceFov)}, - {"nativeBufferViewportGetTransform", - "(" - "J" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTransform)}, - {"nativeBufferViewportSetTransform", - "(" - "J" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTransform)}, - {"nativeBufferViewportEqual", - "(" - "J" - "J" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportEqual)}, - {"nativeBufferViewportGetTargetEye", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetTargetEye)}, - {"nativeBufferViewportSetTargetEye", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetTargetEye)}, - {"nativeBufferViewportGetSourceBufferIndex", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetSourceBufferIndex)}, - {"nativeBufferViewportSetSourceBufferIndex", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceBufferIndex)}, - {"nativeBufferViewportGetExternalSurfaceId", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetExternalSurfaceId)}, - {"nativeBufferViewportSetExternalSurfaceId", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurfaceId)}, - {"nativeBufferViewportSetExternalSurface", - "(" - "J" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetExternalSurface)}, - {"nativeBufferViewportGetReprojection", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportGetReprojection)}, - {"nativeBufferViewportSetReprojection", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetReprojection)}, - {"nativeBufferViewportSetSourceLayer", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferViewportSetSourceLayer)}, - {"nativeBufferSpecCreate", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecCreate)}, - {"nativeBufferSpecDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecDestroy)}, - {"nativeBufferSpecGetSize", - "(" - "J" - "Landroid/graphics/Point;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSize)}, - {"nativeBufferSpecSetSize", - "(" - "J" - "I" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSize)}, - {"nativeBufferSpecSetColorFormat", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetColorFormat)}, - {"nativeBufferSpecSetDepthStencilFormat", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetDepthStencilFormat)}, - {"nativeBufferSpecSetMultiviewLayers", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetMultiviewLayers)}, - {"nativeBufferSpecGetSamples", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecGetSamples)}, - {"nativeBufferSpecSetSamples", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeBufferSpecSetSamples)}, - {"nativeExternalSurfaceCreateWithListeners", - "(" - "J" - "Ljava/lang/Runnable;" - "Ljava/lang/Runnable;" - "Landroid/os/Handler;" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceCreateWithListeners)}, - {"nativeExternalSurfaceDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceDestroy)}, - {"nativeExternalSurfaceGetId", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetId)}, - {"nativeExternalSurfaceGetSurface", - "(" - "J" - ")" - "Landroid/view/Surface;", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeExternalSurfaceGetSurface)}, - {"nativeSwapChainCreate", - "(" - "J" - "[J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainCreate)}, - {"nativeSwapChainDestroy", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainDestroy)}, - {"nativeSwapChainGetBufferCount", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferCount)}, - {"nativeSwapChainGetBufferSize", - "(" - "J" - "I" - "Landroid/graphics/Point;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainGetBufferSize)}, - {"nativeSwapChainResizeBuffer", - "(" - "J" - "I" - "I" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainResizeBuffer)}, - {"nativeSwapChainAcquireFrame", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSwapChainAcquireFrame)}, - {"nativeFrameBindBuffer", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeFrameBindBuffer)}, - {"nativeFrameUnbind", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeFrameUnbind)}, - {"nativeFrameGetFramebufferObject", - "(" - "J" - "I" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetFramebufferObject)}, - {"nativeFrameGetBufferSize", - "(" - "J" - "I" - "Landroid/graphics/Point;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeFrameGetBufferSize)}, - {"nativeFrameSubmit", - "(" - "J" - "J" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeFrameSubmit)}, - {"nativeUsingDynamicLibrary", - "(" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeUsingDynamicLibrary)}, - {"nativeUsingShimLibrary", - "(" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeUsingShimLibrary)}, - {"nativeSetApplicationState", - "(" - "Ljava/lang/ClassLoader;" - "Landroid/content/Context;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetApplicationState)}, - {"nativeSetDynamicLibraryLoadingEnabled", - "(" - "Z" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetDynamicLibraryLoadingEnabled)}, - {"nativeCreate", - "(" - "Ljava/lang/ClassLoader;" - "Landroid/content/Context;" - "J" - "I" - "I" - "F" - "F" - "Lcom/google/vr/ndk/base/GvrApi$PoseTracker;" - ")" - "J", - reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativeCreate)}, - {"nativeRequestContextSharing", - "(" - "J" - "Lcom/google/vr/cardboard/EglReadyListener;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeRequestContextSharing)}, - {"nativeGetError", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetError)}, - {"nativeClearError", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeClearError)}, - {"nativeGetErrorString", - "(" - "I" - ")" - "Ljava/lang/String;", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetErrorString)}, - {"nativeGetUserPrefs", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetUserPrefs)}, - {"nativeUserPrefsGetControllerHandedness", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeUserPrefsGetControllerHandedness)}, - {"nativePause", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativePause)}, - {"nativeResume", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>(Java_com_google_vr_ndk_base_GvrApi_nativeResume)}, - {"nativeReleaseGvrContext", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeReleaseGvrContext)}, - {"nativeInitializeGl", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeInitializeGl)}, - {"nativeOnSurfaceCreatedReprojectionThread", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceCreatedReprojectionThread)}, - {"nativeOnSurfaceChangedReprojectionThread", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeOnSurfaceChangedReprojectionThread)}, - {"nativeGetRecommendedBufferViewports", - "(" - "J" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetRecommendedBufferViewports)}, - {"nativeGetScreenBufferViewports", - "(" - "J" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenBufferViewports)}, - {"nativeGetMaximumEffectiveRenderTargetSize", - "(" - "J" - "Landroid/graphics/Point;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetMaximumEffectiveRenderTargetSize)}, - {"nativeGetScreenTargetSize", - "(" - "J" - "Landroid/graphics/Point;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetScreenTargetSize)}, - {"nativeDistortToScreen", - "(" - "J" - "I" - "J" - "[F" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeDistortToScreen)}, - {"nativeSetDefaultFramebufferActive", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultFramebufferActive)}, - {"nativeRenderReprojectionThread", - "(" - "J" - ")" - "Landroid/graphics/Point;", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeRenderReprojectionThread)}, - {"nativeOnPauseReprojectionThread", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeOnPauseReprojectionThread)}, - {"nativeGetHeadSpaceFromStartSpaceRotation", - "(" - "J" - "[F" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceRotation)}, - {"nativeGetHeadSpaceFromStartSpaceTransform", - "(" - "J" - "[F" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetHeadSpaceFromStartSpaceTransform)}, - {"nativeSetIgnoreManualPauseResumeTracker", - "(" - "J" - "Z" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetIgnoreManualPauseResumeTracker)}, - {"nativePauseTracking", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativePauseTracking)}, - {"nativePauseTrackingGetState", - "(" - "J" - ")" - "[B", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativePauseTrackingGetState)}, - {"nativeResumeTracking", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeResumeTracking)}, - {"nativeResumeTrackingSetState", - "(" - "J" - "[B" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeResumeTrackingSetState)}, - {"nativeResetTracking", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeResetTracking)}, - {"nativeRecenterTracking", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeRecenterTracking)}, - {"nativeGetEyeFromHeadMatrix", - "(" - "J" - "I" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetEyeFromHeadMatrix)}, - {"nativeGetWindowBounds", - "(" - "J" - ")" - "[I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetWindowBounds)}, - {"nativeComputeDistortedPoint", - "(" - "J" - "I" - "[F" - ")" - "[F", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeComputeDistortedPoint)}, - {"nativeSetDefaultViewerProfile", - "(" - "J" - "Ljava/lang/String;" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetDefaultViewerProfile)}, - {"nativeGetViewerVendor", - "(" - "J" - ")" - "Ljava/lang/String;", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerVendor)}, - {"nativeGetViewerModel", - "(" - "J" - ")" - "Ljava/lang/String;", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerModel)}, - {"nativeGetViewerType", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetViewerType)}, - {"nativeSetAsyncReprojectionEnabled", - "(" - "J" - "Z" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetAsyncReprojectionEnabled)}, - {"nativeGetAsyncReprojectionEnabled", - "(" - "J" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetAsyncReprojectionEnabled)}, - {"nativeIsFeatureSupported", - "(" - "J" - "I" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeIsFeatureSupported)}, - {"nativeReconnectSensors", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeReconnectSensors)}, - {"nativeSetIdleListener", - "(" - "J" - "Lcom/google/vr/ndk/base/GvrApi$IdleListener;" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetIdleListener)}, - {"nativeSetViewerParams", - "(" - "J" - "[B" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetViewerParams)}, - {"nativeSetDisplayMetrics", - "(" - "J" - "I" - "I" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetDisplayMetrics)}, - {"nativeGetBorderSizeMeters", - "(" - "J" - ")" - "F", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetBorderSizeMeters)}, - {"nativeSetSurfaceSize", - "(" - "J" - "I" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetSurfaceSize)}, - {"nativeSetLensOffset", - "(" - "J" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeSetLensOffset)}, - {"nativeDumpDebugData", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeDumpDebugData)}, - {"nativeUsingVrDisplayService", - "(" - "J" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeUsingVrDisplayService)}, - {"nativeCreateEvent", - "(" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeCreateEvent)}, - {"nativeCreateValue", - "(" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeCreateValue)}, - {"nativeDestroyEvent", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeDestroyEvent)}, - {"nativeDestroyValue", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeDestroyValue)}, - {"nativeGetCurrentProperties", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetCurrentProperties)}, - {"nativeGetEventFlags", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetEventFlags)}, - {"nativeGetEventTimestamp", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetEventTimestamp)}, - {"nativeGetEventType", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetEventType)}, - {"nativeGetProperty", - "(" - "J" - "I" - "J" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetProperty)}, - {"nativeGetRecenterEventFlags", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventFlags)}, - {"nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform", - "(" - "J" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventStartSpaceFromTrackingSpaceTransform)}, - {"nativeGetRecenterEventType", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeGetRecenterEventType)}, - {"nativePollEvent", - "(" - "J" - "J" - ")" - "Z", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativePollEvent)}, - {"nativeValueAsFlags", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFlags)}, - {"nativeValueAsFloat", - "(" - "J" - ")" - "F", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeValueAsFloat)}, - {"nativeValueAsInt", - "(" - "J" - ")" - "I", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeValueAsInt)}, - {"nativeValueAsMat4f", - "(" - "J" - "[F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeValueAsMat4f)}, - {"nativeValueGetFlags", - "(" - "J" - ")" - "J", - reinterpret_cast<void*>( - Java_com_google_vr_ndk_base_GvrApi_nativeValueGetFlags)}, -}; - -static bool RegisterNativesImpl(JNIEnv* env) { - const int kMethodsGvrApiSize = std::extent<decltype(kMethodsGvrApi)>(); - - if (env->RegisterNatives(GvrApi_clazz(env), kMethodsGvrApi, - kMethodsGvrApiSize) < 0) { - jni_generator::HandleRegistrationError(env, GvrApi_clazz(env), __FILE__); - return false; - } - - return true; -} - -static bool RegisterGvrApiNatives(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace GvrApi - -#endif // com_google_vr_ndk_base_GvrApi_JNI
diff --git a/third_party/gvr-android-sdk/gvr_common_java.info b/third_party/gvr-android-sdk/gvr_common_java.info deleted file mode 100644 index 788e67c..0000000 --- a/third_party/gvr-android-sdk/gvr_common_java.info +++ /dev/null
@@ -1,87 +0,0 @@ -# Generated by //build/android/gyp/aar.py -# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". - -aidl = [] -assets = [] -has_classes_jar = true -has_native_libraries = false -has_proguard_flags = false -has_r_text_file = true -is_manifest_empty = true -manifest_package = "com.google.vr.cardboard" -resources = [ - "res/drawable-hdpi-v4/quantum_ic_close_white_24.png", - "res/drawable-hdpi-v4/quantum_ic_settings_white_24.png", - "res/drawable-hdpi-v4/transition.png", - "res/drawable-mdpi-v4/quantum_ic_close_white_24.png", - "res/drawable-mdpi-v4/quantum_ic_settings_white_24.png", - "res/drawable-mdpi-v4/transition.png", - "res/drawable-v21/rippleable.xml", - "res/drawable-xhdpi-v4/quantum_ic_close_white_24.png", - "res/drawable-xhdpi-v4/quantum_ic_settings_white_24.png", - "res/drawable-xxhdpi-v4/quantum_ic_close_white_24.png", - "res/drawable-xxhdpi-v4/quantum_ic_settings_white_24.png", - "res/drawable-xxxhdpi-v4/quantum_ic_close_white_24.png", - "res/drawable-xxxhdpi-v4/quantum_ic_settings_white_24.png", - "res/drawable/rippleable.xml", - "res/layout-land/back_button.xml", - "res/layout-land/settings_button.xml", - "res/layout-land/ui_layer_with_portrait_support.xml", - "res/layout-ldrtl-land-v17/back_button.xml", - "res/layout-ldrtl-land-v17/settings_button.xml", - "res/layout-ldrtl-v17/back_button.xml", - "res/layout-ldrtl-v17/settings_button.xml", - "res/layout/back_button.xml", - "res/layout/settings_button.xml", - "res/layout/transition_view.xml", - "res/layout/ui_layer.xml", - "res/layout/ui_layer_with_portrait_support.xml", - "res/values-ar/values.xml", - "res/values-bg/values.xml", - "res/values-ca/values.xml", - "res/values-cs/values.xml", - "res/values-da/values.xml", - "res/values-de/values.xml", - "res/values-el/values.xml", - "res/values-en-rGB/values.xml", - "res/values-es-rUS/values.xml", - "res/values-es/values.xml", - "res/values-fa/values.xml", - "res/values-fi/values.xml", - "res/values-fr-rCA/values.xml", - "res/values-fr/values.xml", - "res/values-hi/values.xml", - "res/values-hr/values.xml", - "res/values-hu/values.xml", - "res/values-id/values.xml", - "res/values-it/values.xml", - "res/values-iw/values.xml", - "res/values-ja/values.xml", - "res/values-ko/values.xml", - "res/values-land/values.xml", - "res/values-lt/values.xml", - "res/values-lv/values.xml", - "res/values-nb/values.xml", - "res/values-nl/values.xml", - "res/values-pl/values.xml", - "res/values-pt-rBR/values.xml", - "res/values-pt-rPT/values.xml", - "res/values-ro/values.xml", - "res/values-ru/values.xml", - "res/values-sk/values.xml", - "res/values-sl/values.xml", - "res/values-sr/values.xml", - "res/values-sv/values.xml", - "res/values-th/values.xml", - "res/values-tl/values.xml", - "res/values-tr/values.xml", - "res/values-uk/values.xml", - "res/values-v19/values.xml", - "res/values-v21/values.xml", - "res/values-vi/values.xml", - "res/values-zh-rCN/values.xml", - "res/values-zh-rTW/values.xml", - "res/values/values.xml" -] -subjar_tuples = [] -subjars = []
diff --git a/third_party/gvr-android-sdk/gvr_controller_java.info b/third_party/gvr-android-sdk/gvr_controller_java.info deleted file mode 100644 index f647256a..0000000 --- a/third_party/gvr-android-sdk/gvr_controller_java.info +++ /dev/null
@@ -1,14 +0,0 @@ -# Generated by //build/android/gyp/aar.py -# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". - -aidl = [] -assets = [] -has_classes_jar = true -has_native_libraries = false -has_proguard_flags = false -has_r_text_file = false -is_manifest_empty = true -manifest_package = "com.google.vr.sdk.controller" -resources = [] -subjar_tuples = [] -subjars = []
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1 deleted file mode 100644 index ebe5e82..0000000 --- a/third_party/gvr-android-sdk/libgvr_shim_static_arm.a.sha1 +++ /dev/null
@@ -1 +0,0 @@ -ccef696b378b176b6dcd9817132b0ed72343f952 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1 deleted file mode 100644 index 0b493c06..0000000 --- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64.a.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1a8e9cb3f8fbd6242d2cc473501540a88949fe08 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1 deleted file mode 100644 index d34fbb7..0000000 --- a/third_party/gvr-android-sdk/libgvr_shim_static_arm64_vtables.a.sha1 +++ /dev/null
@@ -1 +0,0 @@ -feb715a379bcc857747166979b5dca8ec66f5d88 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1 b/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1 deleted file mode 100644 index 4475b1b..0000000 --- a/third_party/gvr-android-sdk/libgvr_shim_static_arm_vtables.a.sha1 +++ /dev/null
@@ -1 +0,0 @@ -200852f7657291f0547cd8a35b9a7259edc2878f \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/native_callbacks_jni.h b/third_party/gvr-android-sdk/native_callbacks_jni.h deleted file mode 100644 index d8cc90f..0000000 --- a/third_party/gvr-android-sdk/native_callbacks_jni.h +++ /dev/null
@@ -1,346 +0,0 @@ -// Copyright 2014 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is of the same format as file that generated by -// third_party/jni_zero/jni_zero.py -// For -// com/google/vr/internal/controller/NativeCallbacks - -// Local modification includes: -// 1. Remove all implementation, only keep definition. -// 2. Use absolute path instead of relative path. -// 3. Removed all helper functions such as: Create. -// 4. Removed external functions that don't have implementation in shim file. -// 5. Replace all nativeHandle to handle. This is because jni_generator.py -// require jni functions start with "native" prefix. So we add the prefix to -// generate the file. But the real jni functions in the static library -// doesn't have the prefix. -// 6. Added function RegisterNativeCallbacksNatives at the end of this file. -// 7. Added "vr" as an argument to base::android::LazyGetClass. - -#ifndef com_google_vr_internal_controller_NativeCallbacks_JNI -#define com_google_vr_internal_controller_NativeCallbacks_JNI - -#include "base/android/jni_android.h" -// ---------------------------------------------------------------------------- -// Native JNI methods -// ---------------------------------------------------------------------------- -#include <jni.h> -#include <atomic> -#include <type_traits> - -#include "third_party/jni_zero/jni_int_wrapper.h" -#include "third_party/jni_zero/jni_zero_helper.h" - -// Step 1: forward declarations. -namespace { -const char kNativeCallbacksClassPath[] = - "com/google/vr/internal/controller/NativeCallbacks"; -// Leaking this jclass as we cannot use LazyInstance from some threads. -std::atomic<jclass> g_NativeCallbacks_clazz __attribute__((unused)) (nullptr); -#define NativeCallbacks_clazz(env) \ - base::android::LazyGetClass(env, kNativeCallbacksClassPath, "vr", \ - &g_NativeCallbacks_clazz) - -} // namespace - -namespace NativeCallbacks { -// Step 2: method stubs. - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleStateChanged( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jint newState); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleControllerRecentered( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jfloat qx, - jfloat qy, - jfloat qz, - jfloat qw); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleTouchEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jint action, - jfloat x, - jfloat y); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleOrientationEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jfloat qx, - jfloat qy, - jfloat qz, - jfloat qw); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleButtonEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jint buttonCode, - jboolean down); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleAccelEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jfloat x, - jfloat y, - jfloat z); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleGyroEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jfloat x, - jfloat y, - jfloat z); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handlePositionEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jfloat x, - jfloat y, - jfloat z); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleBatteryEvent( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint controllerIndex, - jlong timestampNanos, - jboolean isCharging, - jint batteryLevelBucket); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceInitFailed( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint failureReason); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceFailed( - JNIEnv* env, - jobject jcaller, - jlong userData); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceUnavailable( - JNIEnv* env, - jobject jcaller, - jlong userData); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceConnected( - JNIEnv* env, - jobject jcaller, - jlong userData, - jint flags); - -JNI_BOUNDARY_EXPORT void -Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceDisconnected( - JNIEnv* env, - jobject jcaller, - jlong userData); - -// Step 3: RegisterNatives. - -static const JNINativeMethod kMethodsNativeCallbacks[] = { - {"handleStateChanged", - "(" - "J" - "I" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleStateChanged)}, - {"handleControllerRecentered", - "(" - "J" - "I" - "J" - "F" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleControllerRecentered)}, - {"handleTouchEvent", - "(" - "J" - "I" - "J" - "I" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleTouchEvent)}, - {"handleOrientationEvent", - "(" - "J" - "I" - "J" - "F" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleOrientationEvent)}, - {"handleButtonEvent", - "(" - "J" - "I" - "J" - "I" - "Z" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleButtonEvent)}, - {"handleAccelEvent", - "(" - "J" - "I" - "J" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleAccelEvent)}, - {"handleGyroEvent", - "(" - "J" - "I" - "J" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleGyroEvent)}, - {"handlePositionEvent", - "(" - "J" - "I" - "J" - "F" - "F" - "F" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handlePositionEvent)}, - {"handleBatteryEvent", - "(" - "J" - "I" - "J" - "Z" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleBatteryEvent)}, - {"handleServiceInitFailed", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceInitFailed)}, - {"handleServiceFailed", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceFailed)}, - {"handleServiceUnavailable", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceUnavailable)}, - {"handleServiceConnected", - "(" - "J" - "I" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceConnected)}, - {"handleServiceDisconnected", - "(" - "J" - ")" - "V", - reinterpret_cast<void*>( - Java_com_google_vr_internal_controller_NativeCallbacks_handleServiceDisconnected)}, -}; - -static bool RegisterNativesImpl(JNIEnv* env) { - const int kMethodsNativeCallbacksSize = - std::extent<decltype(kMethodsNativeCallbacks)>(); - - if (env->RegisterNatives(NativeCallbacks_clazz(env), kMethodsNativeCallbacks, - kMethodsNativeCallbacksSize) < 0) { - jni_generator::HandleRegistrationError(env, NativeCallbacks_clazz(env), - __FILE__); - return false; - } - - return true; -} - -static bool RegisterNativeCallbacksNatives(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace NativeCallbacks - -#endif // com_google_vr_internal_controller_NativeCallbacks_JNI
diff --git a/third_party/gvr-android-sdk/proguard-gvr-chromium.txt b/third_party/gvr-android-sdk/proguard-gvr-chromium.txt deleted file mode 100644 index c9e4cf6e..0000000 --- a/third_party/gvr-android-sdk/proguard-gvr-chromium.txt +++ /dev/null
@@ -1,7 +0,0 @@ --dontwarn com.google.common.logging.nano.Vr$** --dontwarn com.google.vr.** - -# Since we manually register, we need to keep every native method. --keepclasseswithmembers,includedescriptorclasses class com.google.vr.** { - native <methods>; -}
diff --git a/third_party/gvr-android-sdk/src b/third_party/gvr-android-sdk/src deleted file mode 160000 index 233e7fe..0000000 --- a/third_party/gvr-android-sdk/src +++ /dev/null
@@ -1 +0,0 @@ -Subproject commit 233e7fe922a543e0bc55382d64cacd047307d0e7
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt deleted file mode 100644 index a4b42cda..0000000 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/apk_version_history.txt +++ /dev/null
@@ -1,18 +0,0 @@ -History of Daydream Home APK hashes -v1.0 2737c1d56854a2eb15df3c28697fa5267af5c558 -v1.1 12e7c98d6db3ab31a6f9c7e6f07351a9e4b85565 -v1.2 5400db0e25a24e0df9635ab268ef1058a60dfec2 -v1.3 db5eaf6e83a10e809b96375212d5c9dbbe517624 -v1.4 9afe32eb4676d4bcceae81605a3be6aa0e5be3d5 -v1.5 a02e2f95aa6f741f2be0ae03a4829e21fd749cf3 -v1.6 43b876df3398687dfa1ae059ef2f64009c76254e -v1.7 d5c72438acffe723e7717c45deedd8431bc613e7 -v1.8 cbc81aa4db5986f25d2c967f9b1e247cf07cd75e -v1.10 eea1bf917782ba00f9194a14e51a7ba1bdc8b896 -v1.12 ac838d3379a1cc5cefe254173d2a463b2df5b5d0 -v1.13 269adc6d3bbceffcdb200c39a5dc32f69f2ada10 -v1.14 34251a8e603ea9fac61dd1841757c23dd9534d63 -v1.15 d56e9ff51188bab2bc9c843aae60bd15b2fcbb96 -v1.16 a19b7e8feaa32a9d5e37de53414e8951e2b87ce7 -v1.17 686bbb327b689972721953121295becb4f5389c6 -v1.19 53d6c9f8cd18d6b48f1b62884d019914f453dfb3
diff --git a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 deleted file mode 100644 index 4bbe003b..0000000 --- a/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk.sha1 +++ /dev/null
@@ -1 +0,0 @@ -53d6c9f8cd18d6b48f1b62884d019914f453dfb3 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/update.py b/third_party/gvr-android-sdk/test-apks/update.py deleted file mode 100644 index d90a51f..0000000 --- a/third_party/gvr-android-sdk/test-apks/update.py +++ /dev/null
@@ -1,27 +0,0 @@ -import os -import subprocess -import sys - -THIS_DIR = os.path.abspath(os.path.dirname(__file__)) -DAYDREAM_DIR = os.path.abspath(os.path.join(THIS_DIR, 'daydream_home')) -VR_SERVICES_DIR = os.path.abspath(os.path.join(THIS_DIR, 'vr_services')) -VR_KEYBOARD_DIR = os.path.abspath(os.path.join(THIS_DIR, 'vr_keyboard')) - -def main(): - # VR environment variable is deprecated, use the XR one going forward. - if not any(v in os.environ for v in ('DOWNLOAD_VR_TEST_APKS', - 'DOWNLOAD_XR_TEST_APKS')): - return 0 - subprocess.check_call(['download_from_google_storage', - '--bucket', 'chrome-vr-test-apks/daydream_home', - '-d', DAYDREAM_DIR]) - subprocess.check_call(['download_from_google_storage', - '--bucket', 'chrome-vr-test-apks/vr_services', - '-d', VR_SERVICES_DIR]) - subprocess.check_call(['download_from_google_storage', - '--bucket', 'chrome-vr-test-apks/vr_keyboard', - '-d', VR_KEYBOARD_DIR]) - return 0 - -if __name__ == '__main__': - sys.exit(main())
diff --git a/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt deleted file mode 100644 index 7b97d38..0000000 --- a/third_party/gvr-android-sdk/test-apks/vr_keyboard/apk_version_history.txt +++ /dev/null
@@ -1,5 +0,0 @@ -v1.12 a31ceb898c8179e8bda976ff45e497848b9ba0be -v1.13 0fe388ce58b14909cdc9ee045f07076581491629 -v1.16 56ca300b7d28a752ea24f89c1685f28e83a04002 -v1.17 18ab8790479447a9d0b7768c7eb5420ecbfd70a2 -v1.19 e1626c5ef68812f278ec067038577dbf74238e4d
diff --git a/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1 deleted file mode 100644 index 5840a15..0000000 --- a/third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e1626c5ef68812f278ec067038577dbf74238e4d \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt b/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt deleted file mode 100644 index 124affd7..0000000 --- a/third_party/gvr-android-sdk/test-apks/vr_services/apk_version_history.txt +++ /dev/null
@@ -1,22 +0,0 @@ -History of VR Services APK hashes -v1.0 33e2c2bb1045fa1e0c3816fd6e8fb0ce6cbd56d4 -v1.1 524b48921472c133183d68a78a8dc675ea4cad35 -v1.2 982709c5cc24922c381413fa32b9cb8e9f004165 -v1.3 8233707ffc519460e1d21f8e1a5364a6336227f2 -v1.4 3024ad78653f11b53d9f15191eab9f11f70610e2 -^^^ 32-bit -vvv 64-bit -v1.4 3e0cc24655847c7b922149754324a189e7092310 -v1.5 5d6d55728c7c728cef5416f37b0b71615719474e -v1.6 abcdae2281956a76aa3b98d2e8f05a1975170dd0 -v1.7 fcfa178173a2c0cab9c7d51829c2ee76ab66e1d9 -v1.8 f8f45ebf1963c5f9862218baca120ea974b87a08 -v1.10 d288911f89f70a459b9fae4720bd3c2ecea26920 -v1.101 6bb3d2b3bc098a60ed255d74d904157fb223df8d -v1.12 42eebcfe73c4a24d3df6c0513332e93ff3bf6f8c -v1.13 d2137424d2b6aa84dccabcc59270c89a999de4b9 -v1.14 97b24557b761f02d0d2224d097552a95dae44349 -v1.15 712140d07ac97444cf9d1407b2bafd497e7df1fa -v1.16 96b849029526f7d980fe66e40ee0c5641774f897 -v1.17 a8554dcd83afd1d9718bc7d341c82f3ffba2efbb -v1.19 7378cd3efa4386491df7b010b070470f936f2e9e
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 deleted file mode 100644 index b86450f2..0000000 --- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk.sha1 +++ /dev/null
@@ -1 +0,0 @@ -7378cd3efa4386491df7b010b070470f936f2e9e \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1 b/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1 deleted file mode 100644 index 79552110..0000000 --- a/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_outdated.apk.sha1 +++ /dev/null
@@ -1 +0,0 @@ -524b48921472c133183d68a78a8dc675ea4cad35 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 b/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 deleted file mode 100644 index c69cf50..0000000 --- a/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 +++ /dev/null
@@ -1 +0,0 @@ -81cecc241ebe1e9d07f09850d0f83082ad52f225 \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-libraries/proguard.txt b/third_party/gvr-android-sdk/test-libraries/proguard.txt deleted file mode 100644 index 9c85a88..0000000 --- a/third_party/gvr-android-sdk/test-libraries/proguard.txt +++ /dev/null
@@ -1,4 +0,0 @@ -# Suppress some warnings that block compilation in release builds, but don't -# actually affect anything --dontwarn java.awt.** --dontwarn javax.lang.model.element.Modifier
diff --git a/third_party/perfetto b/third_party/perfetto index 905fb0a..7a68d15 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 905fb0a0357086378dc057f82a2e6926bf1341be +Subproject commit 7a68d15808c7e9714206112aaecbcd90ca1f1c18
diff --git a/third_party/selenium-atoms/README.chromium b/third_party/selenium-atoms/README.chromium index a05c890..b44aed9 100644 --- a/third_party/selenium-atoms/README.chromium +++ b/third_party/selenium-atoms/README.chromium
@@ -8,7 +8,6 @@ License: Apache 2 License File: LICENSE - Description: Standard implementation of some WebDriver functions. @@ -46,3 +45,38 @@ Local Modifications: - Applied changes in patch.diff to the selenium tree prior to building the atoms. + + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: Sizzle +URL: https://sizzlejs.com/ +Version: N/A +Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c +Security Critical: no +Shipped: yes +License: MIT, BSD, GPL v2 +License File: LICENSE.sizzle + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: Wicked Good XPath +Short Name: wgxpath +URL: https://github.com/google/wicked-good-xpath +Version: N/A +Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c +Security Critical: no +Shipped: yes +License: MIT +License File: LICENSE.wgxpath + +-------------------- DEPENDENCY DIVIDER -------------------- + +Name: Closure Library +URL: https://developers.google.com/closure/library +Version: N/A +Revision: bd5cbe5b3a3e60b5970d8168474dd69a996c392c +Security Critical: no +Shipped: yes +License: Apache 2.0 +License File: LICENSE.closure
diff --git a/third_party/skia b/third_party/skia index f0987bd..d0f09ad 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit f0987bd082ac9bc3d5ed6257c9ecfad18d9b0467 +Subproject commit d0f09ad481f7d8afd73259b1f46ad0dc8d8a1e6b
diff --git a/third_party/webrtc b/third_party/webrtc index b2e9bab..f698a39 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit b2e9babeb7aac43e3e27bb7f211b8bf994128720 +Subproject commit f698a39eecd1c58108d56d0b541430deebc74a25
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py index 30f81dd2b..13454b2b 100755 --- a/tools/licenses/licenses.py +++ b/tools/licenses/licenses.py
@@ -43,7 +43,8 @@ import action_helpers METADATA_FILE_NAMES = frozenset({ - "README.chromium", + "README.chromium", "README.crashpad", "README.v8", "README.pdfium", + "README.angle" }) # Paths from the root of the tree to directories to skip. @@ -403,28 +404,6 @@ "License": "Apache 2.0", "License File": ["//third_party/dawn/third_party/khronos/LICENSE"], }, - # Dependencies of Selenium Atoms - os.path.join('third_party', 'selenium-atoms', 'sizzle'): { - "Name": "Sizzle", - "URL": "https://sizzlejs.com/", - "Shipped": "yes", - "License": "MIT, BSD and GPL v2", - "License File": ["//third_party/selenium-atoms/LICENSE.sizzle"], - }, - os.path.join('third_party', 'selenium-atoms', 'wgxpath'): { - "Name": "Wicked Good XPath", - "URL": "https://github.com/google/wicked-good-xpath", - "Shipped": "yes", - "License": "MIT", - "License File": ["//third_party/selenium-atoms/LICENSE.wgxpath"], - }, - os.path.join('third_party', 'selenium-atoms', 'closure-lib'): { - "Name": "Closure Library", - "URL": "https://developers.google.com/closure/library", - "Shipped": "yes", - "License": "Apache 2.0", - "License File": ["//third_party/selenium-atoms/LICENSE.closure"], - }, } # These buildtools/third_party directories only contain @@ -1065,7 +1044,8 @@ def MetadataToTemplateEntry(metadata, entry_template): licenses = [] for filepath in metadata['License File']: - licenses.append(codecs.open(filepath, encoding='utf-8').read()) + licenses.append( + codecs.open(filepath, errors="replace", encoding='utf-8').read()) license_content = '\n\n'.join(licenses) env = {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1cb2eee8..20492a3 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -11422,6 +11422,10 @@ <int value="119" label="Console insight closed"/> <int value="120" label="Console insight generation errored"/> <int value="121" label="Console insight hover button was shown"/> + <int value="122" label="Self-XSS warning shown in console"/> + <int value="123" label="Self-XSS warning dialog shown"/> + <int value="124" label="Self-XSS pasting allowed in console"/> + <int value="125" label="Self-XSS pasting allowed in dialog"/> </enum> <enum name="DevToolsAnimationPlaybackRateChanged"> @@ -30659,6 +30663,7 @@ <int value="-1187251500" label="OmniboxPedalsBatch2NonEnglish:disabled"/> <int value="-1186760297" label="ForceSpectreVariant2Mitigation:disabled"/> <int value="-1185833629" label="AppCollectionFolderRefresh:enabled"/> + <int value="-1185656634" label="FileSystemProviderContentCache:enabled"/> <int value="-1185477291" label="ImeDecoderWithSandbox:enabled"/> <int value="-1184904651" label="enable-npapi"/> <int value="-1184775907" label="CommercePriceTrackingChipExperiment:enabled"/> @@ -36848,6 +36853,7 @@ <int value="1757894817" label="PrinterStatusDialog:disabled"/> <int value="1758262950" label="OmniboxUIExperimentVerticalMarginLimitToNonTouchOnly:disabled"/> + <int value="1758331078" label="FileSystemProviderContentCache:disabled"/> <int value="1758688616" label="OmniboxModernizeVisualUpdate:disabled"/> <int value="1759193892" label="SafetyCheckExtensions:disabled"/> <int value="1759323272" label="DefaultCalculatorWebApp:disabled"/> @@ -42308,6 +42314,7 @@ <int value="1205" label="Input"/> <int value="1206" label="Customize spell check"/> <int value="1207" label="Manage user dictionary"/> + <int value="1208" label="App languages"/> <int value="1300" label="Network File Shares"/> <int value="1301" label="Office Files"/> <int value="1302" label="Google Drive"/>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index cae56c46..e20371e 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -701,6 +701,16 @@ </summary> </histogram> +<histogram name="Blink.CommitDocumentLoaderTime" units="ms" + expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + Measures the time it takes to commit a new document in Blink. Collected once + per navigation when a frame is loaded. + </summary> +</histogram> + <histogram base="true" name="Blink.CompositingCommit.UpdateTime" units="microseconds" expires_after="2024-06-01"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimeSuffixes" --> @@ -3262,6 +3272,26 @@ </summary> </histogram> +<histogram name="Blink.PrepareToStopParsingTime" units="ms" + expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + Measures the time it takes to tokenize the HTML document, if necessary, and + perform other tasks around parsing completion. Logged every time there is an + update to the HTML document. + </summary> +</histogram> + +<histogram name="Blink.PumpTokenizerTime" units="ms" expires_after="2024-03-19"> + <owner>nidhijaju@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + Measures the time it takes to tokenize an HTML document in Blink. Collected + once per update to HTML document. + </summary> +</histogram> + <histogram name="Blink.ResourceRequest.BackgroundResourceFetchSupportStatus" enum="BackgroundResourceFetchSupportStatus" expires_after="2024-01-31"> <owner>horo@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index b91f224..3e609d2a 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -2570,18 +2570,27 @@ </summary> </histogram> -<histogram name="Extensions.InjectedScriptExecutionTime" units="ms" - expires_after="never"> +<histogram name="Extensions.InjectedScriptExecutionTime{UserScriptRunLocation}" + units="ms" expires_after="never"> <!-- expires-never: Monitoring performance of a core extension API. --> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> Time taken to execute all scripts for one location within an extension. - Recorded every time content scripts injected by extensions are executed. - Unlike Extensions.InjectScriptTime, this includes execution time of - asynchronously injected scripts. + Recorded every time content scripts injected by extensions are executed + {UserScriptRunLocation}. Unlike Extensions.InjectScriptTime, this includes + execution time of asynchronously injected scripts. </summary> + <token key="UserScriptRunLocation"> + <variant name="" summary="for all script run locations"/> + <variant name=".DocumentEnd" + summary="with run location of `run_at: document_end`"/> + <variant name=".DocumentIdle" + summary="with run location of `run_at: document_idle`"/> + <variant name=".DocumentStart" + summary="with run location of `run_at: document_start`"/> + </token> </histogram> <histogram name="Extensions.InjectEnd_BlockingScriptCount" units="units"
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index 853b144..0c8f254 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -1327,12 +1327,6 @@ <affected-histogram name="Net.QuicSession.SendPacketSize"/> </histogram_suffixes> -<histogram_suffixes name="ExtensionSource" separator="_" ordering="prefix"> - <suffix name="OffStore" label="Extension hosted off the Chrome Web Store"/> - <suffix name="WebStore" label="Extension from the Chrome Web Store"/> - <affected-histogram name="Extensions.ForceInstalledFailureReason3"/> -</histogram_suffixes> - <histogram_suffixes name="FeedLoadLatencyStep" separator="."> <suffix name="ActionUpload" label="Time taken read stored actions and upload them if necessary."/> @@ -4611,13 +4605,6 @@ <affected-histogram name="Setup.Install.LzmaUnPackStatus"/> </histogram_suffixes> -<histogram_suffixes name="UserScriptRunLocation" separator="."> - <suffix name="DocumentEnd" label="Scripts with run_at: document_end."/> - <suffix name="DocumentIdle" label="Scripts with run_at: document_idle."/> - <suffix name="DocumentStart" label="Scripts with run_at: document_start."/> - <affected-histogram name="Extensions.InjectedScriptExecutionTime"/> -</histogram_suffixes> - <histogram_suffixes name="V8SpecialApps" separator="."> <suffix name="calendar" label="Custom histogram for Calendar"/> <suffix name="docs" label="Custom histogram for Google Docs and Drive"/> @@ -4741,13 +4728,6 @@ <affected-histogram name="Net.WebSocket.ErrorCodes"/> </histogram_suffixes> -<histogram_suffixes name="WebStoreLinkExperiment" separator="_"> - <suffix name="Disabled" label="Neither extra webstore link is visible"/> - <suffix name="FooterLink" label="Link in bottom right of footer"/> - <suffix name="PlusIcon" label="Plus icon in apps page"/> - <affected-histogram name="Extensions.AppLaunch"/> -</histogram_suffixes> - <histogram_suffixes name="WebUITabStripTabCount" separator="."> <suffix name="01_05" label="1 to 5 tabs"/> <suffix name="06_20" label="6 to 20 tabs"/>
diff --git a/tools/metrics/histograms/metadata/optimization/enums.xml b/tools/metrics/histograms/metadata/optimization/enums.xml index 475cda5..a63e2af 100644 --- a/tools/metrics/histograms/metadata/optimization/enums.xml +++ b/tools/metrics/histograms/metadata/optimization/enums.xml
@@ -289,6 +289,9 @@ <int value="9" label="Used on-device, but output considered unsafe"> On-device model was used, it completed successfully, but considered unsafe. </int> + <int value="10" label="Used on-device, but output contained PII"> + On-device model was used, but was cancelled because it surfaced PII. + </int> </enum> <enum name="OptimizationGuideOnDeviceModelEligibilityReason">
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index ba585cbf..7257879 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -553,6 +553,21 @@ </summary> </histogram> +<histogram + name="Signin.BoundSessionCredentials.SessionRegistrationGenerateRegistrationTokenDuration" + units="ms" expires_after="2024-04-28"> + <owner>alexilin@chromium.org</owner> + <owner>msalama@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Records how long the generation of a registration token for the bound + session registration has taken. Recorded every time Chrome attempts to + register a bound session after an invitation from the server via an HTTP + header. This will not be recorded if Chrome couldn't parse the server + invitation or just decided to ignore it. + </summary> +</histogram> + <histogram name="Signin.BoundSessionCredentials.SessionRegistrationResult" enum="BoundSessionCredentialsSessionRegistrationResult" expires_after="2024-04-28"> @@ -567,6 +582,20 @@ </summary> </histogram> +<histogram + name="Signin.BoundSessionCredentials.SessionRegistrationTotalDuration" + units="ms" expires_after="2024-04-28"> + <owner>alexilin@chromium.org</owner> + <owner>msalama@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Records how long the bound session registration flow has taken. Recorded + every time Chrome attempts to register a bound session after an invitation + from the server via an HTTP header. This will not be recorded if Chrome + couldn't parse the server invitation or just decided to ignore it. + </summary> +</histogram> + <histogram name="Signin.BoundSessionCredentials.SessionTerminationTrigger" enum="SessionTerminationTrigger" expires_after="2024-05-26"> <owner>alexilin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml index dfe137d..0494789a 100644 --- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml +++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -128,7 +128,7 @@ </histogram> <histogram name="WebRTC.Audio.Agc2.EstimatedNoiseLevel" units="dBFS (negated)" - expires_after="2023-12-31"> + expires_after="2024-05-05"> <owner>alessiob@chromium.org</owner> <owner>silen@chromium.org</owner> <owner>webrtc-audio-uma@google.com</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index d707f6d4..298f1bc 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -8916,6 +8916,51 @@ </metric> </event> +<event name="Event.Scroll"> + <owner>woa-performance@google.com</owner> + <summary> + Metrics related to scroll and scroll jank, + </summary> + <metric name="FrameCount"> + <summary> + The number of frames that are presented during the scroll. If this is less + than or equal to 16, then the presented frame count is considered small; + if this is greater than 16 and less than or equal to 64 presented frames, + then it is considered medium; if this is greater than 64 presented frames, + then it is considered large. + </summary> + </metric> + <metric name="PredictorJankyFrameCount"> + <summary> + The number of frames that are deemed janky to the human eye after Chrome + has applied its scroll prediction algorithm.. + </summary> + </metric> + <metric name="ScrollJank.DelayedFrameCount"> + <summary> + The number of delayed frames. + </summary> + </metric> + <metric name="ScrollJank.MissedVsyncsMax"> + <summary> + The maximum number of vsyncs missed during any and all janks. + </summary> + </metric> + <metric name="ScrollJank.MissedVsyncsSum"> + <summary> + The total number of vsyncs missed during any and all janks that occurred. + </summary> + </metric> + <metric name="VsyncCount"> + <summary> + The number of vsyncs that occur during the scroll. If this is less than or + equal to 16, then the number of vsyncs is considered small; if this is + greater than 16 and less than or equal to 64 vsyncs, then it is considered + medium; if this is greater than 64 vsyncs, then is considered large. + </summary> + </metric> +</event> + <event name="Event.ScrollBegin.Touch"> <owner>nzolghadr@chromium.org</owner> <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 0c8446fe..deb085e 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/3e53e144bee271ec558363df2e561a77d7e0b789/linux-arm64/trace_processor_shell" }, "win": { - "hash": "7c56c118b715ffeccedd9399ef6dd40130eed9f0", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6e600a104c0d4e59e2647e63ecf075078b5bc3e2/trace_processor_shell.exe" + "hash": "1b1f9a9eba84a60170f6bb2bbcdcd3161f61a47c", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/7a68d15808c7e9714206112aaecbcd90ca1f1c18/trace_processor_shell.exe" }, "linux_arm": { "hash": "8aa911491cd365131216862ae495e18424ebe1b2", @@ -22,7 +22,7 @@ }, "linux": { "hash": "10da8a96ca3688e2f43a717c3898576820e25b26", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/905fb0a0357086378dc057f82a2e6926bf1341be/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/7a68d15808c7e9714206112aaecbcd90ca1f1c18/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts b/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts index 9d59af0..abb2c10 100644 --- a/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts +++ b/ui/file_manager/file_manager/common/js/filtered_volume_manager.ts
@@ -249,7 +249,6 @@ if (!this.volumeManager_) { return; } - // TODO(crbug.com/972849): Consider using EventTracker instead. this.volumeManager_.removeEventListener( 'drive-connection-changed', this.onEventBound_); this.volumeManager_.removeEventListener(
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts b/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts deleted file mode 100644 index c3ef675b..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.ts +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import type {MetadataParser} from './metadata_parser.js'; - -/** - * To invoke steps in parallel. - */ -export class FunctionParallel { - private failed_ = false; - private remaining_: number; - nextStep: () => void; - onError: (err: string) => void; - - /** - * @param steps_ Array of functions to invoke in parallel. - * @param logger_ Logger object. - * @param callback_ Callback to invoke on success. - * @param failureCallback_ Callback to invoke on failure. - */ - constructor( - private steps_: Function[], private logger_: MetadataParser, - private callback_: VoidCallback, - private failureCallback_: (err: string) => void) { - this.remaining_ = this.steps_.length; - this.nextStep = this.nextStep_.bind(this); - this.onError = this.onError_.bind(this); - } - - /** - * Error handling function, which fires error callback. - * @param err Error message. - */ - private onError_(err: string) { - if (!this.failed_) { - this.failed_ = true; - this.failureCallback_(err); - } - } - - /** - * Advances to next step. This method should not be used externally. In - * external cases should be used nextStep function, which is defined in - * closure and thus has access to internal variables of functionsequence. - */ - private nextStep_() { - if (--this.remaining_ == 0 && !this.failed_) { - this.callback_(); - } - } - - /** - * This function should be called only once on start, so start all the - * children at once - * @param args Arguments to be passed to all the steps. - */ - start(...args: object[]) { - this.logger_.vlog( - 'Starting [' + this.steps_.length + '] parallel tasks ' + - 'with ' + args.length + ' argument(s)'); - if (this.logger_.verbose) { - for (const arg of args) { - this.logger_.vlog(arg); - } - } - for (const step of this.steps_) { - this.logger_.vlog('Attempting to start step [' + step.name + ']'); - try { - step.apply(this, args); - } catch (e) { - this.onError(e!.toString()); - } - } - } -}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts b/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts deleted file mode 100644 index 9c4ada4..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.ts +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {MetadataParser} from './metadata_parser.js'; - -/** - * Invoke steps in sequence. - */ -export class FunctionSequence { - private currentStepIdx_ = -1; - private failed_ = false; - - started = false; - onError: (err: string) => void; - finish: () => void; - nextStep: (...args: unknown[]) => void; - - /** - * @param steps Array of functions to invoke in sequence. - * @param logger Logger object. - * @param callback Callback to invoke on success. - * @param failureCallback Callback to invoke on failure. - */ - constructor( - private steps_: Function[], public logger: MetadataParser, - private callback_: VoidCallback, - private failureCallback_: (error: string) => void) { - this.onError = this.onError_.bind(this); - this.finish = this.finish_.bind(this); - this.nextStep = this.nextStep_.bind(this); - } - - /** - * Sets new callback - * - * @param callback New callback to call on succeed. - */ - setCallback(callback: VoidCallback) { - this.callback_ = callback; - } - - /** - * Sets new error callback - * - * @param failureCallback New callback to call on failure. - */ - setFailureCallback(failureCallback: (error: string) => void) { - this.failureCallback_ = failureCallback; - } - - - /** - * Error handling function, which traces current error step, stops sequence - * advancing and fires error callback. - * - * @param err Error message. - */ - private onError_(err: string) { - this.logger.vlog( - 'Failed step: ' + this.steps_[this.currentStepIdx_]?.name + ': ' + err); - if (!this.failed_) { - this.failed_ = true; - this.failureCallback_(err); - } - } - - /** - * Finishes sequence processing and jumps to the last step. - * This method should not be used externally. In external - * cases should be used finish function, which is defined in closure and thus - * has access to internal variables of functionsequence. - */ - private finish_() { - if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) { - this.currentStepIdx_ = this.steps_.length; - this.callback_(); - } - } - - /** - * Advances to next step. - * This method should not be used externally. In external cases should be used - * nextStep function, which is defined in closure and thus has access to - * internal variables of functionsequence. - * @param args Arguments to be passed to the next step. - */ - private nextStep_(...args: unknown[]) { - if (this.failed_) { - return; - } - - if (++this.currentStepIdx_ >= this.steps_.length) { - this.logger.vlog('Sequence ended'); - this.callback_.apply(this); - } else { - this.logger.vlog( - 'Attempting to start step [' + - this.steps_[this.currentStepIdx_]?.name + ']'); - try { - this.steps_[this.currentStepIdx_]?.apply(this, args); - } catch (e) { - this.onError(e!.toString()); - } - } - } - - /** - * This function should be called only once on start, so start sequence - * pipeline - * @param args Arguments to be passed to the first step. - */ - start(...args: unknown[]) { - if (this.started) { - throw new Error('"Start" method of FunctionSequence was called twice'); - } - - this.logger.log('Starting sequence with ' + args.length + ' arguments'); - - this.started = true; - this.nextStep.apply(this, args); - } -}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts index 66e77e4..9a357b2f 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts +++ b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.ts
@@ -3,8 +3,6 @@ // found in the LICENSE file. import {ByteReader, SeekOrigin} from './byte_reader.js'; -import {FunctionParallel} from './function_parallel.js'; -import {FunctionSequence} from './function_sequence.js'; import {Id3v2Frame, ParserMetadata} from './metadata_item.js'; import {MetadataParser, MetadataParserLogger} from './metadata_parser.js'; @@ -238,8 +236,131 @@ } /** - * @param file File object to parse. - * @param metadata Metadata object of the file. + * Parse the `file` and attempt to extract id3v1 metadata from it, and place + * these properties on the `metadata` object. + * @param file Input File object to parse. + * @param metadata Output metadata object of the file. + */ + private async parseId3v1(file: File, metadata: ParserMetadata) { + // Reads last 128 bytes of file in bytebuffer, which passes further. In + // last 128 bytes should be placed ID3v1 tag if available. + const reader = + await MetadataParser.readFileBytes(file, file.size - 128, file.size); + + // Attempts to extract ID3v1 tag from 128 bytes long ByteBuffer + if (reader.readString(3) == 'TAG') { + this.vlog('id3v1 found'); + const title = reader.readNullTerminatedString(30).trim(); + + if (title.length > 0) { + metadata.title = title; + } + + reader.seek(3 + 30, SeekOrigin.SEEK_BEG); + + const artist = reader.readNullTerminatedString(30).trim(); + if (artist.length > 0) { + metadata.artist = artist; + } + + reader.seek(3 + 30 + 30, SeekOrigin.SEEK_BEG); + + const album = reader.readNullTerminatedString(30).trim(); + if (album.length > 0) { + metadata.album = album; + } + } + } + + /** + * Parse the `file` and attempt to extract id3v2 metadata from it, and place + * these properties on the `metadata` object. + * @param file Input File object to parse. + * @param metadata Output metadata object of the file. + */ + private async parseId3v2(file: File, metadata: ParserMetadata) { + let reader = await MetadataParser.readFileBytes(file, 0, 10); + + // Check if the first 10 bytes contains ID3 header. + if (reader.readString(3) !== 'ID3') { + return; + } + this.vlog('id3v2 found'); + const major = reader.readScalar(1, false); + const minor = reader.readScalar(1, false); + const flags = reader.readScalar(1, false); + const size = Id3Parser.readSynchSafe_(reader, 4); + const id3v2 = metadata.id3v2 = { + majorVersion: major, + minorVersion: minor, + flags: flags, + size: size, + frames: {} as {[frameName: string]: Id3v2Frame}, + }; + + // Extract all ID3v2 frames + reader = await MetadataParser.readFileBytes(file, 10, 10 + id3v2.size); + + if ((id3v2.majorVersion > 2) && + ((id3v2.flags & Id3Parser.V2.FLAG_EXTENDED_HEADER) != 0)) { + // Skip extended header if found + if (id3v2.majorVersion == 3) { + reader.seek(reader.readScalar(4, false) - 4); + } else if (id3v2.majorVersion == 4) { + reader.seek(Id3Parser.readSynchSafe_(reader, 4) - 4); + } + } + + let frame; + while (frame = this.readFrame_(reader, id3v2.majorVersion)) { + id3v2.frames[frame.name] = frame; + } + if (id3v2.frames['APIC']) { + metadata.thumbnailURL = id3v2.frames['APIC'].imageUrl; + } else if (id3v2.frames['PIC']) { + metadata.thumbnailURL = id3v2.frames['PIC'].imageUrl; + } + + // Adds 'description' object to metadata. 'description' is used to unify + // different parsers and make metadata parser-aware. The key of each + // description item should be used to properly format the value before + // displaying to users. + metadata.description = []; + + for (const [key, frame] of Object.entries(id3v2.frames)) { + const mappedKey = Id3Parser.V2.MAPPERS[key]; + if (mappedKey && frame.value && frame.value.trim().length > 0) { + metadata.description.push({ + key: mappedKey, + value: frame.value.trim(), + }); + } + } + + function extract( + propName: 'album'|'title'|'artist', ...tagNames: string[]) { + for (const tagName of tagNames) { + const tag = id3v2.frames[tagName]; + if (tag && tag.value) { + metadata[propName] = tag.value; + break; + } + } + } + + extract('album', 'TALB', 'TAL'); + extract('title', 'TIT2', 'TT2'); + extract('artist', 'TPE1', 'TP1'); + + metadata.description.sort((a, b) => { + return Id3Parser.METADATA_ORDER.indexOf(a.key) - + Id3Parser.METADATA_ORDER.indexOf(b.key); + }); + } + + /** + * @param file Input File object to parse. + * @param metadata Output metadata object of the file. * @param callback Success callback. * @param onError Error callback. */ @@ -247,192 +368,16 @@ file: File, metadata: ParserMetadata, callback: (metadata: ParserMetadata) => void, onError: (error: string) => void) { - const self = this; - this.log('Starting id3 parser for ' + file.name); - const id3v1Parser = new FunctionSequence( - [ - /** - * Reads last 128 bytes of file in bytebuffer, - * which passes further. - * In last 128 bytes should be placed ID3v1 tag if available. - * @param file File which bytes to read. - */ - function readTail(this: FunctionSequence, file: File) { - MetadataParser.readFileBytes( - file, file.size - 128, file.size, this.nextStep, this.onError); - }, - - /** - * Attempts to extract ID3v1 tag from 128 bytes long ByteBuffer - * @param file File which tags are being extracted. Could be - * used for logging purposes. - * @param reader ByteReader of 128 bytes. - */ - function extractId3v1( - this: FunctionSequence, _file: File, reader: ByteReader) { - if (reader.readString(3) == 'TAG') { - this.logger.vlog('id3v1 found'); - const title = reader.readNullTerminatedString(30).trim(); - - if (title.length > 0) { - metadata.title = title; - } - - reader.seek(3 + 30, SeekOrigin.SEEK_BEG); - - const artist = reader.readNullTerminatedString(30).trim(); - if (artist.length > 0) { - metadata.artist = artist; - } - - reader.seek(3 + 30 + 30, SeekOrigin.SEEK_BEG); - - const album = reader.readNullTerminatedString(30).trim(); - if (album.length > 0) { - metadata.album = album; - } - } - this.nextStep(); - }, - ], - this, () => {}, _error => {}); - - const id3v2Parser = new FunctionSequence( - [ - function readHead(this: FunctionSequence, file: File) { - MetadataParser.readFileBytes( - file, 0, 10, this.nextStep, this.onError); - }, - - /** - * Check if passed array of 10 bytes contains ID3 header. - * @param file File to check and continue reading if ID3 - * metadata found. - * @param reader Reader to fill with stream bytes. - */ - function checkId3v2( - this: FunctionSequence, file: File, reader: ByteReader) { - if (reader.readString(3) == 'ID3') { - this.logger.vlog('id3v2 found'); - const major = reader.readScalar(1, false); - const minor = reader.readScalar(1, false); - const flags = reader.readScalar(1, false); - const size = Id3Parser.readSynchSafe_(reader, 4); - const id3v2 = metadata.id3v2 = { - majorVersion: major, - minorVersion: minor, - flags: flags, - size: size, - frames: {}, - }; - - MetadataParser.readFileBytes( - file, 10, 10 + id3v2.size, this.nextStep, this.onError); - } else { - this.finish(); - } - }, - - /** - * Extracts all ID3v2 frames from given bytebuffer. - * @param file File being parsed. - * @param reader Reader to use for metadata extraction. - */ - function extractFrames( - this: FunctionSequence, _file: File, reader: ByteReader) { - const id3v2 = metadata.id3v2!; - - if ((id3v2.majorVersion > 2) && - ((id3v2.flags & Id3Parser.V2.FLAG_EXTENDED_HEADER) != 0)) { - // Skip extended header if found - if (id3v2.majorVersion == 3) { - reader.seek(reader.readScalar(4, false) - 4); - } else if (id3v2.majorVersion == 4) { - reader.seek(Id3Parser.readSynchSafe_(reader, 4) - 4); - } - } - - let frame; - - while (frame = self.readFrame_(reader, id3v2.majorVersion)) { - id3v2.frames[frame.name] = frame; - } - - this.nextStep(); - }, - - /** - * Adds 'description' object to metadata. - * 'description' used to unify different parsers and make - * metadata parser-aware. - * Description is array if value-type pairs. Type should be used - * to properly format value before displaying to user. - */ - function prepareDescription(this: FunctionSequence) { - const id3v2 = metadata.id3v2!; - - if (id3v2.frames['APIC']) { - metadata.thumbnailURL = id3v2.frames['APIC'].imageUrl; - } else if (id3v2.frames['PIC']) { - metadata.thumbnailURL = id3v2.frames['PIC'].imageUrl; - } - - metadata.description = []; - - for (const [key, frame] of Object.entries(id3v2.frames)) { - const mappedKey = Id3Parser.V2.MAPPERS[key]; - if (mappedKey && frame.value && frame.value.trim().length > 0) { - metadata.description.push({ - key: mappedKey, - value: frame.value.trim(), - }); - } - } - - function extract( - propName: 'album'|'title'|'artist', ...tagNames: string[]) { - for (const tagName of tagNames) { - const tag = id3v2.frames[tagName]; - if (tag && tag.value) { - metadata[propName] = tag.value; - break; - } - } - } - - extract('album', 'TALB', 'TAL'); - extract('title', 'TIT2', 'TT2'); - extract('artist', 'TPE1', 'TP1'); - - metadata.description.sort((a, b) => { - return Id3Parser.METADATA_ORDER.indexOf(a.key) - - Id3Parser.METADATA_ORDER.indexOf(b.key); - }); - this.nextStep(); - }, - ], - this, () => {}, _error => {}); - - const metadataParser = new FunctionParallel( - [ - id3v1Parser.start.bind(id3v1Parser), - id3v2Parser.start.bind(id3v2Parser), - ], - this, () => { - callback.call(null, metadata); - }, onError); - - id3v1Parser.setCallback(metadataParser.nextStep); - id3v2Parser.setCallback(metadataParser.nextStep); - - id3v1Parser.setFailureCallback(metadataParser.onError); - id3v2Parser.setFailureCallback(metadataParser.onError); - - this.vlog('Passed argument : ' + file); - - metadataParser.start(file); + Promise + .all([this.parseId3v1(file, metadata), this.parseId3v2(file, metadata)]) + .then(() => { + callback(metadata); + }) + .catch((e: unknown) => { + onError(e!.toString()); + }); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts index 7112831..c70d4fd 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts +++ b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.ts
@@ -33,15 +33,14 @@ file: File, metadata: ParserMetadata, callback: (metadata: ParserMetadata) => void, errorCallback: (error: string) => void) { - const self = this; - MetadataParser.readFileBytes(file, 0, this.headerSize, (_file, br) => { - try { - self.parseHeader(metadata, br); - callback(metadata); - } catch (e) { - errorCallback(e!.toString()); - } - }, errorCallback); + MetadataParser.readFileBytes(file, 0, this.headerSize) + .then(byteReader => { + this.parseHeader(metadata, byteReader); + callback(metadata); + }) + .catch((e: unknown) => { + errorCallback(e!.toString()); + }); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts index 6d3fd71..f2dc804 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.ts
@@ -78,25 +78,14 @@ } /** - * Utility function to read specified range of bytes from file + * Get a ByteReader for a range of bytes from file. Rejects on error. * @param file The file to read. - * @param begin Starting byte(included). - * @param end Last byte(excluded). - * @param callback Callback to invoke. - * @param onError Error handler. + * @param begin Starting byte (included). + * @param end Last byte (excluded). */ - static readFileBytes( - file: File, begin: number, end: number, - callback: (file: File, byteReader: ByteReader) => void, - onError: (s: string) => void) { - const fileReader = new FileReader(); - fileReader.onerror = event => { - onError(event.type); - }; - fileReader.onloadend = () => { - callback(file, new ByteReader(fileReader.result as ArrayBuffer)); - }; - fileReader.readAsArrayBuffer(file.slice(begin, end)); + static async readFileBytes(file: File, begin: number, end: number): + Promise<ByteReader> { + return new ByteReader(await file.slice(begin, end).arrayBuffer()); } /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js deleted file mode 100644 index c849009..0000000 --- a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2019 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; - -import {InstallLinuxPackageDialog} from './install_linux_package_dialog.js'; - -export function testInstallButtonHiddenUntilInfoReady() { - // Polyfill chrome.app.window.current(). - // @ts-ignore: error TS2339: Property 'app' does not exist on type 'typeof - // chrome'. - chrome.app = {window: {current: () => null}}; - - let getInfoCallback; - // @ts-ignore: error TS2740: Type '{ getLinuxPackageInfo: (entry: - // FileSystemEntry, callback: (arg0: LinuxPackageInfo) => void) => void; }' is - // missing the following properties from type 'typeof fileManagerPrivate': - // setPreferences, getDriveConnectionState, PreferencesChange, - // DriveConnectionStateType, and 185 more. - chrome.fileManagerPrivate = { - // @ts-ignore: error TS6133: 'entry' is declared but its value is never - // read. - getLinuxPackageInfo: (entry, callback) => { - getInfoCallback = callback; - }, - }; - - const info = {name: 'n', version: 'v', info: 'i', summary: 's'}; - const dialogElement = document.createElement('dialog'); - document.body.append(dialogElement); - const dialog = new InstallLinuxPackageDialog(dialogElement); - - // Show dialog and verify that the install button is disabled. - dialog.showInstallLinuxPackageDialog(/** @type {!Entry} */ ({})); - const installButton = document.querySelector('.cr-dialog-ok'); - // @ts-ignore: error TS2339: Property 'disabled' does not exist on type - // 'Element'. - assertTrue(installButton.disabled); - - // The install button should become enabled once info is ready. - // @ts-ignore: error TS2722: Cannot invoke an object which is possibly - // 'undefined'. - getInfoCallback(info); - // @ts-ignore: error TS2339: Property 'disabled' does not exist on type - // 'Element'. - assertFalse(installButton.disabled); -}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts new file mode 100644 index 0000000..3ea22655 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts
@@ -0,0 +1,38 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js'; + +import {installMockChrome} from '../../../common/js/mock_chrome.js'; + +import {InstallLinuxPackageDialog} from './install_linux_package_dialog.js'; + +export function testInstallButtonHiddenUntilInfoReady() { + let getInfoCallback: + Parameters<typeof chrome.fileManagerPrivate.getLinuxPackageInfo>[1] = + () => {}; + installMockChrome({ + fileManagerPrivate: { + getLinuxPackageInfo: (_, callback) => { + getInfoCallback = callback; + }, + }, + }); + + const info: chrome.fileManagerPrivate.LinuxPackageInfo = + {name: 'n', version: 'v', summary: 's', description: 'd'}; + const dialogElement = document.createElement('dialog'); + document.body.append(dialogElement); + const dialog = new InstallLinuxPackageDialog(dialogElement); + + // Show dialog and verify that the install button is disabled. + dialog.showInstallLinuxPackageDialog({} as Entry); + const installButton = + document.querySelector<HTMLButtonElement>('.cr-dialog-ok')!; + assertTrue(installButton.disabled); + + // The install button should become enabled once info is ready. + getInfoCallback(info); + assertFalse(installButton.disabled); +}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts index 50fcd19..456a18b 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.ts
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {EventTracker} from 'chrome://resources/js/event_tracker.js'; - import {Menu} from './menu.js'; import {MenuItem, MenuItemActivationEvent} from './menu_item.js'; @@ -50,12 +48,14 @@ */ private menuEndGap_: number = 0; - private showingEvents_: EventTracker|null = null; + /** + * AbortController allows for global aborting of all event listeners and thus + * their removal from the DOM. + */ + private abortController_: AbortController|null = null; override initialize() { super.initialize(); - // Event tracker for the sub-menu specific listeners. - this.showingEvents_ = new EventTracker(); this.currentMenu = this; this.menuEndGap_ = 18; // padding on cr.menu + 2px } @@ -333,33 +333,26 @@ if (subMenuId) { const subMenu = document.querySelector(subMenuId); if (subMenu) { - const self = this.asEventListener(); - this.showingEvents_!.add(subMenu, 'activate', self); + subMenu.addEventListener( + 'activate', this, {signal: this.abortController_?.signal}); } } }); } - // TODO: Split the handleEvent() in multiple methods to remove this cast. - asEventListener(): EventListener { - return this as unknown as EventListener; - } - override show(mouseDownPos?: {x: number, y: number}) { super.show(mouseDownPos); // When the menu is shown we steal all keyboard events. const doc = this.ownerDocument; - const showingEvents = this.showingEvents_!; - // TODO: Split the handleEvent() in multiple methods to remove the cast - // below. - const self = this as unknown as EventListener; + this.abortController_ = new AbortController(); + const signal = this.abortController_.signal; if (doc) { - showingEvents.add(doc, 'keydown', self, true); + doc.addEventListener('keydown', this, {capture: true, signal}); } - showingEvents.add(this, 'activate', self, true); + this.addEventListener('activate', this, {capture: true, signal}); // Handle mouse-over to trigger sub menu opening on hover. - showingEvents.add(this, 'mouseover', self); - showingEvents.add(this, 'mouseout', self); + this.addEventListener('mouseover', this, {signal}); + this.addEventListener('mouseout', this, {signal}); this.addSubMenuListeners(); } @@ -383,7 +376,7 @@ } override hide() { - this.showingEvents_!.removeAll(); + this.abortController_?.abort(); // Hide any visible sub-menus first this.hideSubMenu_(); super.hide();
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts index 99357ed..a09ffd2 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu_button.ts
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {EventTracker} from 'chrome://resources/ash/common/event_tracker.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; import {assert} from 'chrome://resources/js/assert.js'; @@ -38,7 +37,7 @@ */ private menuEndGap_: number = 0; // padding on cr.menu + 2px - private showingEvents_: EventTracker|null = null; + private abortController_: AbortController|null = null; private menu_: MultiMenu|null = null; private observer_: ResizeObserver|null = null; private observedElement_: HTMLElement|null = null; @@ -71,10 +70,6 @@ this.observer_ = new ResizeObserver(() => { this.positionMenu_(); }); - - // An event tracker for events we only connect to while the menu is - // displayed. - this.showingEvents_ = new EventTracker(); } get menu(): MultiMenu|null { @@ -279,16 +274,16 @@ const doc = this.ownerDocument; assert(doc.defaultView); const win = doc.defaultView; - const self = this as unknown as EventListener; - assert(this.showingEvents_); - this.showingEvents_.add(doc, 'keydown', self, true); - this.showingEvents_.add(doc, 'mousedown', self, true); - this.showingEvents_.add(doc, 'focus', self, true); - this.showingEvents_.add(doc, 'scroll', self, true); - this.showingEvents_.add(win, 'popstate', self); - this.showingEvents_.add(win, 'resize', self); - this.showingEvents_.add(this.menu, 'contextmenu', self); - this.showingEvents_.add(this.menu, 'activate', self); + this.abortController_ = new AbortController(); + const signal = this.abortController_.signal; + doc.addEventListener('keydown', this, {capture: true, signal}); + doc.addEventListener('mousedown', this, {capture: true, signal}); + doc.addEventListener('focus', this, {capture: true, signal}); + doc.addEventListener('scroll', this, {capture: true, signal}); + win.addEventListener('popstate', this, {signal}); + win.addEventListener('resize', this, {signal}); + this.menu.addEventListener('contextmenu', this, {signal}); + this.menu.addEventListener('activate', this, {signal}); this.observedElement_ = this.parentElement; assert(this.observedElement_); @@ -337,7 +332,6 @@ this.setAttribute('aria-expanded', 'false'); this.removeAttribute('menu-shown'); assert(this.menu); - assert(this.showingEvents_); assert(this.observer_); assert(this.observedElement_); @@ -348,7 +342,7 @@ } this.menu.hide(); - this.showingEvents_.removeAll(); + this.abortController_?.abort(); if (shouldTakeFocus) { this.focus(); }
diff --git a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts index 7c712d9e..c280831 100644 --- a/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts +++ b/ui/file_manager/file_manager/state/ducks/ui_entries_unittest.ts
@@ -6,16 +6,17 @@ import {MockVolumeManager} from '../../background/js/mock_volume_manager.js'; import {FakeEntryImpl, GuestOsPlaceholder, VolumeEntry} from '../../common/js/files_app_entry_types.js'; +import {MockFileSystem} from '../../common/js/mock_entry.js'; import {waitUntil} from '../../common/js/test_error_reporting.js'; import {RootType, VolumeType} from '../../common/js/volume_manager_types.js'; import {FileData, State} from '../../externs/ts/state.js'; import type {VolumeInfo} from '../../externs/volume_info.js'; -import {convertEntryToFileData} from '../ducks/all_entries.js'; +import {convertEntryToFileData, readSubDirectories} from '../ducks/all_entries.js'; import {createFakeVolumeMetadata, setUpFileManagerOnWindow, setupStore, waitDeepEquals} from '../for_tests.js'; -import {getEmptyState} from '../store.js'; +import {getEmptyState, getEntry} from '../store.js'; import {addUiEntry, removeUiEntry} from './ui_entries.js'; -import {convertVolumeInfoAndMetadataToVolume} from './volumes.js'; +import {addVolume, convertVolumeInfoAndMetadataToVolume} from './volumes.js'; export function setUp() { // sortEntries() from addUiEntry() reducer requires volumeManager and @@ -308,3 +309,60 @@ done(); } + +/** + * Test MyFiles children should include PlayFiles even PlayFiles ui entry is + * added when there's an ongoing scanning call for MyFiles. + */ +export async function testPlayFilesAddedDuringScanningMyFiles() { + const store = setupStore(); + const {volumeInfo} = createMyFilesDataWithVolumeEntry(); + const myFilesEntry = new VolumeEntry(volumeInfo); + // Populate one sub folder for MyFiles. + const downloadsFS = volumeInfo.fileSystem as MockFileSystem; + downloadsFS.populate([ + '/sub-dir/', + ]); + const subDirEntry = downloadsFS.entries['/sub-dir']!; + // Add MyFiles to the store. + store.dispatch(addVolume( + {volumeInfo, volumeMetadata: createFakeVolumeMetadata(volumeInfo)})); + await waitUntil(() => { + return !!store.getState().allEntries[myFilesEntry.toURL()]; + }); + const myFilesEntryInStore = + getEntry(store.getState(), myFilesEntry.toURL()) as VolumeEntry; + + // Dispatch an action to read children of MyFiles. At this moment, the + // UiChildren of MyFiles is empty so no `StaticReader` will be added to + // MyFiles. + store.dispatch(readSubDirectories(myFilesEntryInStore)); + + // Dispatch an action to add an ui entry at the same time. + const playFilesUiEntry = new GuestOsPlaceholder( + 'Play files', 0, chrome.fileManagerPrivate.VmType.ARCVM); + store.dispatch(addUiEntry(playFilesUiEntry)); + + // Expect PlayFiles should be in the store eventually. + myFilesEntry.addEntry(playFilesUiEntry); + const want: Partial<State> = { + allEntries: { + [myFilesEntry.toURL()]: { + ...convertEntryToFileData(myFilesEntry), + children: [ + subDirEntry.toURL(), + playFilesUiEntry.toURL(), + ], + }, + [playFilesUiEntry.toURL()]: convertEntryToFileData(playFilesUiEntry), + [subDirEntry.toURL()]: convertEntryToFileData(subDirEntry), + }, + }; + + await waitDeepEquals(store, want, (state) => ({ + allEntries: state.allEntries, + })); + const uiChildren = myFilesEntryInStore.getUiChildren(); + assertEquals(1, uiChildren.length); + assertEquals(playFilesUiEntry, uiChildren[0]); +}
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni index c939d16..2e913c0 100644 --- a/ui/file_manager/file_names.gni +++ b/ui/file_manager/file_names.gni
@@ -345,8 +345,6 @@ "file_manager/foreground/js/metadata/exif_parser.ts", "file_manager/foreground/js/metadata/external_metadata_provider.ts", "file_manager/foreground/js/metadata/file_system_metadata_provider.ts", - "file_manager/foreground/js/metadata/function_parallel.ts", - "file_manager/foreground/js/metadata/function_sequence.ts", "file_manager/foreground/js/metadata/id3_parser.ts", "file_manager/foreground/js/metadata/image_parsers.ts", "file_manager/foreground/js/metadata/metadata_cache_item.ts", @@ -537,6 +535,7 @@ "file_manager/foreground/js/ui/file_table_list_unittest.ts", "file_manager/foreground/js/ui/file_table_unittest.ts", "file_manager/foreground/js/ui/grid_unittest.ts", + "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.ts", "file_manager/foreground/js/ui/menu_unittest.ts", "file_manager/foreground/js/ui/multi_menu_unittest.ts", "file_manager/foreground/js/ui/list_single_selection_model_unittest.ts", @@ -626,7 +625,6 @@ unittest_files = [ # Foreground: "file_manager/foreground/js/ui/file_tap_handler_unittest.js", - "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js", "file_manager/foreground/js/ui/directory_tree_unittest.js", "file_manager/foreground/js/navigation_list_model_unittest.js",
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc index a4dcb0f..57adcf7 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -141,7 +141,10 @@ return false; } - VLOG(1) << "Starting DND session."; + VLOG(1) << "Starting Drag-and-Drop session. tracker_id=" << serial->value + << ", data_source=" + << (source == DragEventSource::kMouse ? "mouse" : "touch") + << ", serial tracker=" << connection_->serial_tracker().ToString(); // Create new data source and offers |data|. SetOfferedExchangeDataProvider(data);
diff --git a/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc b/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc index 2f0a7084..437e3d7 100644 --- a/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc +++ b/ui/ozone/platform/wayland/host/wayland_serial_tracker.cc
@@ -70,7 +70,7 @@ if (!serial) { out << "<none>"; } else { - out << "serial=" << serial->value << ", time=" << serial->timestamp; + out << "tracker_id=" << serial->value << ", time=" << serial->timestamp; }; }; std::ostringstream out;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc index 8f262de..86b8f52 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc
@@ -131,7 +131,7 @@ return false; } - VLOG(1) << "Starting DND session. serial=" << serial->value + VLOG(1) << "Starting Window Drag session. tracker_id=" << serial->value << ", data_source=" << (drag_source == DragEventSource::kMouse ? "mouse" : "touch") << ", serial tracker=" << connection_->serial_tracker().ToString();
diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc index 1d0c1c7..33bc04d 100644 --- a/ui/views/layout/box_layout.cc +++ b/ui/views/layout/box_layout.cc
@@ -85,6 +85,29 @@ return view_->GetVisible() && !view_->GetProperty(kViewIgnoredByLayoutKey); } +// BoxLayoutFlexSpecification -------------------------------------------------- + +BoxLayoutFlexSpecification::BoxLayoutFlexSpecification() = default; + +BoxLayoutFlexSpecification BoxLayoutFlexSpecification::WithWeight( + int weight) const { + DCHECK_GE(weight, 0); + BoxLayoutFlexSpecification spec = *this; + spec.weight_ = weight; + return spec; +} + +BoxLayoutFlexSpecification BoxLayoutFlexSpecification::UseMinSize( + bool use_min_size) const { + BoxLayoutFlexSpecification spec = *this; + spec.use_min_size_ = use_min_size; + return spec; +} + +BoxLayoutFlexSpecification::~BoxLayoutFlexSpecification() = default; + +// BoxLayout -------------------------------------------------- + BoxLayout::BoxLayout(BoxLayout::Orientation orientation, const gfx::Insets& inside_border_insets, int between_child_spacing, @@ -125,13 +148,15 @@ DCHECK(view); DCHECK_EQ(host_, view->parent()); DCHECK_GE(flex_weight, 0); - flex_map_[view].flex_weight = flex_weight; - flex_map_[view].use_min_size = use_min_size; + const_cast<View*>(view)->SetProperty(kBoxLayoutFlexKey, + BoxLayoutFlexSpecification() + .WithWeight(flex_weight) + .UseMinSize(use_min_size)); } void BoxLayout::ClearFlexForView(const View* view) { DCHECK(view); - flex_map_.erase(view); + const_cast<View*>(view)->ClearProperty(kBoxLayoutFlexKey); } void BoxLayout::SetDefaultFlex(int default_flex) { @@ -382,12 +407,8 @@ } int BoxLayout::GetFlexForView(const View* view) const { - // Give precedence to flex provided via the layout. - if (auto it = flex_map_.find(view); it != flex_map_.end()) { - return it->second.flex_weight; - } - // Respect flex provided via the `kFlexBehaviorKey`. - if (auto* flex_behavior_key = view->GetProperty(kFlexBehaviorKey)) { + // Respect flex provided via the `kBoxLayoutFlexKey`. + if (auto* flex_behavior_key = view->GetProperty(kBoxLayoutFlexKey)) { return flex_behavior_key->weight(); } // Fall back to default. @@ -395,9 +416,10 @@ } int BoxLayout::GetMinimumSizeForView(const View* view) const { - auto it = flex_map_.find(view); - if (it == flex_map_.end() || !it->second.use_min_size) + auto* flex_behavior_key = view->GetProperty(kBoxLayoutFlexKey); + if (!flex_behavior_key || !flex_behavior_key->use_min_size()) { return 0; + } return (orientation_ == Orientation::kHorizontal) ? view->GetMinimumSize().width()
diff --git a/ui/views/layout/box_layout.h b/ui/views/layout/box_layout.h index dcdb9847..38a712d 100644 --- a/ui/views/layout/box_layout.h +++ b/ui/views/layout/box_layout.h
@@ -5,8 +5,6 @@ #ifndef UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ #define UI_VIEWS_LAYOUT_BOX_LAYOUT_H_ -#include <map> - #include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr_exclusion.h" #include "ui/gfx/geometry/insets.h" @@ -20,6 +18,25 @@ namespace views { +class VIEWS_EXPORT BoxLayoutFlexSpecification { + public: + BoxLayoutFlexSpecification(); + ~BoxLayoutFlexSpecification(); + + // Makes a copy of this specification with a different weight. + BoxLayoutFlexSpecification WithWeight(int weight) const; + + // Whether to use minimum values to make copies of this specification. + BoxLayoutFlexSpecification UseMinSize(bool use_min_size) const; + + int weight() const { return weight_; } + bool use_min_size() const { return use_min_size_; } + + private: + int weight_ = 1; + bool use_min_size_ = false; +}; + // A Layout manager that arranges child views vertically or horizontally in a // side-by-side fashion with spacing around and between the child views. The // child views are always sized according to their preferred size. If the @@ -219,13 +236,6 @@ gfx::Insets margins_; }; - struct Flex { - int flex_weight; - bool use_min_size; - }; - - using FlexMap = std::map<const View*, Flex>; - // Returns the flex for the specified |view|. int GetFlexForView(const View* view) const; @@ -343,9 +353,6 @@ // kStretch by default. CrossAxisAlignment cross_axis_alignment_ = CrossAxisAlignment::kStretch; - // A map of views to their flex weights. - FlexMap flex_map_; - // The flex weight for views if none is set. Defaults to 0. int default_flex_ = 0;
diff --git a/ui/views/layout/box_layout_unittest.cc b/ui/views/layout/box_layout_unittest.cc index a64ad8f..6c97d70 100644 --- a/ui/views/layout/box_layout_unittest.cc +++ b/ui/views/layout/box_layout_unittest.cc
@@ -726,17 +726,18 @@ EXPECT_EQ(gfx::Rect(0, 0, 20, 50).ToString(), v1->bounds().ToString()); EXPECT_EQ(gfx::Rect(0, 50, 20, 50).ToString(), v2->bounds().ToString()); - // Set `kFlexBehaviorKey` so that the first view fills 2/3 of the available - // space. Flex set via `kFlexBehaviorKey` takes higher precedence than default - // flex. - v1->SetProperty(kFlexBehaviorKey, FlexSpecification().WithWeight(2)); + // Set `kBoxLayoutFlexKey` so that the first view fills 2/3 of the available + // space. Flex set via `kBoxLayoutFlexKey` takes higher precedence than + // default flex. + v1->SetProperty(kBoxLayoutFlexKey, + BoxLayoutFlexSpecification().WithWeight(2)); HandleHostLayoutManagerChanges(); EXPECT_EQ(gfx::Rect(0, 0, 20, 60).ToString(), v1->bounds().ToString()); EXPECT_EQ(gfx::Rect(0, 60, 20, 40).ToString(), v2->bounds().ToString()); // Set flex so that the first view fills 3/4 of the available space. Flex for // a view set on the `layout` takes higher precedence than flex set via - // `kFlexBehaviorKey`. + // `kBoxLayoutFlexKey`. layout->SetFlexForView(v1, 3); HandleHostLayoutManagerChanges(); EXPECT_EQ(gfx::Rect(0, 0, 20, 65).ToString(), v1->bounds().ToString());
diff --git a/ui/views/view_class_properties.cc b/ui/views/view_class_properties.cc index 65639cc..134c3c7c 100644 --- a/ui/views/view_class_properties.cc +++ b/ui/views/view_class_properties.cc
@@ -8,6 +8,7 @@ #include "ui/gfx/geometry/insets.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/controls/highlight_path_generator.h" +#include "ui/views/layout/box_layout.h" #include "ui/views/layout/flex_layout_types.h" #if !defined(USE_AURA) @@ -21,6 +22,8 @@ DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::DialogDelegate*) DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, + views::BoxLayoutFlexSpecification*) +DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::HighlightPathGenerator*) DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::FlexSpecification*) DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(VIEWS_EXPORT, views::LayoutAlignment*) @@ -34,6 +37,9 @@ DEFINE_UI_CLASS_PROPERTY_KEY(views::DialogDelegate*, kAnchoredDialogKey, nullptr) +DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(BoxLayoutFlexSpecification, + kBoxLayoutFlexKey, + nullptr) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(views::HighlightPathGenerator, kHighlightPathGeneratorKey, nullptr)
diff --git a/ui/views/view_class_properties.h b/ui/views/view_class_properties.h index 986396a..fc6daa3 100644 --- a/ui/views/view_class_properties.h +++ b/ui/views/view_class_properties.h
@@ -21,6 +21,7 @@ class DialogDelegate; class FlexSpecification; class HighlightPathGenerator; +class BoxLayoutFlexSpecification; // The hit test component (e.g. HTCLIENT) for a View in a window frame. Defaults // to HTNOWHERE. @@ -48,13 +49,18 @@ VIEWS_EXPORT extern const ui::ClassProperty<DialogDelegate*>* const kAnchoredDialogKey; +// A property to store how a view should flex when placed in a layout. +// Only supported by BoxLayout. +VIEWS_EXPORT extern const ui::ClassProperty<BoxLayoutFlexSpecification*>* const + kBoxLayoutFlexKey; + // A property to store a highlight-path generator. This generator is used to // generate a highlight path for focus rings or ink-drop effects. VIEWS_EXPORT extern const ui::ClassProperty<HighlightPathGenerator*>* const kHighlightPathGeneratorKey; // A property to store how a view should flex when placed in a layout. -// Currently only fully supported by FlexLayout. BoxLayout supports weight. +// Currently only supported by FlexLayout. VIEWS_EXPORT extern const ui::ClassProperty<FlexSpecification*>* const kFlexBehaviorKey;
diff --git a/v8 b/v8 index 3970923..fccd7ef 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 3970923e265f3f8a2420cefd55ee1bdabe44e6a4 +Subproject commit fccd7efb786d611b5d6d2903e6900c562aaa7dd4